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); |