Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux-2.6-microblaze.git] / drivers / counter / 104-quad-8.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Counter driver for the ACCES 104-QUAD-8
4  * Copyright (C) 2016 William Breathitt Gray
5  *
6  * This driver supports the ACCES 104-QUAD-8 and ACCES 104-QUAD-4.
7  */
8 #include <linux/bitops.h>
9 #include <linux/counter.h>
10 #include <linux/device.h>
11 #include <linux/errno.h>
12 #include <linux/io.h>
13 #include <linux/ioport.h>
14 #include <linux/interrupt.h>
15 #include <linux/isa.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/moduleparam.h>
19 #include <linux/types.h>
20 #include <linux/spinlock.h>
21
22 #define QUAD8_EXTENT 32
23
24 static unsigned int base[max_num_isa_dev(QUAD8_EXTENT)];
25 static unsigned int num_quad8;
26 module_param_hw_array(base, uint, ioport, &num_quad8, 0);
27 MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
28
29 static unsigned int irq[max_num_isa_dev(QUAD8_EXTENT)];
30 module_param_hw_array(irq, uint, irq, NULL, 0);
31 MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers");
32
33 #define QUAD8_NUM_COUNTERS 8
34
35 /**
36  * struct quad8 - device private data structure
37  * @lock:               lock to prevent clobbering device states during R/W ops
38  * @counter:            instance of the counter_device
39  * @fck_prescaler:      array of filter clock prescaler configurations
40  * @preset:             array of preset values
41  * @count_mode:         array of count mode configurations
42  * @quadrature_mode:    array of quadrature mode configurations
43  * @quadrature_scale:   array of quadrature mode scale configurations
44  * @ab_enable:          array of A and B inputs enable configurations
45  * @preset_enable:      array of set_to_preset_on_index attribute configurations
46  * @irq_trigger:        array of current IRQ trigger function configurations
47  * @next_irq_trigger:   array of next IRQ trigger function configurations
48  * @synchronous_mode:   array of index function synchronous mode configurations
49  * @index_polarity:     array of index function polarity configurations
50  * @cable_fault_enable: differential encoder cable status enable configurations
51  * @base:               base port address of the device
52  */
53 struct quad8 {
54         spinlock_t lock;
55         struct counter_device counter;
56         unsigned int fck_prescaler[QUAD8_NUM_COUNTERS];
57         unsigned int preset[QUAD8_NUM_COUNTERS];
58         unsigned int count_mode[QUAD8_NUM_COUNTERS];
59         unsigned int quadrature_mode[QUAD8_NUM_COUNTERS];
60         unsigned int quadrature_scale[QUAD8_NUM_COUNTERS];
61         unsigned int ab_enable[QUAD8_NUM_COUNTERS];
62         unsigned int preset_enable[QUAD8_NUM_COUNTERS];
63         unsigned int irq_trigger[QUAD8_NUM_COUNTERS];
64         unsigned int next_irq_trigger[QUAD8_NUM_COUNTERS];
65         unsigned int synchronous_mode[QUAD8_NUM_COUNTERS];
66         unsigned int index_polarity[QUAD8_NUM_COUNTERS];
67         unsigned int cable_fault_enable;
68         unsigned int base;
69 };
70
71 #define QUAD8_REG_INTERRUPT_STATUS 0x10
72 #define QUAD8_REG_CHAN_OP 0x11
73 #define QUAD8_REG_INDEX_INTERRUPT 0x12
74 #define QUAD8_REG_INDEX_INPUT_LEVELS 0x16
75 #define QUAD8_DIFF_ENCODER_CABLE_STATUS 0x17
76 /* Borrow Toggle flip-flop */
77 #define QUAD8_FLAG_BT BIT(0)
78 /* Carry Toggle flip-flop */
79 #define QUAD8_FLAG_CT BIT(1)
80 /* Error flag */
81 #define QUAD8_FLAG_E BIT(4)
82 /* Up/Down flag */
83 #define QUAD8_FLAG_UD BIT(5)
84 /* Reset and Load Signal Decoders */
85 #define QUAD8_CTR_RLD 0x00
86 /* Counter Mode Register */
87 #define QUAD8_CTR_CMR 0x20
88 /* Input / Output Control Register */
89 #define QUAD8_CTR_IOR 0x40
90 /* Index Control Register */
91 #define QUAD8_CTR_IDR 0x60
92 /* Reset Byte Pointer (three byte data pointer) */
93 #define QUAD8_RLD_RESET_BP 0x01
94 /* Reset Counter */
95 #define QUAD8_RLD_RESET_CNTR 0x02
96 /* Reset Borrow Toggle, Carry Toggle, Compare Toggle, and Sign flags */
97 #define QUAD8_RLD_RESET_FLAGS 0x04
98 /* Reset Error flag */
99 #define QUAD8_RLD_RESET_E 0x06
100 /* Preset Register to Counter */
101 #define QUAD8_RLD_PRESET_CNTR 0x08
102 /* Transfer Counter to Output Latch */
103 #define QUAD8_RLD_CNTR_OUT 0x10
104 /* Transfer Preset Register LSB to FCK Prescaler */
105 #define QUAD8_RLD_PRESET_PSC 0x18
106 #define QUAD8_CHAN_OP_RESET_COUNTERS 0x01
107 #define QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC 0x04
108 #define QUAD8_CMR_QUADRATURE_X1 0x08
109 #define QUAD8_CMR_QUADRATURE_X2 0x10
110 #define QUAD8_CMR_QUADRATURE_X4 0x18
111
112 static int quad8_signal_read(struct counter_device *counter,
113                              struct counter_signal *signal,
114                              enum counter_signal_level *level)
115 {
116         const struct quad8 *const priv = counter->priv;
117         unsigned int state;
118
119         /* Only Index signal levels can be read */
120         if (signal->id < 16)
121                 return -EINVAL;
122
123         state = inb(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS)
124                 & BIT(signal->id - 16);
125
126         *level = (state) ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
127
128         return 0;
129 }
130
131 static int quad8_count_read(struct counter_device *counter,
132                             struct counter_count *count, u64 *val)
133 {
134         struct quad8 *const priv = counter->priv;
135         const int base_offset = priv->base + 2 * count->id;
136         unsigned int flags;
137         unsigned int borrow;
138         unsigned int carry;
139         unsigned long irqflags;
140         int i;
141
142         flags = inb(base_offset + 1);
143         borrow = flags & QUAD8_FLAG_BT;
144         carry = !!(flags & QUAD8_FLAG_CT);
145
146         /* Borrow XOR Carry effectively doubles count range */
147         *val = (unsigned long)(borrow ^ carry) << 24;
148
149         spin_lock_irqsave(&priv->lock, irqflags);
150
151         /* Reset Byte Pointer; transfer Counter to Output Latch */
152         outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
153              base_offset + 1);
154
155         for (i = 0; i < 3; i++)
156                 *val |= (unsigned long)inb(base_offset) << (8 * i);
157
158         spin_unlock_irqrestore(&priv->lock, irqflags);
159
160         return 0;
161 }
162
163 static int quad8_count_write(struct counter_device *counter,
164                              struct counter_count *count, u64 val)
165 {
166         struct quad8 *const priv = counter->priv;
167         const int base_offset = priv->base + 2 * count->id;
168         unsigned long irqflags;
169         int i;
170
171         /* Only 24-bit values are supported */
172         if (val > 0xFFFFFF)
173                 return -ERANGE;
174
175         spin_lock_irqsave(&priv->lock, irqflags);
176
177         /* Reset Byte Pointer */
178         outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
179
180         /* Counter can only be set via Preset Register */
181         for (i = 0; i < 3; i++)
182                 outb(val >> (8 * i), base_offset);
183
184         /* Transfer Preset Register to Counter */
185         outb(QUAD8_CTR_RLD | QUAD8_RLD_PRESET_CNTR, base_offset + 1);
186
187         /* Reset Byte Pointer */
188         outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
189
190         /* Set Preset Register back to original value */
191         val = priv->preset[count->id];
192         for (i = 0; i < 3; i++)
193                 outb(val >> (8 * i), base_offset);
194
195         /* Reset Borrow, Carry, Compare, and Sign flags */
196         outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, base_offset + 1);
197         /* Reset Error flag */
198         outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
199
200         spin_unlock_irqrestore(&priv->lock, irqflags);
201
202         return 0;
203 }
204
205 static const enum counter_function quad8_count_functions_list[] = {
206         COUNTER_FUNCTION_PULSE_DIRECTION,
207         COUNTER_FUNCTION_QUADRATURE_X1_A,
208         COUNTER_FUNCTION_QUADRATURE_X2_A,
209         COUNTER_FUNCTION_QUADRATURE_X4,
210 };
211
212 static int quad8_function_read(struct counter_device *counter,
213                                struct counter_count *count,
214                                enum counter_function *function)
215 {
216         struct quad8 *const priv = counter->priv;
217         const int id = count->id;
218         unsigned long irqflags;
219
220         spin_lock_irqsave(&priv->lock, irqflags);
221
222         if (priv->quadrature_mode[id])
223                 switch (priv->quadrature_scale[id]) {
224                 case 0:
225                         *function = COUNTER_FUNCTION_QUADRATURE_X1_A;
226                         break;
227                 case 1:
228                         *function = COUNTER_FUNCTION_QUADRATURE_X2_A;
229                         break;
230                 case 2:
231                         *function = COUNTER_FUNCTION_QUADRATURE_X4;
232                         break;
233                 }
234         else
235                 *function = COUNTER_FUNCTION_PULSE_DIRECTION;
236
237         spin_unlock_irqrestore(&priv->lock, irqflags);
238
239         return 0;
240 }
241
242 static int quad8_function_write(struct counter_device *counter,
243                                 struct counter_count *count,
244                                 enum counter_function function)
245 {
246         struct quad8 *const priv = counter->priv;
247         const int id = count->id;
248         unsigned int *const quadrature_mode = priv->quadrature_mode + id;
249         unsigned int *const scale = priv->quadrature_scale + id;
250         unsigned int *const synchronous_mode = priv->synchronous_mode + id;
251         const int base_offset = priv->base + 2 * id + 1;
252         unsigned long irqflags;
253         unsigned int mode_cfg;
254         unsigned int idr_cfg;
255
256         spin_lock_irqsave(&priv->lock, irqflags);
257
258         mode_cfg = priv->count_mode[id] << 1;
259         idr_cfg = priv->index_polarity[id] << 1;
260
261         if (function == COUNTER_FUNCTION_PULSE_DIRECTION) {
262                 *quadrature_mode = 0;
263
264                 /* Quadrature scaling only available in quadrature mode */
265                 *scale = 0;
266
267                 /* Synchronous function not supported in non-quadrature mode */
268                 if (*synchronous_mode) {
269                         *synchronous_mode = 0;
270                         /* Disable synchronous function mode */
271                         outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
272                 }
273         } else {
274                 *quadrature_mode = 1;
275
276                 switch (function) {
277                 case COUNTER_FUNCTION_QUADRATURE_X1_A:
278                         *scale = 0;
279                         mode_cfg |= QUAD8_CMR_QUADRATURE_X1;
280                         break;
281                 case COUNTER_FUNCTION_QUADRATURE_X2_A:
282                         *scale = 1;
283                         mode_cfg |= QUAD8_CMR_QUADRATURE_X2;
284                         break;
285                 case COUNTER_FUNCTION_QUADRATURE_X4:
286                         *scale = 2;
287                         mode_cfg |= QUAD8_CMR_QUADRATURE_X4;
288                         break;
289                 default:
290                         /* should never reach this path */
291                         spin_unlock_irqrestore(&priv->lock, irqflags);
292                         return -EINVAL;
293                 }
294         }
295
296         /* Load mode configuration to Counter Mode Register */
297         outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
298
299         spin_unlock_irqrestore(&priv->lock, irqflags);
300
301         return 0;
302 }
303
304 static int quad8_direction_read(struct counter_device *counter,
305                                 struct counter_count *count,
306                                 enum counter_count_direction *direction)
307 {
308         const struct quad8 *const priv = counter->priv;
309         unsigned int ud_flag;
310         const unsigned int flag_addr = priv->base + 2 * count->id + 1;
311
312         /* U/D flag: nonzero = up, zero = down */
313         ud_flag = inb(flag_addr) & QUAD8_FLAG_UD;
314
315         *direction = (ud_flag) ? COUNTER_COUNT_DIRECTION_FORWARD :
316                 COUNTER_COUNT_DIRECTION_BACKWARD;
317
318         return 0;
319 }
320
321 static const enum counter_synapse_action quad8_index_actions_list[] = {
322         COUNTER_SYNAPSE_ACTION_NONE,
323         COUNTER_SYNAPSE_ACTION_RISING_EDGE,
324 };
325
326 static const enum counter_synapse_action quad8_synapse_actions_list[] = {
327         COUNTER_SYNAPSE_ACTION_NONE,
328         COUNTER_SYNAPSE_ACTION_RISING_EDGE,
329         COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
330         COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
331 };
332
333 static int quad8_action_read(struct counter_device *counter,
334                              struct counter_count *count,
335                              struct counter_synapse *synapse,
336                              enum counter_synapse_action *action)
337 {
338         struct quad8 *const priv = counter->priv;
339         int err;
340         enum counter_function function;
341         const size_t signal_a_id = count->synapses[0].signal->id;
342         enum counter_count_direction direction;
343
344         /* Handle Index signals */
345         if (synapse->signal->id >= 16) {
346                 if (priv->preset_enable[count->id])
347                         *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
348                 else
349                         *action = COUNTER_SYNAPSE_ACTION_NONE;
350
351                 return 0;
352         }
353
354         err = quad8_function_read(counter, count, &function);
355         if (err)
356                 return err;
357
358         /* Default action mode */
359         *action = COUNTER_SYNAPSE_ACTION_NONE;
360
361         /* Determine action mode based on current count function mode */
362         switch (function) {
363         case COUNTER_FUNCTION_PULSE_DIRECTION:
364                 if (synapse->signal->id == signal_a_id)
365                         *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
366                 return 0;
367         case COUNTER_FUNCTION_QUADRATURE_X1_A:
368                 if (synapse->signal->id == signal_a_id) {
369                         err = quad8_direction_read(counter, count, &direction);
370                         if (err)
371                                 return err;
372
373                         if (direction == COUNTER_COUNT_DIRECTION_FORWARD)
374                                 *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
375                         else
376                                 *action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE;
377                 }
378                 return 0;
379         case COUNTER_FUNCTION_QUADRATURE_X2_A:
380                 if (synapse->signal->id == signal_a_id)
381                         *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
382                 return 0;
383         case COUNTER_FUNCTION_QUADRATURE_X4:
384                 *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
385                 return 0;
386         default:
387                 /* should never reach this path */
388                 return -EINVAL;
389         }
390 }
391
392 enum {
393         QUAD8_EVENT_NONE = -1,
394         QUAD8_EVENT_CARRY = 0,
395         QUAD8_EVENT_COMPARE = 1,
396         QUAD8_EVENT_CARRY_BORROW = 2,
397         QUAD8_EVENT_INDEX = 3,
398 };
399
400 static int quad8_events_configure(struct counter_device *counter)
401 {
402         struct quad8 *const priv = counter->priv;
403         unsigned long irq_enabled = 0;
404         unsigned long irqflags;
405         size_t channel;
406         unsigned long ior_cfg;
407         unsigned long base_offset;
408
409         spin_lock_irqsave(&priv->lock, irqflags);
410
411         /* Enable interrupts for the requested channels, disable for the rest */
412         for (channel = 0; channel < QUAD8_NUM_COUNTERS; channel++) {
413                 if (priv->next_irq_trigger[channel] == QUAD8_EVENT_NONE)
414                         continue;
415
416                 if (priv->irq_trigger[channel] != priv->next_irq_trigger[channel]) {
417                         /* Save new IRQ function configuration */
418                         priv->irq_trigger[channel] = priv->next_irq_trigger[channel];
419
420                         /* Load configuration to I/O Control Register */
421                         ior_cfg = priv->ab_enable[channel] |
422                                   priv->preset_enable[channel] << 1 |
423                                   priv->irq_trigger[channel] << 3;
424                         base_offset = priv->base + 2 * channel + 1;
425                         outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
426                 }
427
428                 /* Reset next IRQ trigger function configuration */
429                 priv->next_irq_trigger[channel] = QUAD8_EVENT_NONE;
430
431                 /* Enable IRQ line */
432                 irq_enabled |= BIT(channel);
433         }
434
435         outb(irq_enabled, priv->base + QUAD8_REG_INDEX_INTERRUPT);
436
437         spin_unlock_irqrestore(&priv->lock, irqflags);
438
439         return 0;
440 }
441
442 static int quad8_watch_validate(struct counter_device *counter,
443                                 const struct counter_watch *watch)
444 {
445         struct quad8 *const priv = counter->priv;
446
447         if (watch->channel > QUAD8_NUM_COUNTERS - 1)
448                 return -EINVAL;
449
450         switch (watch->event) {
451         case COUNTER_EVENT_OVERFLOW:
452                 if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
453                         priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_CARRY;
454                 else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_CARRY)
455                         return -EINVAL;
456                 return 0;
457         case COUNTER_EVENT_THRESHOLD:
458                 if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
459                         priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_COMPARE;
460                 else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_COMPARE)
461                         return -EINVAL;
462                 return 0;
463         case COUNTER_EVENT_OVERFLOW_UNDERFLOW:
464                 if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
465                         priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_CARRY_BORROW;
466                 else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_CARRY_BORROW)
467                         return -EINVAL;
468                 return 0;
469         case COUNTER_EVENT_INDEX:
470                 if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
471                         priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_INDEX;
472                 else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_INDEX)
473                         return -EINVAL;
474                 return 0;
475         default:
476                 return -EINVAL;
477         }
478 }
479
480 static const struct counter_ops quad8_ops = {
481         .signal_read = quad8_signal_read,
482         .count_read = quad8_count_read,
483         .count_write = quad8_count_write,
484         .function_read = quad8_function_read,
485         .function_write = quad8_function_write,
486         .action_read = quad8_action_read,
487         .events_configure = quad8_events_configure,
488         .watch_validate = quad8_watch_validate,
489 };
490
491 static const char *const quad8_index_polarity_modes[] = {
492         "negative",
493         "positive"
494 };
495
496 static int quad8_index_polarity_get(struct counter_device *counter,
497                                     struct counter_signal *signal,
498                                     u32 *index_polarity)
499 {
500         const struct quad8 *const priv = counter->priv;
501         const size_t channel_id = signal->id - 16;
502
503         *index_polarity = priv->index_polarity[channel_id];
504
505         return 0;
506 }
507
508 static int quad8_index_polarity_set(struct counter_device *counter,
509                                     struct counter_signal *signal,
510                                     u32 index_polarity)
511 {
512         struct quad8 *const priv = counter->priv;
513         const size_t channel_id = signal->id - 16;
514         const int base_offset = priv->base + 2 * channel_id + 1;
515         unsigned long irqflags;
516         unsigned int idr_cfg = index_polarity << 1;
517
518         spin_lock_irqsave(&priv->lock, irqflags);
519
520         idr_cfg |= priv->synchronous_mode[channel_id];
521
522         priv->index_polarity[channel_id] = index_polarity;
523
524         /* Load Index Control configuration to Index Control Register */
525         outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
526
527         spin_unlock_irqrestore(&priv->lock, irqflags);
528
529         return 0;
530 }
531
532 static const char *const quad8_synchronous_modes[] = {
533         "non-synchronous",
534         "synchronous"
535 };
536
537 static int quad8_synchronous_mode_get(struct counter_device *counter,
538                                       struct counter_signal *signal,
539                                       u32 *synchronous_mode)
540 {
541         const struct quad8 *const priv = counter->priv;
542         const size_t channel_id = signal->id - 16;
543
544         *synchronous_mode = priv->synchronous_mode[channel_id];
545
546         return 0;
547 }
548
549 static int quad8_synchronous_mode_set(struct counter_device *counter,
550                                       struct counter_signal *signal,
551                                       u32 synchronous_mode)
552 {
553         struct quad8 *const priv = counter->priv;
554         const size_t channel_id = signal->id - 16;
555         const int base_offset = priv->base + 2 * channel_id + 1;
556         unsigned long irqflags;
557         unsigned int idr_cfg = synchronous_mode;
558
559         spin_lock_irqsave(&priv->lock, irqflags);
560
561         idr_cfg |= priv->index_polarity[channel_id] << 1;
562
563         /* Index function must be non-synchronous in non-quadrature mode */
564         if (synchronous_mode && !priv->quadrature_mode[channel_id]) {
565                 spin_unlock_irqrestore(&priv->lock, irqflags);
566                 return -EINVAL;
567         }
568
569         priv->synchronous_mode[channel_id] = synchronous_mode;
570
571         /* Load Index Control configuration to Index Control Register */
572         outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
573
574         spin_unlock_irqrestore(&priv->lock, irqflags);
575
576         return 0;
577 }
578
579 static int quad8_count_floor_read(struct counter_device *counter,
580                                   struct counter_count *count, u64 *floor)
581 {
582         /* Only a floor of 0 is supported */
583         *floor = 0;
584
585         return 0;
586 }
587
588 static int quad8_count_mode_read(struct counter_device *counter,
589                                  struct counter_count *count,
590                                  enum counter_count_mode *cnt_mode)
591 {
592         const struct quad8 *const priv = counter->priv;
593
594         /* Map 104-QUAD-8 count mode to Generic Counter count mode */
595         switch (priv->count_mode[count->id]) {
596         case 0:
597                 *cnt_mode = COUNTER_COUNT_MODE_NORMAL;
598                 break;
599         case 1:
600                 *cnt_mode = COUNTER_COUNT_MODE_RANGE_LIMIT;
601                 break;
602         case 2:
603                 *cnt_mode = COUNTER_COUNT_MODE_NON_RECYCLE;
604                 break;
605         case 3:
606                 *cnt_mode = COUNTER_COUNT_MODE_MODULO_N;
607                 break;
608         }
609
610         return 0;
611 }
612
613 static int quad8_count_mode_write(struct counter_device *counter,
614                                   struct counter_count *count,
615                                   enum counter_count_mode cnt_mode)
616 {
617         struct quad8 *const priv = counter->priv;
618         unsigned int count_mode;
619         unsigned int mode_cfg;
620         const int base_offset = priv->base + 2 * count->id + 1;
621         unsigned long irqflags;
622
623         /* Map Generic Counter count mode to 104-QUAD-8 count mode */
624         switch (cnt_mode) {
625         case COUNTER_COUNT_MODE_NORMAL:
626                 count_mode = 0;
627                 break;
628         case COUNTER_COUNT_MODE_RANGE_LIMIT:
629                 count_mode = 1;
630                 break;
631         case COUNTER_COUNT_MODE_NON_RECYCLE:
632                 count_mode = 2;
633                 break;
634         case COUNTER_COUNT_MODE_MODULO_N:
635                 count_mode = 3;
636                 break;
637         default:
638                 /* should never reach this path */
639                 return -EINVAL;
640         }
641
642         spin_lock_irqsave(&priv->lock, irqflags);
643
644         priv->count_mode[count->id] = count_mode;
645
646         /* Set count mode configuration value */
647         mode_cfg = count_mode << 1;
648
649         /* Add quadrature mode configuration */
650         if (priv->quadrature_mode[count->id])
651                 mode_cfg |= (priv->quadrature_scale[count->id] + 1) << 3;
652
653         /* Load mode configuration to Counter Mode Register */
654         outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
655
656         spin_unlock_irqrestore(&priv->lock, irqflags);
657
658         return 0;
659 }
660
661 static int quad8_count_enable_read(struct counter_device *counter,
662                                    struct counter_count *count, u8 *enable)
663 {
664         const struct quad8 *const priv = counter->priv;
665
666         *enable = priv->ab_enable[count->id];
667
668         return 0;
669 }
670
671 static int quad8_count_enable_write(struct counter_device *counter,
672                                     struct counter_count *count, u8 enable)
673 {
674         struct quad8 *const priv = counter->priv;
675         const int base_offset = priv->base + 2 * count->id;
676         unsigned long irqflags;
677         unsigned int ior_cfg;
678
679         spin_lock_irqsave(&priv->lock, irqflags);
680
681         priv->ab_enable[count->id] = enable;
682
683         ior_cfg = enable | priv->preset_enable[count->id] << 1 |
684                   priv->irq_trigger[count->id] << 3;
685
686         /* Load I/O control configuration */
687         outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
688
689         spin_unlock_irqrestore(&priv->lock, irqflags);
690
691         return 0;
692 }
693
694 static const char *const quad8_noise_error_states[] = {
695         "No excessive noise is present at the count inputs",
696         "Excessive noise is present at the count inputs"
697 };
698
699 static int quad8_error_noise_get(struct counter_device *counter,
700                                  struct counter_count *count, u32 *noise_error)
701 {
702         const struct quad8 *const priv = counter->priv;
703         const int base_offset = priv->base + 2 * count->id + 1;
704
705         *noise_error = !!(inb(base_offset) & QUAD8_FLAG_E);
706
707         return 0;
708 }
709
710 static int quad8_count_preset_read(struct counter_device *counter,
711                                    struct counter_count *count, u64 *preset)
712 {
713         const struct quad8 *const priv = counter->priv;
714
715         *preset = priv->preset[count->id];
716
717         return 0;
718 }
719
720 static void quad8_preset_register_set(struct quad8 *const priv, const int id,
721                                       const unsigned int preset)
722 {
723         const unsigned int base_offset = priv->base + 2 * id;
724         int i;
725
726         priv->preset[id] = preset;
727
728         /* Reset Byte Pointer */
729         outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
730
731         /* Set Preset Register */
732         for (i = 0; i < 3; i++)
733                 outb(preset >> (8 * i), base_offset);
734 }
735
736 static int quad8_count_preset_write(struct counter_device *counter,
737                                     struct counter_count *count, u64 preset)
738 {
739         struct quad8 *const priv = counter->priv;
740         unsigned long irqflags;
741
742         /* Only 24-bit values are supported */
743         if (preset > 0xFFFFFF)
744                 return -ERANGE;
745
746         spin_lock_irqsave(&priv->lock, irqflags);
747
748         quad8_preset_register_set(priv, count->id, preset);
749
750         spin_unlock_irqrestore(&priv->lock, irqflags);
751
752         return 0;
753 }
754
755 static int quad8_count_ceiling_read(struct counter_device *counter,
756                                     struct counter_count *count, u64 *ceiling)
757 {
758         struct quad8 *const priv = counter->priv;
759         unsigned long irqflags;
760
761         spin_lock_irqsave(&priv->lock, irqflags);
762
763         /* Range Limit and Modulo-N count modes use preset value as ceiling */
764         switch (priv->count_mode[count->id]) {
765         case 1:
766         case 3:
767                 *ceiling = priv->preset[count->id];
768                 break;
769         default:
770                 /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */
771                 *ceiling = 0x1FFFFFF;
772                 break;
773         }
774
775         spin_unlock_irqrestore(&priv->lock, irqflags);
776
777         return 0;
778 }
779
780 static int quad8_count_ceiling_write(struct counter_device *counter,
781                                      struct counter_count *count, u64 ceiling)
782 {
783         struct quad8 *const priv = counter->priv;
784         unsigned long irqflags;
785
786         /* Only 24-bit values are supported */
787         if (ceiling > 0xFFFFFF)
788                 return -ERANGE;
789
790         spin_lock_irqsave(&priv->lock, irqflags);
791
792         /* Range Limit and Modulo-N count modes use preset value as ceiling */
793         switch (priv->count_mode[count->id]) {
794         case 1:
795         case 3:
796                 quad8_preset_register_set(priv, count->id, ceiling);
797                 spin_unlock_irqrestore(&priv->lock, irqflags);
798                 return 0;
799         }
800
801         spin_unlock_irqrestore(&priv->lock, irqflags);
802
803         return -EINVAL;
804 }
805
806 static int quad8_count_preset_enable_read(struct counter_device *counter,
807                                           struct counter_count *count,
808                                           u8 *preset_enable)
809 {
810         const struct quad8 *const priv = counter->priv;
811
812         *preset_enable = !priv->preset_enable[count->id];
813
814         return 0;
815 }
816
817 static int quad8_count_preset_enable_write(struct counter_device *counter,
818                                            struct counter_count *count,
819                                            u8 preset_enable)
820 {
821         struct quad8 *const priv = counter->priv;
822         const int base_offset = priv->base + 2 * count->id + 1;
823         unsigned long irqflags;
824         unsigned int ior_cfg;
825
826         /* Preset enable is active low in Input/Output Control register */
827         preset_enable = !preset_enable;
828
829         spin_lock_irqsave(&priv->lock, irqflags);
830
831         priv->preset_enable[count->id] = preset_enable;
832
833         ior_cfg = priv->ab_enable[count->id] | preset_enable << 1 |
834                   priv->irq_trigger[count->id] << 3;
835
836         /* Load I/O control configuration to Input / Output Control Register */
837         outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
838
839         spin_unlock_irqrestore(&priv->lock, irqflags);
840
841         return 0;
842 }
843
844 static int quad8_signal_cable_fault_read(struct counter_device *counter,
845                                          struct counter_signal *signal,
846                                          u8 *cable_fault)
847 {
848         struct quad8 *const priv = counter->priv;
849         const size_t channel_id = signal->id / 2;
850         unsigned long irqflags;
851         bool disabled;
852         unsigned int status;
853
854         spin_lock_irqsave(&priv->lock, irqflags);
855
856         disabled = !(priv->cable_fault_enable & BIT(channel_id));
857
858         if (disabled) {
859                 spin_unlock_irqrestore(&priv->lock, irqflags);
860                 return -EINVAL;
861         }
862
863         /* Logic 0 = cable fault */
864         status = inb(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
865
866         spin_unlock_irqrestore(&priv->lock, irqflags);
867
868         /* Mask respective channel and invert logic */
869         *cable_fault = !(status & BIT(channel_id));
870
871         return 0;
872 }
873
874 static int quad8_signal_cable_fault_enable_read(struct counter_device *counter,
875                                                 struct counter_signal *signal,
876                                                 u8 *enable)
877 {
878         const struct quad8 *const priv = counter->priv;
879         const size_t channel_id = signal->id / 2;
880
881         *enable = !!(priv->cable_fault_enable & BIT(channel_id));
882
883         return 0;
884 }
885
886 static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
887                                                  struct counter_signal *signal,
888                                                  u8 enable)
889 {
890         struct quad8 *const priv = counter->priv;
891         const size_t channel_id = signal->id / 2;
892         unsigned long irqflags;
893         unsigned int cable_fault_enable;
894
895         spin_lock_irqsave(&priv->lock, irqflags);
896
897         if (enable)
898                 priv->cable_fault_enable |= BIT(channel_id);
899         else
900                 priv->cable_fault_enable &= ~BIT(channel_id);
901
902         /* Enable is active low in Differential Encoder Cable Status register */
903         cable_fault_enable = ~priv->cable_fault_enable;
904
905         outb(cable_fault_enable, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
906
907         spin_unlock_irqrestore(&priv->lock, irqflags);
908
909         return 0;
910 }
911
912 static int quad8_signal_fck_prescaler_read(struct counter_device *counter,
913                                            struct counter_signal *signal,
914                                            u8 *prescaler)
915 {
916         const struct quad8 *const priv = counter->priv;
917
918         *prescaler = priv->fck_prescaler[signal->id / 2];
919
920         return 0;
921 }
922
923 static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
924                                             struct counter_signal *signal,
925                                             u8 prescaler)
926 {
927         struct quad8 *const priv = counter->priv;
928         const size_t channel_id = signal->id / 2;
929         const int base_offset = priv->base + 2 * channel_id;
930         unsigned long irqflags;
931
932         spin_lock_irqsave(&priv->lock, irqflags);
933
934         priv->fck_prescaler[channel_id] = prescaler;
935
936         /* Reset Byte Pointer */
937         outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
938
939         /* Set filter clock factor */
940         outb(prescaler, base_offset);
941         outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
942              base_offset + 1);
943
944         spin_unlock_irqrestore(&priv->lock, irqflags);
945
946         return 0;
947 }
948
949 static struct counter_comp quad8_signal_ext[] = {
950         COUNTER_COMP_SIGNAL_BOOL("cable_fault", quad8_signal_cable_fault_read,
951                                  NULL),
952         COUNTER_COMP_SIGNAL_BOOL("cable_fault_enable",
953                                  quad8_signal_cable_fault_enable_read,
954                                  quad8_signal_cable_fault_enable_write),
955         COUNTER_COMP_SIGNAL_U8("filter_clock_prescaler",
956                                quad8_signal_fck_prescaler_read,
957                                quad8_signal_fck_prescaler_write)
958 };
959
960 static DEFINE_COUNTER_ENUM(quad8_index_pol_enum, quad8_index_polarity_modes);
961 static DEFINE_COUNTER_ENUM(quad8_synch_mode_enum, quad8_synchronous_modes);
962
963 static struct counter_comp quad8_index_ext[] = {
964         COUNTER_COMP_SIGNAL_ENUM("index_polarity", quad8_index_polarity_get,
965                                  quad8_index_polarity_set,
966                                  quad8_index_pol_enum),
967         COUNTER_COMP_SIGNAL_ENUM("synchronous_mode", quad8_synchronous_mode_get,
968                                  quad8_synchronous_mode_set,
969                                  quad8_synch_mode_enum),
970 };
971
972 #define QUAD8_QUAD_SIGNAL(_id, _name) {         \
973         .id = (_id),                            \
974         .name = (_name),                        \
975         .ext = quad8_signal_ext,                \
976         .num_ext = ARRAY_SIZE(quad8_signal_ext) \
977 }
978
979 #define QUAD8_INDEX_SIGNAL(_id, _name) {        \
980         .id = (_id),                            \
981         .name = (_name),                        \
982         .ext = quad8_index_ext,                 \
983         .num_ext = ARRAY_SIZE(quad8_index_ext)  \
984 }
985
986 static struct counter_signal quad8_signals[] = {
987         QUAD8_QUAD_SIGNAL(0, "Channel 1 Quadrature A"),
988         QUAD8_QUAD_SIGNAL(1, "Channel 1 Quadrature B"),
989         QUAD8_QUAD_SIGNAL(2, "Channel 2 Quadrature A"),
990         QUAD8_QUAD_SIGNAL(3, "Channel 2 Quadrature B"),
991         QUAD8_QUAD_SIGNAL(4, "Channel 3 Quadrature A"),
992         QUAD8_QUAD_SIGNAL(5, "Channel 3 Quadrature B"),
993         QUAD8_QUAD_SIGNAL(6, "Channel 4 Quadrature A"),
994         QUAD8_QUAD_SIGNAL(7, "Channel 4 Quadrature B"),
995         QUAD8_QUAD_SIGNAL(8, "Channel 5 Quadrature A"),
996         QUAD8_QUAD_SIGNAL(9, "Channel 5 Quadrature B"),
997         QUAD8_QUAD_SIGNAL(10, "Channel 6 Quadrature A"),
998         QUAD8_QUAD_SIGNAL(11, "Channel 6 Quadrature B"),
999         QUAD8_QUAD_SIGNAL(12, "Channel 7 Quadrature A"),
1000         QUAD8_QUAD_SIGNAL(13, "Channel 7 Quadrature B"),
1001         QUAD8_QUAD_SIGNAL(14, "Channel 8 Quadrature A"),
1002         QUAD8_QUAD_SIGNAL(15, "Channel 8 Quadrature B"),
1003         QUAD8_INDEX_SIGNAL(16, "Channel 1 Index"),
1004         QUAD8_INDEX_SIGNAL(17, "Channel 2 Index"),
1005         QUAD8_INDEX_SIGNAL(18, "Channel 3 Index"),
1006         QUAD8_INDEX_SIGNAL(19, "Channel 4 Index"),
1007         QUAD8_INDEX_SIGNAL(20, "Channel 5 Index"),
1008         QUAD8_INDEX_SIGNAL(21, "Channel 6 Index"),
1009         QUAD8_INDEX_SIGNAL(22, "Channel 7 Index"),
1010         QUAD8_INDEX_SIGNAL(23, "Channel 8 Index")
1011 };
1012
1013 #define QUAD8_COUNT_SYNAPSES(_id) {                                     \
1014         {                                                               \
1015                 .actions_list = quad8_synapse_actions_list,             \
1016                 .num_actions = ARRAY_SIZE(quad8_synapse_actions_list),  \
1017                 .signal = quad8_signals + 2 * (_id)                     \
1018         },                                                              \
1019         {                                                               \
1020                 .actions_list = quad8_synapse_actions_list,             \
1021                 .num_actions = ARRAY_SIZE(quad8_synapse_actions_list),  \
1022                 .signal = quad8_signals + 2 * (_id) + 1                 \
1023         },                                                              \
1024         {                                                               \
1025                 .actions_list = quad8_index_actions_list,               \
1026                 .num_actions = ARRAY_SIZE(quad8_index_actions_list),    \
1027                 .signal = quad8_signals + 2 * (_id) + 16                \
1028         }                                                               \
1029 }
1030
1031 static struct counter_synapse quad8_count_synapses[][3] = {
1032         QUAD8_COUNT_SYNAPSES(0), QUAD8_COUNT_SYNAPSES(1),
1033         QUAD8_COUNT_SYNAPSES(2), QUAD8_COUNT_SYNAPSES(3),
1034         QUAD8_COUNT_SYNAPSES(4), QUAD8_COUNT_SYNAPSES(5),
1035         QUAD8_COUNT_SYNAPSES(6), QUAD8_COUNT_SYNAPSES(7)
1036 };
1037
1038 static const enum counter_count_mode quad8_cnt_modes[] = {
1039         COUNTER_COUNT_MODE_NORMAL,
1040         COUNTER_COUNT_MODE_RANGE_LIMIT,
1041         COUNTER_COUNT_MODE_NON_RECYCLE,
1042         COUNTER_COUNT_MODE_MODULO_N,
1043 };
1044
1045 static DEFINE_COUNTER_AVAILABLE(quad8_count_mode_available, quad8_cnt_modes);
1046
1047 static DEFINE_COUNTER_ENUM(quad8_error_noise_enum, quad8_noise_error_states);
1048
1049 static struct counter_comp quad8_count_ext[] = {
1050         COUNTER_COMP_CEILING(quad8_count_ceiling_read,
1051                              quad8_count_ceiling_write),
1052         COUNTER_COMP_FLOOR(quad8_count_floor_read, NULL),
1053         COUNTER_COMP_COUNT_MODE(quad8_count_mode_read, quad8_count_mode_write,
1054                                 quad8_count_mode_available),
1055         COUNTER_COMP_DIRECTION(quad8_direction_read),
1056         COUNTER_COMP_ENABLE(quad8_count_enable_read, quad8_count_enable_write),
1057         COUNTER_COMP_COUNT_ENUM("error_noise", quad8_error_noise_get, NULL,
1058                                 quad8_error_noise_enum),
1059         COUNTER_COMP_PRESET(quad8_count_preset_read, quad8_count_preset_write),
1060         COUNTER_COMP_PRESET_ENABLE(quad8_count_preset_enable_read,
1061                                    quad8_count_preset_enable_write),
1062 };
1063
1064 #define QUAD8_COUNT(_id, _cntname) {                                    \
1065         .id = (_id),                                                    \
1066         .name = (_cntname),                                             \
1067         .functions_list = quad8_count_functions_list,                   \
1068         .num_functions = ARRAY_SIZE(quad8_count_functions_list),        \
1069         .synapses = quad8_count_synapses[(_id)],                        \
1070         .num_synapses = 2,                                              \
1071         .ext = quad8_count_ext,                                         \
1072         .num_ext = ARRAY_SIZE(quad8_count_ext)                          \
1073 }
1074
1075 static struct counter_count quad8_counts[] = {
1076         QUAD8_COUNT(0, "Channel 1 Count"),
1077         QUAD8_COUNT(1, "Channel 2 Count"),
1078         QUAD8_COUNT(2, "Channel 3 Count"),
1079         QUAD8_COUNT(3, "Channel 4 Count"),
1080         QUAD8_COUNT(4, "Channel 5 Count"),
1081         QUAD8_COUNT(5, "Channel 6 Count"),
1082         QUAD8_COUNT(6, "Channel 7 Count"),
1083         QUAD8_COUNT(7, "Channel 8 Count")
1084 };
1085
1086 static irqreturn_t quad8_irq_handler(int irq, void *private)
1087 {
1088         struct quad8 *const priv = private;
1089         const unsigned long base = priv->base;
1090         unsigned long irq_status;
1091         unsigned long channel;
1092         u8 event;
1093
1094         irq_status = inb(base + QUAD8_REG_INTERRUPT_STATUS);
1095         if (!irq_status)
1096                 return IRQ_NONE;
1097
1098         for_each_set_bit(channel, &irq_status, QUAD8_NUM_COUNTERS) {
1099                 switch (priv->irq_trigger[channel]) {
1100                 case QUAD8_EVENT_CARRY:
1101                         event = COUNTER_EVENT_OVERFLOW;
1102                                 break;
1103                 case QUAD8_EVENT_COMPARE:
1104                         event = COUNTER_EVENT_THRESHOLD;
1105                                 break;
1106                 case QUAD8_EVENT_CARRY_BORROW:
1107                         event = COUNTER_EVENT_OVERFLOW_UNDERFLOW;
1108                                 break;
1109                 case QUAD8_EVENT_INDEX:
1110                         event = COUNTER_EVENT_INDEX;
1111                                 break;
1112                 default:
1113                         /* should never reach this path */
1114                         WARN_ONCE(true, "invalid interrupt trigger function %u configured for channel %lu\n",
1115                                   priv->irq_trigger[channel], channel);
1116                         continue;
1117                 }
1118
1119                 counter_push_event(&priv->counter, event, channel);
1120         }
1121
1122         /* Clear pending interrupts on device */
1123         outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base + QUAD8_REG_CHAN_OP);
1124
1125         return IRQ_HANDLED;
1126 }
1127
1128 static int quad8_probe(struct device *dev, unsigned int id)
1129 {
1130         struct quad8 *priv;
1131         int i, j;
1132         unsigned int base_offset;
1133         int err;
1134
1135         if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) {
1136                 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
1137                         base[id], base[id] + QUAD8_EXTENT);
1138                 return -EBUSY;
1139         }
1140
1141         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1142         if (!priv)
1143                 return -ENOMEM;
1144
1145         /* Initialize Counter device and driver data */
1146         priv->counter.name = dev_name(dev);
1147         priv->counter.parent = dev;
1148         priv->counter.ops = &quad8_ops;
1149         priv->counter.counts = quad8_counts;
1150         priv->counter.num_counts = ARRAY_SIZE(quad8_counts);
1151         priv->counter.signals = quad8_signals;
1152         priv->counter.num_signals = ARRAY_SIZE(quad8_signals);
1153         priv->counter.priv = priv;
1154         priv->base = base[id];
1155
1156         spin_lock_init(&priv->lock);
1157
1158         /* Reset Index/Interrupt Register */
1159         outb(0x00, base[id] + QUAD8_REG_INDEX_INTERRUPT);
1160         /* Reset all counters and disable interrupt function */
1161         outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
1162         /* Set initial configuration for all counters */
1163         for (i = 0; i < QUAD8_NUM_COUNTERS; i++) {
1164                 base_offset = base[id] + 2 * i;
1165                 /* Reset Byte Pointer */
1166                 outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
1167                 /* Reset filter clock factor */
1168                 outb(0, base_offset);
1169                 outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
1170                      base_offset + 1);
1171                 /* Reset Byte Pointer */
1172                 outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
1173                 /* Reset Preset Register */
1174                 for (j = 0; j < 3; j++)
1175                         outb(0x00, base_offset);
1176                 /* Reset Borrow, Carry, Compare, and Sign flags */
1177                 outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_FLAGS, base_offset + 1);
1178                 /* Reset Error flag */
1179                 outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
1180                 /* Binary encoding; Normal count; non-quadrature mode */
1181                 outb(QUAD8_CTR_CMR, base_offset + 1);
1182                 /* Disable A and B inputs; preset on index; FLG1 as Carry */
1183                 outb(QUAD8_CTR_IOR, base_offset + 1);
1184                 /* Disable index function; negative index polarity */
1185                 outb(QUAD8_CTR_IDR, base_offset + 1);
1186                 /* Initialize next IRQ trigger function configuration */
1187                 priv->next_irq_trigger[i] = QUAD8_EVENT_NONE;
1188         }
1189         /* Disable Differential Encoder Cable Status for all channels */
1190         outb(0xFF, base[id] + QUAD8_DIFF_ENCODER_CABLE_STATUS);
1191         /* Enable all counters and enable interrupt function */
1192         outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base[id] + QUAD8_REG_CHAN_OP);
1193
1194         err = devm_request_irq(dev, irq[id], quad8_irq_handler, IRQF_SHARED,
1195                                priv->counter.name, priv);
1196         if (err)
1197                 return err;
1198
1199         return devm_counter_register(dev, &priv->counter);
1200 }
1201
1202 static struct isa_driver quad8_driver = {
1203         .probe = quad8_probe,
1204         .driver = {
1205                 .name = "104-quad-8"
1206         }
1207 };
1208
1209 module_isa_driver(quad8_driver, num_quad8);
1210
1211 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
1212 MODULE_DESCRIPTION("ACCES 104-QUAD-8 driver");
1213 MODULE_LICENSE("GPL v2");