Merge tags 'ib-mfd-clk-gpio-regulator-rtc-v5.13', 'ib-mfd-extcon-v5.13', 'ib-mfd...
[sfrench/cifs-2.6.git] / drivers / staging / comedi / drivers / addi_apci_1500.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * addi_apci_1500.c
4  * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
5  *
6  *      ADDI-DATA GmbH
7  *      Dieselstrasse 3
8  *      D-77833 Ottersweier
9  *      Tel: +19(0)7223/9493-0
10  *      Fax: +49(0)7223/9493-92
11  *      http://www.addi-data.com
12  *      info@addi-data.com
13  */
14
15 #include <linux/module.h>
16 #include <linux/interrupt.h>
17
18 #include "../comedi_pci.h"
19 #include "amcc_s5933.h"
20 #include "z8536.h"
21
22 /*
23  * PCI Bar 0 Register map (devpriv->amcc)
24  * see amcc_s5933.h for register and bit defines
25  */
26
27 /*
28  * PCI Bar 1 Register map (dev->iobase)
29  * see z8536.h for Z8536 internal registers and bit defines
30  */
31 #define APCI1500_Z8536_PORTC_REG        0x00
32 #define APCI1500_Z8536_PORTB_REG        0x01
33 #define APCI1500_Z8536_PORTA_REG        0x02
34 #define APCI1500_Z8536_CTRL_REG         0x03
35
36 /*
37  * PCI Bar 2 Register map (devpriv->addon)
38  */
39 #define APCI1500_CLK_SEL_REG            0x00
40 #define APCI1500_DI_REG                 0x00
41 #define APCI1500_DO_REG                 0x02
42
43 struct apci1500_private {
44         unsigned long amcc;
45         unsigned long addon;
46
47         unsigned int clk_src;
48
49         /* Digital trigger configuration [0]=AND [1]=OR */
50         unsigned int pm[2];     /* Pattern Mask */
51         unsigned int pt[2];     /* Pattern Transition */
52         unsigned int pp[2];     /* Pattern Polarity */
53 };
54
55 static unsigned int z8536_read(struct comedi_device *dev, unsigned int reg)
56 {
57         unsigned long flags;
58         unsigned int val;
59
60         spin_lock_irqsave(&dev->spinlock, flags);
61         outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG);
62         val = inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
63         spin_unlock_irqrestore(&dev->spinlock, flags);
64
65         return val;
66 }
67
68 static void z8536_write(struct comedi_device *dev,
69                         unsigned int val, unsigned int reg)
70 {
71         unsigned long flags;
72
73         spin_lock_irqsave(&dev->spinlock, flags);
74         outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG);
75         outb(val, dev->iobase + APCI1500_Z8536_CTRL_REG);
76         spin_unlock_irqrestore(&dev->spinlock, flags);
77 }
78
79 static void z8536_reset(struct comedi_device *dev)
80 {
81         unsigned long flags;
82
83         /*
84          * Even if the state of the Z8536 is not known, the following
85          * sequence will reset it and put it in State 0.
86          */
87         spin_lock_irqsave(&dev->spinlock, flags);
88         inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
89         outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
90         inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
91         outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
92         outb(1, dev->iobase + APCI1500_Z8536_CTRL_REG);
93         outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
94         spin_unlock_irqrestore(&dev->spinlock, flags);
95
96         /* Disable all Ports and Counter/Timers */
97         z8536_write(dev, 0x00, Z8536_CFG_CTRL_REG);
98
99         /*
100          * Port A is connected to Ditial Input channels 0-7.
101          * Configure the port to allow interrupt detection.
102          */
103         z8536_write(dev, Z8536_PAB_MODE_PTS_BIT |
104                          Z8536_PAB_MODE_SB |
105                          Z8536_PAB_MODE_PMS_DISABLE,
106                     Z8536_PA_MODE_REG);
107         z8536_write(dev, 0xff, Z8536_PB_DPP_REG);
108         z8536_write(dev, 0xff, Z8536_PA_DD_REG);
109
110         /*
111          * Port B is connected to Ditial Input channels 8-13.
112          * Configure the port to allow interrupt detection.
113          *
114          * NOTE: Bits 7 and 6 of Port B are connected to internal
115          * diagnostic signals and bit 7 is inverted.
116          */
117         z8536_write(dev, Z8536_PAB_MODE_PTS_BIT |
118                          Z8536_PAB_MODE_SB |
119                          Z8536_PAB_MODE_PMS_DISABLE,
120                     Z8536_PB_MODE_REG);
121         z8536_write(dev, 0x7f, Z8536_PB_DPP_REG);
122         z8536_write(dev, 0xff, Z8536_PB_DD_REG);
123
124         /*
125          * Not sure what Port C is connected to...
126          */
127         z8536_write(dev, 0x09, Z8536_PC_DPP_REG);
128         z8536_write(dev, 0x0e, Z8536_PC_DD_REG);
129
130         /*
131          * Clear and disable all interrupt sources.
132          *
133          * Just in case, the reset of the Z8536 should have already
134          * done this.
135          */
136         z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PA_CMDSTAT_REG);
137         z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG);
138
139         z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PB_CMDSTAT_REG);
140         z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG);
141
142         z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(0));
143         z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(0));
144
145         z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(1));
146         z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(1));
147
148         z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(2));
149         z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(2));
150
151         /* Disable all interrupts */
152         z8536_write(dev, 0x00, Z8536_INT_CTRL_REG);
153 }
154
155 static void apci1500_port_enable(struct comedi_device *dev, bool enable)
156 {
157         unsigned int cfg;
158
159         cfg = z8536_read(dev, Z8536_CFG_CTRL_REG);
160         if (enable)
161                 cfg |= (Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE);
162         else
163                 cfg &= ~(Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE);
164         z8536_write(dev, cfg, Z8536_CFG_CTRL_REG);
165 }
166
167 static void apci1500_timer_enable(struct comedi_device *dev,
168                                   unsigned int chan, bool enable)
169 {
170         unsigned int bit;
171         unsigned int cfg;
172
173         if (chan == 0)
174                 bit = Z8536_CFG_CTRL_CT1E;
175         else if (chan == 1)
176                 bit = Z8536_CFG_CTRL_CT2E;
177         else
178                 bit = Z8536_CFG_CTRL_PCE_CT3E;
179
180         cfg = z8536_read(dev, Z8536_CFG_CTRL_REG);
181         if (enable) {
182                 cfg |= bit;
183         } else {
184                 cfg &= ~bit;
185                 z8536_write(dev, 0x00, Z8536_CT_CMDSTAT_REG(chan));
186         }
187         z8536_write(dev, cfg, Z8536_CFG_CTRL_REG);
188 }
189
190 static bool apci1500_ack_irq(struct comedi_device *dev,
191                              unsigned int reg)
192 {
193         unsigned int val;
194
195         val = z8536_read(dev, reg);
196         if ((val & Z8536_STAT_IE_IP) == Z8536_STAT_IE_IP) {
197                 val &= 0x0f;                    /* preserve any write bits */
198                 val |= Z8536_CMD_CLR_IP_IUS;
199                 z8536_write(dev, val, reg);
200
201                 return true;
202         }
203         return false;
204 }
205
206 static irqreturn_t apci1500_interrupt(int irq, void *d)
207 {
208         struct comedi_device *dev = d;
209         struct apci1500_private *devpriv = dev->private;
210         struct comedi_subdevice *s = dev->read_subdev;
211         unsigned short status = 0;
212         unsigned int val;
213
214         val = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
215         if (!(val & INTCSR_INTR_ASSERTED))
216                 return IRQ_NONE;
217
218         if (apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG))
219                 status |= 0x01; /* port a event (inputs 0-7) */
220
221         if (apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG)) {
222                 /* Tests if this is an external error */
223                 val = inb(dev->iobase + APCI1500_Z8536_PORTB_REG);
224                 val &= 0xc0;
225                 if (val) {
226                         if (val & 0x80) /* voltage error */
227                                 status |= 0x40;
228                         if (val & 0x40) /* short circuit error */
229                                 status |= 0x80;
230                 } else {
231                         status |= 0x02; /* port b event (inputs 8-13) */
232                 }
233         }
234
235         /*
236          * NOTE: The 'status' returned by the sample matches the
237          * interrupt mask information from the APCI-1500 Users Manual.
238          *
239          *    Mask     Meaning
240          * ----------  ------------------------------------------
241          * 0b00000001  Event 1 has occurred
242          * 0b00000010  Event 2 has occurred
243          * 0b00000100  Counter/timer 1 has run down (not implemented)
244          * 0b00001000  Counter/timer 2 has run down (not implemented)
245          * 0b00010000  Counter 3 has run down (not implemented)
246          * 0b00100000  Watchdog has run down (not implemented)
247          * 0b01000000  Voltage error
248          * 0b10000000  Short-circuit error
249          */
250         comedi_buf_write_samples(s, &status, 1);
251         comedi_handle_events(dev, s);
252
253         return IRQ_HANDLED;
254 }
255
256 static int apci1500_di_cancel(struct comedi_device *dev,
257                               struct comedi_subdevice *s)
258 {
259         /* Disables the main interrupt on the board */
260         z8536_write(dev, 0x00, Z8536_INT_CTRL_REG);
261
262         /* Disable Ports A & B */
263         apci1500_port_enable(dev, false);
264
265         /* Ack any pending interrupts */
266         apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG);
267         apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG);
268
269         /* Disable pattern interrupts */
270         z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG);
271         z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG);
272
273         /* Enable Ports A & B */
274         apci1500_port_enable(dev, true);
275
276         return 0;
277 }
278
279 static int apci1500_di_inttrig_start(struct comedi_device *dev,
280                                      struct comedi_subdevice *s,
281                                      unsigned int trig_num)
282 {
283         struct apci1500_private *devpriv = dev->private;
284         struct comedi_cmd *cmd = &s->async->cmd;
285         unsigned int pa_mode = Z8536_PAB_MODE_PMS_DISABLE;
286         unsigned int pb_mode = Z8536_PAB_MODE_PMS_DISABLE;
287         unsigned int pa_trig = trig_num & 0x01;
288         unsigned int pb_trig = (trig_num >> 1) & 0x01;
289         bool valid_trig = false;
290         unsigned int val;
291
292         if (trig_num != cmd->start_arg)
293                 return -EINVAL;
294
295         /* Disable Ports A & B */
296         apci1500_port_enable(dev, false);
297
298         /* Set Port A for selected trigger pattern */
299         z8536_write(dev, devpriv->pm[pa_trig] & 0xff, Z8536_PA_PM_REG);
300         z8536_write(dev, devpriv->pt[pa_trig] & 0xff, Z8536_PA_PT_REG);
301         z8536_write(dev, devpriv->pp[pa_trig] & 0xff, Z8536_PA_PP_REG);
302
303         /* Set Port B for selected trigger pattern */
304         z8536_write(dev, (devpriv->pm[pb_trig] >> 8) & 0xff, Z8536_PB_PM_REG);
305         z8536_write(dev, (devpriv->pt[pb_trig] >> 8) & 0xff, Z8536_PB_PT_REG);
306         z8536_write(dev, (devpriv->pp[pb_trig] >> 8) & 0xff, Z8536_PB_PP_REG);
307
308         /* Set Port A trigger mode (if enabled) and enable interrupt */
309         if (devpriv->pm[pa_trig] & 0xff) {
310                 pa_mode = pa_trig ? Z8536_PAB_MODE_PMS_AND
311                                   : Z8536_PAB_MODE_PMS_OR;
312
313                 val = z8536_read(dev, Z8536_PA_MODE_REG);
314                 val &= ~Z8536_PAB_MODE_PMS_MASK;
315                 val |= (pa_mode | Z8536_PAB_MODE_IMO);
316                 z8536_write(dev, val, Z8536_PA_MODE_REG);
317
318                 z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PA_CMDSTAT_REG);
319
320                 valid_trig = true;
321
322                 dev_dbg(dev->class_dev,
323                         "Port A configured for %s mode pattern detection\n",
324                         pa_trig ? "AND" : "OR");
325         }
326
327         /* Set Port B trigger mode (if enabled) and enable interrupt */
328         if (devpriv->pm[pb_trig] & 0xff00) {
329                 pb_mode = pb_trig ? Z8536_PAB_MODE_PMS_AND
330                                   : Z8536_PAB_MODE_PMS_OR;
331
332                 val = z8536_read(dev, Z8536_PB_MODE_REG);
333                 val &= ~Z8536_PAB_MODE_PMS_MASK;
334                 val |= (pb_mode | Z8536_PAB_MODE_IMO);
335                 z8536_write(dev, val, Z8536_PB_MODE_REG);
336
337                 z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PB_CMDSTAT_REG);
338
339                 valid_trig = true;
340
341                 dev_dbg(dev->class_dev,
342                         "Port B configured for %s mode pattern detection\n",
343                         pb_trig ? "AND" : "OR");
344         }
345
346         /* Enable Ports A & B */
347         apci1500_port_enable(dev, true);
348
349         if (!valid_trig) {
350                 dev_dbg(dev->class_dev,
351                         "digital trigger %d is not configured\n", trig_num);
352                 return -EINVAL;
353         }
354
355         /* Authorizes the main interrupt on the board */
356         z8536_write(dev, Z8536_INT_CTRL_MIE | Z8536_INT_CTRL_DLC,
357                     Z8536_INT_CTRL_REG);
358
359         return 0;
360 }
361
362 static int apci1500_di_cmd(struct comedi_device *dev,
363                            struct comedi_subdevice *s)
364 {
365         s->async->inttrig = apci1500_di_inttrig_start;
366
367         return 0;
368 }
369
370 static int apci1500_di_cmdtest(struct comedi_device *dev,
371                                struct comedi_subdevice *s,
372                                struct comedi_cmd *cmd)
373 {
374         int err = 0;
375
376         /* Step 1 : check if triggers are trivially valid */
377
378         err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
379         err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
380         err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
381         err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
382         err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
383
384         if (err)
385                 return 1;
386
387         /* Step 2a : make sure trigger sources are unique */
388         /* Step 2b : and mutually compatible */
389
390         /* Step 3: check if arguments are trivially valid */
391
392         /*
393          * Internal start source triggers:
394          *
395          *   0  AND mode for Port A (digital inputs 0-7)
396          *      AND mode for Port B (digital inputs 8-13 and internal signals)
397          *
398          *   1  OR mode for Port A (digital inputs 0-7)
399          *      AND mode for Port B (digital inputs 8-13 and internal signals)
400          *
401          *   2  AND mode for Port A (digital inputs 0-7)
402          *      OR mode for Port B (digital inputs 8-13 and internal signals)
403          *
404          *   3  OR mode for Port A (digital inputs 0-7)
405          *      OR mode for Port B (digital inputs 8-13 and internal signals)
406          */
407         err |= comedi_check_trigger_arg_max(&cmd->start_arg, 3);
408
409         err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
410         err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
411         err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
412                                            cmd->chanlist_len);
413         err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
414
415         if (err)
416                 return 3;
417
418         /* Step 4: fix up any arguments */
419
420         /* Step 5: check channel list if it exists */
421
422         return 0;
423 }
424
425 /*
426  * The pattern-recognition logic must be configured before the digital
427  * input async command is started.
428  *
429  * Digital input channels 0 to 13 can generate interrupts. Channels 14
430  * and 15 are connected to internal board status/diagnostic signals.
431  *
432  * Channel 14 - Voltage error (the external supply is < 5V)
433  * Channel 15 - Short-circuit/overtemperature error
434  *
435  *      data[0] : INSN_CONFIG_DIGITAL_TRIG
436  *      data[1] : trigger number
437  *                0 = AND mode
438  *                1 = OR mode
439  *      data[2] : configuration operation:
440  *                COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
441  *                COMEDI_DIGITAL_TRIG_ENABLE_EDGES = edge interrupts
442  *                COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = level interrupts
443  *      data[3] : left-shift for data[4] and data[5]
444  *      data[4] : rising-edge/high level channels
445  *      data[5] : falling-edge/low level channels
446  */
447 static int apci1500_di_cfg_trig(struct comedi_device *dev,
448                                 struct comedi_subdevice *s,
449                                 struct comedi_insn *insn,
450                                 unsigned int *data)
451 {
452         struct apci1500_private *devpriv = dev->private;
453         unsigned int trig = data[1];
454         unsigned int shift = data[3];
455         unsigned int hi_mask;
456         unsigned int lo_mask;
457         unsigned int chan_mask;
458         unsigned int old_mask;
459         unsigned int pm;
460         unsigned int pt;
461         unsigned int pp;
462         unsigned int invalid_chan;
463
464         if (trig > 1) {
465                 dev_dbg(dev->class_dev,
466                         "invalid digital trigger number (0=AND, 1=OR)\n");
467                 return -EINVAL;
468         }
469
470         if (shift <= 16) {
471                 hi_mask = data[4] << shift;
472                 lo_mask = data[5] << shift;
473                 old_mask = (1U << shift) - 1;
474                 invalid_chan = (data[4] | data[5]) >> (16 - shift);
475         } else {
476                 hi_mask = 0;
477                 lo_mask = 0;
478                 old_mask = 0xffff;
479                 invalid_chan = data[4] | data[5];
480         }
481         chan_mask = hi_mask | lo_mask;
482
483         if (invalid_chan) {
484                 dev_dbg(dev->class_dev, "invalid digital trigger channel\n");
485                 return -EINVAL;
486         }
487
488         pm = devpriv->pm[trig] & old_mask;
489         pt = devpriv->pt[trig] & old_mask;
490         pp = devpriv->pp[trig] & old_mask;
491
492         switch (data[2]) {
493         case COMEDI_DIGITAL_TRIG_DISABLE:
494                 /* clear trigger configuration */
495                 pm = 0;
496                 pt = 0;
497                 pp = 0;
498                 break;
499         case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
500                 pm |= chan_mask;        /* enable channels */
501                 pt |= chan_mask;        /* enable edge detection */
502                 pp |= hi_mask;          /* rising-edge channels */
503                 pp &= ~lo_mask;         /* falling-edge channels */
504                 break;
505         case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS:
506                 pm |= chan_mask;        /* enable channels */
507                 pt &= ~chan_mask;       /* enable level detection */
508                 pp |= hi_mask;          /* high level channels */
509                 pp &= ~lo_mask;         /* low level channels */
510                 break;
511         default:
512                 return -EINVAL;
513         }
514
515         /*
516          * The AND mode trigger can only have one channel (max) enabled
517          * for edge detection.
518          */
519         if (trig == 0) {
520                 int ret = 0;
521                 unsigned int src;
522
523                 src = pt & 0xff;
524                 if (src)
525                         ret |= comedi_check_trigger_is_unique(src);
526
527                 src = (pt >> 8) & 0xff;
528                 if (src)
529                         ret |= comedi_check_trigger_is_unique(src);
530
531                 if (ret) {
532                         dev_dbg(dev->class_dev,
533                                 "invalid AND trigger configuration\n");
534                         return ret;
535                 }
536         }
537
538         /* save the trigger configuration */
539         devpriv->pm[trig] = pm;
540         devpriv->pt[trig] = pt;
541         devpriv->pp[trig] = pp;
542
543         return insn->n;
544 }
545
546 static int apci1500_di_insn_config(struct comedi_device *dev,
547                                    struct comedi_subdevice *s,
548                                    struct comedi_insn *insn,
549                                    unsigned int *data)
550 {
551         switch (data[0]) {
552         case INSN_CONFIG_DIGITAL_TRIG:
553                 return apci1500_di_cfg_trig(dev, s, insn, data);
554         default:
555                 return -EINVAL;
556         }
557 }
558
559 static int apci1500_di_insn_bits(struct comedi_device *dev,
560                                  struct comedi_subdevice *s,
561                                  struct comedi_insn *insn,
562                                  unsigned int *data)
563 {
564         struct apci1500_private *devpriv = dev->private;
565
566         data[1] = inw(devpriv->addon + APCI1500_DI_REG);
567
568         return insn->n;
569 }
570
571 static int apci1500_do_insn_bits(struct comedi_device *dev,
572                                  struct comedi_subdevice *s,
573                                  struct comedi_insn *insn,
574                                  unsigned int *data)
575 {
576         struct apci1500_private *devpriv = dev->private;
577
578         if (comedi_dio_update_state(s, data))
579                 outw(s->state, devpriv->addon + APCI1500_DO_REG);
580
581         data[1] = s->state;
582
583         return insn->n;
584 }
585
586 static int apci1500_timer_insn_config(struct comedi_device *dev,
587                                       struct comedi_subdevice *s,
588                                       struct comedi_insn *insn,
589                                       unsigned int *data)
590 {
591         struct apci1500_private *devpriv = dev->private;
592         unsigned int chan = CR_CHAN(insn->chanspec);
593         unsigned int val;
594
595         switch (data[0]) {
596         case INSN_CONFIG_ARM:
597                 val = data[1] & s->maxdata;
598                 z8536_write(dev, val & 0xff, Z8536_CT_RELOAD_LSB_REG(chan));
599                 z8536_write(dev, (val >> 8) & 0xff,
600                             Z8536_CT_RELOAD_MSB_REG(chan));
601
602                 apci1500_timer_enable(dev, chan, true);
603                 z8536_write(dev, Z8536_CT_CMDSTAT_GCB,
604                             Z8536_CT_CMDSTAT_REG(chan));
605                 break;
606         case INSN_CONFIG_DISARM:
607                 apci1500_timer_enable(dev, chan, false);
608                 break;
609
610         case INSN_CONFIG_GET_COUNTER_STATUS:
611                 data[1] = 0;
612                 val = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
613                 if (val & Z8536_CT_STAT_CIP)
614                         data[1] |= COMEDI_COUNTER_COUNTING;
615                 if (val & Z8536_CT_CMDSTAT_GCB)
616                         data[1] |= COMEDI_COUNTER_ARMED;
617                 if (val & Z8536_STAT_IP) {
618                         data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
619                         apci1500_ack_irq(dev, Z8536_CT_CMDSTAT_REG(chan));
620                 }
621                 data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
622                           COMEDI_COUNTER_TERMINAL_COUNT;
623                 break;
624
625         case INSN_CONFIG_SET_COUNTER_MODE:
626                 /* Simulate the 8254 timer modes */
627                 switch (data[1]) {
628                 case I8254_MODE0:
629                         /* Interrupt on Terminal Count */
630                         val = Z8536_CT_MODE_ECE |
631                               Z8536_CT_MODE_DCS_ONESHOT;
632                         break;
633                 case I8254_MODE1:
634                         /* Hardware Retriggerable One-Shot */
635                         val = Z8536_CT_MODE_ETE |
636                               Z8536_CT_MODE_DCS_ONESHOT;
637                         break;
638                 case I8254_MODE2:
639                         /* Rate Generator */
640                         val = Z8536_CT_MODE_CSC |
641                               Z8536_CT_MODE_DCS_PULSE;
642                         break;
643                 case I8254_MODE3:
644                         /* Square Wave Mode */
645                         val = Z8536_CT_MODE_CSC |
646                               Z8536_CT_MODE_DCS_SQRWAVE;
647                         break;
648                 case I8254_MODE4:
649                         /* Software Triggered Strobe */
650                         val = Z8536_CT_MODE_REB |
651                               Z8536_CT_MODE_DCS_PULSE;
652                         break;
653                 case I8254_MODE5:
654                         /* Hardware Triggered Strobe (watchdog) */
655                         val = Z8536_CT_MODE_EOE |
656                               Z8536_CT_MODE_ETE |
657                               Z8536_CT_MODE_REB |
658                               Z8536_CT_MODE_DCS_PULSE;
659                         break;
660                 default:
661                         return -EINVAL;
662                 }
663                 apci1500_timer_enable(dev, chan, false);
664                 z8536_write(dev, val, Z8536_CT_MODE_REG(chan));
665                 break;
666
667         case INSN_CONFIG_SET_CLOCK_SRC:
668                 if (data[1] > 2)
669                         return -EINVAL;
670                 devpriv->clk_src = data[1];
671                 if (devpriv->clk_src == 2)
672                         devpriv->clk_src = 3;
673                 outw(devpriv->clk_src, devpriv->addon + APCI1500_CLK_SEL_REG);
674                 break;
675         case INSN_CONFIG_GET_CLOCK_SRC:
676                 switch (devpriv->clk_src) {
677                 case 0:
678                         data[1] = 0;            /* 111.86 kHz / 2 */
679                         data[2] = 17879;        /* 17879 ns (approx) */
680                         break;
681                 case 1:
682                         data[1] = 1;            /* 3.49 kHz / 2 */
683                         data[2] = 573066;       /* 573066 ns (approx) */
684                         break;
685                 case 3:
686                         data[1] = 2;            /* 1.747 kHz / 2 */
687                         data[2] = 1164822;      /* 1164822 ns (approx) */
688                         break;
689                 default:
690                         return -EINVAL;
691                 }
692                 break;
693
694         case INSN_CONFIG_SET_GATE_SRC:
695                 if (chan == 0)
696                         return -EINVAL;
697
698                 val = z8536_read(dev, Z8536_CT_MODE_REG(chan));
699                 val &= Z8536_CT_MODE_EGE;
700                 if (data[1] == 1)
701                         val |= Z8536_CT_MODE_EGE;
702                 else if (data[1] > 1)
703                         return -EINVAL;
704                 z8536_write(dev, val, Z8536_CT_MODE_REG(chan));
705                 break;
706         case INSN_CONFIG_GET_GATE_SRC:
707                 if (chan == 0)
708                         return -EINVAL;
709                 break;
710
711         default:
712                 return -EINVAL;
713         }
714         return insn->n;
715 }
716
717 static int apci1500_timer_insn_write(struct comedi_device *dev,
718                                      struct comedi_subdevice *s,
719                                      struct comedi_insn *insn,
720                                      unsigned int *data)
721 {
722         unsigned int chan = CR_CHAN(insn->chanspec);
723         unsigned int cmd;
724
725         cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
726         cmd &= Z8536_CT_CMDSTAT_GCB;    /* preserve gate */
727         cmd |= Z8536_CT_CMD_TCB;        /* set trigger */
728
729         /* software trigger a timer, it only makes sense to do one write */
730         if (insn->n)
731                 z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan));
732
733         return insn->n;
734 }
735
736 static int apci1500_timer_insn_read(struct comedi_device *dev,
737                                     struct comedi_subdevice *s,
738                                     struct comedi_insn *insn,
739                                     unsigned int *data)
740 {
741         unsigned int chan = CR_CHAN(insn->chanspec);
742         unsigned int cmd;
743         unsigned int val;
744         int i;
745
746         cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
747         cmd &= Z8536_CT_CMDSTAT_GCB;    /* preserve gate */
748         cmd |= Z8536_CT_CMD_RCC;        /* set RCC */
749
750         for (i = 0; i < insn->n; i++) {
751                 z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan));
752
753                 val = z8536_read(dev, Z8536_CT_VAL_MSB_REG(chan)) << 8;
754                 val |= z8536_read(dev, Z8536_CT_VAL_LSB_REG(chan));
755
756                 data[i] = val;
757         }
758
759         return insn->n;
760 }
761
762 static int apci1500_auto_attach(struct comedi_device *dev,
763                                 unsigned long context)
764 {
765         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
766         struct apci1500_private *devpriv;
767         struct comedi_subdevice *s;
768         int ret;
769
770         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
771         if (!devpriv)
772                 return -ENOMEM;
773
774         ret = comedi_pci_enable(dev);
775         if (ret)
776                 return ret;
777
778         dev->iobase = pci_resource_start(pcidev, 1);
779         devpriv->amcc = pci_resource_start(pcidev, 0);
780         devpriv->addon = pci_resource_start(pcidev, 2);
781
782         z8536_reset(dev);
783
784         if (pcidev->irq > 0) {
785                 ret = request_irq(pcidev->irq, apci1500_interrupt, IRQF_SHARED,
786                                   dev->board_name, dev);
787                 if (ret == 0)
788                         dev->irq = pcidev->irq;
789         }
790
791         ret = comedi_alloc_subdevices(dev, 3);
792         if (ret)
793                 return ret;
794
795         /* Digital Input subdevice */
796         s = &dev->subdevices[0];
797         s->type         = COMEDI_SUBD_DI;
798         s->subdev_flags = SDF_READABLE;
799         s->n_chan       = 16;
800         s->maxdata      = 1;
801         s->range_table  = &range_digital;
802         s->insn_bits    = apci1500_di_insn_bits;
803         if (dev->irq) {
804                 dev->read_subdev = s;
805                 s->subdev_flags |= SDF_CMD_READ;
806                 s->len_chanlist = 1;
807                 s->insn_config  = apci1500_di_insn_config;
808                 s->do_cmdtest   = apci1500_di_cmdtest;
809                 s->do_cmd       = apci1500_di_cmd;
810                 s->cancel       = apci1500_di_cancel;
811         }
812
813         /* Digital Output subdevice */
814         s = &dev->subdevices[1];
815         s->type         = COMEDI_SUBD_DO;
816         s->subdev_flags = SDF_WRITABLE;
817         s->n_chan       = 16;
818         s->maxdata      = 1;
819         s->range_table  = &range_digital;
820         s->insn_bits    = apci1500_do_insn_bits;
821
822         /* reset all the digital outputs */
823         outw(0x0, devpriv->addon + APCI1500_DO_REG);
824
825         /* Counter/Timer(Watchdog) subdevice */
826         s = &dev->subdevices[2];
827         s->type         = COMEDI_SUBD_TIMER;
828         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
829         s->n_chan       = 3;
830         s->maxdata      = 0xffff;
831         s->range_table  = &range_unknown;
832         s->insn_config  = apci1500_timer_insn_config;
833         s->insn_write   = apci1500_timer_insn_write;
834         s->insn_read    = apci1500_timer_insn_read;
835
836         /* Enable the PCI interrupt */
837         if (dev->irq) {
838                 outl(0x2000 | INTCSR_INBOX_FULL_INT,
839                      devpriv->amcc + AMCC_OP_REG_INTCSR);
840                 inl(devpriv->amcc + AMCC_OP_REG_IMB1);
841                 inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
842                 outl(INTCSR_INBOX_INTR_STATUS | 0x2000 | INTCSR_INBOX_FULL_INT,
843                      devpriv->amcc + AMCC_OP_REG_INTCSR);
844         }
845
846         return 0;
847 }
848
849 static void apci1500_detach(struct comedi_device *dev)
850 {
851         struct apci1500_private *devpriv = dev->private;
852
853         if (devpriv->amcc)
854                 outl(0x0, devpriv->amcc + AMCC_OP_REG_INTCSR);
855         comedi_pci_detach(dev);
856 }
857
858 static struct comedi_driver apci1500_driver = {
859         .driver_name    = "addi_apci_1500",
860         .module         = THIS_MODULE,
861         .auto_attach    = apci1500_auto_attach,
862         .detach         = apci1500_detach,
863 };
864
865 static int apci1500_pci_probe(struct pci_dev *dev,
866                               const struct pci_device_id *id)
867 {
868         return comedi_pci_auto_config(dev, &apci1500_driver, id->driver_data);
869 }
870
871 static const struct pci_device_id apci1500_pci_table[] = {
872         { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80fc) },
873         { 0 }
874 };
875 MODULE_DEVICE_TABLE(pci, apci1500_pci_table);
876
877 static struct pci_driver apci1500_pci_driver = {
878         .name           = "addi_apci_1500",
879         .id_table       = apci1500_pci_table,
880         .probe          = apci1500_pci_probe,
881         .remove         = comedi_pci_auto_unconfig,
882 };
883 module_comedi_pci_driver(apci1500_driver, apci1500_pci_driver);
884
885 MODULE_AUTHOR("Comedi https://www.comedi.org");
886 MODULE_DESCRIPTION("ADDI-DATA APCI-1500, 16 channel DI / 16 channel DO boards");
887 MODULE_LICENSE("GPL");