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/bitfield.h>
9#include <linux/bits.h>
10#include <linux/counter.h>
11#include <linux/device.h>
12#include <linux/err.h>
13#include <linux/io.h>
14#include <linux/ioport.h>
15#include <linux/interrupt.h>
16#include <linux/isa.h>
17#include <linux/kernel.h>
18#include <linux/list.h>
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/regmap.h>
22#include <linux/spinlock.h>
23#include <linux/types.h>
24
25#include <asm/unaligned.h>
26
27#define QUAD8_EXTENT 32
28
29static unsigned int base[max_num_isa_dev(QUAD8_EXTENT)];
30static unsigned int num_quad8;
31module_param_hw_array(base, uint, ioport, &num_quad8, 0);
32MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
33
34static unsigned int irq[max_num_isa_dev(QUAD8_EXTENT)];
35static unsigned int num_irq;
36module_param_hw_array(irq, uint, irq, &num_irq, 0);
37MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers");
38
39#define QUAD8_NUM_COUNTERS 8
40
41#define QUAD8_DATA(_channel) ((_channel) * 2)
42#define QUAD8_CONTROL(_channel) (QUAD8_DATA(_channel) + 1)
43#define QUAD8_INTERRUPT_STATUS 0x10
44#define QUAD8_CHANNEL_OPERATION 0x11
45#define QUAD8_INDEX_INTERRUPT 0x12
46#define QUAD8_INDEX_INPUT_LEVELS 0x16
47#define QUAD8_CABLE_STATUS 0x17
48
49/**
50 * struct quad8 - device private data structure
51 * @lock:		lock to prevent clobbering device states during R/W ops
52 * @cmr:		array of Counter Mode Register states
53 * @ior:		array of Input / Output Control Register states
54 * @idr:		array of Index Control Register states
55 * @fck_prescaler:	array of filter clock prescaler configurations
56 * @preset:		array of preset values
57 * @cable_fault_enable:	differential encoder cable status enable configurations
58 * @map:		regmap for the device
59 */
60struct quad8 {
61	spinlock_t lock;
62	u8 cmr[QUAD8_NUM_COUNTERS];
63	u8 ior[QUAD8_NUM_COUNTERS];
64	u8 idr[QUAD8_NUM_COUNTERS];
65	unsigned int fck_prescaler[QUAD8_NUM_COUNTERS];
66	unsigned int preset[QUAD8_NUM_COUNTERS];
67	unsigned int cable_fault_enable;
68	struct regmap *map;
69};
70
71static const struct regmap_range quad8_wr_ranges[] = {
72	regmap_reg_range(0x0, 0xF), regmap_reg_range(0x11, 0x12), regmap_reg_range(0x17, 0x17),
73};
74static const struct regmap_range quad8_rd_ranges[] = {
75	regmap_reg_range(0x0, 0x12), regmap_reg_range(0x16, 0x18),
76};
77static const struct regmap_access_table quad8_wr_table = {
78	.yes_ranges = quad8_wr_ranges,
79	.n_yes_ranges = ARRAY_SIZE(quad8_wr_ranges),
80};
81static const struct regmap_access_table quad8_rd_table = {
82	.yes_ranges = quad8_rd_ranges,
83	.n_yes_ranges = ARRAY_SIZE(quad8_rd_ranges),
84};
85static const struct regmap_config quad8_regmap_config = {
86	.reg_bits = 8,
87	.reg_stride = 1,
88	.val_bits = 8,
89	.io_port = true,
90	.wr_table = &quad8_wr_table,
91	.rd_table = &quad8_rd_table,
92};
93
94/* Error flag */
95#define FLAG_E BIT(4)
96/* Up/Down flag */
97#define FLAG_UD BIT(5)
98/* Counting up */
99#define UP 0x1
100
101#define REGISTER_SELECTION GENMASK(6, 5)
102
103/* Reset and Load Signal Decoders */
104#define SELECT_RLD u8_encode_bits(0x0, REGISTER_SELECTION)
105/* Counter Mode Register */
106#define SELECT_CMR u8_encode_bits(0x1, REGISTER_SELECTION)
107/* Input / Output Control Register */
108#define SELECT_IOR u8_encode_bits(0x2, REGISTER_SELECTION)
109/* Index Control Register */
110#define SELECT_IDR u8_encode_bits(0x3, REGISTER_SELECTION)
111
112/*
113 * Reset and Load Signal Decoders
114 */
115#define RESETS GENMASK(2, 1)
116#define LOADS GENMASK(4, 3)
117/* Reset Byte Pointer (three byte data pointer) */
118#define RESET_BP BIT(0)
119/* Reset Borrow Toggle, Carry toggle, Compare toggle, Sign, and Index flags */
120#define RESET_BT_CT_CPT_S_IDX u8_encode_bits(0x2, RESETS)
121/* Reset Error flag */
122#define RESET_E u8_encode_bits(0x3, RESETS)
123/* Preset Register to Counter */
124#define TRANSFER_PR_TO_CNTR u8_encode_bits(0x1, LOADS)
125/* Transfer Counter to Output Latch */
126#define TRANSFER_CNTR_TO_OL u8_encode_bits(0x2, LOADS)
127/* Transfer Preset Register LSB to FCK Prescaler */
128#define TRANSFER_PR0_TO_PSC u8_encode_bits(0x3, LOADS)
129
130/*
131 * Counter Mode Registers
132 */
133#define COUNT_ENCODING BIT(0)
134#define COUNT_MODE GENMASK(2, 1)
135#define QUADRATURE_MODE GENMASK(4, 3)
136/* Binary count */
137#define BINARY u8_encode_bits(0x0, COUNT_ENCODING)
138/* Normal count */
139#define NORMAL_COUNT 0x0
140/* Range Limit */
141#define RANGE_LIMIT 0x1
142/* Non-recycle count */
143#define NON_RECYCLE_COUNT 0x2
144/* Modulo-N */
145#define MODULO_N 0x3
146/* Non-quadrature */
147#define NON_QUADRATURE 0x0
148/* Quadrature X1 */
149#define QUADRATURE_X1 0x1
150/* Quadrature X2 */
151#define QUADRATURE_X2 0x2
152/* Quadrature X4 */
153#define QUADRATURE_X4 0x3
154
155/*
156 * Input/Output Control Register
157 */
158#define AB_GATE BIT(0)
159#define LOAD_PIN BIT(1)
160#define FLG_PINS GENMASK(4, 3)
161/* Disable inputs A and B */
162#define DISABLE_AB u8_encode_bits(0x0, AB_GATE)
163/* Load Counter input */
164#define LOAD_CNTR 0x0
165/* FLG1 = CARRY(active low); FLG2 = BORROW(active low) */
166#define FLG1_CARRY_FLG2_BORROW 0x0
167/* FLG1 = COMPARE(active low); FLG2 = BORROW(active low) */
168#define FLG1_COMPARE_FLG2_BORROW 0x1
169/* FLG1 = Carry(active low)/Borrow(active low); FLG2 = U/D(active low) flag */
170#define FLG1_CARRYBORROW_FLG2_UD 0x2
171/* FLG1 = INDX (low pulse at INDEX pin active level); FLG2 = E flag */
172#define FLG1_INDX_FLG2_E 0x3
173
174/*
175 * INDEX CONTROL REGISTERS
176 */
177#define INDEX_MODE BIT(0)
178#define INDEX_POLARITY BIT(1)
179/* Disable Index mode */
180#define DISABLE_INDEX_MODE 0x0
181/* Enable Index mode */
182#define ENABLE_INDEX_MODE 0x1
183/* Negative Index Polarity */
184#define NEGATIVE_INDEX_POLARITY 0x0
185/* Positive Index Polarity */
186#define POSITIVE_INDEX_POLARITY 0x1
187
188/*
189 * Channel Operation Register
190 */
191#define COUNTERS_OPERATION BIT(0)
192#define INTERRUPT_FUNCTION BIT(2)
193/* Enable all Counters */
194#define ENABLE_COUNTERS u8_encode_bits(0x0, COUNTERS_OPERATION)
195/* Reset all Counters */
196#define RESET_COUNTERS u8_encode_bits(0x1, COUNTERS_OPERATION)
197/* Disable the interrupt function */
198#define DISABLE_INTERRUPT_FUNCTION u8_encode_bits(0x0, INTERRUPT_FUNCTION)
199/* Enable the interrupt function */
200#define ENABLE_INTERRUPT_FUNCTION u8_encode_bits(0x1, INTERRUPT_FUNCTION)
201/* Any write to the Channel Operation register clears any pending interrupts */
202#define CLEAR_PENDING_INTERRUPTS (ENABLE_COUNTERS | ENABLE_INTERRUPT_FUNCTION)
203
204/* Each Counter is 24 bits wide */
205#define LS7267_CNTR_MAX GENMASK(23, 0)
206
207static __always_inline int quad8_control_register_update(struct regmap *const map, u8 *const buf,
208							 const size_t channel, const u8 val,
209							 const u8 field)
210{
211	u8p_replace_bits(&buf[channel], val, field);
212	return regmap_write(map, QUAD8_CONTROL(channel), buf[channel]);
213}
214
215static int quad8_signal_read(struct counter_device *counter,
216			     struct counter_signal *signal,
217			     enum counter_signal_level *level)
218{
219	const struct quad8 *const priv = counter_priv(counter);
220	int ret;
221
222	/* Only Index signal levels can be read */
223	if (signal->id < 16)
224		return -EINVAL;
225
226	ret = regmap_test_bits(priv->map, QUAD8_INDEX_INPUT_LEVELS, BIT(signal->id - 16));
227	if (ret < 0)
228		return ret;
229
230	*level = (ret) ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
231
232	return 0;
233}
234
235static int quad8_count_read(struct counter_device *counter,
236			    struct counter_count *count, u64 *val)
237{
238	struct quad8 *const priv = counter_priv(counter);
239	unsigned long irqflags;
240	u8 value[3];
241	int ret;
242
243	spin_lock_irqsave(&priv->lock, irqflags);
244
245	ret = regmap_write(priv->map, QUAD8_CONTROL(count->id),
246			   SELECT_RLD | RESET_BP | TRANSFER_CNTR_TO_OL);
247	if (ret)
248		goto exit_unlock;
249	ret = regmap_noinc_read(priv->map, QUAD8_DATA(count->id), value, sizeof(value));
250
251exit_unlock:
252	spin_unlock_irqrestore(&priv->lock, irqflags);
253
254	*val = get_unaligned_le24(value);
255
256	return ret;
257}
258
259static int quad8_preset_register_set(struct quad8 *const priv, const size_t id,
260				     const unsigned long preset)
261{
262	u8 value[3];
263	int ret;
264
265	put_unaligned_le24(preset, value);
266
267	ret = regmap_write(priv->map, QUAD8_CONTROL(id), SELECT_RLD | RESET_BP);
268	if (ret)
269		return ret;
270	return regmap_noinc_write(priv->map, QUAD8_DATA(id), value, sizeof(value));
271}
272
273static int quad8_flag_register_reset(struct quad8 *const priv, const size_t id)
274{
275	int ret;
276
277	ret = regmap_write(priv->map, QUAD8_CONTROL(id), SELECT_RLD | RESET_BT_CT_CPT_S_IDX);
278	if (ret)
279		return ret;
280	return regmap_write(priv->map, QUAD8_CONTROL(id), SELECT_RLD | RESET_E);
281}
282
283static int quad8_count_write(struct counter_device *counter,
284			     struct counter_count *count, u64 val)
285{
286	struct quad8 *const priv = counter_priv(counter);
287	unsigned long irqflags;
288	int ret;
289
290	if (val > LS7267_CNTR_MAX)
291		return -ERANGE;
292
293	spin_lock_irqsave(&priv->lock, irqflags);
294
295	/* Counter can only be set via Preset Register */
296	ret = quad8_preset_register_set(priv, count->id, val);
297	if (ret)
298		goto exit_unlock;
299	ret = regmap_write(priv->map, QUAD8_CONTROL(count->id), SELECT_RLD | TRANSFER_PR_TO_CNTR);
300	if (ret)
301		goto exit_unlock;
302
303	ret = quad8_flag_register_reset(priv, count->id);
304	if (ret)
305		goto exit_unlock;
306
307	/* Set Preset Register back to original value */
308	ret = quad8_preset_register_set(priv, count->id, priv->preset[count->id]);
309
310exit_unlock:
311	spin_unlock_irqrestore(&priv->lock, irqflags);
312
313	return ret;
314}
315
316static const enum counter_function quad8_count_functions_list[] = {
317	COUNTER_FUNCTION_PULSE_DIRECTION,
318	COUNTER_FUNCTION_QUADRATURE_X1_A,
319	COUNTER_FUNCTION_QUADRATURE_X2_A,
320	COUNTER_FUNCTION_QUADRATURE_X4,
321};
322
323static int quad8_function_get(const struct quad8 *const priv, const size_t id,
324			      enum counter_function *const function)
325{
326	switch (u8_get_bits(priv->cmr[id], QUADRATURE_MODE)) {
327	case NON_QUADRATURE:
328		*function = COUNTER_FUNCTION_PULSE_DIRECTION;
329		return 0;
330	case QUADRATURE_X1:
331		*function = COUNTER_FUNCTION_QUADRATURE_X1_A;
332		return 0;
333	case QUADRATURE_X2:
334		*function = COUNTER_FUNCTION_QUADRATURE_X2_A;
335		return 0;
336	case QUADRATURE_X4:
337		*function = COUNTER_FUNCTION_QUADRATURE_X4;
338		return 0;
339	default:
340		/* should never reach this path */
341		return -EINVAL;
342	}
343}
344
345static int quad8_function_read(struct counter_device *counter,
346			       struct counter_count *count,
347			       enum counter_function *function)
348{
349	struct quad8 *const priv = counter_priv(counter);
350	unsigned long irqflags;
351	int retval;
352
353	spin_lock_irqsave(&priv->lock, irqflags);
354
355	retval = quad8_function_get(priv, count->id, function);
356
357	spin_unlock_irqrestore(&priv->lock, irqflags);
358
359	return retval;
360}
361
362static int quad8_function_write(struct counter_device *counter,
363				struct counter_count *count,
364				enum counter_function function)
365{
366	struct quad8 *const priv = counter_priv(counter);
367	const int id = count->id;
368	unsigned long irqflags;
369	unsigned int mode_cfg;
370	bool synchronous_mode;
371	int ret;
372
373	switch (function) {
374	case COUNTER_FUNCTION_PULSE_DIRECTION:
375		mode_cfg = NON_QUADRATURE;
376		break;
377	case COUNTER_FUNCTION_QUADRATURE_X1_A:
378		mode_cfg = QUADRATURE_X1;
379		break;
380	case COUNTER_FUNCTION_QUADRATURE_X2_A:
381		mode_cfg = QUADRATURE_X2;
382		break;
383	case COUNTER_FUNCTION_QUADRATURE_X4:
384		mode_cfg = QUADRATURE_X4;
385		break;
386	default:
387		/* should never reach this path */
388		return -EINVAL;
389	}
390
391	spin_lock_irqsave(&priv->lock, irqflags);
392
393	/* Synchronous function not supported in non-quadrature mode */
394	synchronous_mode = u8_get_bits(priv->idr[id], INDEX_MODE) == ENABLE_INDEX_MODE;
395	if (synchronous_mode && mode_cfg == NON_QUADRATURE) {
396		ret = quad8_control_register_update(priv->map, priv->idr, id, DISABLE_INDEX_MODE,
397						    INDEX_MODE);
398		if (ret)
399			goto exit_unlock;
400	}
401
402	ret = quad8_control_register_update(priv->map, priv->cmr, id, mode_cfg, QUADRATURE_MODE);
403
404exit_unlock:
405	spin_unlock_irqrestore(&priv->lock, irqflags);
406
407	return ret;
408}
409
410static int quad8_direction_read(struct counter_device *counter,
411				struct counter_count *count,
412				enum counter_count_direction *direction)
413{
414	const struct quad8 *const priv = counter_priv(counter);
415	unsigned int flag;
416	int ret;
417
418	ret = regmap_read(priv->map, QUAD8_CONTROL(count->id), &flag);
419	if (ret)
420		return ret;
421	*direction = (u8_get_bits(flag, FLAG_UD) == UP) ? COUNTER_COUNT_DIRECTION_FORWARD :
422		COUNTER_COUNT_DIRECTION_BACKWARD;
423
424	return 0;
425}
426
427static const enum counter_synapse_action quad8_index_actions_list[] = {
428	COUNTER_SYNAPSE_ACTION_NONE,
429	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
430};
431
432static const enum counter_synapse_action quad8_synapse_actions_list[] = {
433	COUNTER_SYNAPSE_ACTION_NONE,
434	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
435	COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
436	COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
437};
438
439static int quad8_action_read(struct counter_device *counter,
440			     struct counter_count *count,
441			     struct counter_synapse *synapse,
442			     enum counter_synapse_action *action)
443{
444	struct quad8 *const priv = counter_priv(counter);
445	unsigned long irqflags;
446	int err;
447	enum counter_function function;
448	const size_t signal_a_id = count->synapses[0].signal->id;
449	enum counter_count_direction direction;
450
451	/* Default action mode */
452	*action = COUNTER_SYNAPSE_ACTION_NONE;
453
454	/* Handle Index signals */
455	if (synapse->signal->id >= 16) {
456		if (u8_get_bits(priv->ior[count->id], LOAD_PIN) == LOAD_CNTR)
457			*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
458		return 0;
459	}
460
461	spin_lock_irqsave(&priv->lock, irqflags);
462
463	/* Get Count function and direction atomically */
464	err = quad8_function_get(priv, count->id, &function);
465	if (err) {
466		spin_unlock_irqrestore(&priv->lock, irqflags);
467		return err;
468	}
469	err = quad8_direction_read(counter, count, &direction);
470	if (err) {
471		spin_unlock_irqrestore(&priv->lock, irqflags);
472		return err;
473	}
474
475	spin_unlock_irqrestore(&priv->lock, irqflags);
476
477	/* Determine action mode based on current count function mode */
478	switch (function) {
479	case COUNTER_FUNCTION_PULSE_DIRECTION:
480		if (synapse->signal->id == signal_a_id)
481			*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
482		return 0;
483	case COUNTER_FUNCTION_QUADRATURE_X1_A:
484		if (synapse->signal->id == signal_a_id) {
485			if (direction == COUNTER_COUNT_DIRECTION_FORWARD)
486				*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
487			else
488				*action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE;
489		}
490		return 0;
491	case COUNTER_FUNCTION_QUADRATURE_X2_A:
492		if (synapse->signal->id == signal_a_id)
493			*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
494		return 0;
495	case COUNTER_FUNCTION_QUADRATURE_X4:
496		*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
497		return 0;
498	default:
499		/* should never reach this path */
500		return -EINVAL;
501	}
502}
503
504static int quad8_events_configure(struct counter_device *counter)
505{
506	struct quad8 *const priv = counter_priv(counter);
507	unsigned long irq_enabled = 0;
508	unsigned long irqflags;
509	struct counter_event_node *event_node;
510	u8 flg_pins;
511	int ret;
512
513	spin_lock_irqsave(&priv->lock, irqflags);
514
515	list_for_each_entry(event_node, &counter->events_list, l) {
516		switch (event_node->event) {
517		case COUNTER_EVENT_OVERFLOW:
518			flg_pins = FLG1_CARRY_FLG2_BORROW;
519			break;
520		case COUNTER_EVENT_THRESHOLD:
521			flg_pins = FLG1_COMPARE_FLG2_BORROW;
522			break;
523		case COUNTER_EVENT_OVERFLOW_UNDERFLOW:
524			flg_pins = FLG1_CARRYBORROW_FLG2_UD;
525			break;
526		case COUNTER_EVENT_INDEX:
527			flg_pins = FLG1_INDX_FLG2_E;
528			break;
529		default:
530			/* should never reach this path */
531			ret = -EINVAL;
532			goto exit_unlock;
533		}
534
535		/* Enable IRQ line */
536		irq_enabled |= BIT(event_node->channel);
537
538		/* Skip configuration if it is the same as previously set */
539		if (flg_pins == u8_get_bits(priv->ior[event_node->channel], FLG_PINS))
540			continue;
541
542		/* Save new IRQ function configuration */
543		ret = quad8_control_register_update(priv->map, priv->ior, event_node->channel,
544						    flg_pins, FLG_PINS);
545		if (ret)
546			goto exit_unlock;
547	}
548
549	ret = regmap_write(priv->map, QUAD8_INDEX_INTERRUPT, irq_enabled);
550
551exit_unlock:
552	spin_unlock_irqrestore(&priv->lock, irqflags);
553
554	return ret;
555}
556
557static int quad8_watch_validate(struct counter_device *counter,
558				const struct counter_watch *watch)
559{
560	struct counter_event_node *event_node;
561
562	if (watch->channel > QUAD8_NUM_COUNTERS - 1)
563		return -EINVAL;
564
565	switch (watch->event) {
566	case COUNTER_EVENT_OVERFLOW:
567	case COUNTER_EVENT_THRESHOLD:
568	case COUNTER_EVENT_OVERFLOW_UNDERFLOW:
569	case COUNTER_EVENT_INDEX:
570		list_for_each_entry(event_node, &counter->next_events_list, l)
571			if (watch->channel == event_node->channel &&
572				watch->event != event_node->event)
573				return -EINVAL;
574		return 0;
575	default:
576		return -EINVAL;
577	}
578}
579
580static const struct counter_ops quad8_ops = {
581	.signal_read = quad8_signal_read,
582	.count_read = quad8_count_read,
583	.count_write = quad8_count_write,
584	.function_read = quad8_function_read,
585	.function_write = quad8_function_write,
586	.action_read = quad8_action_read,
587	.events_configure = quad8_events_configure,
588	.watch_validate = quad8_watch_validate,
589};
590
591static const char *const quad8_index_polarity_modes[] = {
592	"negative",
593	"positive"
594};
595
596static int quad8_index_polarity_get(struct counter_device *counter,
597				    struct counter_signal *signal,
598				    u32 *index_polarity)
599{
600	const struct quad8 *const priv = counter_priv(counter);
601	const size_t channel_id = signal->id - 16;
602
603	*index_polarity = u8_get_bits(priv->idr[channel_id], INDEX_POLARITY);
604
605	return 0;
606}
607
608static int quad8_index_polarity_set(struct counter_device *counter,
609				    struct counter_signal *signal,
610				    u32 index_polarity)
611{
612	struct quad8 *const priv = counter_priv(counter);
613	const size_t channel_id = signal->id - 16;
614	unsigned long irqflags;
615	int ret;
616
617	spin_lock_irqsave(&priv->lock, irqflags);
618
619	ret = quad8_control_register_update(priv->map, priv->idr, channel_id, index_polarity,
620					    INDEX_POLARITY);
621
622	spin_unlock_irqrestore(&priv->lock, irqflags);
623
624	return ret;
625}
626
627static int quad8_polarity_read(struct counter_device *counter,
628			       struct counter_signal *signal,
629			       enum counter_signal_polarity *polarity)
630{
631	int err;
632	u32 index_polarity;
633
634	err = quad8_index_polarity_get(counter, signal, &index_polarity);
635	if (err)
636		return err;
637
638	*polarity = (index_polarity == POSITIVE_INDEX_POLARITY) ? COUNTER_SIGNAL_POLARITY_POSITIVE :
639		COUNTER_SIGNAL_POLARITY_NEGATIVE;
640
641	return 0;
642}
643
644static int quad8_polarity_write(struct counter_device *counter,
645				struct counter_signal *signal,
646				enum counter_signal_polarity polarity)
647{
648	const u32 pol = (polarity == COUNTER_SIGNAL_POLARITY_POSITIVE) ? POSITIVE_INDEX_POLARITY :
649									 NEGATIVE_INDEX_POLARITY;
650
651	return quad8_index_polarity_set(counter, signal, pol);
652}
653
654static const char *const quad8_synchronous_modes[] = {
655	"non-synchronous",
656	"synchronous"
657};
658
659static int quad8_synchronous_mode_get(struct counter_device *counter,
660				      struct counter_signal *signal,
661				      u32 *synchronous_mode)
662{
663	const struct quad8 *const priv = counter_priv(counter);
664	const size_t channel_id = signal->id - 16;
665
666	*synchronous_mode = u8_get_bits(priv->idr[channel_id], INDEX_MODE);
667
668	return 0;
669}
670
671static int quad8_synchronous_mode_set(struct counter_device *counter,
672				      struct counter_signal *signal,
673				      u32 synchronous_mode)
674{
675	struct quad8 *const priv = counter_priv(counter);
676	const size_t channel_id = signal->id - 16;
677	u8 quadrature_mode;
678	unsigned long irqflags;
679	int ret;
680
681	spin_lock_irqsave(&priv->lock, irqflags);
682
683	/* Index function must be non-synchronous in non-quadrature mode */
684	quadrature_mode = u8_get_bits(priv->idr[channel_id], QUADRATURE_MODE);
685	if (synchronous_mode && quadrature_mode == NON_QUADRATURE) {
686		ret = -EINVAL;
687		goto exit_unlock;
688	}
689
690	ret = quad8_control_register_update(priv->map, priv->idr, channel_id, synchronous_mode,
691					    INDEX_MODE);
692
693exit_unlock:
694	spin_unlock_irqrestore(&priv->lock, irqflags);
695
696	return ret;
697}
698
699static int quad8_count_floor_read(struct counter_device *counter,
700				  struct counter_count *count, u64 *floor)
701{
702	/* Only a floor of 0 is supported */
703	*floor = 0;
704
705	return 0;
706}
707
708static int quad8_count_mode_read(struct counter_device *counter,
709				 struct counter_count *count,
710				 enum counter_count_mode *cnt_mode)
711{
712	const struct quad8 *const priv = counter_priv(counter);
713
714	switch (u8_get_bits(priv->cmr[count->id], COUNT_MODE)) {
715	case NORMAL_COUNT:
716		*cnt_mode = COUNTER_COUNT_MODE_NORMAL;
717		break;
718	case RANGE_LIMIT:
719		*cnt_mode = COUNTER_COUNT_MODE_RANGE_LIMIT;
720		break;
721	case NON_RECYCLE_COUNT:
722		*cnt_mode = COUNTER_COUNT_MODE_NON_RECYCLE;
723		break;
724	case MODULO_N:
725		*cnt_mode = COUNTER_COUNT_MODE_MODULO_N;
726		break;
727	}
728
729	return 0;
730}
731
732static int quad8_count_mode_write(struct counter_device *counter,
733				  struct counter_count *count,
734				  enum counter_count_mode cnt_mode)
735{
736	struct quad8 *const priv = counter_priv(counter);
737	unsigned int count_mode;
738	unsigned long irqflags;
739	int ret;
740
741	switch (cnt_mode) {
742	case COUNTER_COUNT_MODE_NORMAL:
743		count_mode = NORMAL_COUNT;
744		break;
745	case COUNTER_COUNT_MODE_RANGE_LIMIT:
746		count_mode = RANGE_LIMIT;
747		break;
748	case COUNTER_COUNT_MODE_NON_RECYCLE:
749		count_mode = NON_RECYCLE_COUNT;
750		break;
751	case COUNTER_COUNT_MODE_MODULO_N:
752		count_mode = MODULO_N;
753		break;
754	default:
755		/* should never reach this path */
756		return -EINVAL;
757	}
758
759	spin_lock_irqsave(&priv->lock, irqflags);
760
761	ret = quad8_control_register_update(priv->map, priv->cmr, count->id, count_mode,
762					    COUNT_MODE);
763
764	spin_unlock_irqrestore(&priv->lock, irqflags);
765
766	return ret;
767}
768
769static int quad8_count_enable_read(struct counter_device *counter,
770				   struct counter_count *count, u8 *enable)
771{
772	const struct quad8 *const priv = counter_priv(counter);
773
774	*enable = u8_get_bits(priv->ior[count->id], AB_GATE);
775
776	return 0;
777}
778
779static int quad8_count_enable_write(struct counter_device *counter,
780				    struct counter_count *count, u8 enable)
781{
782	struct quad8 *const priv = counter_priv(counter);
783	unsigned long irqflags;
784	int ret;
785
786	spin_lock_irqsave(&priv->lock, irqflags);
787
788	ret = quad8_control_register_update(priv->map, priv->ior, count->id, enable, AB_GATE);
789
790	spin_unlock_irqrestore(&priv->lock, irqflags);
791
792	return ret;
793}
794
795static const char *const quad8_noise_error_states[] = {
796	"No excessive noise is present at the count inputs",
797	"Excessive noise is present at the count inputs"
798};
799
800static int quad8_error_noise_get(struct counter_device *counter,
801				 struct counter_count *count, u32 *noise_error)
802{
803	const struct quad8 *const priv = counter_priv(counter);
804	unsigned int flag;
805	int ret;
806
807	ret = regmap_read(priv->map, QUAD8_CONTROL(count->id), &flag);
808	if (ret)
809		return ret;
810	*noise_error = u8_get_bits(flag, FLAG_E);
811
812	return 0;
813}
814
815static int quad8_count_preset_read(struct counter_device *counter,
816				   struct counter_count *count, u64 *preset)
817{
818	const struct quad8 *const priv = counter_priv(counter);
819
820	*preset = priv->preset[count->id];
821
822	return 0;
823}
824
825static int quad8_count_preset_write(struct counter_device *counter,
826				    struct counter_count *count, u64 preset)
827{
828	struct quad8 *const priv = counter_priv(counter);
829	unsigned long irqflags;
830	int ret;
831
832	if (preset > LS7267_CNTR_MAX)
833		return -ERANGE;
834
835	spin_lock_irqsave(&priv->lock, irqflags);
836
837	priv->preset[count->id] = preset;
838	ret = quad8_preset_register_set(priv, count->id, preset);
839
840	spin_unlock_irqrestore(&priv->lock, irqflags);
841
842	return ret;
843}
844
845static int quad8_count_ceiling_read(struct counter_device *counter,
846				    struct counter_count *count, u64 *ceiling)
847{
848	struct quad8 *const priv = counter_priv(counter);
849	unsigned long irqflags;
850
851	spin_lock_irqsave(&priv->lock, irqflags);
852
853	/* Range Limit and Modulo-N count modes use preset value as ceiling */
854	switch (u8_get_bits(priv->cmr[count->id], COUNT_MODE)) {
855	case RANGE_LIMIT:
856	case MODULO_N:
857		*ceiling = priv->preset[count->id];
858		break;
859	default:
860		*ceiling = LS7267_CNTR_MAX;
861		break;
862	}
863
864	spin_unlock_irqrestore(&priv->lock, irqflags);
865
866	return 0;
867}
868
869static int quad8_count_ceiling_write(struct counter_device *counter,
870				     struct counter_count *count, u64 ceiling)
871{
872	struct quad8 *const priv = counter_priv(counter);
873	unsigned long irqflags;
874	int ret;
875
876	if (ceiling > LS7267_CNTR_MAX)
877		return -ERANGE;
878
879	spin_lock_irqsave(&priv->lock, irqflags);
880
881	/* Range Limit and Modulo-N count modes use preset value as ceiling */
882	switch (u8_get_bits(priv->cmr[count->id], COUNT_MODE)) {
883	case RANGE_LIMIT:
884	case MODULO_N:
885		priv->preset[count->id] = ceiling;
886		ret = quad8_preset_register_set(priv, count->id, ceiling);
887		break;
888	default:
889		ret = -EINVAL;
890		break;
891	}
892
893	spin_unlock_irqrestore(&priv->lock, irqflags);
894
895	return ret;
896}
897
898static int quad8_count_preset_enable_read(struct counter_device *counter,
899					  struct counter_count *count,
900					  u8 *preset_enable)
901{
902	const struct quad8 *const priv = counter_priv(counter);
903
904	/* Preset enable is active low in Input/Output Control register */
905	*preset_enable = !u8_get_bits(priv->ior[count->id], LOAD_PIN);
906
907	return 0;
908}
909
910static int quad8_count_preset_enable_write(struct counter_device *counter,
911					   struct counter_count *count,
912					   u8 preset_enable)
913{
914	struct quad8 *const priv = counter_priv(counter);
915	unsigned long irqflags;
916	int ret;
917
918	spin_lock_irqsave(&priv->lock, irqflags);
919
920	/* Preset enable is active low in Input/Output Control register */
921	ret = quad8_control_register_update(priv->map, priv->ior, count->id, !preset_enable,
922					    LOAD_PIN);
923
924	spin_unlock_irqrestore(&priv->lock, irqflags);
925
926	return ret;
927}
928
929static int quad8_signal_cable_fault_read(struct counter_device *counter,
930					 struct counter_signal *signal,
931					 u8 *cable_fault)
932{
933	struct quad8 *const priv = counter_priv(counter);
934	const size_t channel_id = signal->id / 2;
935	unsigned long irqflags;
936	bool disabled;
937	int ret;
938
939	spin_lock_irqsave(&priv->lock, irqflags);
940
941	disabled = !(priv->cable_fault_enable & BIT(channel_id));
942
943	if (disabled) {
944		spin_unlock_irqrestore(&priv->lock, irqflags);
945		return -EINVAL;
946	}
947
948	ret = regmap_test_bits(priv->map, QUAD8_CABLE_STATUS, BIT(channel_id));
949	if (ret < 0) {
950		spin_unlock_irqrestore(&priv->lock, irqflags);
951		return ret;
952	}
953
954	spin_unlock_irqrestore(&priv->lock, irqflags);
955
956	/* Logic 0 = cable fault */
957	*cable_fault = !ret;
958
959	return 0;
960}
961
962static int quad8_signal_cable_fault_enable_read(struct counter_device *counter,
963						struct counter_signal *signal,
964						u8 *enable)
965{
966	const struct quad8 *const priv = counter_priv(counter);
967	const size_t channel_id = signal->id / 2;
968
969	*enable = !!(priv->cable_fault_enable & BIT(channel_id));
970
971	return 0;
972}
973
974static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
975						 struct counter_signal *signal,
976						 u8 enable)
977{
978	struct quad8 *const priv = counter_priv(counter);
979	const size_t channel_id = signal->id / 2;
980	unsigned long irqflags;
981	unsigned int cable_fault_enable;
982	int ret;
983
984	spin_lock_irqsave(&priv->lock, irqflags);
985
986	if (enable)
987		priv->cable_fault_enable |= BIT(channel_id);
988	else
989		priv->cable_fault_enable &= ~BIT(channel_id);
990
991	/* Enable is active low in Differential Encoder Cable Status register */
992	cable_fault_enable = ~priv->cable_fault_enable;
993
994	ret = regmap_write(priv->map, QUAD8_CABLE_STATUS, cable_fault_enable);
995
996	spin_unlock_irqrestore(&priv->lock, irqflags);
997
998	return ret;
999}
1000
1001static int quad8_signal_fck_prescaler_read(struct counter_device *counter,
1002					   struct counter_signal *signal,
1003					   u8 *prescaler)
1004{
1005	const struct quad8 *const priv = counter_priv(counter);
1006
1007	*prescaler = priv->fck_prescaler[signal->id / 2];
1008
1009	return 0;
1010}
1011
1012static int quad8_filter_clock_prescaler_set(struct quad8 *const priv, const size_t id,
1013					    const u8 prescaler)
1014{
1015	int ret;
1016
1017	ret = regmap_write(priv->map, QUAD8_CONTROL(id), SELECT_RLD | RESET_BP);
1018	if (ret)
1019		return ret;
1020	ret = regmap_write(priv->map, QUAD8_DATA(id), prescaler);
1021	if (ret)
1022		return ret;
1023	return regmap_write(priv->map, QUAD8_CONTROL(id), SELECT_RLD | TRANSFER_PR0_TO_PSC);
1024}
1025
1026static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
1027					    struct counter_signal *signal,
1028					    u8 prescaler)
1029{
1030	struct quad8 *const priv = counter_priv(counter);
1031	const size_t channel_id = signal->id / 2;
1032	unsigned long irqflags;
1033	int ret;
1034
1035	spin_lock_irqsave(&priv->lock, irqflags);
1036
1037	priv->fck_prescaler[channel_id] = prescaler;
1038	ret = quad8_filter_clock_prescaler_set(priv, channel_id, prescaler);
1039
1040	spin_unlock_irqrestore(&priv->lock, irqflags);
1041
1042	return ret;
1043}
1044
1045static struct counter_comp quad8_signal_ext[] = {
1046	COUNTER_COMP_SIGNAL_BOOL("cable_fault", quad8_signal_cable_fault_read,
1047				 NULL),
1048	COUNTER_COMP_SIGNAL_BOOL("cable_fault_enable",
1049				 quad8_signal_cable_fault_enable_read,
1050				 quad8_signal_cable_fault_enable_write),
1051	COUNTER_COMP_SIGNAL_U8("filter_clock_prescaler",
1052			       quad8_signal_fck_prescaler_read,
1053			       quad8_signal_fck_prescaler_write)
1054};
1055
1056static const enum counter_signal_polarity quad8_polarities[] = {
1057	COUNTER_SIGNAL_POLARITY_POSITIVE,
1058	COUNTER_SIGNAL_POLARITY_NEGATIVE,
1059};
1060
1061static DEFINE_COUNTER_AVAILABLE(quad8_polarity_available, quad8_polarities);
1062
1063static DEFINE_COUNTER_ENUM(quad8_index_pol_enum, quad8_index_polarity_modes);
1064static DEFINE_COUNTER_ENUM(quad8_synch_mode_enum, quad8_synchronous_modes);
1065
1066static struct counter_comp quad8_index_ext[] = {
1067	COUNTER_COMP_SIGNAL_ENUM("index_polarity", quad8_index_polarity_get,
1068				 quad8_index_polarity_set,
1069				 quad8_index_pol_enum),
1070	COUNTER_COMP_POLARITY(quad8_polarity_read, quad8_polarity_write,
1071			      quad8_polarity_available),
1072	COUNTER_COMP_SIGNAL_ENUM("synchronous_mode", quad8_synchronous_mode_get,
1073				 quad8_synchronous_mode_set,
1074				 quad8_synch_mode_enum),
1075};
1076
1077#define QUAD8_QUAD_SIGNAL(_id, _name) {		\
1078	.id = (_id),				\
1079	.name = (_name),			\
1080	.ext = quad8_signal_ext,		\
1081	.num_ext = ARRAY_SIZE(quad8_signal_ext)	\
1082}
1083
1084#define	QUAD8_INDEX_SIGNAL(_id, _name) {	\
1085	.id = (_id),				\
1086	.name = (_name),			\
1087	.ext = quad8_index_ext,			\
1088	.num_ext = ARRAY_SIZE(quad8_index_ext)	\
1089}
1090
1091static struct counter_signal quad8_signals[] = {
1092	QUAD8_QUAD_SIGNAL(0, "Channel 1 Quadrature A"),
1093	QUAD8_QUAD_SIGNAL(1, "Channel 1 Quadrature B"),
1094	QUAD8_QUAD_SIGNAL(2, "Channel 2 Quadrature A"),
1095	QUAD8_QUAD_SIGNAL(3, "Channel 2 Quadrature B"),
1096	QUAD8_QUAD_SIGNAL(4, "Channel 3 Quadrature A"),
1097	QUAD8_QUAD_SIGNAL(5, "Channel 3 Quadrature B"),
1098	QUAD8_QUAD_SIGNAL(6, "Channel 4 Quadrature A"),
1099	QUAD8_QUAD_SIGNAL(7, "Channel 4 Quadrature B"),
1100	QUAD8_QUAD_SIGNAL(8, "Channel 5 Quadrature A"),
1101	QUAD8_QUAD_SIGNAL(9, "Channel 5 Quadrature B"),
1102	QUAD8_QUAD_SIGNAL(10, "Channel 6 Quadrature A"),
1103	QUAD8_QUAD_SIGNAL(11, "Channel 6 Quadrature B"),
1104	QUAD8_QUAD_SIGNAL(12, "Channel 7 Quadrature A"),
1105	QUAD8_QUAD_SIGNAL(13, "Channel 7 Quadrature B"),
1106	QUAD8_QUAD_SIGNAL(14, "Channel 8 Quadrature A"),
1107	QUAD8_QUAD_SIGNAL(15, "Channel 8 Quadrature B"),
1108	QUAD8_INDEX_SIGNAL(16, "Channel 1 Index"),
1109	QUAD8_INDEX_SIGNAL(17, "Channel 2 Index"),
1110	QUAD8_INDEX_SIGNAL(18, "Channel 3 Index"),
1111	QUAD8_INDEX_SIGNAL(19, "Channel 4 Index"),
1112	QUAD8_INDEX_SIGNAL(20, "Channel 5 Index"),
1113	QUAD8_INDEX_SIGNAL(21, "Channel 6 Index"),
1114	QUAD8_INDEX_SIGNAL(22, "Channel 7 Index"),
1115	QUAD8_INDEX_SIGNAL(23, "Channel 8 Index")
1116};
1117
1118#define QUAD8_COUNT_SYNAPSES(_id) {					\
1119	{								\
1120		.actions_list = quad8_synapse_actions_list,		\
1121		.num_actions = ARRAY_SIZE(quad8_synapse_actions_list),	\
1122		.signal = quad8_signals + 2 * (_id)			\
1123	},								\
1124	{								\
1125		.actions_list = quad8_synapse_actions_list,		\
1126		.num_actions = ARRAY_SIZE(quad8_synapse_actions_list),	\
1127		.signal = quad8_signals + 2 * (_id) + 1			\
1128	},								\
1129	{								\
1130		.actions_list = quad8_index_actions_list,		\
1131		.num_actions = ARRAY_SIZE(quad8_index_actions_list),	\
1132		.signal = quad8_signals + 2 * (_id) + 16		\
1133	}								\
1134}
1135
1136static struct counter_synapse quad8_count_synapses[][3] = {
1137	QUAD8_COUNT_SYNAPSES(0), QUAD8_COUNT_SYNAPSES(1),
1138	QUAD8_COUNT_SYNAPSES(2), QUAD8_COUNT_SYNAPSES(3),
1139	QUAD8_COUNT_SYNAPSES(4), QUAD8_COUNT_SYNAPSES(5),
1140	QUAD8_COUNT_SYNAPSES(6), QUAD8_COUNT_SYNAPSES(7)
1141};
1142
1143static const enum counter_count_mode quad8_cnt_modes[] = {
1144	COUNTER_COUNT_MODE_NORMAL,
1145	COUNTER_COUNT_MODE_RANGE_LIMIT,
1146	COUNTER_COUNT_MODE_NON_RECYCLE,
1147	COUNTER_COUNT_MODE_MODULO_N,
1148};
1149
1150static DEFINE_COUNTER_AVAILABLE(quad8_count_mode_available, quad8_cnt_modes);
1151
1152static DEFINE_COUNTER_ENUM(quad8_error_noise_enum, quad8_noise_error_states);
1153
1154static struct counter_comp quad8_count_ext[] = {
1155	COUNTER_COMP_CEILING(quad8_count_ceiling_read,
1156			     quad8_count_ceiling_write),
1157	COUNTER_COMP_FLOOR(quad8_count_floor_read, NULL),
1158	COUNTER_COMP_COUNT_MODE(quad8_count_mode_read, quad8_count_mode_write,
1159				quad8_count_mode_available),
1160	COUNTER_COMP_DIRECTION(quad8_direction_read),
1161	COUNTER_COMP_ENABLE(quad8_count_enable_read, quad8_count_enable_write),
1162	COUNTER_COMP_COUNT_ENUM("error_noise", quad8_error_noise_get, NULL,
1163				quad8_error_noise_enum),
1164	COUNTER_COMP_PRESET(quad8_count_preset_read, quad8_count_preset_write),
1165	COUNTER_COMP_PRESET_ENABLE(quad8_count_preset_enable_read,
1166				   quad8_count_preset_enable_write),
1167};
1168
1169#define QUAD8_COUNT(_id, _cntname) {					\
1170	.id = (_id),							\
1171	.name = (_cntname),						\
1172	.functions_list = quad8_count_functions_list,			\
1173	.num_functions = ARRAY_SIZE(quad8_count_functions_list),	\
1174	.synapses = quad8_count_synapses[(_id)],			\
1175	.num_synapses =	2,						\
1176	.ext = quad8_count_ext,						\
1177	.num_ext = ARRAY_SIZE(quad8_count_ext)				\
1178}
1179
1180static struct counter_count quad8_counts[] = {
1181	QUAD8_COUNT(0, "Channel 1 Count"),
1182	QUAD8_COUNT(1, "Channel 2 Count"),
1183	QUAD8_COUNT(2, "Channel 3 Count"),
1184	QUAD8_COUNT(3, "Channel 4 Count"),
1185	QUAD8_COUNT(4, "Channel 5 Count"),
1186	QUAD8_COUNT(5, "Channel 6 Count"),
1187	QUAD8_COUNT(6, "Channel 7 Count"),
1188	QUAD8_COUNT(7, "Channel 8 Count")
1189};
1190
1191static irqreturn_t quad8_irq_handler(int irq, void *private)
1192{
1193	struct counter_device *counter = private;
1194	struct quad8 *const priv = counter_priv(counter);
1195	unsigned int status;
1196	unsigned long irq_status;
1197	unsigned long channel;
1198	unsigned int flg_pins;
1199	u8 event;
1200	int ret;
1201
1202	ret = regmap_read(priv->map, QUAD8_INTERRUPT_STATUS, &status);
1203	if (ret)
1204		return ret;
1205	if (!status)
1206		return IRQ_NONE;
1207
1208	irq_status = status;
1209	for_each_set_bit(channel, &irq_status, QUAD8_NUM_COUNTERS) {
1210		flg_pins = u8_get_bits(priv->ior[channel], FLG_PINS);
1211		switch (flg_pins) {
1212		case FLG1_CARRY_FLG2_BORROW:
1213			event = COUNTER_EVENT_OVERFLOW;
1214				break;
1215		case FLG1_COMPARE_FLG2_BORROW:
1216			event = COUNTER_EVENT_THRESHOLD;
1217				break;
1218		case FLG1_CARRYBORROW_FLG2_UD:
1219			event = COUNTER_EVENT_OVERFLOW_UNDERFLOW;
1220				break;
1221		case FLG1_INDX_FLG2_E:
1222			event = COUNTER_EVENT_INDEX;
1223				break;
1224		default:
1225			/* should never reach this path */
1226			WARN_ONCE(true, "invalid interrupt trigger function %u configured for channel %lu\n",
1227				  flg_pins, channel);
1228			continue;
1229		}
1230
1231		counter_push_event(counter, event, channel);
1232	}
1233
1234	ret = regmap_write(priv->map, QUAD8_CHANNEL_OPERATION, CLEAR_PENDING_INTERRUPTS);
1235	if (ret)
1236		return ret;
1237
1238	return IRQ_HANDLED;
1239}
1240
1241static int quad8_init_counter(struct quad8 *const priv, const size_t channel)
1242{
1243	int ret;
1244
1245	ret = quad8_filter_clock_prescaler_set(priv, channel, 0);
1246	if (ret)
1247		return ret;
1248	ret = quad8_preset_register_set(priv, channel, 0);
1249	if (ret)
1250		return ret;
1251	ret = quad8_flag_register_reset(priv, channel);
1252	if (ret)
1253		return ret;
1254
1255	/* Binary encoding; Normal count; non-quadrature mode */
1256	priv->cmr[channel] = SELECT_CMR | BINARY | u8_encode_bits(NORMAL_COUNT, COUNT_MODE) |
1257			     u8_encode_bits(NON_QUADRATURE, QUADRATURE_MODE);
1258	ret = regmap_write(priv->map, QUAD8_CONTROL(channel), priv->cmr[channel]);
1259	if (ret)
1260		return ret;
1261
1262	/* Disable A and B inputs; preset on index; FLG1 as Carry */
1263	priv->ior[channel] = SELECT_IOR | DISABLE_AB | u8_encode_bits(LOAD_CNTR, LOAD_PIN) |
1264			     u8_encode_bits(FLG1_CARRY_FLG2_BORROW, FLG_PINS);
1265	ret = regmap_write(priv->map, QUAD8_CONTROL(channel), priv->ior[channel]);
1266	if (ret)
1267		return ret;
1268
1269	/* Disable index function; negative index polarity */
1270	priv->idr[channel] = SELECT_IDR | u8_encode_bits(DISABLE_INDEX_MODE, INDEX_MODE) |
1271			     u8_encode_bits(NEGATIVE_INDEX_POLARITY, INDEX_POLARITY);
1272	return regmap_write(priv->map, QUAD8_CONTROL(channel), priv->idr[channel]);
1273}
1274
1275static int quad8_probe(struct device *dev, unsigned int id)
1276{
1277	struct counter_device *counter;
1278	struct quad8 *priv;
1279	void __iomem *regs;
1280	unsigned long i;
1281	int ret;
1282
1283	if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) {
1284		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
1285			base[id], base[id] + QUAD8_EXTENT);
1286		return -EBUSY;
1287	}
1288
1289	counter = devm_counter_alloc(dev, sizeof(*priv));
1290	if (!counter)
1291		return -ENOMEM;
1292	priv = counter_priv(counter);
1293
1294	regs = devm_ioport_map(dev, base[id], QUAD8_EXTENT);
1295	if (!regs)
1296		return -ENOMEM;
1297
1298	priv->map = devm_regmap_init_mmio(dev, regs, &quad8_regmap_config);
1299	if (IS_ERR(priv->map))
1300		return dev_err_probe(dev, PTR_ERR(priv->map),
1301				     "Unable to initialize register map\n");
1302
1303	/* Initialize Counter device and driver data */
1304	counter->name = dev_name(dev);
1305	counter->parent = dev;
1306	counter->ops = &quad8_ops;
1307	counter->counts = quad8_counts;
1308	counter->num_counts = ARRAY_SIZE(quad8_counts);
1309	counter->signals = quad8_signals;
1310	counter->num_signals = ARRAY_SIZE(quad8_signals);
1311
1312	spin_lock_init(&priv->lock);
1313
1314	/* Reset Index/Interrupt Register */
1315	ret = regmap_write(priv->map, QUAD8_INDEX_INTERRUPT, 0x00);
1316	if (ret)
1317		return ret;
1318	/* Reset all counters and disable interrupt function */
1319	ret = regmap_write(priv->map, QUAD8_CHANNEL_OPERATION,
1320			   RESET_COUNTERS | DISABLE_INTERRUPT_FUNCTION);
1321	if (ret)
1322		return ret;
1323	/* Set initial configuration for all counters */
1324	for (i = 0; i < QUAD8_NUM_COUNTERS; i++) {
1325		ret = quad8_init_counter(priv, i);
1326		if (ret)
1327			return ret;
1328	}
1329	/* Disable Differential Encoder Cable Status for all channels */
1330	ret = regmap_write(priv->map, QUAD8_CABLE_STATUS, GENMASK(7, 0));
1331	if (ret)
1332		return ret;
1333	/* Enable all counters and enable interrupt function */
1334	ret = regmap_write(priv->map, QUAD8_CHANNEL_OPERATION,
1335			   ENABLE_COUNTERS | ENABLE_INTERRUPT_FUNCTION);
1336	if (ret)
1337		return ret;
1338
1339	ret = devm_request_irq(&counter->dev, irq[id], quad8_irq_handler,
1340			       IRQF_SHARED, counter->name, counter);
1341	if (ret)
1342		return ret;
1343
1344	ret = devm_counter_add(dev, counter);
1345	if (ret < 0)
1346		return dev_err_probe(dev, ret, "Failed to add counter\n");
1347
1348	return 0;
1349}
1350
1351static struct isa_driver quad8_driver = {
1352	.probe = quad8_probe,
1353	.driver = {
1354		.name = "104-quad-8"
1355	}
1356};
1357
1358module_isa_driver_with_irq(quad8_driver, num_quad8, num_irq);
1359
1360MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
1361MODULE_DESCRIPTION("ACCES 104-QUAD-8 driver");
1362MODULE_LICENSE("GPL v2");
1363MODULE_IMPORT_NS(COUNTER);
1364