]>
Commit | Line | Data |
---|---|---|
3d41c443 HS |
1 | #include "../comedidev.h" |
2 | #include "comedi_fc.h" | |
3 | ||
4 | #include "addi-data/addi_common.h" | |
3d41c443 | 5 | |
bf6a1578 | 6 | #include "addi-data/hwdrv_apci2032.c" |
317285d7 | 7 | |
25adf2cc HS |
8 | static irqreturn_t v_ADDI_Interrupt(int irq, void *d) |
9 | { | |
c0c3c7df | 10 | v_APCI2032_Interrupt(irq, d); |
25adf2cc HS |
11 | return IRQ_RETVAL(1); |
12 | } | |
13 | ||
791c9792 | 14 | static int apci2032_reset(struct comedi_device *dev) |
25adf2cc | 15 | { |
791c9792 HS |
16 | struct addi_private *devpriv = dev->private; |
17 | ||
18 | devpriv->b_DigitalOutputRegister = 0; | |
19 | ui_Type = 0; | |
f5f760e1 HS |
20 | outl(0x0, dev->iobase + APCI2032_DIGITAL_OP); |
21 | outl(0x0, dev->iobase + APCI2032_DIGITAL_OP_INTERRUPT); | |
22 | outl(0x0, dev->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); | |
23 | outl(0x0, dev->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_RELOAD_VALUE); | |
25adf2cc | 24 | |
25adf2cc HS |
25 | return 0; |
26 | } | |
27 | ||
25adf2cc HS |
28 | static int apci2032_auto_attach(struct comedi_device *dev, |
29 | unsigned long context_unused) | |
30 | { | |
31 | struct pci_dev *pcidev = comedi_to_pci_dev(dev); | |
25adf2cc HS |
32 | struct addi_private *devpriv; |
33 | struct comedi_subdevice *s; | |
0c33bdd0 | 34 | int ret; |
25adf2cc | 35 | |
c0c3c7df | 36 | dev->board_name = dev->driver->driver_name; |
25adf2cc HS |
37 | |
38 | devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); | |
39 | if (!devpriv) | |
40 | return -ENOMEM; | |
41 | dev->private = devpriv; | |
42 | ||
43 | ret = comedi_pci_enable(pcidev, dev->board_name); | |
44 | if (ret) | |
45 | return ret; | |
70ff4065 | 46 | dev->iobase = pci_resource_start(pcidev, 1); |
25adf2cc | 47 | |
25adf2cc HS |
48 | if (pcidev->irq > 0) { |
49 | ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, | |
50 | dev->board_name, dev); | |
51 | if (ret == 0) | |
52 | dev->irq = pcidev->irq; | |
53 | } | |
54 | ||
0c33bdd0 | 55 | ret = comedi_alloc_subdevices(dev, 2); |
25adf2cc HS |
56 | if (ret) |
57 | return ret; | |
58 | ||
0c33bdd0 | 59 | /* Initialize the digital output subdevice */ |
25adf2cc | 60 | s = &dev->subdevices[0]; |
c0c3c7df | 61 | s->type = COMEDI_SUBD_DO; |
61034e00 | 62 | s->subdev_flags = SDF_WRITEABLE; |
c0c3c7df HS |
63 | s->n_chan = 32; |
64 | s->maxdata = 1; | |
65 | s->range_table = &range_digital; | |
66 | s->insn_config = i_APCI2032_ConfigDigitalOutput; | |
67 | s->insn_bits = apci2032_do_insn_bits; | |
68 | s->insn_read = i_APCI2032_ReadInterruptStatus; | |
25adf2cc | 69 | |
0c33bdd0 HS |
70 | /* Initialize the watchdog subdevice */ |
71 | s = &dev->subdevices[1]; | |
c0c3c7df | 72 | s->type = COMEDI_SUBD_TIMER; |
61034e00 | 73 | s->subdev_flags = SDF_WRITEABLE; |
c0c3c7df HS |
74 | s->n_chan = 1; |
75 | s->maxdata = 0; | |
76 | s->len_chanlist = 1; | |
77 | s->range_table = &range_digital; | |
78 | s->insn_write = i_APCI2032_StartStopWriteWatchdog; | |
79 | s->insn_read = i_APCI2032_ReadWatchdog; | |
80 | s->insn_config = i_APCI2032_ConfigWatchdog; | |
25adf2cc | 81 | |
791c9792 | 82 | apci2032_reset(dev); |
25adf2cc HS |
83 | return 0; |
84 | } | |
85 | ||
86 | static void apci2032_detach(struct comedi_device *dev) | |
87 | { | |
88 | struct pci_dev *pcidev = comedi_to_pci_dev(dev); | |
89 | struct addi_private *devpriv = dev->private; | |
90 | ||
91 | if (devpriv) { | |
92 | if (dev->iobase) | |
791c9792 | 93 | apci2032_reset(dev); |
25adf2cc HS |
94 | if (dev->irq) |
95 | free_irq(dev->irq, dev); | |
25adf2cc HS |
96 | } |
97 | if (pcidev) { | |
98 | if (dev->iobase) | |
99 | comedi_pci_disable(pcidev); | |
100 | } | |
101 | } | |
102 | ||
20a22b70 HS |
103 | static struct comedi_driver apci2032_driver = { |
104 | .driver_name = "addi_apci_2032", | |
105 | .module = THIS_MODULE, | |
25adf2cc HS |
106 | .auto_attach = apci2032_auto_attach, |
107 | .detach = apci2032_detach, | |
20a22b70 HS |
108 | }; |
109 | ||
a690b7e5 | 110 | static int apci2032_pci_probe(struct pci_dev *dev, |
20a22b70 HS |
111 | const struct pci_device_id *ent) |
112 | { | |
113 | return comedi_pci_auto_config(dev, &apci2032_driver); | |
114 | } | |
115 | ||
53b80019 | 116 | static void apci2032_pci_remove(struct pci_dev *dev) |
20a22b70 HS |
117 | { |
118 | comedi_pci_auto_unconfig(dev); | |
119 | } | |
120 | ||
121 | static DEFINE_PCI_DEVICE_TABLE(apci2032_pci_table) = { | |
317285d7 HS |
122 | { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004) }, |
123 | { 0 } | |
124 | }; | |
20a22b70 | 125 | MODULE_DEVICE_TABLE(pci, apci2032_pci_table); |
317285d7 | 126 | |
20a22b70 HS |
127 | static struct pci_driver apci2032_pci_driver = { |
128 | .name = "addi_apci_2032", | |
129 | .id_table = apci2032_pci_table, | |
130 | .probe = apci2032_pci_probe, | |
a471eace | 131 | .remove = apci2032_pci_remove, |
20a22b70 HS |
132 | }; |
133 | module_comedi_pci_driver(apci2032_driver, apci2032_pci_driver); | |
90f703d3 AT |
134 | |
135 | MODULE_AUTHOR("Comedi http://www.comedi.org"); | |
136 | MODULE_DESCRIPTION("Comedi low-level driver"); | |
137 | MODULE_LICENSE("GPL"); |