Merge git://git.infradead.org/users/willy/linux-nvme
[firefly-linux-kernel-4.4.55.git] / drivers / staging / comedi / drivers / amplc_dio200_common.c
1 /*
2     comedi/drivers/amplc_dio200_common.c
3
4     Common support code for "amplc_dio200" and "amplc_dio200_pci".
5
6     Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/>
7
8     COMEDI - Linux Control and Measurement Device Interface
9     Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
10
11     This program is free software; you can redistribute it and/or modify
12     it under the terms of the GNU General Public License as published by
13     the Free Software Foundation; either version 2 of the License, or
14     (at your option) any later version.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     You should have received a copy of the GNU General Public License
22     along with this program; if not, write to the Free Software
23     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25 */
26
27 #include <linux/interrupt.h>
28 #include <linux/slab.h>
29
30 #include "../comedidev.h"
31
32 #include "amplc_dio200.h"
33 #include "comedi_fc.h"
34 #include "8253.h"
35
36 /* 8255 control register bits */
37 #define CR_C_LO_IO      0x01
38 #define CR_B_IO         0x02
39 #define CR_B_MODE       0x04
40 #define CR_C_HI_IO      0x08
41 #define CR_A_IO         0x10
42 #define CR_A_MODE(a)    ((a)<<5)
43 #define CR_CW           0x80
44
45 /* 200 series registers */
46 #define DIO200_IO_SIZE          0x20
47 #define DIO200_PCIE_IO_SIZE     0x4000
48 #define DIO200_XCLK_SCE         0x18    /* Group X clock selection register */
49 #define DIO200_YCLK_SCE         0x19    /* Group Y clock selection register */
50 #define DIO200_ZCLK_SCE         0x1a    /* Group Z clock selection register */
51 #define DIO200_XGAT_SCE         0x1b    /* Group X gate selection register */
52 #define DIO200_YGAT_SCE         0x1c    /* Group Y gate selection register */
53 #define DIO200_ZGAT_SCE         0x1d    /* Group Z gate selection register */
54 #define DIO200_INT_SCE          0x1e    /* Interrupt enable/status register */
55 /* Extra registers for new PCIe boards */
56 #define DIO200_ENHANCE          0x20    /* 1 to enable enhanced features */
57 #define DIO200_VERSION          0x24    /* Hardware version register */
58 #define DIO200_TS_CONFIG        0x600   /* Timestamp timer config register */
59 #define DIO200_TS_COUNT         0x602   /* Timestamp timer count register */
60
61 /*
62  * Functions for constructing value for DIO_200_?CLK_SCE and
63  * DIO_200_?GAT_SCE registers:
64  *
65  * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
66  * 'chan' is the channel: 0, 1 or 2.
67  * 'source' is the signal source: 0 to 7, or 0 to 31 for "enhanced" boards.
68  */
69 static unsigned char clk_gat_sce(unsigned int which, unsigned int chan,
70                                  unsigned int source)
71 {
72         return (which << 5) | (chan << 3) |
73                ((source & 030) << 3) | (source & 007);
74 }
75
76 static unsigned char clk_sce(unsigned int which, unsigned int chan,
77                              unsigned int source)
78 {
79         return clk_gat_sce(which, chan, source);
80 }
81
82 static unsigned char gat_sce(unsigned int which, unsigned int chan,
83                              unsigned int source)
84 {
85         return clk_gat_sce(which, chan, source);
86 }
87
88 /*
89  * Periods of the internal clock sources in nanoseconds.
90  */
91 static const unsigned int clock_period[32] = {
92         [1] = 100,              /* 10 MHz */
93         [2] = 1000,             /* 1 MHz */
94         [3] = 10000,            /* 100 kHz */
95         [4] = 100000,           /* 10 kHz */
96         [5] = 1000000,          /* 1 kHz */
97         [11] = 50,              /* 20 MHz (enhanced boards) */
98         /* clock sources 12 and later reserved for enhanced boards */
99 };
100
101 /*
102  * Timestamp timer configuration register (for new PCIe boards).
103  */
104 #define TS_CONFIG_RESET         0x100   /* Reset counter to zero. */
105 #define TS_CONFIG_CLK_SRC_MASK  0x0FF   /* Clock source. */
106 #define TS_CONFIG_MAX_CLK_SRC   2       /* Maximum clock source value. */
107
108 /*
109  * Periods of the timestamp timer clock sources in nanoseconds.
110  */
111 static const unsigned int ts_clock_period[TS_CONFIG_MAX_CLK_SRC + 1] = {
112         1,                      /* 1 nanosecond (but with 20 ns granularity). */
113         1000,                   /* 1 microsecond. */
114         1000000,                /* 1 millisecond. */
115 };
116
117 struct dio200_subdev_8254 {
118         unsigned int ofs;               /* Counter base offset */
119         unsigned int clk_sce_ofs;       /* CLK_SCE base address */
120         unsigned int gat_sce_ofs;       /* GAT_SCE base address */
121         int which;                      /* Bit 5 of CLK_SCE or GAT_SCE */
122         unsigned int clock_src[3];      /* Current clock sources */
123         unsigned int gate_src[3];       /* Current gate sources */
124         spinlock_t spinlock;
125 };
126
127 struct dio200_subdev_8255 {
128         unsigned int ofs;               /* DIO base offset */
129 };
130
131 struct dio200_subdev_intr {
132         spinlock_t spinlock;
133         unsigned int ofs;
134         unsigned int valid_isns;
135         unsigned int enabled_isns;
136         unsigned int stopcount;
137         bool active:1;
138         bool continuous:1;
139 };
140
141 static inline const struct dio200_layout *
142 dio200_board_layout(const struct dio200_board *board)
143 {
144         return &board->layout;
145 }
146
147 static inline const struct dio200_layout *
148 dio200_dev_layout(struct comedi_device *dev)
149 {
150         return dio200_board_layout(comedi_board(dev));
151 }
152
153 /*
154  * Read 8-bit register.
155  */
156 static unsigned char dio200_read8(struct comedi_device *dev,
157                                   unsigned int offset)
158 {
159         const struct dio200_board *thisboard = comedi_board(dev);
160         struct dio200_private *devpriv = dev->private;
161
162         offset <<= thisboard->mainshift;
163         if (devpriv->io.regtype == io_regtype)
164                 return inb(devpriv->io.u.iobase + offset);
165         else
166                 return readb(devpriv->io.u.membase + offset);
167 }
168
169 /*
170  * Write 8-bit register.
171  */
172 static void dio200_write8(struct comedi_device *dev, unsigned int offset,
173                           unsigned char val)
174 {
175         const struct dio200_board *thisboard = comedi_board(dev);
176         struct dio200_private *devpriv = dev->private;
177
178         offset <<= thisboard->mainshift;
179         if (devpriv->io.regtype == io_regtype)
180                 outb(val, devpriv->io.u.iobase + offset);
181         else
182                 writeb(val, devpriv->io.u.membase + offset);
183 }
184
185 /*
186  * Read 32-bit register.
187  */
188 static unsigned int dio200_read32(struct comedi_device *dev,
189                                   unsigned int offset)
190 {
191         const struct dio200_board *thisboard = comedi_board(dev);
192         struct dio200_private *devpriv = dev->private;
193
194         offset <<= thisboard->mainshift;
195         if (devpriv->io.regtype == io_regtype)
196                 return inl(devpriv->io.u.iobase + offset);
197         else
198                 return readl(devpriv->io.u.membase + offset);
199 }
200
201 /*
202  * Write 32-bit register.
203  */
204 static void dio200_write32(struct comedi_device *dev, unsigned int offset,
205                            unsigned int val)
206 {
207         const struct dio200_board *thisboard = comedi_board(dev);
208         struct dio200_private *devpriv = dev->private;
209
210         offset <<= thisboard->mainshift;
211         if (devpriv->io.regtype == io_regtype)
212                 outl(val, devpriv->io.u.iobase + offset);
213         else
214                 writel(val, devpriv->io.u.membase + offset);
215 }
216
217 /*
218  * 'insn_bits' function for an 'INTERRUPT' subdevice.
219  */
220 static int
221 dio200_subdev_intr_insn_bits(struct comedi_device *dev,
222                              struct comedi_subdevice *s,
223                              struct comedi_insn *insn, unsigned int *data)
224 {
225         const struct dio200_layout *layout = dio200_dev_layout(dev);
226         struct dio200_subdev_intr *subpriv = s->private;
227
228         if (layout->has_int_sce) {
229                 /* Just read the interrupt status register.  */
230                 data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns;
231         } else {
232                 /* No interrupt status register. */
233                 data[0] = 0;
234         }
235
236         return insn->n;
237 }
238
239 /*
240  * Called to stop acquisition for an 'INTERRUPT' subdevice.
241  */
242 static void dio200_stop_intr(struct comedi_device *dev,
243                              struct comedi_subdevice *s)
244 {
245         const struct dio200_layout *layout = dio200_dev_layout(dev);
246         struct dio200_subdev_intr *subpriv = s->private;
247
248         subpriv->active = false;
249         subpriv->enabled_isns = 0;
250         if (layout->has_int_sce)
251                 dio200_write8(dev, subpriv->ofs, 0);
252 }
253
254 /*
255  * Called to start acquisition for an 'INTERRUPT' subdevice.
256  */
257 static int dio200_start_intr(struct comedi_device *dev,
258                              struct comedi_subdevice *s)
259 {
260         unsigned int n;
261         unsigned isn_bits;
262         const struct dio200_layout *layout = dio200_dev_layout(dev);
263         struct dio200_subdev_intr *subpriv = s->private;
264         struct comedi_cmd *cmd = &s->async->cmd;
265         int retval = 0;
266
267         if (!subpriv->continuous && subpriv->stopcount == 0) {
268                 /* An empty acquisition! */
269                 s->async->events |= COMEDI_CB_EOA;
270                 subpriv->active = false;
271                 retval = 1;
272         } else {
273                 /* Determine interrupt sources to enable. */
274                 isn_bits = 0;
275                 if (cmd->chanlist) {
276                         for (n = 0; n < cmd->chanlist_len; n++)
277                                 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
278                 }
279                 isn_bits &= subpriv->valid_isns;
280                 /* Enable interrupt sources. */
281                 subpriv->enabled_isns = isn_bits;
282                 if (layout->has_int_sce)
283                         dio200_write8(dev, subpriv->ofs, isn_bits);
284         }
285
286         return retval;
287 }
288
289 /*
290  * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
291  */
292 static int
293 dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
294                           unsigned int trignum)
295 {
296         struct dio200_subdev_intr *subpriv;
297         unsigned long flags;
298         int event = 0;
299
300         if (trignum != 0)
301                 return -EINVAL;
302
303         subpriv = s->private;
304
305         spin_lock_irqsave(&subpriv->spinlock, flags);
306         s->async->inttrig = NULL;
307         if (subpriv->active)
308                 event = dio200_start_intr(dev, s);
309
310         spin_unlock_irqrestore(&subpriv->spinlock, flags);
311
312         if (event)
313                 comedi_event(dev, s);
314
315         return 1;
316 }
317
318 static void dio200_read_scan_intr(struct comedi_device *dev,
319                                   struct comedi_subdevice *s,
320                                   unsigned int triggered)
321 {
322         struct dio200_subdev_intr *subpriv = s->private;
323         unsigned short val;
324         unsigned int n, ch, len;
325
326         val = 0;
327         len = s->async->cmd.chanlist_len;
328         for (n = 0; n < len; n++) {
329                 ch = CR_CHAN(s->async->cmd.chanlist[n]);
330                 if (triggered & (1U << ch))
331                         val |= (1U << n);
332         }
333         /* Write the scan to the buffer. */
334         if (comedi_buf_put(s->async, val)) {
335                 s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
336         } else {
337                 /* Error!  Stop acquisition.  */
338                 dio200_stop_intr(dev, s);
339                 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
340                 comedi_error(dev, "buffer overflow");
341         }
342
343         /* Check for end of acquisition. */
344         if (!subpriv->continuous) {
345                 /* stop_src == TRIG_COUNT */
346                 if (subpriv->stopcount > 0) {
347                         subpriv->stopcount--;
348                         if (subpriv->stopcount == 0) {
349                                 s->async->events |= COMEDI_CB_EOA;
350                                 dio200_stop_intr(dev, s);
351                         }
352                 }
353         }
354 }
355
356 /*
357  * This is called from the interrupt service routine to handle a read
358  * scan on an 'INTERRUPT' subdevice.
359  */
360 static int dio200_handle_read_intr(struct comedi_device *dev,
361                                    struct comedi_subdevice *s)
362 {
363         const struct dio200_layout *layout = dio200_dev_layout(dev);
364         struct dio200_subdev_intr *subpriv = s->private;
365         unsigned triggered;
366         unsigned intstat;
367         unsigned cur_enabled;
368         unsigned int oldevents;
369         unsigned long flags;
370
371         triggered = 0;
372
373         spin_lock_irqsave(&subpriv->spinlock, flags);
374         oldevents = s->async->events;
375         if (layout->has_int_sce) {
376                 /*
377                  * Collect interrupt sources that have triggered and disable
378                  * them temporarily.  Loop around until no extra interrupt
379                  * sources have triggered, at which point, the valid part of
380                  * the interrupt status register will read zero, clearing the
381                  * cause of the interrupt.
382                  *
383                  * Mask off interrupt sources already seen to avoid infinite
384                  * loop in case of misconfiguration.
385                  */
386                 cur_enabled = subpriv->enabled_isns;
387                 while ((intstat = (dio200_read8(dev, subpriv->ofs) &
388                                    subpriv->valid_isns & ~triggered)) != 0) {
389                         triggered |= intstat;
390                         cur_enabled &= ~triggered;
391                         dio200_write8(dev, subpriv->ofs, cur_enabled);
392                 }
393         } else {
394                 /*
395                  * No interrupt status register.  Assume the single interrupt
396                  * source has triggered.
397                  */
398                 triggered = subpriv->enabled_isns;
399         }
400
401         if (triggered) {
402                 /*
403                  * Some interrupt sources have triggered and have been
404                  * temporarily disabled to clear the cause of the interrupt.
405                  *
406                  * Reenable them NOW to minimize the time they are disabled.
407                  */
408                 cur_enabled = subpriv->enabled_isns;
409                 if (layout->has_int_sce)
410                         dio200_write8(dev, subpriv->ofs, cur_enabled);
411
412                 if (subpriv->active) {
413                         /*
414                          * The command is still active.
415                          *
416                          * Ignore interrupt sources that the command isn't
417                          * interested in (just in case there's a race
418                          * condition).
419                          */
420                         if (triggered & subpriv->enabled_isns)
421                                 /* Collect scan data. */
422                                 dio200_read_scan_intr(dev, s, triggered);
423                 }
424         }
425         spin_unlock_irqrestore(&subpriv->spinlock, flags);
426
427         if (oldevents != s->async->events)
428                 comedi_event(dev, s);
429
430         return (triggered != 0);
431 }
432
433 /*
434  * 'cancel' function for an 'INTERRUPT' subdevice.
435  */
436 static int dio200_subdev_intr_cancel(struct comedi_device *dev,
437                                      struct comedi_subdevice *s)
438 {
439         struct dio200_subdev_intr *subpriv = s->private;
440         unsigned long flags;
441
442         spin_lock_irqsave(&subpriv->spinlock, flags);
443         if (subpriv->active)
444                 dio200_stop_intr(dev, s);
445
446         spin_unlock_irqrestore(&subpriv->spinlock, flags);
447
448         return 0;
449 }
450
451 /*
452  * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
453  */
454 static int
455 dio200_subdev_intr_cmdtest(struct comedi_device *dev,
456                            struct comedi_subdevice *s, struct comedi_cmd *cmd)
457 {
458         int err = 0;
459
460         /* Step 1 : check if triggers are trivially valid */
461
462         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
463         err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
464         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
465         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
466         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
467
468         if (err)
469                 return 1;
470
471         /* Step 2a : make sure trigger sources are unique */
472
473         err |= cfc_check_trigger_is_unique(cmd->start_src);
474         err |= cfc_check_trigger_is_unique(cmd->stop_src);
475
476         /* Step 2b : and mutually compatible */
477
478         if (err)
479                 return 2;
480
481         /* Step 3: check if arguments are trivially valid */
482
483         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
484         err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
485         err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
486         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
487
488         switch (cmd->stop_src) {
489         case TRIG_COUNT:
490                 /* any count allowed */
491                 break;
492         case TRIG_NONE:
493                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
494                 break;
495         default:
496                 break;
497         }
498
499         if (err)
500                 return 3;
501
502         /* step 4: fix up any arguments */
503
504         /* if (err) return 4; */
505
506         return 0;
507 }
508
509 /*
510  * 'do_cmd' function for an 'INTERRUPT' subdevice.
511  */
512 static int dio200_subdev_intr_cmd(struct comedi_device *dev,
513                                   struct comedi_subdevice *s)
514 {
515         struct comedi_cmd *cmd = &s->async->cmd;
516         struct dio200_subdev_intr *subpriv = s->private;
517         unsigned long flags;
518         int event = 0;
519
520         spin_lock_irqsave(&subpriv->spinlock, flags);
521         subpriv->active = 1;
522
523         /* Set up end of acquisition. */
524         switch (cmd->stop_src) {
525         case TRIG_COUNT:
526                 subpriv->continuous = false;
527                 subpriv->stopcount = cmd->stop_arg;
528                 break;
529         default:
530                 /* TRIG_NONE */
531                 subpriv->continuous = true;
532                 subpriv->stopcount = 0;
533                 break;
534         }
535
536         /* Set up start of acquisition. */
537         switch (cmd->start_src) {
538         case TRIG_INT:
539                 s->async->inttrig = dio200_inttrig_start_intr;
540                 break;
541         default:
542                 /* TRIG_NOW */
543                 event = dio200_start_intr(dev, s);
544                 break;
545         }
546         spin_unlock_irqrestore(&subpriv->spinlock, flags);
547
548         if (event)
549                 comedi_event(dev, s);
550
551         return 0;
552 }
553
554 /*
555  * This function initializes an 'INTERRUPT' subdevice.
556  */
557 static int
558 dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
559                         unsigned int offset, unsigned valid_isns)
560 {
561         const struct dio200_layout *layout = dio200_dev_layout(dev);
562         struct dio200_subdev_intr *subpriv;
563
564         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
565         if (!subpriv)
566                 return -ENOMEM;
567
568         subpriv->ofs = offset;
569         subpriv->valid_isns = valid_isns;
570         spin_lock_init(&subpriv->spinlock);
571
572         if (layout->has_int_sce)
573                 /* Disable interrupt sources. */
574                 dio200_write8(dev, subpriv->ofs, 0);
575
576         s->private = subpriv;
577         s->type = COMEDI_SUBD_DI;
578         s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
579         if (layout->has_int_sce) {
580                 s->n_chan = DIO200_MAX_ISNS;
581                 s->len_chanlist = DIO200_MAX_ISNS;
582         } else {
583                 /* No interrupt source register.  Support single channel. */
584                 s->n_chan = 1;
585                 s->len_chanlist = 1;
586         }
587         s->range_table = &range_digital;
588         s->maxdata = 1;
589         s->insn_bits = dio200_subdev_intr_insn_bits;
590         s->do_cmdtest = dio200_subdev_intr_cmdtest;
591         s->do_cmd = dio200_subdev_intr_cmd;
592         s->cancel = dio200_subdev_intr_cancel;
593
594         return 0;
595 }
596
597 /*
598  * Interrupt service routine.
599  */
600 static irqreturn_t dio200_interrupt(int irq, void *d)
601 {
602         struct comedi_device *dev = d;
603         struct dio200_private *devpriv = dev->private;
604         struct comedi_subdevice *s;
605         int handled;
606
607         if (!dev->attached)
608                 return IRQ_NONE;
609
610         if (devpriv->intr_sd >= 0) {
611                 s = &dev->subdevices[devpriv->intr_sd];
612                 handled = dio200_handle_read_intr(dev, s);
613         } else {
614                 handled = 0;
615         }
616
617         return IRQ_RETVAL(handled);
618 }
619
620 /*
621  * Read an '8254' counter subdevice channel.
622  */
623 static unsigned int
624 dio200_subdev_8254_read_chan(struct comedi_device *dev,
625                              struct comedi_subdevice *s, unsigned int chan)
626 {
627         struct dio200_subdev_8254 *subpriv = s->private;
628         unsigned int val;
629
630         /* latch counter */
631         val = chan << 6;
632         dio200_write8(dev, subpriv->ofs + i8254_control_reg, val);
633         /* read lsb, msb */
634         val = dio200_read8(dev, subpriv->ofs + chan);
635         val += dio200_read8(dev, subpriv->ofs + chan) << 8;
636         return val;
637 }
638
639 /*
640  * Write an '8254' subdevice channel.
641  */
642 static void
643 dio200_subdev_8254_write_chan(struct comedi_device *dev,
644                               struct comedi_subdevice *s, unsigned int chan,
645                               unsigned int count)
646 {
647         struct dio200_subdev_8254 *subpriv = s->private;
648
649         /* write lsb, msb */
650         dio200_write8(dev, subpriv->ofs + chan, count & 0xff);
651         dio200_write8(dev, subpriv->ofs + chan, (count >> 8) & 0xff);
652 }
653
654 /*
655  * Set mode of an '8254' subdevice channel.
656  */
657 static void
658 dio200_subdev_8254_set_mode(struct comedi_device *dev,
659                             struct comedi_subdevice *s, unsigned int chan,
660                             unsigned int mode)
661 {
662         struct dio200_subdev_8254 *subpriv = s->private;
663         unsigned int byte;
664
665         byte = chan << 6;
666         byte |= 0x30;           /* access order: lsb, msb */
667         byte |= (mode & 0xf);   /* counter mode and BCD|binary */
668         dio200_write8(dev, subpriv->ofs + i8254_control_reg, byte);
669 }
670
671 /*
672  * Read status byte of an '8254' counter subdevice channel.
673  */
674 static unsigned int
675 dio200_subdev_8254_status(struct comedi_device *dev,
676                           struct comedi_subdevice *s, unsigned int chan)
677 {
678         struct dio200_subdev_8254 *subpriv = s->private;
679
680         /* latch status */
681         dio200_write8(dev, subpriv->ofs + i8254_control_reg,
682                       0xe0 | (2 << chan));
683         /* read status */
684         return dio200_read8(dev, subpriv->ofs + chan);
685 }
686
687 /*
688  * Handle 'insn_read' for an '8254' counter subdevice.
689  */
690 static int
691 dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
692                         struct comedi_insn *insn, unsigned int *data)
693 {
694         struct dio200_subdev_8254 *subpriv = s->private;
695         int chan = CR_CHAN(insn->chanspec);
696         unsigned int n;
697         unsigned long flags;
698
699         for (n = 0; n < insn->n; n++) {
700                 spin_lock_irqsave(&subpriv->spinlock, flags);
701                 data[n] = dio200_subdev_8254_read_chan(dev, s, chan);
702                 spin_unlock_irqrestore(&subpriv->spinlock, flags);
703         }
704         return insn->n;
705 }
706
707 /*
708  * Handle 'insn_write' for an '8254' counter subdevice.
709  */
710 static int
711 dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
712                          struct comedi_insn *insn, unsigned int *data)
713 {
714         struct dio200_subdev_8254 *subpriv = s->private;
715         int chan = CR_CHAN(insn->chanspec);
716         unsigned int n;
717         unsigned long flags;
718
719         for (n = 0; n < insn->n; n++) {
720                 spin_lock_irqsave(&subpriv->spinlock, flags);
721                 dio200_subdev_8254_write_chan(dev, s, chan, data[n]);
722                 spin_unlock_irqrestore(&subpriv->spinlock, flags);
723         }
724         return insn->n;
725 }
726
727 /*
728  * Set gate source for an '8254' counter subdevice channel.
729  */
730 static int
731 dio200_subdev_8254_set_gate_src(struct comedi_device *dev,
732                                 struct comedi_subdevice *s,
733                                 unsigned int counter_number,
734                                 unsigned int gate_src)
735 {
736         const struct dio200_layout *layout = dio200_dev_layout(dev);
737         struct dio200_subdev_8254 *subpriv = s->private;
738         unsigned char byte;
739
740         if (!layout->has_clk_gat_sce)
741                 return -1;
742         if (counter_number > 2)
743                 return -1;
744         if (gate_src > (layout->has_enhancements ? 31 : 7))
745                 return -1;
746
747         subpriv->gate_src[counter_number] = gate_src;
748         byte = gat_sce(subpriv->which, counter_number, gate_src);
749         dio200_write8(dev, subpriv->gat_sce_ofs, byte);
750
751         return 0;
752 }
753
754 /*
755  * Get gate source for an '8254' counter subdevice channel.
756  */
757 static int
758 dio200_subdev_8254_get_gate_src(struct comedi_device *dev,
759                                 struct comedi_subdevice *s,
760                                 unsigned int counter_number)
761 {
762         const struct dio200_layout *layout = dio200_dev_layout(dev);
763         struct dio200_subdev_8254 *subpriv = s->private;
764
765         if (!layout->has_clk_gat_sce)
766                 return -1;
767         if (counter_number > 2)
768                 return -1;
769
770         return subpriv->gate_src[counter_number];
771 }
772
773 /*
774  * Set clock source for an '8254' counter subdevice channel.
775  */
776 static int
777 dio200_subdev_8254_set_clock_src(struct comedi_device *dev,
778                                  struct comedi_subdevice *s,
779                                  unsigned int counter_number,
780                                  unsigned int clock_src)
781 {
782         const struct dio200_layout *layout = dio200_dev_layout(dev);
783         struct dio200_subdev_8254 *subpriv = s->private;
784         unsigned char byte;
785
786         if (!layout->has_clk_gat_sce)
787                 return -1;
788         if (counter_number > 2)
789                 return -1;
790         if (clock_src > (layout->has_enhancements ? 31 : 7))
791                 return -1;
792
793         subpriv->clock_src[counter_number] = clock_src;
794         byte = clk_sce(subpriv->which, counter_number, clock_src);
795         dio200_write8(dev, subpriv->clk_sce_ofs, byte);
796
797         return 0;
798 }
799
800 /*
801  * Get clock source for an '8254' counter subdevice channel.
802  */
803 static int
804 dio200_subdev_8254_get_clock_src(struct comedi_device *dev,
805                                  struct comedi_subdevice *s,
806                                  unsigned int counter_number,
807                                  unsigned int *period_ns)
808 {
809         const struct dio200_layout *layout = dio200_dev_layout(dev);
810         struct dio200_subdev_8254 *subpriv = s->private;
811         unsigned clock_src;
812
813         if (!layout->has_clk_gat_sce)
814                 return -1;
815         if (counter_number > 2)
816                 return -1;
817
818         clock_src = subpriv->clock_src[counter_number];
819         *period_ns = clock_period[clock_src];
820         return clock_src;
821 }
822
823 /*
824  * Handle 'insn_config' for an '8254' counter subdevice.
825  */
826 static int
827 dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
828                           struct comedi_insn *insn, unsigned int *data)
829 {
830         struct dio200_subdev_8254 *subpriv = s->private;
831         int ret = 0;
832         int chan = CR_CHAN(insn->chanspec);
833         unsigned long flags;
834
835         spin_lock_irqsave(&subpriv->spinlock, flags);
836         switch (data[0]) {
837         case INSN_CONFIG_SET_COUNTER_MODE:
838                 if (data[1] > (I8254_MODE5 | I8254_BINARY))
839                         ret = -EINVAL;
840                 else
841                         dio200_subdev_8254_set_mode(dev, s, chan, data[1]);
842                 break;
843         case INSN_CONFIG_8254_READ_STATUS:
844                 data[1] = dio200_subdev_8254_status(dev, s, chan);
845                 break;
846         case INSN_CONFIG_SET_GATE_SRC:
847                 ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]);
848                 if (ret < 0)
849                         ret = -EINVAL;
850                 break;
851         case INSN_CONFIG_GET_GATE_SRC:
852                 ret = dio200_subdev_8254_get_gate_src(dev, s, chan);
853                 if (ret < 0) {
854                         ret = -EINVAL;
855                         break;
856                 }
857                 data[2] = ret;
858                 break;
859         case INSN_CONFIG_SET_CLOCK_SRC:
860                 ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]);
861                 if (ret < 0)
862                         ret = -EINVAL;
863                 break;
864         case INSN_CONFIG_GET_CLOCK_SRC:
865                 ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]);
866                 if (ret < 0) {
867                         ret = -EINVAL;
868                         break;
869                 }
870                 data[1] = ret;
871                 break;
872         default:
873                 ret = -EINVAL;
874                 break;
875         }
876         spin_unlock_irqrestore(&subpriv->spinlock, flags);
877         return ret < 0 ? ret : insn->n;
878 }
879
880 /*
881  * This function initializes an '8254' counter subdevice.
882  */
883 static int
884 dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
885                         unsigned int offset)
886 {
887         const struct dio200_layout *layout = dio200_dev_layout(dev);
888         struct dio200_subdev_8254 *subpriv;
889         unsigned int chan;
890
891         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
892         if (!subpriv)
893                 return -ENOMEM;
894
895         s->private = subpriv;
896         s->type = COMEDI_SUBD_COUNTER;
897         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
898         s->n_chan = 3;
899         s->maxdata = 0xFFFF;
900         s->insn_read = dio200_subdev_8254_read;
901         s->insn_write = dio200_subdev_8254_write;
902         s->insn_config = dio200_subdev_8254_config;
903
904         spin_lock_init(&subpriv->spinlock);
905         subpriv->ofs = offset;
906         if (layout->has_clk_gat_sce) {
907                 /* Derive CLK_SCE and GAT_SCE register offsets from
908                  * 8254 offset. */
909                 subpriv->clk_sce_ofs = DIO200_XCLK_SCE + (offset >> 3);
910                 subpriv->gat_sce_ofs = DIO200_XGAT_SCE + (offset >> 3);
911                 subpriv->which = (offset >> 2) & 1;
912         }
913
914         /* Initialize channels. */
915         for (chan = 0; chan < 3; chan++) {
916                 dio200_subdev_8254_set_mode(dev, s, chan,
917                                             I8254_MODE0 | I8254_BINARY);
918                 if (layout->has_clk_gat_sce) {
919                         /* Gate source 0 is VCC (logic 1). */
920                         dio200_subdev_8254_set_gate_src(dev, s, chan, 0);
921                         /* Clock source 0 is the dedicated clock input. */
922                         dio200_subdev_8254_set_clock_src(dev, s, chan, 0);
923                 }
924         }
925
926         return 0;
927 }
928
929 /*
930  * This function sets I/O directions for an '8255' DIO subdevice.
931  */
932 static void dio200_subdev_8255_set_dir(struct comedi_device *dev,
933                                        struct comedi_subdevice *s)
934 {
935         struct dio200_subdev_8255 *subpriv = s->private;
936         int config;
937
938         config = CR_CW;
939         /* 1 in io_bits indicates output, 1 in config indicates input */
940         if (!(s->io_bits & 0x0000ff))
941                 config |= CR_A_IO;
942         if (!(s->io_bits & 0x00ff00))
943                 config |= CR_B_IO;
944         if (!(s->io_bits & 0x0f0000))
945                 config |= CR_C_LO_IO;
946         if (!(s->io_bits & 0xf00000))
947                 config |= CR_C_HI_IO;
948         dio200_write8(dev, subpriv->ofs + 3, config);
949 }
950
951 /*
952  * Handle 'insn_bits' for an '8255' DIO subdevice.
953  */
954 static int dio200_subdev_8255_bits(struct comedi_device *dev,
955                                    struct comedi_subdevice *s,
956                                    struct comedi_insn *insn, unsigned int *data)
957 {
958         struct dio200_subdev_8255 *subpriv = s->private;
959
960         if (data[0]) {
961                 s->state &= ~data[0];
962                 s->state |= (data[0] & data[1]);
963                 if (data[0] & 0xff)
964                         dio200_write8(dev, subpriv->ofs, s->state & 0xff);
965                 if (data[0] & 0xff00)
966                         dio200_write8(dev, subpriv->ofs + 1,
967                                       (s->state >> 8) & 0xff);
968                 if (data[0] & 0xff0000)
969                         dio200_write8(dev, subpriv->ofs + 2,
970                                       (s->state >> 16) & 0xff);
971         }
972         data[1] = dio200_read8(dev, subpriv->ofs);
973         data[1] |= dio200_read8(dev, subpriv->ofs + 1) << 8;
974         data[1] |= dio200_read8(dev, subpriv->ofs + 2) << 16;
975         return 2;
976 }
977
978 /*
979  * Handle 'insn_config' for an '8255' DIO subdevice.
980  */
981 static int dio200_subdev_8255_config(struct comedi_device *dev,
982                                      struct comedi_subdevice *s,
983                                      struct comedi_insn *insn,
984                                      unsigned int *data)
985 {
986         unsigned int mask;
987         unsigned int bits;
988
989         mask = 1 << CR_CHAN(insn->chanspec);
990         if (mask & 0x0000ff)
991                 bits = 0x0000ff;
992         else if (mask & 0x00ff00)
993                 bits = 0x00ff00;
994         else if (mask & 0x0f0000)
995                 bits = 0x0f0000;
996         else
997                 bits = 0xf00000;
998         switch (data[0]) {
999         case INSN_CONFIG_DIO_INPUT:
1000                 s->io_bits &= ~bits;
1001                 break;
1002         case INSN_CONFIG_DIO_OUTPUT:
1003                 s->io_bits |= bits;
1004                 break;
1005         case INSN_CONFIG_DIO_QUERY:
1006                 data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
1007                 return insn->n;
1008                 break;
1009         default:
1010                 return -EINVAL;
1011         }
1012         dio200_subdev_8255_set_dir(dev, s);
1013         return 1;
1014 }
1015
1016 /*
1017  * This function initializes an '8255' DIO subdevice.
1018  *
1019  * offset is the offset to the 8255 chip.
1020  */
1021 static int dio200_subdev_8255_init(struct comedi_device *dev,
1022                                    struct comedi_subdevice *s,
1023                                    unsigned int offset)
1024 {
1025         struct dio200_subdev_8255 *subpriv;
1026
1027         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1028         if (!subpriv)
1029                 return -ENOMEM;
1030         subpriv->ofs = offset;
1031         s->private = subpriv;
1032         s->type = COMEDI_SUBD_DIO;
1033         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1034         s->n_chan = 24;
1035         s->range_table = &range_digital;
1036         s->maxdata = 1;
1037         s->insn_bits = dio200_subdev_8255_bits;
1038         s->insn_config = dio200_subdev_8255_config;
1039         s->state = 0;
1040         s->io_bits = 0;
1041         dio200_subdev_8255_set_dir(dev, s);
1042         return 0;
1043 }
1044
1045 /*
1046  * Handle 'insn_read' for a timer subdevice.
1047  */
1048 static int dio200_subdev_timer_read(struct comedi_device *dev,
1049                                     struct comedi_subdevice *s,
1050                                     struct comedi_insn *insn,
1051                                     unsigned int *data)
1052 {
1053         unsigned int n;
1054
1055         for (n = 0; n < insn->n; n++)
1056                 data[n] = dio200_read32(dev, DIO200_TS_COUNT);
1057         return n;
1058 }
1059
1060 /*
1061  * Reset timer subdevice.
1062  */
1063 static void dio200_subdev_timer_reset(struct comedi_device *dev,
1064                                       struct comedi_subdevice *s)
1065 {
1066         unsigned int clock;
1067
1068         clock = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
1069         dio200_write32(dev, DIO200_TS_CONFIG, clock | TS_CONFIG_RESET);
1070         dio200_write32(dev, DIO200_TS_CONFIG, clock);
1071 }
1072
1073 /*
1074  * Get timer subdevice clock source and period.
1075  */
1076 static void dio200_subdev_timer_get_clock_src(struct comedi_device *dev,
1077                                               struct comedi_subdevice *s,
1078                                               unsigned int *src,
1079                                               unsigned int *period)
1080 {
1081         unsigned int clk;
1082
1083         clk = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
1084         *src = clk;
1085         *period = (clk < ARRAY_SIZE(ts_clock_period)) ?
1086                   ts_clock_period[clk] : 0;
1087 }
1088
1089 /*
1090  * Set timer subdevice clock source.
1091  */
1092 static int dio200_subdev_timer_set_clock_src(struct comedi_device *dev,
1093                                              struct comedi_subdevice *s,
1094                                              unsigned int src)
1095 {
1096         if (src > TS_CONFIG_MAX_CLK_SRC)
1097                 return -EINVAL;
1098         dio200_write32(dev, DIO200_TS_CONFIG, src);
1099         return 0;
1100 }
1101
1102 /*
1103  * Handle 'insn_config' for a timer subdevice.
1104  */
1105 static int dio200_subdev_timer_config(struct comedi_device *dev,
1106                                       struct comedi_subdevice *s,
1107                                       struct comedi_insn *insn,
1108                                       unsigned int *data)
1109 {
1110         int ret = 0;
1111
1112         switch (data[0]) {
1113         case INSN_CONFIG_RESET:
1114                 dio200_subdev_timer_reset(dev, s);
1115                 break;
1116         case INSN_CONFIG_SET_CLOCK_SRC:
1117                 ret = dio200_subdev_timer_set_clock_src(dev, s, data[1]);
1118                 if (ret < 0)
1119                         ret = -EINVAL;
1120                 break;
1121         case INSN_CONFIG_GET_CLOCK_SRC:
1122                 dio200_subdev_timer_get_clock_src(dev, s, &data[1], &data[2]);
1123                 break;
1124         default:
1125                 ret = -EINVAL;
1126                 break;
1127         }
1128         return ret < 0 ? ret : insn->n;
1129 }
1130
1131 /*
1132  * This function initializes a timer subdevice.
1133  *
1134  * Uses the timestamp timer registers.  There is only one timestamp timer.
1135  */
1136 static int dio200_subdev_timer_init(struct comedi_device *dev,
1137                                     struct comedi_subdevice *s)
1138 {
1139         s->type = COMEDI_SUBD_TIMER;
1140         s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
1141         s->n_chan = 1;
1142         s->maxdata = 0xFFFFFFFF;
1143         s->insn_read = dio200_subdev_timer_read;
1144         s->insn_config = dio200_subdev_timer_config;
1145         return 0;
1146 }
1147
1148 void amplc_dio200_set_enhance(struct comedi_device *dev, unsigned char val)
1149 {
1150         dio200_write8(dev, DIO200_ENHANCE, val);
1151 }
1152 EXPORT_SYMBOL_GPL(amplc_dio200_set_enhance);
1153
1154 int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq,
1155                                unsigned long req_irq_flags)
1156 {
1157         const struct dio200_board *thisboard = comedi_board(dev);
1158         struct dio200_private *devpriv = dev->private;
1159         const struct dio200_layout *layout = dio200_board_layout(thisboard);
1160         struct comedi_subdevice *s;
1161         int sdx;
1162         unsigned int n;
1163         int ret;
1164
1165         devpriv->intr_sd = -1;
1166
1167         ret = comedi_alloc_subdevices(dev, layout->n_subdevs);
1168         if (ret)
1169                 return ret;
1170
1171         for (n = 0; n < dev->n_subdevices; n++) {
1172                 s = &dev->subdevices[n];
1173                 switch (layout->sdtype[n]) {
1174                 case sd_8254:
1175                         /* counter subdevice (8254) */
1176                         ret = dio200_subdev_8254_init(dev, s,
1177                                                       layout->sdinfo[n]);
1178                         if (ret < 0)
1179                                 return ret;
1180                         break;
1181                 case sd_8255:
1182                         /* digital i/o subdevice (8255) */
1183                         ret = dio200_subdev_8255_init(dev, s,
1184                                                       layout->sdinfo[n]);
1185                         if (ret < 0)
1186                                 return ret;
1187                         break;
1188                 case sd_intr:
1189                         /* 'INTERRUPT' subdevice */
1190                         if (irq) {
1191                                 ret = dio200_subdev_intr_init(dev, s,
1192                                                               DIO200_INT_SCE,
1193                                                               layout->sdinfo[n]
1194                                                              );
1195                                 if (ret < 0)
1196                                         return ret;
1197                                 devpriv->intr_sd = n;
1198                         } else {
1199                                 s->type = COMEDI_SUBD_UNUSED;
1200                         }
1201                         break;
1202                 case sd_timer:
1203                         ret = dio200_subdev_timer_init(dev, s);
1204                         if (ret < 0)
1205                                 return ret;
1206                         break;
1207                 default:
1208                         s->type = COMEDI_SUBD_UNUSED;
1209                         break;
1210                 }
1211         }
1212         sdx = devpriv->intr_sd;
1213         if (sdx >= 0 && sdx < dev->n_subdevices)
1214                 dev->read_subdev = &dev->subdevices[sdx];
1215         if (irq) {
1216                 if (request_irq(irq, dio200_interrupt, req_irq_flags,
1217                                 dev->board_name, dev) >= 0) {
1218                         dev->irq = irq;
1219                 } else {
1220                         dev_warn(dev->class_dev,
1221                                  "warning! irq %u unavailable!\n", irq);
1222                 }
1223         }
1224         dev_info(dev->class_dev, "attached\n");
1225         return 0;
1226 }
1227 EXPORT_SYMBOL_GPL(amplc_dio200_common_attach);
1228
1229 void amplc_dio200_common_detach(struct comedi_device *dev)
1230 {
1231         const struct dio200_board *thisboard = comedi_board(dev);
1232         struct dio200_private *devpriv = dev->private;
1233         const struct dio200_layout *layout;
1234         unsigned n;
1235
1236         if (!thisboard || !devpriv)
1237                 return;
1238         if (dev->irq)
1239                 free_irq(dev->irq, dev);
1240         if (dev->subdevices) {
1241                 layout = dio200_board_layout(thisboard);
1242                 for (n = 0; n < dev->n_subdevices; n++) {
1243                         switch (layout->sdtype[n]) {
1244                         case sd_8254:
1245                         case sd_8255:
1246                         case sd_intr:
1247                                 comedi_spriv_free(dev, n);
1248                                 break;
1249                         case sd_timer:
1250                         default:
1251                                 break;
1252                         }
1253                 }
1254         }
1255 }
1256 EXPORT_SYMBOL_GPL(amplc_dio200_common_detach);
1257
1258 static int __init amplc_dio200_common_init(void)
1259 {
1260         return 0;
1261 }
1262 module_init(amplc_dio200_common_init);
1263
1264 static void __exit amplc_dio200_common_exit(void)
1265 {
1266 }
1267 module_exit(amplc_dio200_common_exit);
1268
1269 MODULE_AUTHOR("Comedi http://www.comedi.org");
1270 MODULE_DESCRIPTION("Comedi helper for amplc_dio200 and amplc_dio200_pci");
1271 MODULE_LICENSE("GPL");