staging: comedi: addi_apci_1564: separate from addi_common.c
authorChase Southwood <chase.southwood@yahoo.com>
Thu, 24 Apr 2014 07:19:01 +0000 (02:19 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 25 Apr 2014 22:04:30 +0000 (15:04 -0700)
Using the addi-data "common" code in addi_apci_1564 introduces a lot of
bloat.  By separating this driver off from addi_common.c, a lot of the
common code can be stripped out.  This patch copies the code over from
addi_common.c, and removes the #include of the file.  The auto_attach
function from the common code replaces the one that was previously in this
driver, though renamed to that it stays within the namespace associated
with this driver, and the detach function has been renamed for this reason
as well.

Signed-off-by: Chase Southwood <chase.southwood@yahoo.com>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/addi_apci_1564.c

index 11aa0bd5d7b1bdd5648d52f9b9646eafb19ccdac..792916d230e122386c19fe97abccb7cbbcdeac6d 100644 (file)
@@ -9,7 +9,6 @@
 
 #include "addi-data/addi_eeprom.c"
 #include "addi-data/hwdrv_apci1564.c"
-#include "addi-data/addi_common.c"
 
 static const struct addi_board apci1564_boardtypes[] = {
        {
@@ -34,19 +33,255 @@ static const struct addi_board apci1564_boardtypes[] = {
        },
 };
 
+static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev,
+                                    struct comedi_subdevice *s,
+                                    struct comedi_insn *insn,
+                                    unsigned int *data)
+{
+       const struct addi_board *this_board = comedi_board(dev);
+       struct addi_private *devpriv = dev->private;
+       unsigned short w_Address = CR_CHAN(insn->chanspec);
+       unsigned short w_Data;
+
+       w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc,
+               this_board->pc_EepromChip, 2 * w_Address);
+       data[0] = w_Data;
+
+       return insn->n;
+}
+
+static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
+{
+       struct comedi_device *dev = d;
+       const struct addi_board *this_board = comedi_board(dev);
+
+       this_board->interrupt(irq, d);
+       return IRQ_RETVAL(1);
+}
+
+static int i_ADDI_Reset(struct comedi_device *dev)
+{
+       const struct addi_board *this_board = comedi_board(dev);
+
+       this_board->reset(dev);
+       return 0;
+}
+
 static int apci1564_auto_attach(struct comedi_device *dev,
-                               unsigned long context)
+                                     unsigned long context_unused)
+{
+       struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+       const struct addi_board *this_board = comedi_board(dev);
+       struct addi_private *devpriv;
+       struct comedi_subdevice *s;
+       int ret, n_subdevices;
+       unsigned int dw_Dummy;
+
+       dev->board_name = this_board->pc_DriverName;
+
+       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+       if (!devpriv)
+               return -ENOMEM;
+
+       ret = comedi_pci_enable(dev);
+       if (ret)
+               return ret;
+
+       if (this_board->i_IorangeBase1)
+               dev->iobase = pci_resource_start(pcidev, 1);
+       else
+               dev->iobase = pci_resource_start(pcidev, 0);
+
+       devpriv->iobase = dev->iobase;
+       devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
+       devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2);
+       devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3);
+
+       /* Initialize parameters that can be overridden in EEPROM */
+       devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel;
+       devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel;
+       devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata;
+       devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata;
+       devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel;
+       devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel;
+       devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata;
+       devpriv->s_EeParameters.i_Timer = this_board->i_Timer;
+       devpriv->s_EeParameters.ui_MinAcquisitiontimeNs =
+               this_board->ui_MinAcquisitiontimeNs;
+       devpriv->s_EeParameters.ui_MinDelaytimeNs =
+               this_board->ui_MinDelaytimeNs;
+
+       /* ## */
+
+       if (pcidev->irq > 0) {
+               ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
+                                 dev->board_name, dev);
+               if (ret == 0)
+                       dev->irq = pcidev->irq;
+       }
+
+       /*  Read eepeom and fill addi_board Structure */
+
+       if (this_board->i_PCIEeprom) {
+               if (!(strcmp(this_board->pc_EepromChip, "S5920"))) {
+                       /*  Set 3 wait stait */
+                       if (!(strcmp(dev->board_name, "apci035")))
+                               outl(0x80808082, devpriv->i_IobaseAmcc + 0x60);
+                       else
+                               outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
+
+                       /*  Enable the interrupt for the controller */
+                       dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
+                       outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
+               }
+               addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0));
+       }
+
+       n_subdevices = 7;
+       ret = comedi_alloc_subdevices(dev, n_subdevices);
+       if (ret)
+               return ret;
+
+       /*  Allocate and Initialise AI Subdevice Structures */
+       s = &dev->subdevices[0];
+       if ((devpriv->s_EeParameters.i_NbrAiChannel)
+               || (this_board->i_NbrAiChannelDiff)) {
+               dev->read_subdev = s;
+               s->type = COMEDI_SUBD_AI;
+               s->subdev_flags =
+                       SDF_READABLE | SDF_COMMON | SDF_GROUND
+                       | SDF_DIFF;
+               if (devpriv->s_EeParameters.i_NbrAiChannel) {
+                       s->n_chan =
+                               devpriv->s_EeParameters.i_NbrAiChannel;
+                       devpriv->b_SingelDiff = 0;
+               } else {
+                       s->n_chan = this_board->i_NbrAiChannelDiff;
+                       devpriv->b_SingelDiff = 1;
+               }
+               s->maxdata = devpriv->s_EeParameters.i_AiMaxdata;
+               s->len_chanlist = this_board->i_AiChannelList;
+               s->range_table = this_board->pr_AiRangelist;
+
+               s->insn_config = this_board->ai_config;
+               s->insn_read = this_board->ai_read;
+               s->insn_write = this_board->ai_write;
+               s->insn_bits = this_board->ai_bits;
+               s->do_cmdtest = this_board->ai_cmdtest;
+               s->do_cmd = this_board->ai_cmd;
+               s->cancel = this_board->ai_cancel;
+
+       } else {
+               s->type = COMEDI_SUBD_UNUSED;
+       }
+
+       /*  Allocate and Initialise AO Subdevice Structures */
+       s = &dev->subdevices[1];
+       if (devpriv->s_EeParameters.i_NbrAoChannel) {
+               s->type = COMEDI_SUBD_AO;
+               s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+               s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel;
+               s->maxdata = devpriv->s_EeParameters.i_AoMaxdata;
+               s->len_chanlist =
+                       devpriv->s_EeParameters.i_NbrAoChannel;
+               s->insn_write = this_board->ao_write;
+       } else {
+               s->type = COMEDI_SUBD_UNUSED;
+       }
+       /*  Allocate and Initialise DI Subdevice Structures */
+       s = &dev->subdevices[2];
+       if (devpriv->s_EeParameters.i_NbrDiChannel) {
+               s->type = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+               s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel;
+               s->maxdata = 1;
+               s->len_chanlist =
+                       devpriv->s_EeParameters.i_NbrDiChannel;
+               s->range_table = &range_digital;
+               s->insn_config = this_board->di_config;
+               s->insn_read = this_board->di_read;
+               s->insn_write = this_board->di_write;
+               s->insn_bits = this_board->di_bits;
+       } else {
+               s->type = COMEDI_SUBD_UNUSED;
+       }
+       /*  Allocate and Initialise DO Subdevice Structures */
+       s = &dev->subdevices[3];
+       if (devpriv->s_EeParameters.i_NbrDoChannel) {
+               s->type = COMEDI_SUBD_DO;
+               s->subdev_flags =
+                       SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+               s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel;
+               s->maxdata = devpriv->s_EeParameters.i_DoMaxdata;
+               s->len_chanlist =
+                       devpriv->s_EeParameters.i_NbrDoChannel;
+               s->range_table = &range_digital;
+
+               /* insn_config - for digital output memory */
+               s->insn_config = this_board->do_config;
+               s->insn_write = this_board->do_write;
+               s->insn_bits = this_board->do_bits;
+               s->insn_read = this_board->do_read;
+       } else {
+               s->type = COMEDI_SUBD_UNUSED;
+       }
+
+       /*  Allocate and Initialise Timer Subdevice Structures */
+       s = &dev->subdevices[4];
+       if (devpriv->s_EeParameters.i_Timer) {
+               s->type = COMEDI_SUBD_TIMER;
+               s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+               s->n_chan = 1;
+               s->maxdata = 0;
+               s->len_chanlist = 1;
+               s->range_table = &range_digital;
+
+               s->insn_write = this_board->timer_write;
+               s->insn_read = this_board->timer_read;
+               s->insn_config = this_board->timer_config;
+               s->insn_bits = this_board->timer_bits;
+       } else {
+               s->type = COMEDI_SUBD_UNUSED;
+       }
+
+       /*  Allocate and Initialise TTL */
+       s = &dev->subdevices[5];
+       s->type = COMEDI_SUBD_UNUSED;
+
+       /* EEPROM */
+       s = &dev->subdevices[6];
+       if (this_board->i_PCIEeprom) {
+               s->type = COMEDI_SUBD_MEMORY;
+               s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+               s->n_chan = 256;
+               s->maxdata = 0xffff;
+               s->insn_read = i_ADDIDATA_InsnReadEeprom;
+       } else {
+               s->type = COMEDI_SUBD_UNUSED;
+       }
+
+       i_ADDI_Reset(dev);
+       return 0;
+}
+
+static void apci1564_detach(struct comedi_device *dev)
 {
-       dev->board_ptr = &apci1564_boardtypes[0];
+       struct addi_private *devpriv = dev->private;
 
-       return addi_auto_attach(dev, context);
+       if (devpriv) {
+               if (dev->iobase)
+                       i_ADDI_Reset(dev);
+               if (dev->irq)
+                       free_irq(dev->irq, dev);
+       }
+       comedi_pci_disable(dev);
 }
 
 static struct comedi_driver apci1564_driver = {
        .driver_name    = "addi_apci_1564",
        .module         = THIS_MODULE,
        .auto_attach    = apci1564_auto_attach,
-       .detach         = i_ADDI_Detach,
+       .detach         = apci1564_detach,
 };
 
 static int apci1564_pci_probe(struct pci_dev *dev,