staging: comedi: addi_apci_1032: call v_APCI1032_Interrupt() directly
[firefly-linux-kernel-4.4.55.git] / drivers / staging / comedi / drivers / addi_apci_1032.c
1 #include "../comedidev.h"
2 #include "comedi_fc.h"
3 #include "amcc_s5933.h"
4
5 #include "addi-data/addi_common.h"
6
7 #include "addi-data/hwdrv_apci1032.c"
8
9 static const struct addi_board apci1032_boardtypes[] = {
10         {
11                 .pc_DriverName          = "apci1032",
12                 .i_VendorId             = PCI_VENDOR_ID_ADDIDATA,
13                 .i_DeviceId             = 0x1003,
14                 .i_PCIEeprom            = ADDIDATA_EEPROM,
15                 .pc_EepromChip          = ADDIDATA_93C76,
16                 .i_NbrDiChannel         = 32,
17         },
18 };
19
20 static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
21 {
22         v_APCI1032_Interrupt(irq, d);
23         return IRQ_RETVAL(1);
24 }
25
26 static const void *addi_find_boardinfo(struct comedi_device *dev,
27                                        struct pci_dev *pcidev)
28 {
29         const void *p = dev->driver->board_name;
30         const struct addi_board *this_board;
31         int i;
32
33         for (i = 0; i < dev->driver->num_names; i++) {
34                 this_board = p;
35                 if (this_board->i_VendorId == pcidev->vendor &&
36                     this_board->i_DeviceId == pcidev->device)
37                         return this_board;
38                 p += dev->driver->offset;
39         }
40         return NULL;
41 }
42
43 static int apci1032_attach_pci(struct comedi_device *dev,
44                                struct pci_dev *pcidev)
45 {
46         const struct addi_board *this_board;
47         struct addi_private *devpriv;
48         struct comedi_subdevice *s;
49         int ret, n_subdevices;
50
51         this_board = addi_find_boardinfo(dev, pcidev);
52         if (!this_board)
53                 return -ENODEV;
54         dev->board_ptr = this_board;
55         dev->board_name = this_board->pc_DriverName;
56
57         devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
58         if (!devpriv)
59                 return -ENOMEM;
60         dev->private = devpriv;
61
62         ret = comedi_pci_enable(pcidev, dev->board_name);
63         if (ret)
64                 return ret;
65
66         dev->iobase = pci_resource_start(pcidev, 2);
67
68         if (pcidev->irq > 0) {
69                 ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
70                                   dev->board_name, dev);
71                 if (ret == 0)
72                         dev->irq = pcidev->irq;
73         }
74
75         n_subdevices = 7;
76         ret = comedi_alloc_subdevices(dev, n_subdevices);
77         if (ret)
78                 return ret;
79
80         /*  Allocate and Initialise AI Subdevice Structures */
81         s = &dev->subdevices[0];
82         s->type = COMEDI_SUBD_UNUSED;
83
84         /*  Allocate and Initialise AO Subdevice Structures */
85         s = &dev->subdevices[1];
86         s->type = COMEDI_SUBD_UNUSED;
87
88         /*  Allocate and Initialise DI Subdevice Structures */
89         s = &dev->subdevices[2];
90         s->type         = COMEDI_SUBD_DI;
91         s->subdev_flags = SDF_READABLE;
92         s->n_chan       = 32;
93         s->maxdata      = 1;
94         s->len_chanlist = 32;
95         s->range_table  = &range_digital;
96         s->insn_config  = i_APCI1032_ConfigDigitalInput;
97         s->insn_read    = i_APCI1032_Read1DigitalInput;
98         s->insn_bits    = i_APCI1032_ReadMoreDigitalInput;
99
100         /*  Allocate and Initialise DO Subdevice Structures */
101         s = &dev->subdevices[3];
102         s->type = COMEDI_SUBD_UNUSED;
103
104         /*  Allocate and Initialise Timer Subdevice Structures */
105         s = &dev->subdevices[4];
106         s->type = COMEDI_SUBD_UNUSED;
107
108         /*  Allocate and Initialise TTL */
109         s = &dev->subdevices[5];
110         s->type = COMEDI_SUBD_UNUSED;
111
112         /* EEPROM */
113         s = &dev->subdevices[6];
114         s->type = COMEDI_SUBD_UNUSED;
115
116         i_APCI1032_Reset(dev);
117         return 0;
118 }
119
120 static void apci1032_detach(struct comedi_device *dev)
121 {
122         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
123         struct addi_private *devpriv = dev->private;
124
125         if (devpriv) {
126                 if (dev->iobase)
127                         i_APCI1032_Reset(dev);
128                 if (dev->irq)
129                         free_irq(dev->irq, dev);
130         }
131         if (pcidev) {
132                 if (dev->iobase)
133                         comedi_pci_disable(pcidev);
134         }
135 }
136
137 static struct comedi_driver apci1032_driver = {
138         .driver_name    = "addi_apci_1032",
139         .module         = THIS_MODULE,
140         .attach_pci     = apci1032_attach_pci,
141         .detach         = apci1032_detach,
142         .num_names      = ARRAY_SIZE(apci1032_boardtypes),
143         .board_name     = &apci1032_boardtypes[0].pc_DriverName,
144         .offset         = sizeof(struct addi_board),
145 };
146
147 static int __devinit apci1032_pci_probe(struct pci_dev *dev,
148                                         const struct pci_device_id *ent)
149 {
150         return comedi_pci_auto_config(dev, &apci1032_driver);
151 }
152
153 static void __devexit apci1032_pci_remove(struct pci_dev *dev)
154 {
155         comedi_pci_auto_unconfig(dev);
156 }
157
158 static DEFINE_PCI_DEVICE_TABLE(apci1032_pci_table) = {
159         { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1003) },
160         { 0 }
161 };
162 MODULE_DEVICE_TABLE(pci, apci1032_pci_table);
163
164 static struct pci_driver apci1032_pci_driver = {
165         .name           = "addi_apci_1032",
166         .id_table       = apci1032_pci_table,
167         .probe          = apci1032_pci_probe,
168         .remove         = __devexit_p(apci1032_pci_remove),
169 };
170 module_comedi_pci_driver(apci1032_driver, apci1032_pci_driver);
171
172 MODULE_AUTHOR("Comedi http://www.comedi.org");
173 MODULE_DESCRIPTION("Comedi low-level driver");
174 MODULE_LICENSE("GPL");