aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/drivers/das1800.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/drivers/das1800.c')
-rw-r--r--drivers/staging/comedi/drivers/das1800.c86
1 files changed, 44 insertions, 42 deletions
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
index 53baf37cd21a..bfa42620a3f6 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -444,9 +444,9 @@ static const struct comedi_lrange range_ao_2 = {
static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
uint16_t sample)
{
- const struct das1800_board *thisboard = dev->board_ptr;
+ const struct das1800_board *board = dev->board_ptr;
- sample += 1 << (thisboard->resolution - 1);
+ sample += 1 << (board->resolution - 1);
return sample;
}
@@ -725,7 +725,7 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
- const struct das1800_board *thisboard = dev->board_ptr;
+ const struct das1800_board *board = dev->board_ptr;
int err = 0;
unsigned int arg;
@@ -765,7 +765,7 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
if (cmd->convert_src == TRIG_TIMER) {
err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- thisboard->ai_speed);
+ board->ai_speed);
}
err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
@@ -1048,7 +1048,7 @@ static int das1800_ai_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
- const struct das1800_board *thisboard = dev->board_ptr;
+ const struct das1800_board *board = dev->board_ptr;
int i, n;
int chan, range, aref, chan_range;
int timeout = 1000;
@@ -1098,7 +1098,7 @@ static int das1800_ai_rinsn(struct comedi_device *dev,
dpnt = inw(dev->iobase + DAS1800_FIFO);
/* shift data to offset binary for bipolar ranges */
if ((conv_flags & UB) == 0)
- dpnt += 1 << (thisboard->resolution - 1);
+ dpnt += 1 << (board->resolution - 1);
data[n] = dpnt;
}
exit:
@@ -1112,16 +1112,16 @@ static int das1800_ao_winsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
- const struct das1800_board *thisboard = dev->board_ptr;
+ const struct das1800_board *board = dev->board_ptr;
struct das1800_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
/* int range = CR_RANGE(insn->chanspec); */
- int update_chan = thisboard->ao_n_chan - 1;
+ int update_chan = board->ao_n_chan - 1;
unsigned short output;
unsigned long irq_flags;
/* card expects two's complement data */
- output = data[0] - (1 << (thisboard->resolution - 1));
+ output = data[0] - (1 << (board->resolution - 1));
/* if the write is to the 'update' channel, we need to remember its value */
if (chan == update_chan)
devpriv->ao_update_bits = output;
@@ -1216,72 +1216,76 @@ static void das1800_free_dma(struct comedi_device *dev)
comedi_isadma_free(devpriv->dma);
}
-static int das1800_probe(struct comedi_device *dev)
+static const struct das1800_board *das1800_probe(struct comedi_device *dev)
{
const struct das1800_board *board = dev->board_ptr;
- int index;
+ int index = board ? board - das1800_boards : -EINVAL;
int id;
- /* calc the offset to the boardinfo that was found by the core */
- index = board - das1800_boards;
-
- /* verify that the board id matches the boardinfo */
+ /*
+ * The dev->board_ptr will be set by comedi_device_attach() if the
+ * board name provided by the user matches a board->name in this
+ * driver. If so, this function sanity checks the id to verify that
+ * the board is correct.
+ *
+ * If the dev->board_ptr is not set, the user is trying to attach
+ * an unspecified board to this driver. In this case the id is used
+ * to 'probe' for the correct dev->board_ptr.
+ */
id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;
switch (id) {
case 0x3:
if (index == das1801st_da || index == das1802st_da ||
index == das1701st_da || index == das1702st_da)
- return index;
+ return board;
index = das1801st;
break;
case 0x4:
if (index == das1802hr_da || index == das1702hr_da)
- return index;
+ return board;
index = das1802hr;
break;
case 0x5:
if (index == das1801ao || index == das1802ao ||
index == das1701ao || index == das1702ao)
- return index;
+ return board;
index = das1801ao;
break;
case 0x6:
if (index == das1802hr || index == das1702hr)
- return index;
+ return board;
index = das1802hr;
break;
case 0x7:
if (index == das1801st || index == das1802st ||
index == das1701st || index == das1702st)
- return index;
+ return board;
index = das1801st;
break;
case 0x8:
if (index == das1801hc || index == das1802hc)
- return index;
+ return board;
index = das1801hc;
- break;
default:
dev_err(dev->class_dev,
"Board model: probe returned 0x%x (unknown, please report)\n",
id);
- break;
+ return NULL;
}
dev_err(dev->class_dev,
"Board model (probed, not recommended): %s series\n",
das1800_boards[index].name);
- return index;
+ return &das1800_boards[index];
}
static int das1800_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- const struct das1800_board *thisboard;
+ const struct das1800_board *board;
struct das1800_private *devpriv;
struct comedi_subdevice *s;
unsigned int irq = it->options[1];
- int board;
int ret;
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
@@ -1293,17 +1297,15 @@ static int das1800_attach(struct comedi_device *dev,
return ret;
board = das1800_probe(dev);
- if (board < 0) {
+ if (!board) {
dev_err(dev->class_dev, "unable to determine board type\n");
return -ENODEV;
}
-
- dev->board_ptr = das1800_boards + board;
- thisboard = dev->board_ptr;
- dev->board_name = thisboard->name;
+ dev->board_ptr = board;
+ dev->board_name = board->name;
/* if it is an 'ao' board with fancy analog out then we need extra io ports */
- if (thisboard->ao_ability == 2) {
+ if (board->ao_ability == 2) {
unsigned long iobase2 = dev->iobase + IOBASE2;
ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE);
@@ -1363,11 +1365,11 @@ static int das1800_attach(struct comedi_device *dev,
s = &dev->subdevices[0];
s->type = COMEDI_SUBD_AI;
s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
- if (thisboard->common)
+ if (board->common)
s->subdev_flags |= SDF_COMMON;
- s->n_chan = thisboard->qram_len;
- s->maxdata = (1 << thisboard->resolution) - 1;
- s->range_table = thisboard->range_ai;
+ s->n_chan = board->qram_len;
+ s->maxdata = (1 << board->resolution) - 1;
+ s->range_table = board->range_ai;
s->insn_read = das1800_ai_rinsn;
if (dev->irq) {
dev->read_subdev = s;
@@ -1381,11 +1383,11 @@ static int das1800_attach(struct comedi_device *dev,
/* analog out */
s = &dev->subdevices[1];
- if (thisboard->ao_ability == 1) {
+ if (board->ao_ability == 1) {
s->type = COMEDI_SUBD_AO;
s->subdev_flags = SDF_WRITABLE;
- s->n_chan = thisboard->ao_n_chan;
- s->maxdata = (1 << thisboard->resolution) - 1;
+ s->n_chan = board->ao_n_chan;
+ s->maxdata = (1 << board->resolution) - 1;
s->range_table = &range_bipolar10;
s->insn_write = das1800_ao_winsn;
} else {
@@ -1405,7 +1407,7 @@ static int das1800_attach(struct comedi_device *dev,
s = &dev->subdevices[3];
s->type = COMEDI_SUBD_DO;
s->subdev_flags = SDF_WRITABLE;
- s->n_chan = thisboard->do_n_chan;
+ s->n_chan = board->do_n_chan;
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = das1800_do_wbits;
@@ -1416,9 +1418,9 @@ static int das1800_attach(struct comedi_device *dev,
outb(0, dev->iobase + DAS1800_DIGITAL);
/* initialize analog out channels */
- if (thisboard->ao_ability == 1) {
+ if (board->ao_ability == 1) {
/* select 'update' dac channel for baseAddress + 0x0 */
- outb(DAC(thisboard->ao_n_chan - 1),
+ outb(DAC(board->ao_n_chan - 1),
dev->iobase + DAS1800_SELECT);
outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
}