Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/drivers/staging/comedi/drivers/addi_apci_1564.c

  1 #include <linux/module.h>
  2 #include <linux/pci.h>
  3 
  4 #include "../comedidev.h"
  5 #include "comedi_fc.h"
  6 
  7 #include "addi-data/addi_common.h"
  8 
  9 #include "addi-data/hwdrv_apci1564.c"
 10 
 11 static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
 12 {
 13         apci1564_interrupt(irq, d);
 14         return IRQ_RETVAL(1);
 15 }
 16 
 17 static int apci1564_di_insn_bits(struct comedi_device *dev,
 18                                  struct comedi_subdevice *s,
 19                                  struct comedi_insn *insn,
 20                                  unsigned int *data)
 21 {
 22         struct addi_private *devpriv = dev->private;
 23 
 24         data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_DI_REG);
 25 
 26         return insn->n;
 27 }
 28 
 29 static int apci1564_do_insn_bits(struct comedi_device *dev,
 30                                  struct comedi_subdevice *s,
 31                                  struct comedi_insn *insn,
 32                                  unsigned int *data)
 33 {
 34         struct addi_private *devpriv = dev->private;
 35 
 36         s->state = inl(devpriv->i_IobaseAmcc + APCI1564_DO_REG);
 37 
 38         if (comedi_dio_update_state(s, data))
 39                 outl(s->state, devpriv->i_IobaseAmcc + APCI1564_DO_REG);
 40 
 41         data[1] = s->state;
 42 
 43         return insn->n;
 44 }
 45 
 46 static int apci1564_reset(struct comedi_device *dev)
 47 {
 48         struct addi_private *devpriv = dev->private;
 49 
 50         ui_Type = 0;
 51 
 52         /* Disable the input interrupts and reset status register */
 53         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
 54         inl(devpriv->i_IobaseAmcc + APCI1564_DI_INT_STATUS_REG);
 55         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE1_REG);
 56         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE2_REG);
 57 
 58         /* Reset the output channels and disable interrupts */
 59         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_REG);
 60         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_INT_CTRL_REG);
 61 
 62         /* Reset the watchdog registers */
 63         addi_watchdog_reset(devpriv->i_IobaseAmcc + APCI1564_WDOG_REG);
 64 
 65         /* Reset the timer registers */
 66         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
 67         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_RELOAD_REG);
 68 
 69         /* Reset the counter registers */
 70         outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
 71         outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
 72         outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
 73         outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
 74 
 75         return 0;
 76 }
 77 
 78 static int apci1564_auto_attach(struct comedi_device *dev,
 79                                       unsigned long context_unused)
 80 {
 81         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 82         struct addi_private *devpriv;
 83         struct comedi_subdevice *s;
 84         int ret;
 85 
 86         dev->board_name = dev->driver->driver_name;
 87 
 88         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
 89         if (!devpriv)
 90                 return -ENOMEM;
 91 
 92         ret = comedi_pci_enable(dev);
 93         if (ret)
 94                 return ret;
 95 
 96         dev->iobase = pci_resource_start(pcidev, 1);
 97         devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
 98 
 99         apci1564_reset(dev);
100 
101         if (pcidev->irq > 0) {
102                 ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
103                                   dev->board_name, dev);
104                 if (ret == 0)
105                         dev->irq = pcidev->irq;
106         }
107 
108         ret = comedi_alloc_subdevices(dev, 3);
109         if (ret)
110                 return ret;
111 
112         /*  Allocate and Initialise DI Subdevice Structures */
113         s = &dev->subdevices[0];
114         s->type = COMEDI_SUBD_DI;
115         s->subdev_flags = SDF_READABLE;
116         s->n_chan = 32;
117         s->maxdata = 1;
118         s->len_chanlist = 32;
119         s->range_table = &range_digital;
120         s->insn_config = apci1564_di_config;
121         s->insn_bits = apci1564_di_insn_bits;
122 
123         /*  Allocate and Initialise DO Subdevice Structures */
124         s = &dev->subdevices[1];
125         s->type = COMEDI_SUBD_DO;
126         s->subdev_flags = SDF_WRITEABLE;
127         s->n_chan = 32;
128         s->maxdata = 0xffffffff;
129         s->len_chanlist = 32;
130         s->range_table = &range_digital;
131         s->insn_config = apci1564_do_config;
132         s->insn_bits = apci1564_do_insn_bits;
133         s->insn_read = apci1564_do_read;
134 
135         /*  Allocate and Initialise Timer Subdevice Structures */
136         s = &dev->subdevices[2];
137         s->type = COMEDI_SUBD_TIMER;
138         s->subdev_flags = SDF_WRITEABLE;
139         s->n_chan = 1;
140         s->maxdata = 0;
141         s->len_chanlist = 1;
142         s->range_table = &range_digital;
143         s->insn_write = apci1564_timer_write;
144         s->insn_read = apci1564_timer_read;
145         s->insn_config = apci1564_timer_config;
146 
147         return 0;
148 }
149 
150 static void apci1564_detach(struct comedi_device *dev)
151 {
152         struct addi_private *devpriv = dev->private;
153 
154         if (devpriv) {
155                 if (dev->iobase)
156                         apci1564_reset(dev);
157                 if (dev->irq)
158                         free_irq(dev->irq, dev);
159         }
160         comedi_pci_disable(dev);
161 }
162 
163 static struct comedi_driver apci1564_driver = {
164         .driver_name    = "addi_apci_1564",
165         .module         = THIS_MODULE,
166         .auto_attach    = apci1564_auto_attach,
167         .detach         = apci1564_detach,
168 };
169 
170 static int apci1564_pci_probe(struct pci_dev *dev,
171                               const struct pci_device_id *id)
172 {
173         return comedi_pci_auto_config(dev, &apci1564_driver, id->driver_data);
174 }
175 
176 static const struct pci_device_id apci1564_pci_table[] = {
177         { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006) },
178         { 0 }
179 };
180 MODULE_DEVICE_TABLE(pci, apci1564_pci_table);
181 
182 static struct pci_driver apci1564_pci_driver = {
183         .name           = "addi_apci_1564",
184         .id_table       = apci1564_pci_table,
185         .probe          = apci1564_pci_probe,
186         .remove         = comedi_pci_auto_unconfig,
187 };
188 module_comedi_pci_driver(apci1564_driver, apci1564_pci_driver);
189 
190 MODULE_AUTHOR("Comedi http://www.comedi.org");
191 MODULE_DESCRIPTION("ADDI-DATA APCI-1564, 32 channel DI / 32 channel DO boards");
192 MODULE_LICENSE("GPL");
193 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us