104-quad-8.c (142c8622b5b28f4fa2b5609c69474e03e723779f) 104-quad-8.c (98ffe02529117095fad0399ce16235d66b8b5f8d)
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>
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/errno.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>
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/types.h>
21#include <linux/regmap.h>
22#include <linux/spinlock.h>
22#include <linux/spinlock.h>
23#include <linux/types.h>
23
24#include <asm/unaligned.h>
25
26#define QUAD8_EXTENT 32
27
28static unsigned int base[max_num_isa_dev(QUAD8_EXTENT)];
29static unsigned int num_quad8;
30module_param_hw_array(base, uint, ioport, &num_quad8, 0);
31MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
32
33static unsigned int irq[max_num_isa_dev(QUAD8_EXTENT)];
34static unsigned int num_irq;
35module_param_hw_array(irq, uint, irq, &num_irq, 0);
36MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers");
37
38#define QUAD8_NUM_COUNTERS 8
39
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
40/**
41 * struct channel_reg - channel register structure
42 * @data: Count data
43 * @control: Channel flags and control
44 */
45struct channel_reg {
46 u8 data;
47 u8 control;
48};
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
49
50/**
48
49/**
51 * struct quad8_reg - device register structure
52 * @channel: quadrature counter data and control
53 * @interrupt_status: channel interrupt status
54 * @channel_oper: enable/reset counters and interrupt functions
55 * @index_interrupt: enable channel interrupts
56 * @reserved: reserved for Factory Use
57 * @index_input_levels: index signal logical input level
58 * @cable_status: differential encoder cable status
59 */
60struct quad8_reg {
61 struct channel_reg channel[QUAD8_NUM_COUNTERS];
62 u8 interrupt_status;
63 u8 channel_oper;
64 u8 index_interrupt;
65 u8 reserved[3];
66 u8 index_input_levels;
67 u8 cable_status;
68};
69
70/**
71 * struct quad8 - device private data structure
72 * @lock: lock to prevent clobbering device states during R/W ops
73 * @cmr: array of Counter Mode Register states
74 * @ior: array of Input / Output Control Register states
75 * @idr: array of Index Control Register states
76 * @fck_prescaler: array of filter clock prescaler configurations
77 * @preset: array of preset values
78 * @cable_fault_enable: differential encoder cable status enable configurations
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
79 * @reg: I/O address offset for the device registers
58 * @map: regmap for the device
80 */
81struct quad8 {
82 spinlock_t lock;
83 u8 cmr[QUAD8_NUM_COUNTERS];
84 u8 ior[QUAD8_NUM_COUNTERS];
85 u8 idr[QUAD8_NUM_COUNTERS];
86 unsigned int fck_prescaler[QUAD8_NUM_COUNTERS];
87 unsigned int preset[QUAD8_NUM_COUNTERS];
88 unsigned int cable_fault_enable;
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;
89 struct quad8_reg __iomem *reg;
68 struct regmap *map;
90};
91
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
92/* Error flag */
93#define FLAG_E BIT(4)
94/* Up/Down flag */
95#define FLAG_UD BIT(5)
96/* Counting up */
97#define UP 0x1
98
99#define REGISTER_SELECTION GENMASK(6, 5)

--- 97 unchanged lines hidden (view full) ---

197/* Enable the interrupt function */
198#define ENABLE_INTERRUPT_FUNCTION u8_encode_bits(0x1, INTERRUPT_FUNCTION)
199/* Any write to the Channel Operation register clears any pending interrupts */
200#define CLEAR_PENDING_INTERRUPTS (ENABLE_COUNTERS | ENABLE_INTERRUPT_FUNCTION)
201
202/* Each Counter is 24 bits wide */
203#define LS7267_CNTR_MAX GENMASK(23, 0)
204
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)

--- 97 unchanged lines hidden (view full) ---

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
205static __always_inline void quad8_control_register_update(struct quad8 *const priv, u8 *const buf,
206 const size_t channel, const u8 val,
207 const u8 field)
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)
208{
209 u8p_replace_bits(&buf[channel], val, field);
210{
211 u8p_replace_bits(&buf[channel], val, field);
210 iowrite8(buf[channel], &priv->reg->channel[channel].control);
212 return regmap_write(map, QUAD8_CONTROL(channel), buf[channel]);
211}
212
213static int quad8_signal_read(struct counter_device *counter,
214 struct counter_signal *signal,
215 enum counter_signal_level *level)
216{
217 const struct quad8 *const priv = counter_priv(counter);
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);
218 unsigned int state;
220 int ret;
219
220 /* Only Index signal levels can be read */
221 if (signal->id < 16)
222 return -EINVAL;
223
221
222 /* Only Index signal levels can be read */
223 if (signal->id < 16)
224 return -EINVAL;
225
224 state = ioread8(&priv->reg->index_input_levels) & BIT(signal->id - 16);
226 ret = regmap_test_bits(priv->map, QUAD8_INDEX_INPUT_LEVELS, BIT(signal->id - 16));
227 if (ret < 0)
228 return ret;
225
229
226 *level = (state) ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
230 *level = (ret) ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
227
228 return 0;
229}
230
231static int quad8_count_read(struct counter_device *counter,
232 struct counter_count *count, u64 *val)
233{
234 struct quad8 *const priv = counter_priv(counter);
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);
235 struct channel_reg __iomem *const chan = priv->reg->channel + count->id;
236 unsigned long irqflags;
237 u8 value[3];
239 unsigned long irqflags;
240 u8 value[3];
241 int ret;
238
239 spin_lock_irqsave(&priv->lock, irqflags);
240
242
243 spin_lock_irqsave(&priv->lock, irqflags);
244
241 iowrite8(SELECT_RLD | RESET_BP | TRANSFER_CNTR_TO_OL, &chan->control);
242 ioread8_rep(&chan->data, value, sizeof(value));
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));
243
250
251exit_unlock:
244 spin_unlock_irqrestore(&priv->lock, irqflags);
245
246 *val = get_unaligned_le24(value);
247
252 spin_unlock_irqrestore(&priv->lock, irqflags);
253
254 *val = get_unaligned_le24(value);
255
248 return 0;
256 return ret;
249}
250
257}
258
251static void quad8_preset_register_set(struct quad8 *const priv, const size_t id,
252 const unsigned long preset)
259static int quad8_preset_register_set(struct quad8 *const priv, const size_t id,
260 const unsigned long preset)
253{
261{
254 struct channel_reg __iomem *const chan = priv->reg->channel + id;
255 u8 value[3];
262 u8 value[3];
263 int ret;
256
257 put_unaligned_le24(preset, value);
258
264
265 put_unaligned_le24(preset, value);
266
259 iowrite8(SELECT_RLD | RESET_BP, &chan->control);
260 iowrite8_rep(&chan->data, value, sizeof(value));
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));
261}
262
271}
272
263static void quad8_flag_register_reset(struct quad8 *const priv, const size_t id)
273static int quad8_flag_register_reset(struct quad8 *const priv, const size_t id)
264{
274{
265 struct channel_reg __iomem *const chan = priv->reg->channel + id;
275 int ret;
266
276
267 iowrite8(SELECT_RLD | RESET_BT_CT_CPT_S_IDX, &chan->control);
268 iowrite8(SELECT_RLD | RESET_E, &chan->control);
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);
269}
270
271static int quad8_count_write(struct counter_device *counter,
272 struct counter_count *count, u64 val)
273{
274 struct quad8 *const priv = counter_priv(counter);
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);
275 struct channel_reg __iomem *const chan = priv->reg->channel + count->id;
276 unsigned long irqflags;
287 unsigned long irqflags;
288 int ret;
277
278 if (val > LS7267_CNTR_MAX)
279 return -ERANGE;
280
281 spin_lock_irqsave(&priv->lock, irqflags);
282
283 /* Counter can only be set via Preset Register */
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 */
284 quad8_preset_register_set(priv, count->id, val);
285 iowrite8(SELECT_RLD | TRANSFER_PR_TO_CNTR, &chan->control);
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;
286
302
287 quad8_flag_register_reset(priv, count->id);
303 ret = quad8_flag_register_reset(priv, count->id);
304 if (ret)
305 goto exit_unlock;
288
289 /* Set Preset Register back to original value */
306
307 /* Set Preset Register back to original value */
290 quad8_preset_register_set(priv, count->id, priv->preset[count->id]);
308 ret = quad8_preset_register_set(priv, count->id, priv->preset[count->id]);
291
309
310exit_unlock:
292 spin_unlock_irqrestore(&priv->lock, irqflags);
293
311 spin_unlock_irqrestore(&priv->lock, irqflags);
312
294 return 0;
313 return ret;
295}
296
297static const enum counter_function quad8_count_functions_list[] = {
298 COUNTER_FUNCTION_PULSE_DIRECTION,
299 COUNTER_FUNCTION_QUADRATURE_X1_A,
300 COUNTER_FUNCTION_QUADRATURE_X2_A,
301 COUNTER_FUNCTION_QUADRATURE_X4,
302};

--- 41 unchanged lines hidden (view full) ---

344 struct counter_count *count,
345 enum counter_function function)
346{
347 struct quad8 *const priv = counter_priv(counter);
348 const int id = count->id;
349 unsigned long irqflags;
350 unsigned int mode_cfg;
351 bool synchronous_mode;
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};

--- 41 unchanged lines hidden (view full) ---

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;
352
353 switch (function) {
354 case COUNTER_FUNCTION_PULSE_DIRECTION:
355 mode_cfg = NON_QUADRATURE;
356 break;
357 case COUNTER_FUNCTION_QUADRATURE_X1_A:
358 mode_cfg = QUADRATURE_X1;
359 break;

--- 7 unchanged lines hidden (view full) ---

367 /* should never reach this path */
368 return -EINVAL;
369 }
370
371 spin_lock_irqsave(&priv->lock, irqflags);
372
373 /* Synchronous function not supported in non-quadrature mode */
374 synchronous_mode = u8_get_bits(priv->idr[id], INDEX_MODE) == ENABLE_INDEX_MODE;
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;

--- 7 unchanged lines hidden (view full) ---

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;
375 if (synchronous_mode && mode_cfg == NON_QUADRATURE)
376 quad8_control_register_update(priv, priv->idr, id, DISABLE_INDEX_MODE, 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 }
377
401
378 quad8_control_register_update(priv, priv->cmr, id, mode_cfg, QUADRATURE_MODE);
402 ret = quad8_control_register_update(priv->map, priv->cmr, id, mode_cfg, QUADRATURE_MODE);
379
403
404exit_unlock:
380 spin_unlock_irqrestore(&priv->lock, irqflags);
381
405 spin_unlock_irqrestore(&priv->lock, irqflags);
406
382 return 0;
407 return ret;
383}
384
385static int quad8_direction_read(struct counter_device *counter,
386 struct counter_count *count,
387 enum counter_count_direction *direction)
388{
389 const struct quad8 *const priv = counter_priv(counter);
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);
390 u8 __iomem *const flag_addr = &priv->reg->channel[count->id].control;
391 u8 flag;
415 unsigned int flag;
416 int ret;
392
417
393 flag = ioread8(flag_addr);
418 ret = regmap_read(priv->map, QUAD8_CONTROL(count->id), &flag);
419 if (ret)
420 return ret;
394 *direction = (u8_get_bits(flag, FLAG_UD) == UP) ? COUNTER_COUNT_DIRECTION_FORWARD :
395 COUNTER_COUNT_DIRECTION_BACKWARD;
396
397 return 0;
398}
399
400static const enum counter_synapse_action quad8_index_actions_list[] = {
401 COUNTER_SYNAPSE_ACTION_NONE,

--- 74 unchanged lines hidden (view full) ---

476
477static int quad8_events_configure(struct counter_device *counter)
478{
479 struct quad8 *const priv = counter_priv(counter);
480 unsigned long irq_enabled = 0;
481 unsigned long irqflags;
482 struct counter_event_node *event_node;
483 u8 flg_pins;
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,

--- 74 unchanged lines hidden (view full) ---

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;
484
485 spin_lock_irqsave(&priv->lock, irqflags);
486
487 list_for_each_entry(event_node, &counter->events_list, l) {
488 switch (event_node->event) {
489 case COUNTER_EVENT_OVERFLOW:
490 flg_pins = FLG1_CARRY_FLG2_BORROW;
491 break;
492 case COUNTER_EVENT_THRESHOLD:
493 flg_pins = FLG1_COMPARE_FLG2_BORROW;
494 break;
495 case COUNTER_EVENT_OVERFLOW_UNDERFLOW:
496 flg_pins = FLG1_CARRYBORROW_FLG2_UD;
497 break;
498 case COUNTER_EVENT_INDEX:
499 flg_pins = FLG1_INDX_FLG2_E;
500 break;
501 default:
502 /* should never reach this path */
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 */
503 spin_unlock_irqrestore(&priv->lock, irqflags);
504 return -EINVAL;
531 ret = -EINVAL;
532 goto exit_unlock;
505 }
506
507 /* Enable IRQ line */
508 irq_enabled |= BIT(event_node->channel);
509
510 /* Skip configuration if it is the same as previously set */
511 if (flg_pins == u8_get_bits(priv->ior[event_node->channel], FLG_PINS))
512 continue;
513
514 /* Save new IRQ function configuration */
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 */
515 quad8_control_register_update(priv, priv->ior, event_node->channel, flg_pins,
516 FLG_PINS);
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;
517 }
518
547 }
548
519 iowrite8(irq_enabled, &priv->reg->index_interrupt);
549 ret = regmap_write(priv->map, QUAD8_INDEX_INTERRUPT, irq_enabled);
520
550
551exit_unlock:
521 spin_unlock_irqrestore(&priv->lock, irqflags);
522
552 spin_unlock_irqrestore(&priv->lock, irqflags);
553
523 return 0;
554 return ret;
524}
525
526static int quad8_watch_validate(struct counter_device *counter,
527 const struct counter_watch *watch)
528{
529 struct counter_event_node *event_node;
530
531 if (watch->channel > QUAD8_NUM_COUNTERS - 1)

--- 44 unchanged lines hidden (view full) ---

576
577static int quad8_index_polarity_set(struct counter_device *counter,
578 struct counter_signal *signal,
579 u32 index_polarity)
580{
581 struct quad8 *const priv = counter_priv(counter);
582 const size_t channel_id = signal->id - 16;
583 unsigned long irqflags;
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)

--- 44 unchanged lines hidden (view full) ---

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;
584
585 spin_lock_irqsave(&priv->lock, irqflags);
586
616
617 spin_lock_irqsave(&priv->lock, irqflags);
618
587 quad8_control_register_update(priv, priv->idr, channel_id, index_polarity, INDEX_POLARITY);
619 ret = quad8_control_register_update(priv->map, priv->idr, channel_id, index_polarity,
620 INDEX_POLARITY);
588
589 spin_unlock_irqrestore(&priv->lock, irqflags);
590
621
622 spin_unlock_irqrestore(&priv->lock, irqflags);
623
591 return 0;
624 return ret;
592}
593
594static int quad8_polarity_read(struct counter_device *counter,
595 struct counter_signal *signal,
596 enum counter_signal_polarity *polarity)
597{
598 int err;
599 u32 index_polarity;

--- 38 unchanged lines hidden (view full) ---

638static int quad8_synchronous_mode_set(struct counter_device *counter,
639 struct counter_signal *signal,
640 u32 synchronous_mode)
641{
642 struct quad8 *const priv = counter_priv(counter);
643 const size_t channel_id = signal->id - 16;
644 u8 quadrature_mode;
645 unsigned long irqflags;
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;

--- 38 unchanged lines hidden (view full) ---

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;
646
647 spin_lock_irqsave(&priv->lock, irqflags);
648
649 /* Index function must be non-synchronous in non-quadrature mode */
650 quadrature_mode = u8_get_bits(priv->idr[channel_id], QUADRATURE_MODE);
651 if (synchronous_mode && quadrature_mode == NON_QUADRATURE) {
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) {
652 spin_unlock_irqrestore(&priv->lock, irqflags);
653 return -EINVAL;
686 ret = -EINVAL;
687 goto exit_unlock;
654 }
655
688 }
689
656 quad8_control_register_update(priv, priv->idr, channel_id, synchronous_mode, INDEX_MODE);
690 ret = quad8_control_register_update(priv->map, priv->idr, channel_id, synchronous_mode,
691 INDEX_MODE);
657
692
693exit_unlock:
658 spin_unlock_irqrestore(&priv->lock, irqflags);
659
694 spin_unlock_irqrestore(&priv->lock, irqflags);
695
660 return 0;
696 return ret;
661}
662
663static int quad8_count_floor_read(struct counter_device *counter,
664 struct counter_count *count, u64 *floor)
665{
666 /* Only a floor of 0 is supported */
667 *floor = 0;
668

--- 26 unchanged lines hidden (view full) ---

695
696static int quad8_count_mode_write(struct counter_device *counter,
697 struct counter_count *count,
698 enum counter_count_mode cnt_mode)
699{
700 struct quad8 *const priv = counter_priv(counter);
701 unsigned int count_mode;
702 unsigned long irqflags;
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

--- 26 unchanged lines hidden (view full) ---

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;
703
704 switch (cnt_mode) {
705 case COUNTER_COUNT_MODE_NORMAL:
706 count_mode = NORMAL_COUNT;
707 break;
708 case COUNTER_COUNT_MODE_RANGE_LIMIT:
709 count_mode = RANGE_LIMIT;
710 break;

--- 5 unchanged lines hidden (view full) ---

716 break;
717 default:
718 /* should never reach this path */
719 return -EINVAL;
720 }
721
722 spin_lock_irqsave(&priv->lock, irqflags);
723
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;

--- 5 unchanged lines hidden (view full) ---

753 break;
754 default:
755 /* should never reach this path */
756 return -EINVAL;
757 }
758
759 spin_lock_irqsave(&priv->lock, irqflags);
760
724 quad8_control_register_update(priv, priv->cmr, count->id, count_mode, COUNT_MODE);
761 ret = quad8_control_register_update(priv->map, priv->cmr, count->id, count_mode,
762 COUNT_MODE);
725
726 spin_unlock_irqrestore(&priv->lock, irqflags);
727
763
764 spin_unlock_irqrestore(&priv->lock, irqflags);
765
728 return 0;
766 return ret;
729}
730
731static int quad8_count_enable_read(struct counter_device *counter,
732 struct counter_count *count, u8 *enable)
733{
734 const struct quad8 *const priv = counter_priv(counter);
735
736 *enable = u8_get_bits(priv->ior[count->id], AB_GATE);
737
738 return 0;
739}
740
741static int quad8_count_enable_write(struct counter_device *counter,
742 struct counter_count *count, u8 enable)
743{
744 struct quad8 *const priv = counter_priv(counter);
745 unsigned long irqflags;
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;
746
747 spin_lock_irqsave(&priv->lock, irqflags);
748
785
786 spin_lock_irqsave(&priv->lock, irqflags);
787
749 quad8_control_register_update(priv, priv->ior, count->id, enable, AB_GATE);
788 ret = quad8_control_register_update(priv->map, priv->ior, count->id, enable, AB_GATE);
750
751 spin_unlock_irqrestore(&priv->lock, irqflags);
752
789
790 spin_unlock_irqrestore(&priv->lock, irqflags);
791
753 return 0;
792 return ret;
754}
755
756static const char *const quad8_noise_error_states[] = {
757 "No excessive noise is present at the count inputs",
758 "Excessive noise is present at the count inputs"
759};
760
761static int quad8_error_noise_get(struct counter_device *counter,
762 struct counter_count *count, u32 *noise_error)
763{
764 const struct quad8 *const priv = counter_priv(counter);
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);
765 u8 __iomem *const flag_addr = &priv->reg->channel[count->id].control;
766 u8 flag;
804 unsigned int flag;
805 int ret;
767
806
768 flag = ioread8(flag_addr);
807 ret = regmap_read(priv->map, QUAD8_CONTROL(count->id), &flag);
808 if (ret)
809 return ret;
769 *noise_error = u8_get_bits(flag, FLAG_E);
770
771 return 0;
772}
773
774static int quad8_count_preset_read(struct counter_device *counter,
775 struct counter_count *count, u64 *preset)
776{

--- 4 unchanged lines hidden (view full) ---

781 return 0;
782}
783
784static int quad8_count_preset_write(struct counter_device *counter,
785 struct counter_count *count, u64 preset)
786{
787 struct quad8 *const priv = counter_priv(counter);
788 unsigned long irqflags;
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{

--- 4 unchanged lines hidden (view full) ---

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;
789
790 if (preset > LS7267_CNTR_MAX)
791 return -ERANGE;
792
793 spin_lock_irqsave(&priv->lock, irqflags);
794
795 priv->preset[count->id] = preset;
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;
796 quad8_preset_register_set(priv, count->id, preset);
838 ret = quad8_preset_register_set(priv, count->id, preset);
797
798 spin_unlock_irqrestore(&priv->lock, irqflags);
799
839
840 spin_unlock_irqrestore(&priv->lock, irqflags);
841
800 return 0;
842 return ret;
801}
802
803static int quad8_count_ceiling_read(struct counter_device *counter,
804 struct counter_count *count, u64 *ceiling)
805{
806 struct quad8 *const priv = counter_priv(counter);
807 unsigned long irqflags;
808

--- 15 unchanged lines hidden (view full) ---

824 return 0;
825}
826
827static int quad8_count_ceiling_write(struct counter_device *counter,
828 struct counter_count *count, u64 ceiling)
829{
830 struct quad8 *const priv = counter_priv(counter);
831 unsigned long irqflags;
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

--- 15 unchanged lines hidden (view full) ---

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;
832
833 if (ceiling > LS7267_CNTR_MAX)
834 return -ERANGE;
835
836 spin_lock_irqsave(&priv->lock, irqflags);
837
838 /* Range Limit and Modulo-N count modes use preset value as ceiling */
839 switch (u8_get_bits(priv->cmr[count->id], COUNT_MODE)) {
840 case RANGE_LIMIT:
841 case MODULO_N:
842 priv->preset[count->id] = ceiling;
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;
843 quad8_preset_register_set(priv, count->id, ceiling);
844 spin_unlock_irqrestore(&priv->lock, irqflags);
845 return 0;
886 ret = quad8_preset_register_set(priv, count->id, ceiling);
887 break;
888 default:
889 ret = -EINVAL;
890 break;
846 }
847
848 spin_unlock_irqrestore(&priv->lock, irqflags);
849
891 }
892
893 spin_unlock_irqrestore(&priv->lock, irqflags);
894
850 return -EINVAL;
895 return ret;
851}
852
853static int quad8_count_preset_enable_read(struct counter_device *counter,
854 struct counter_count *count,
855 u8 *preset_enable)
856{
857 const struct quad8 *const priv = counter_priv(counter);
858

--- 4 unchanged lines hidden (view full) ---

863}
864
865static int quad8_count_preset_enable_write(struct counter_device *counter,
866 struct counter_count *count,
867 u8 preset_enable)
868{
869 struct quad8 *const priv = counter_priv(counter);
870 unsigned long irqflags;
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

--- 4 unchanged lines hidden (view full) ---

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;
871
872 spin_lock_irqsave(&priv->lock, irqflags);
873
874 /* Preset enable is active low in Input/Output Control register */
917
918 spin_lock_irqsave(&priv->lock, irqflags);
919
920 /* Preset enable is active low in Input/Output Control register */
875 quad8_control_register_update(priv, priv->ior, count->id, !preset_enable, LOAD_PIN);
921 ret = quad8_control_register_update(priv->map, priv->ior, count->id, !preset_enable,
922 LOAD_PIN);
876
877 spin_unlock_irqrestore(&priv->lock, irqflags);
878
923
924 spin_unlock_irqrestore(&priv->lock, irqflags);
925
879 return 0;
926 return ret;
880}
881
882static int quad8_signal_cable_fault_read(struct counter_device *counter,
883 struct counter_signal *signal,
884 u8 *cable_fault)
885{
886 struct quad8 *const priv = counter_priv(counter);
887 const size_t channel_id = signal->id / 2;
888 unsigned long irqflags;
889 bool disabled;
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;
890 unsigned int status;
937 int ret;
891
892 spin_lock_irqsave(&priv->lock, irqflags);
893
894 disabled = !(priv->cable_fault_enable & BIT(channel_id));
895
896 if (disabled) {
897 spin_unlock_irqrestore(&priv->lock, irqflags);
898 return -EINVAL;
899 }
900
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
901 /* Logic 0 = cable fault */
902 status = ioread8(&priv->reg->cable_status);
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 }
903
904 spin_unlock_irqrestore(&priv->lock, irqflags);
905
953
954 spin_unlock_irqrestore(&priv->lock, irqflags);
955
906 /* Mask respective channel and invert logic */
907 *cable_fault = !(status & BIT(channel_id));
956 /* Logic 0 = cable fault */
957 *cable_fault = !ret;
908
909 return 0;
910}
911
912static int quad8_signal_cable_fault_enable_read(struct counter_device *counter,
913 struct counter_signal *signal,
914 u8 *enable)
915{

--- 8 unchanged lines hidden (view full) ---

924static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
925 struct counter_signal *signal,
926 u8 enable)
927{
928 struct quad8 *const priv = counter_priv(counter);
929 const size_t channel_id = signal->id / 2;
930 unsigned long irqflags;
931 unsigned int cable_fault_enable;
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{

--- 8 unchanged lines hidden (view full) ---

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;
932
933 spin_lock_irqsave(&priv->lock, irqflags);
934
935 if (enable)
936 priv->cable_fault_enable |= BIT(channel_id);
937 else
938 priv->cable_fault_enable &= ~BIT(channel_id);
939
940 /* Enable is active low in Differential Encoder Cable Status register */
941 cable_fault_enable = ~priv->cable_fault_enable;
942
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
943 iowrite8(cable_fault_enable, &priv->reg->cable_status);
994 ret = regmap_write(priv->map, QUAD8_CABLE_STATUS, cable_fault_enable);
944
945 spin_unlock_irqrestore(&priv->lock, irqflags);
946
995
996 spin_unlock_irqrestore(&priv->lock, irqflags);
997
947 return 0;
998 return ret;
948}
949
950static int quad8_signal_fck_prescaler_read(struct counter_device *counter,
951 struct counter_signal *signal,
952 u8 *prescaler)
953{
954 const struct quad8 *const priv = counter_priv(counter);
955
956 *prescaler = priv->fck_prescaler[signal->id / 2];
957
958 return 0;
959}
960
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
961static void quad8_filter_clock_prescaler_set(struct quad8 *const priv, const size_t id,
962 const u8 prescaler)
1012static int quad8_filter_clock_prescaler_set(struct quad8 *const priv, const size_t id,
1013 const u8 prescaler)
963{
1014{
964 struct channel_reg __iomem *const chan = priv->reg->channel + id;
1015 int ret;
965
1016
966 iowrite8(SELECT_RLD | RESET_BP, &chan->control);
967 iowrite8(prescaler, &chan->data);
968 iowrite8(SELECT_RLD | TRANSFER_PR0_TO_PSC, &chan->control);
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);
969}
970
971static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
972 struct counter_signal *signal,
973 u8 prescaler)
974{
975 struct quad8 *const priv = counter_priv(counter);
976 const size_t channel_id = signal->id / 2;
977 unsigned long irqflags;
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;
978
979 spin_lock_irqsave(&priv->lock, irqflags);
980
981 priv->fck_prescaler[channel_id] = prescaler;
1034
1035 spin_lock_irqsave(&priv->lock, irqflags);
1036
1037 priv->fck_prescaler[channel_id] = prescaler;
982 quad8_filter_clock_prescaler_set(priv, channel_id, prescaler);
1038 ret = quad8_filter_clock_prescaler_set(priv, channel_id, prescaler);
983
984 spin_unlock_irqrestore(&priv->lock, irqflags);
985
1039
1040 spin_unlock_irqrestore(&priv->lock, irqflags);
1041
986 return 0;
1042 return ret;
987}
988
989static struct counter_comp quad8_signal_ext[] = {
990 COUNTER_COMP_SIGNAL_BOOL("cable_fault", quad8_signal_cable_fault_read,
991 NULL),
992 COUNTER_COMP_SIGNAL_BOOL("cable_fault_enable",
993 quad8_signal_cable_fault_enable_read,
994 quad8_signal_cable_fault_enable_write),

--- 136 unchanged lines hidden (view full) ---

1131 QUAD8_COUNT(6, "Channel 7 Count"),
1132 QUAD8_COUNT(7, "Channel 8 Count")
1133};
1134
1135static irqreturn_t quad8_irq_handler(int irq, void *private)
1136{
1137 struct counter_device *counter = private;
1138 struct quad8 *const priv = counter_priv(counter);
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),

--- 136 unchanged lines hidden (view full) ---

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;
1139 unsigned long irq_status;
1140 unsigned long channel;
1141 unsigned int flg_pins;
1142 u8 event;
1196 unsigned long irq_status;
1197 unsigned long channel;
1198 unsigned int flg_pins;
1199 u8 event;
1200 int ret;
1143
1201
1144 irq_status = ioread8(&priv->reg->interrupt_status);
1145 if (!irq_status)
1202 ret = regmap_read(priv->map, QUAD8_INTERRUPT_STATUS, &status);
1203 if (ret)
1204 return ret;
1205 if (!status)
1146 return IRQ_NONE;
1147
1206 return IRQ_NONE;
1207
1208 irq_status = status;
1148 for_each_set_bit(channel, &irq_status, QUAD8_NUM_COUNTERS) {
1149 flg_pins = u8_get_bits(priv->ior[channel], FLG_PINS);
1150 switch (flg_pins) {
1151 case FLG1_CARRY_FLG2_BORROW:
1152 event = COUNTER_EVENT_OVERFLOW;
1153 break;
1154 case FLG1_COMPARE_FLG2_BORROW:
1155 event = COUNTER_EVENT_THRESHOLD;

--- 9 unchanged lines hidden (view full) ---

1165 WARN_ONCE(true, "invalid interrupt trigger function %u configured for channel %lu\n",
1166 flg_pins, channel);
1167 continue;
1168 }
1169
1170 counter_push_event(counter, event, channel);
1171 }
1172
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;

--- 9 unchanged lines hidden (view full) ---

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
1173 /* Clear pending interrupts on device */
1174 iowrite8(CLEAR_PENDING_INTERRUPTS, &priv->reg->channel_oper);
1234 ret = regmap_write(priv->map, QUAD8_CHANNEL_OPERATION, CLEAR_PENDING_INTERRUPTS);
1235 if (ret)
1236 return ret;
1175
1176 return IRQ_HANDLED;
1177}
1178
1237
1238 return IRQ_HANDLED;
1239}
1240
1179static void quad8_init_counter(struct quad8 *const priv, const size_t channel)
1241static int quad8_init_counter(struct quad8 *const priv, const size_t channel)
1180{
1242{
1181 struct channel_reg __iomem *const chan = priv->reg->channel + channel;
1243 int ret;
1182
1244
1183 quad8_filter_clock_prescaler_set(priv, channel, 0);
1184 quad8_preset_register_set(priv, channel, 0);
1185 quad8_flag_register_reset(priv, channel);
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;
1186
1187 /* Binary encoding; Normal count; non-quadrature mode */
1188 priv->cmr[channel] = SELECT_CMR | BINARY | u8_encode_bits(NORMAL_COUNT, COUNT_MODE) |
1189 u8_encode_bits(NON_QUADRATURE, QUADRATURE_MODE);
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);
1190 iowrite8(priv->cmr[channel], &chan->control);
1258 ret = regmap_write(priv->map, QUAD8_CONTROL(channel), priv->cmr[channel]);
1259 if (ret)
1260 return ret;
1191
1192 /* Disable A and B inputs; preset on index; FLG1 as Carry */
1193 priv->ior[channel] = SELECT_IOR | DISABLE_AB | u8_encode_bits(LOAD_CNTR, LOAD_PIN) |
1194 u8_encode_bits(FLG1_CARRY_FLG2_BORROW, FLG_PINS);
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);
1195 iowrite8(priv->ior[channel], &chan->control);
1265 ret = regmap_write(priv->map, QUAD8_CONTROL(channel), priv->ior[channel]);
1266 if (ret)
1267 return ret;
1196
1197 /* Disable index function; negative index polarity */
1198 priv->idr[channel] = SELECT_IDR | u8_encode_bits(DISABLE_INDEX_MODE, INDEX_MODE) |
1199 u8_encode_bits(NEGATIVE_INDEX_POLARITY, INDEX_POLARITY);
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);
1200 iowrite8(priv->idr[channel], &chan->control);
1272 return regmap_write(priv->map, QUAD8_CONTROL(channel), priv->idr[channel]);
1201}
1202
1203static int quad8_probe(struct device *dev, unsigned int id)
1204{
1205 struct counter_device *counter;
1206 struct quad8 *priv;
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;
1207 unsigned long i;
1280 unsigned long i;
1208 int err;
1281 int ret;
1209
1210 if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) {
1211 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
1212 base[id], base[id] + QUAD8_EXTENT);
1213 return -EBUSY;
1214 }
1215
1216 counter = devm_counter_alloc(dev, sizeof(*priv));
1217 if (!counter)
1218 return -ENOMEM;
1219 priv = counter_priv(counter);
1220
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
1221 priv->reg = devm_ioport_map(dev, base[id], QUAD8_EXTENT);
1222 if (!priv->reg)
1294 regs = devm_ioport_map(dev, base[id], QUAD8_EXTENT);
1295 if (!regs)
1223 return -ENOMEM;
1224
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
1225 /* Initialize Counter device and driver data */
1226 counter->name = dev_name(dev);
1227 counter->parent = dev;
1228 counter->ops = &quad8_ops;
1229 counter->counts = quad8_counts;
1230 counter->num_counts = ARRAY_SIZE(quad8_counts);
1231 counter->signals = quad8_signals;
1232 counter->num_signals = ARRAY_SIZE(quad8_signals);
1233
1234 spin_lock_init(&priv->lock);
1235
1236 /* Reset Index/Interrupt Register */
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 */
1237 iowrite8(0x00, &priv->reg->index_interrupt);
1315 ret = regmap_write(priv->map, QUAD8_INDEX_INTERRUPT, 0x00);
1316 if (ret)
1317 return ret;
1238 /* Reset all counters and disable interrupt function */
1318 /* Reset all counters and disable interrupt function */
1239 iowrite8(RESET_COUNTERS | DISABLE_INTERRUPT_FUNCTION, &priv->reg->channel_oper);
1319 ret = regmap_write(priv->map, QUAD8_CHANNEL_OPERATION,
1320 RESET_COUNTERS | DISABLE_INTERRUPT_FUNCTION);
1321 if (ret)
1322 return ret;
1240 /* Set initial configuration for all counters */
1323 /* Set initial configuration for all counters */
1241 for (i = 0; i < QUAD8_NUM_COUNTERS; i++)
1242 quad8_init_counter(priv, i);
1324 for (i = 0; i < QUAD8_NUM_COUNTERS; i++) {
1325 ret = quad8_init_counter(priv, i);
1326 if (ret)
1327 return ret;
1328 }
1243 /* Disable Differential Encoder Cable Status for all channels */
1329 /* Disable Differential Encoder Cable Status for all channels */
1244 iowrite8(0xFF, &priv->reg->cable_status);
1330 ret = regmap_write(priv->map, QUAD8_CABLE_STATUS, GENMASK(7, 0));
1331 if (ret)
1332 return ret;
1245 /* Enable all counters and enable interrupt function */
1333 /* Enable all counters and enable interrupt function */
1246 iowrite8(ENABLE_COUNTERS | ENABLE_INTERRUPT_FUNCTION, &priv->reg->channel_oper);
1334 ret = regmap_write(priv->map, QUAD8_CHANNEL_OPERATION,
1335 ENABLE_COUNTERS | ENABLE_INTERRUPT_FUNCTION);
1336 if (ret)
1337 return ret;
1247
1338
1248 err = devm_request_irq(&counter->dev, irq[id], quad8_irq_handler,
1339 ret = devm_request_irq(&counter->dev, irq[id], quad8_irq_handler,
1249 IRQF_SHARED, counter->name, counter);
1340 IRQF_SHARED, counter->name, counter);
1250 if (err)
1251 return err;
1341 if (ret)
1342 return ret;
1252
1343
1253 err = devm_counter_add(dev, counter);
1254 if (err < 0)
1255 return dev_err_probe(dev, err, "Failed to add counter\n");
1344 ret = devm_counter_add(dev, counter);
1345 if (ret < 0)
1346 return dev_err_probe(dev, ret, "Failed to add counter\n");
1256
1257 return 0;
1258}
1259
1260static struct isa_driver quad8_driver = {
1261 .probe = quad8_probe,
1262 .driver = {
1263 .name = "104-quad-8"
1264 }
1265};
1266
1267module_isa_driver_with_irq(quad8_driver, num_quad8, num_irq);
1268
1269MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
1270MODULE_DESCRIPTION("ACCES 104-QUAD-8 driver");
1271MODULE_LICENSE("GPL v2");
1272MODULE_IMPORT_NS(COUNTER);
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);