Linux Audio

Check our new training course

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