staging: comedi: ni_6527: remove DRIVER_NAME define
[firefly-linux-kernel-4.4.55.git] / drivers / staging / comedi / drivers / ni_6527.c
1 /*
2     comedi/drivers/ni_6527.c
3     driver for National Instruments PCI-6527
4
5     COMEDI - Linux Control and Measurement Device Interface
6     Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 */
18 /*
19 Driver: ni_6527
20 Description: National Instruments 6527
21 Author: ds
22 Status: works
23 Devices: [National Instruments] PCI-6527 (ni6527), PXI-6527
24 Updated: Sat, 25 Jan 2003 13:24:40 -0800
25
26
27 */
28
29 /*
30    Manuals (available from ftp://ftp.natinst.com/support/manuals)
31
32         370106b.pdf     6527 Register Level Programmer Manual
33
34  */
35
36 #define DEBUG 1
37 #define DEBUG_FLAGS
38
39 #include <linux/module.h>
40 #include <linux/pci.h>
41 #include <linux/interrupt.h>
42
43 #include "../comedidev.h"
44
45 #include "comedi_fc.h"
46 #include "mite.h"
47
48 #define NI6527_DIO_SIZE 4096
49 #define NI6527_MITE_SIZE 4096
50
51 #define Port_Register(x)                        (0x00+(x))
52 #define ID_Register                             0x06
53
54 #define Clear_Register                          0x07
55 #define ClrEdge                         0x08
56 #define ClrOverflow                     0x04
57 #define ClrFilter                       0x02
58 #define ClrInterval                     0x01
59
60 #define Filter_Interval(x)                      (0x08+(x))
61 #define Filter_Enable(x)                        (0x0c+(x))
62
63 #define Change_Status                           0x14
64 #define MasterInterruptStatus           0x04
65 #define Overflow                        0x02
66 #define EdgeStatus                      0x01
67
68 #define Master_Interrupt_Control                0x15
69 #define FallingEdgeIntEnable            0x10
70 #define RisingEdgeIntEnable             0x08
71 #define MasterInterruptEnable           0x04
72 #define OverflowIntEnable               0x02
73 #define EdgeIntEnable                   0x01
74
75 #define Rising_Edge_Detection_Enable(x)         (0x018+(x))
76 #define Falling_Edge_Detection_Enable(x)        (0x020+(x))
77
78 enum ni6527_boardid {
79         BOARD_PCI6527,
80         BOARD_PXI6527,
81 };
82
83 struct ni6527_board {
84         const char *name;
85 };
86
87 static const struct ni6527_board ni6527_boards[] = {
88         [BOARD_PCI6527] = {
89                 .name           = "pci-6527",
90         },
91         [BOARD_PXI6527] = {
92                 .name           = "pxi-6527",
93         },
94 };
95
96 struct ni6527_private {
97         struct mite_struct *mite;
98         unsigned int filter_interval;
99         unsigned int filter_enable;
100 };
101
102 static int ni6527_di_insn_config(struct comedi_device *dev,
103                                  struct comedi_subdevice *s,
104                                  struct comedi_insn *insn, unsigned int *data)
105 {
106         struct ni6527_private *devpriv = dev->private;
107         int chan = CR_CHAN(insn->chanspec);
108         unsigned int interval;
109
110         if (insn->n != 2)
111                 return -EINVAL;
112
113         if (data[0] != INSN_CONFIG_FILTER)
114                 return -EINVAL;
115
116         if (data[1]) {
117                 interval = (data[1] + 100) / 200;
118                 data[1] = interval * 200;
119
120                 if (interval != devpriv->filter_interval) {
121                         writeb(interval & 0xff,
122                                devpriv->mite->daq_io_addr + Filter_Interval(0));
123                         writeb((interval >> 8) & 0xff,
124                                devpriv->mite->daq_io_addr + Filter_Interval(1));
125                         writeb((interval >> 16) & 0x0f,
126                                devpriv->mite->daq_io_addr + Filter_Interval(2));
127
128                         writeb(ClrInterval,
129                                devpriv->mite->daq_io_addr + Clear_Register);
130
131                         devpriv->filter_interval = interval;
132                 }
133
134                 devpriv->filter_enable |= 1 << chan;
135         } else {
136                 devpriv->filter_enable &= ~(1 << chan);
137         }
138
139         writeb(devpriv->filter_enable,
140                devpriv->mite->daq_io_addr + Filter_Enable(0));
141         writeb(devpriv->filter_enable >> 8,
142                devpriv->mite->daq_io_addr + Filter_Enable(1));
143         writeb(devpriv->filter_enable >> 16,
144                devpriv->mite->daq_io_addr + Filter_Enable(2));
145
146         return 2;
147 }
148
149 static int ni6527_di_insn_bits(struct comedi_device *dev,
150                                struct comedi_subdevice *s,
151                                struct comedi_insn *insn, unsigned int *data)
152 {
153         struct ni6527_private *devpriv = dev->private;
154
155         data[1] = readb(devpriv->mite->daq_io_addr + Port_Register(0));
156         data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8;
157         data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16;
158
159         return insn->n;
160 }
161
162 static int ni6527_do_insn_bits(struct comedi_device *dev,
163                                struct comedi_subdevice *s,
164                                struct comedi_insn *insn,
165                                unsigned int *data)
166 {
167         struct ni6527_private *devpriv = dev->private;
168         unsigned int mask;
169
170         mask = comedi_dio_update_state(s, data);
171         if (mask) {
172                 /* Outputs are inverted */
173                 if (mask & 0x0000ff) {
174                         writeb(s->state ^ 0xff,
175                                devpriv->mite->daq_io_addr + Port_Register(3));
176                 }
177                 if (mask & 0x00ff00) {
178                         writeb((s->state >> 8) ^ 0xff,
179                                devpriv->mite->daq_io_addr + Port_Register(4));
180                 }
181                 if (mask & 0xff0000) {
182                         writeb((s->state >> 16) ^ 0xff,
183                                devpriv->mite->daq_io_addr + Port_Register(5));
184                 }
185         }
186
187         data[1] = s->state;
188
189         return insn->n;
190 }
191
192 static irqreturn_t ni6527_interrupt(int irq, void *d)
193 {
194         struct comedi_device *dev = d;
195         struct ni6527_private *devpriv = dev->private;
196         struct comedi_subdevice *s = &dev->subdevices[2];
197         unsigned int status;
198
199         status = readb(devpriv->mite->daq_io_addr + Change_Status);
200         if ((status & MasterInterruptStatus) == 0)
201                 return IRQ_NONE;
202         if ((status & EdgeStatus) == 0)
203                 return IRQ_NONE;
204
205         writeb(ClrEdge | ClrOverflow,
206                devpriv->mite->daq_io_addr + Clear_Register);
207
208         comedi_buf_put(s->async, 0);
209         s->async->events |= COMEDI_CB_EOS;
210         comedi_event(dev, s);
211         return IRQ_HANDLED;
212 }
213
214 static int ni6527_intr_cmdtest(struct comedi_device *dev,
215                                struct comedi_subdevice *s,
216                                struct comedi_cmd *cmd)
217 {
218         int err = 0;
219
220         /* Step 1 : check if triggers are trivially valid */
221
222         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
223         err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_OTHER);
224         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
225         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
226         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT);
227
228         if (err)
229                 return 1;
230
231         /* Step 2a : make sure trigger sources are unique */
232         /* Step 2b : and mutually compatible */
233
234         if (err)
235                 return 2;
236
237         /* Step 3: check if arguments are trivially valid */
238
239         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
240         err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
241         err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
242         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
243         err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
244
245         if (err)
246                 return 3;
247
248         /* step 4: fix up any arguments */
249
250         if (err)
251                 return 4;
252
253         return 0;
254 }
255
256 static int ni6527_intr_cmd(struct comedi_device *dev,
257                            struct comedi_subdevice *s)
258 {
259         struct ni6527_private *devpriv = dev->private;
260         /* struct comedi_cmd *cmd = &s->async->cmd; */
261
262         writeb(ClrEdge | ClrOverflow,
263                devpriv->mite->daq_io_addr + Clear_Register);
264         writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
265                MasterInterruptEnable | EdgeIntEnable,
266                devpriv->mite->daq_io_addr + Master_Interrupt_Control);
267
268         return 0;
269 }
270
271 static int ni6527_intr_cancel(struct comedi_device *dev,
272                               struct comedi_subdevice *s)
273 {
274         struct ni6527_private *devpriv = dev->private;
275
276         writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
277
278         return 0;
279 }
280
281 static int ni6527_intr_insn_bits(struct comedi_device *dev,
282                                  struct comedi_subdevice *s,
283                                  struct comedi_insn *insn, unsigned int *data)
284 {
285         data[1] = 0;
286         return insn->n;
287 }
288
289 static int ni6527_intr_insn_config(struct comedi_device *dev,
290                                    struct comedi_subdevice *s,
291                                    struct comedi_insn *insn, unsigned int *data)
292 {
293         struct ni6527_private *devpriv = dev->private;
294
295         if (insn->n < 1)
296                 return -EINVAL;
297         if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
298                 return -EINVAL;
299
300         writeb(data[1],
301                devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
302         writeb(data[1] >> 8,
303                devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
304         writeb(data[1] >> 16,
305                devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
306
307         writeb(data[2],
308                devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
309         writeb(data[2] >> 8,
310                devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
311         writeb(data[2] >> 16,
312                devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
313
314         return 2;
315 }
316
317 static int ni6527_auto_attach(struct comedi_device *dev,
318                               unsigned long context)
319 {
320         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
321         const struct ni6527_board *board = NULL;
322         struct ni6527_private *devpriv;
323         struct comedi_subdevice *s;
324         int ret;
325
326         if (context < ARRAY_SIZE(ni6527_boards))
327                 board = &ni6527_boards[context];
328         if (!board)
329                 return -ENODEV;
330         dev->board_ptr = board;
331         dev->board_name = board->name;
332
333         ret = comedi_pci_enable(dev);
334         if (ret)
335                 return ret;
336
337         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
338         if (!devpriv)
339                 return -ENOMEM;
340
341         devpriv->mite = mite_alloc(pcidev);
342         if (!devpriv->mite)
343                 return -ENOMEM;
344
345         ret = mite_setup(devpriv->mite);
346         if (ret < 0) {
347                 dev_err(dev->class_dev, "error setting up mite\n");
348                 return ret;
349         }
350
351         dev_info(dev->class_dev, "board: %s, ID=0x%02x\n", dev->board_name,
352                  readb(devpriv->mite->daq_io_addr + ID_Register));
353
354         ret = comedi_alloc_subdevices(dev, 3);
355         if (ret)
356                 return ret;
357
358         s = &dev->subdevices[0];
359         s->type = COMEDI_SUBD_DI;
360         s->subdev_flags = SDF_READABLE;
361         s->n_chan = 24;
362         s->range_table = &range_digital;
363         s->maxdata = 1;
364         s->insn_config = ni6527_di_insn_config;
365         s->insn_bits = ni6527_di_insn_bits;
366
367         s = &dev->subdevices[1];
368         s->type = COMEDI_SUBD_DO;
369         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
370         s->n_chan = 24;
371         s->range_table = &range_unknown;  /* FIXME: actually conductance */
372         s->maxdata = 1;
373         s->insn_bits = ni6527_do_insn_bits;
374
375         s = &dev->subdevices[2];
376         dev->read_subdev = s;
377         s->type = COMEDI_SUBD_DI;
378         s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
379         s->n_chan = 1;
380         s->range_table = &range_unknown;
381         s->maxdata = 1;
382         s->do_cmdtest = ni6527_intr_cmdtest;
383         s->do_cmd = ni6527_intr_cmd;
384         s->cancel = ni6527_intr_cancel;
385         s->insn_bits = ni6527_intr_insn_bits;
386         s->insn_config = ni6527_intr_insn_config;
387
388         writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0));
389         writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(1));
390         writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(2));
391
392         writeb(ClrEdge | ClrOverflow | ClrFilter | ClrInterval,
393                devpriv->mite->daq_io_addr + Clear_Register);
394         writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
395
396         ret = request_irq(mite_irq(devpriv->mite), ni6527_interrupt,
397                           IRQF_SHARED, dev->board_name, dev);
398         if (ret < 0)
399                 dev_warn(dev->class_dev, "irq not available\n");
400         else
401                 dev->irq = mite_irq(devpriv->mite);
402
403         return 0;
404 }
405
406 static void ni6527_detach(struct comedi_device *dev)
407 {
408         struct ni6527_private *devpriv = dev->private;
409
410         if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr)
411                 writeb(0x00,
412                        devpriv->mite->daq_io_addr + Master_Interrupt_Control);
413         if (dev->irq)
414                 free_irq(dev->irq, dev);
415         if (devpriv && devpriv->mite) {
416                 mite_unsetup(devpriv->mite);
417                 mite_free(devpriv->mite);
418         }
419         comedi_pci_disable(dev);
420 }
421
422 static struct comedi_driver ni6527_driver = {
423         .driver_name = "ni_6527",
424         .module = THIS_MODULE,
425         .auto_attach = ni6527_auto_attach,
426         .detach = ni6527_detach,
427 };
428
429 static int ni6527_pci_probe(struct pci_dev *dev,
430                             const struct pci_device_id *id)
431 {
432         return comedi_pci_auto_config(dev, &ni6527_driver, id->driver_data);
433 }
434
435 static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = {
436         { PCI_VDEVICE(NI, 0x2b10), BOARD_PXI6527 },
437         { PCI_VDEVICE(NI, 0x2b20), BOARD_PCI6527 },
438         { 0 }
439 };
440 MODULE_DEVICE_TABLE(pci, ni6527_pci_table);
441
442 static struct pci_driver ni6527_pci_driver = {
443         .name           = "ni_6527",
444         .id_table       = ni6527_pci_table,
445         .probe          = ni6527_pci_probe,
446         .remove         = comedi_pci_auto_unconfig,
447 };
448 module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver);
449
450 MODULE_AUTHOR("Comedi http://www.comedi.org");
451 MODULE_DESCRIPTION("Comedi low-level driver");
452 MODULE_LICENSE("GPL");