diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 7d009463b92d3d17cba320a3fbf7be50acdf99fd..104594bca25462fbfd97aa34f7b50d31bd95cf35 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -106,64 +106,6 @@ struct s626_private { unsigned int ao_readback[S626_DAC_CHANNELS]; }; -struct dio_private { - uint16_t RDDIn; - uint16_t WRDOut; - uint16_t RDEdgSel; - uint16_t WREdgSel; - uint16_t RDCapSel; - uint16_t WRCapSel; - uint16_t RDCapFlg; - uint16_t RDIntSel; - uint16_t WRIntSel; -}; - -static struct dio_private dio_private_A = { - .RDDIn = LP_RDDINA, - .WRDOut = LP_WRDOUTA, - .RDEdgSel = LP_RDEDGSELA, - .WREdgSel = LP_WREDGSELA, - .RDCapSel = LP_RDCAPSELA, - .WRCapSel = LP_WRCAPSELA, - .RDCapFlg = LP_RDCAPFLGA, - .RDIntSel = LP_RDINTSELA, - .WRIntSel = LP_WRINTSELA, -}; - -static struct dio_private dio_private_B = { - .RDDIn = LP_RDDINB, - .WRDOut = LP_WRDOUTB, - .RDEdgSel = LP_RDEDGSELB, - .WREdgSel = LP_WREDGSELB, - .RDCapSel = LP_RDCAPSELB, - .WRCapSel = LP_WRCAPSELB, - .RDCapFlg = LP_RDCAPFLGB, - .RDIntSel = LP_RDINTSELB, - .WRIntSel = LP_WRINTSELB, -}; - -static struct dio_private dio_private_C = { - .RDDIn = LP_RDDINC, - .WRDOut = LP_WRDOUTC, - .RDEdgSel = LP_RDEDGSELC, - .WREdgSel = LP_WREDGSELC, - .RDCapSel = LP_RDCAPSELC, - .WRCapSel = LP_WRCAPSELC, - .RDCapFlg = LP_RDCAPFLGC, - .RDIntSel = LP_RDINTSELC, - .WRIntSel = LP_WRINTSELC, -}; - -/* to group dio devices (48 bits mask and data are not allowed ???) -static struct dio_private *dio_private_word[]={ - &dio_private_A, - &dio_private_B, - &dio_private_C, -}; -*/ - -#define diopriv ((struct dio_private *)s->private) - /* COUNTER OBJECT ------------------------------------------------ */ struct enc_private { /* Pointers to functions that differ for A and B counters: */ @@ -670,43 +612,24 @@ static unsigned int s626_ai_reg_to_uint(int data) static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan) { - unsigned int group; - unsigned int bitmask; + unsigned int group = chan / 16; + unsigned int mask = 1 << (chan - (16 * group)); unsigned int status; - /* select dio bank */ - group = chan / 16; - bitmask = 1 << (chan - (16 * group)); - /* set channel to capture positive edge */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDEdgSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WREdgSel, - bitmask | status); + status = DEBIread(dev, LP_RDEDGSEL(group)); + DEBIwrite(dev, LP_WREDGSEL(group), mask | status); /* enable interrupt on selected channel */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDIntSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRIntSel, - bitmask | status); + status = DEBIread(dev, LP_RDINTSEL(group)); + DEBIwrite(dev, LP_WRINTSEL(group), mask | status); /* enable edge capture write command */ DEBIwrite(dev, LP_MISC1, MISC1_EDCAP); /* enable edge capture on selected channel */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDCapSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, - bitmask | status); + status = DEBIread(dev, LP_RDCAPSEL(group)); + DEBIwrite(dev, LP_WRCAPSEL(group), mask | status); return 0; } @@ -718,9 +641,7 @@ static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group, DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); /* enable edge capture on selected channel */ - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, mask); + DEBIwrite(dev, LP_WRCAPSEL(group), mask); return 0; } @@ -732,13 +653,9 @@ static int s626_dio_clear_irq(struct comedi_device *dev) /* disable edge capture write command */ DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); - for (group = 0; group < S626_DIO_BANKS; group++) { - /* clear pending events and interrupt */ - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, - 0xffff); - } + /* clear all dio pending events and interrupt */ + for (group = 0; group < S626_DIO_BANKS; group++) + DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff); return 0; } @@ -834,12 +751,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d) for (group = 0; group < S626_DIO_BANKS; group++) { irqbit = 0; /* read interrupt type */ - irqbit = DEBIread(dev, - ((struct dio_private *)(dev-> - subdevices + - 2 + - group)-> - private)->RDCapFlg); + irqbit = DEBIread(dev, LP_RDCAPFLG(group)); /* check if interrupt is generated from dio channels */ if (irqbit) { @@ -1679,22 +1591,20 @@ static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static void s626_dio_init(struct comedi_device *dev) { uint16_t group; - struct comedi_subdevice *s; /* Prepare to treat writes to WRCapSel as capture disables. */ DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); /* For each group of sixteen channels ... */ for (group = 0; group < S626_DIO_BANKS; group++) { - s = dev->subdevices + 2 + group; - DEBIwrite(dev, diopriv->WRIntSel, 0); /* Disable all interrupts. */ - DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF); /* Disable all event */ - /* captures. */ - DEBIwrite(dev, diopriv->WREdgSel, 0); /* Init all DIOs to */ - /* default edge */ - /* polarity. */ - DEBIwrite(dev, diopriv->WRDOut, 0); /* Program all outputs */ - /* to inactive state. */ + /* Disable all interrupts */ + DEBIwrite(dev, LP_WRINTSEL(group), 0); + /* Disable all event captures */ + DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff); + /* Init all DIOs to default edge polarity */ + DEBIwrite(dev, LP_WREDGSEL(group), 0); + /* Program all outputs to inactive state */ + DEBIwrite(dev, LP_WRDOUT(group), 0); } } @@ -1708,6 +1618,8 @@ static int s626_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + unsigned long group = (unsigned long)s->private; + /* * The insn data consists of a mask in data[0] and the new data in * data[1]. The mask defines which bits we are concerning about. @@ -1724,9 +1636,9 @@ static int s626_dio_insn_bits(struct comedi_device *dev, /* Write out the new digital output lines */ - DEBIwrite(dev, diopriv->WRDOut, s->state); + DEBIwrite(dev, LP_WRDOUT(group), s->state); } - data[1] = DEBIread(dev, diopriv->RDDIn); + data[1] = DEBIread(dev, LP_RDDIN(group)); return insn->n; } @@ -1735,6 +1647,7 @@ static int s626_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + unsigned long group = (unsigned long)s->private; switch (data[0]) { case INSN_CONFIG_DIO_QUERY: @@ -1754,7 +1667,7 @@ static int s626_dio_insn_config(struct comedi_device *dev, return -EINVAL; break; } - DEBIwrite(dev, diopriv->WRDOut, s->io_bits); + DEBIwrite(dev, LP_WRDOUT(group), s->io_bits); return 1; } @@ -2739,7 +2652,7 @@ static int s626_auto_attach(struct comedi_device *dev, s->n_chan = 16; s->maxdata = 1; s->io_bits = 0xffff; - s->private = &dio_private_A; + s->private = (void *)0; /* DIO group 0 */ s->range_table = &range_digital; s->insn_config = s626_dio_insn_config; s->insn_bits = s626_dio_insn_bits; @@ -2751,7 +2664,7 @@ static int s626_auto_attach(struct comedi_device *dev, s->n_chan = 16; s->maxdata = 1; s->io_bits = 0xffff; - s->private = &dio_private_B; + s->private = (void *)1; /* DIO group 1 */ s->range_table = &range_digital; s->insn_config = s626_dio_insn_config; s->insn_bits = s626_dio_insn_bits; @@ -2763,7 +2676,7 @@ static int s626_auto_attach(struct comedi_device *dev, s->n_chan = 16; s->maxdata = 1; s->io_bits = 0xffff; - s->private = &dio_private_C; + s->private = (void *)2; /* DIO group 2 */ s->range_table = &range_digital; s->insn_config = s626_dio_insn_config; s->insn_bits = s626_dio_insn_bits; diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h index ff4b3a5e4e5f2096d1a4c889f591e77f9a73b440..938dcd9f86f6a6e76d6e68b31764ad91e59a414f 100644 --- a/drivers/staging/comedi/drivers/s626.h +++ b/drivers/staging/comedi/drivers/s626.h @@ -267,36 +267,17 @@ #define LP_DACPOL 0x0082 /* Write DAC polarity. */ #define LP_GSEL 0x0084 /* Write ADC gain. */ #define LP_ISEL 0x0086 /* Write ADC channel select. */ -/* Digital I/O (write only): */ -#define LP_WRINTSELA 0x0042 /* Write A interrupt enable. */ -#define LP_WREDGSELA 0x0044 /* Write A edge selection. */ -#define LP_WRCAPSELA 0x0046 /* Write A capture enable. */ -#define LP_WRDOUTA 0x0048 /* Write A digital output. */ -#define LP_WRINTSELB 0x0052 /* Write B interrupt enable. */ -#define LP_WREDGSELB 0x0054 /* Write B edge selection. */ -#define LP_WRCAPSELB 0x0056 /* Write B capture enable. */ -#define LP_WRDOUTB 0x0058 /* Write B digital output. */ -#define LP_WRINTSELC 0x0062 /* Write C interrupt enable. */ -#define LP_WREDGSELC 0x0064 /* Write C edge selection. */ -#define LP_WRCAPSELC 0x0066 /* Write C capture enable. */ -#define LP_WRDOUTC 0x0068 /* Write C digital output. */ - -/* Digital I/O (read only): */ -#define LP_RDDINA 0x0040 /* Read digital input. */ -#define LP_RDCAPFLGA 0x0048 /* Read edges captured. */ -#define LP_RDINTSELA 0x004A /* Read interrupt enable register. */ -#define LP_RDEDGSELA 0x004C /* Read edge selection register. */ -#define LP_RDCAPSELA 0x004E /* Read capture enable register. */ -#define LP_RDDINB 0x0050 /* Read digital input. */ -#define LP_RDCAPFLGB 0x0058 /* Read edges captured. */ -#define LP_RDINTSELB 0x005A /* Read interrupt enable register. */ -#define LP_RDEDGSELB 0x005C /* Read edge selection register. */ -#define LP_RDCAPSELB 0x005E /* Read capture enable register. */ -#define LP_RDDINC 0x0060 /* Read digital input. */ -#define LP_RDCAPFLGC 0x0068 /* Read edges captured. */ -#define LP_RDINTSELC 0x006A /* Read interrupt enable register. */ -#define LP_RDEDGSELC 0x006C /* Read edge selection register. */ -#define LP_RDCAPSELC 0x006E /* Read capture enable register. */ + +/* Digital I/O registers */ +#define LP_RDDIN(x) (0x0040 + (x) * 0x10) /* R: digital input */ +#define LP_WRINTSEL(x) (0x0042 + (x) * 0x10) /* W: int enable */ +#define LP_WREDGSEL(x) (0x0044 + (x) * 0x10) /* W: edge selection */ +#define LP_WRCAPSEL(x) (0x0046 + (x) * 0x10) /* W: capture enable */ +#define LP_RDCAPFLG(x) (0x0048 + (x) * 0x10) /* R: edges captured */ +#define LP_WRDOUT(x) (0x0048 + (x) * 0x10) /* W: digital output */ +#define LP_RDINTSEL(x) (0x004a + (x) * 0x10) /* R: int enable */ +#define LP_RDEDGSEL(x) (0x004c + (x) * 0x10) /* R: edge selection */ +#define LP_RDCAPSEL(x) (0x004e + (x) * 0x10) /* R: capture enable */ /* Counter Registers (read/write): */ #define LP_CR0A 0x0000 /* 0A setup register. */