Lines Matching +full:ext +full:- +full:reset +full:- +full:output
1 // SPDX-License-Identifier: GPL-2.0
3 * Counter driver for the ACCES 104-QUAD-8
6 * This driver supports the ACCES 104-QUAD-8 and ACCES 104-QUAD-4.
25 MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
30 * struct quad8 - device private data structure
64 /* Borrow Toggle flip-flop */
66 /* Carry Toggle flip-flop */
72 /* Reset and Load Signal Decoders */
76 /* Input / Output Control Register */
80 /* Reset Byte Pointer (three byte data pointer) */
82 /* Reset Counter */
84 /* Reset Borrow Toggle, Carry Toggle, Compare Toggle, and Sign flags */
86 /* Reset Error flag */
90 /* Transfer Counter to Output Latch */
104 const struct quad8 *const priv = counter->priv; in quad8_signal_read()
108 if (signal->id < 16) in quad8_signal_read()
109 return -EINVAL; in quad8_signal_read()
111 state = inb(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS) in quad8_signal_read()
112 & BIT(signal->id - 16); in quad8_signal_read()
122 struct quad8 *const priv = counter->priv; in quad8_count_read()
123 const int base_offset = priv->base + 2 * count->id; in quad8_count_read()
136 mutex_lock(&priv->lock); in quad8_count_read()
138 /* Reset Byte Pointer; transfer Counter to Output Latch */ in quad8_count_read()
145 mutex_unlock(&priv->lock); in quad8_count_read()
153 struct quad8 *const priv = counter->priv; in quad8_count_write()
154 const int base_offset = priv->base + 2 * count->id; in quad8_count_write()
157 /* Only 24-bit values are supported */ in quad8_count_write()
159 return -ERANGE; in quad8_count_write()
161 mutex_lock(&priv->lock); in quad8_count_write()
163 /* Reset Byte Pointer */ in quad8_count_write()
173 /* Reset Byte Pointer */ in quad8_count_write()
177 val = priv->preset[count->id]; in quad8_count_write()
181 /* Reset Borrow, Carry, Compare, and Sign flags */ in quad8_count_write()
183 /* Reset Error flag */ in quad8_count_write()
186 mutex_unlock(&priv->lock); in quad8_count_write()
208 struct quad8 *const priv = counter->priv; in quad8_function_get()
209 const int id = count->id; in quad8_function_get()
211 mutex_lock(&priv->lock); in quad8_function_get()
213 if (priv->quadrature_mode[id]) in quad8_function_get()
214 switch (priv->quadrature_scale[id]) { in quad8_function_get()
228 mutex_unlock(&priv->lock); in quad8_function_get()
236 struct quad8 *const priv = counter->priv; in quad8_function_set()
237 const int id = count->id; in quad8_function_set()
238 unsigned int *const quadrature_mode = priv->quadrature_mode + id; in quad8_function_set()
239 unsigned int *const scale = priv->quadrature_scale + id; in quad8_function_set()
240 unsigned int *const synchronous_mode = priv->synchronous_mode + id; in quad8_function_set()
241 const int base_offset = priv->base + 2 * id + 1; in quad8_function_set()
245 mutex_lock(&priv->lock); in quad8_function_set()
247 mode_cfg = priv->count_mode[id] << 1; in quad8_function_set()
248 idr_cfg = priv->index_polarity[id] << 1; in quad8_function_set()
256 /* Synchronous function not supported in non-quadrature mode */ in quad8_function_set()
280 mutex_unlock(&priv->lock); in quad8_function_set()
281 return -EINVAL; in quad8_function_set()
288 mutex_unlock(&priv->lock); in quad8_function_set()
296 const struct quad8 *const priv = counter->priv; in quad8_direction_get()
298 const unsigned int flag_addr = priv->base + 2 * count->id + 1; in quad8_direction_get()
330 struct quad8 *const priv = counter->priv; in quad8_action_get()
333 const size_t signal_a_id = count->synapses[0].signal->id; in quad8_action_get()
337 if (synapse->signal->id >= 16) { in quad8_action_get()
338 if (priv->preset_enable[count->id]) in quad8_action_get()
356 if (synapse->signal->id == signal_a_id) in quad8_action_get()
360 if (synapse->signal->id == signal_a_id) { in quad8_action_get()
370 if (synapse->signal->id == signal_a_id) in quad8_action_get()
378 return -EINVAL; in quad8_action_get()
399 const struct quad8 *const priv = counter->priv; in quad8_index_polarity_get()
400 const size_t channel_id = signal->id - 16; in quad8_index_polarity_get()
402 *index_polarity = priv->index_polarity[channel_id]; in quad8_index_polarity_get()
410 struct quad8 *const priv = counter->priv; in quad8_index_polarity_set()
411 const size_t channel_id = signal->id - 16; in quad8_index_polarity_set()
412 const int base_offset = priv->base + 2 * channel_id + 1; in quad8_index_polarity_set()
415 mutex_lock(&priv->lock); in quad8_index_polarity_set()
417 idr_cfg |= priv->synchronous_mode[channel_id]; in quad8_index_polarity_set()
419 priv->index_polarity[channel_id] = index_polarity; in quad8_index_polarity_set()
424 mutex_unlock(&priv->lock); in quad8_index_polarity_set()
437 "non-synchronous",
444 const struct quad8 *const priv = counter->priv; in quad8_synchronous_mode_get()
445 const size_t channel_id = signal->id - 16; in quad8_synchronous_mode_get()
447 *synchronous_mode = priv->synchronous_mode[channel_id]; in quad8_synchronous_mode_get()
455 struct quad8 *const priv = counter->priv; in quad8_synchronous_mode_set()
456 const size_t channel_id = signal->id - 16; in quad8_synchronous_mode_set()
457 const int base_offset = priv->base + 2 * channel_id + 1; in quad8_synchronous_mode_set()
460 mutex_lock(&priv->lock); in quad8_synchronous_mode_set()
462 idr_cfg |= priv->index_polarity[channel_id] << 1; in quad8_synchronous_mode_set()
464 /* Index function must be non-synchronous in non-quadrature mode */ in quad8_synchronous_mode_set()
465 if (synchronous_mode && !priv->quadrature_mode[channel_id]) { in quad8_synchronous_mode_set()
466 mutex_unlock(&priv->lock); in quad8_synchronous_mode_set()
467 return -EINVAL; in quad8_synchronous_mode_set()
470 priv->synchronous_mode[channel_id] = synchronous_mode; in quad8_synchronous_mode_set()
475 mutex_unlock(&priv->lock); in quad8_synchronous_mode_set()
497 const struct quad8 *const priv = counter->priv; in quad8_count_mode_get()
499 /* Map 104-QUAD-8 count mode to Generic Counter count mode */ in quad8_count_mode_get()
500 switch (priv->count_mode[count->id]) { in quad8_count_mode_get()
521 struct quad8 *const priv = counter->priv; in quad8_count_mode_set()
523 const int base_offset = priv->base + 2 * count->id + 1; in quad8_count_mode_set()
525 /* Map Generic Counter count mode to 104-QUAD-8 count mode */ in quad8_count_mode_set()
541 return -EINVAL; in quad8_count_mode_set()
544 mutex_lock(&priv->lock); in quad8_count_mode_set()
546 priv->count_mode[count->id] = cnt_mode; in quad8_count_mode_set()
552 if (priv->quadrature_mode[count->id]) in quad8_count_mode_set()
553 mode_cfg |= (priv->quadrature_scale[count->id] + 1) << 3; in quad8_count_mode_set()
558 mutex_unlock(&priv->lock); in quad8_count_mode_set()
583 const struct quad8 *const priv = counter->priv; in quad8_count_enable_read()
585 return sprintf(buf, "%u\n", priv->ab_enable[count->id]); in quad8_count_enable_read()
591 struct quad8 *const priv = counter->priv; in quad8_count_enable_write()
592 const int base_offset = priv->base + 2 * count->id; in quad8_count_enable_write()
601 mutex_lock(&priv->lock); in quad8_count_enable_write()
603 priv->ab_enable[count->id] = ab_enable; in quad8_count_enable_write()
605 ior_cfg = ab_enable | priv->preset_enable[count->id] << 1; in quad8_count_enable_write()
610 mutex_unlock(&priv->lock); in quad8_count_enable_write()
623 const struct quad8 *const priv = counter->priv; in quad8_error_noise_get()
624 const int base_offset = priv->base + 2 * count->id + 1; in quad8_error_noise_get()
640 const struct quad8 *const priv = counter->priv; in quad8_count_preset_read()
642 return sprintf(buf, "%u\n", priv->preset[count->id]); in quad8_count_preset_read()
648 const unsigned int base_offset = priv->base + 2 * id; in quad8_preset_register_set()
651 priv->preset[id] = preset; in quad8_preset_register_set()
653 /* Reset Byte Pointer */ in quad8_preset_register_set()
664 struct quad8 *const priv = counter->priv; in quad8_count_preset_write()
672 /* Only 24-bit values are supported */ in quad8_count_preset_write()
674 return -ERANGE; in quad8_count_preset_write()
676 mutex_lock(&priv->lock); in quad8_count_preset_write()
678 quad8_preset_register_set(priv, count->id, preset); in quad8_count_preset_write()
680 mutex_unlock(&priv->lock); in quad8_count_preset_write()
688 struct quad8 *const priv = counter->priv; in quad8_count_ceiling_read()
690 mutex_lock(&priv->lock); in quad8_count_ceiling_read()
692 /* Range Limit and Modulo-N count modes use preset value as ceiling */ in quad8_count_ceiling_read()
693 switch (priv->count_mode[count->id]) { in quad8_count_ceiling_read()
696 mutex_unlock(&priv->lock); in quad8_count_ceiling_read()
697 return sprintf(buf, "%u\n", priv->preset[count->id]); in quad8_count_ceiling_read()
700 mutex_unlock(&priv->lock); in quad8_count_ceiling_read()
709 struct quad8 *const priv = counter->priv; in quad8_count_ceiling_write()
717 /* Only 24-bit values are supported */ in quad8_count_ceiling_write()
719 return -ERANGE; in quad8_count_ceiling_write()
721 mutex_lock(&priv->lock); in quad8_count_ceiling_write()
723 /* Range Limit and Modulo-N count modes use preset value as ceiling */ in quad8_count_ceiling_write()
724 switch (priv->count_mode[count->id]) { in quad8_count_ceiling_write()
727 quad8_preset_register_set(priv, count->id, ceiling); in quad8_count_ceiling_write()
728 mutex_unlock(&priv->lock); in quad8_count_ceiling_write()
732 mutex_unlock(&priv->lock); in quad8_count_ceiling_write()
734 return -EINVAL; in quad8_count_ceiling_write()
740 const struct quad8 *const priv = counter->priv; in quad8_count_preset_enable_read()
742 return sprintf(buf, "%u\n", !priv->preset_enable[count->id]); in quad8_count_preset_enable_read()
748 struct quad8 *const priv = counter->priv; in quad8_count_preset_enable_write()
749 const int base_offset = priv->base + 2 * count->id + 1; in quad8_count_preset_enable_write()
758 /* Preset enable is active low in Input/Output Control register */ in quad8_count_preset_enable_write()
761 mutex_lock(&priv->lock); in quad8_count_preset_enable_write()
763 priv->preset_enable[count->id] = preset_enable; in quad8_count_preset_enable_write()
765 ior_cfg = priv->ab_enable[count->id] | (unsigned int)preset_enable << 1; in quad8_count_preset_enable_write()
767 /* Load I/O control configuration to Input / Output Control Register */ in quad8_count_preset_enable_write()
770 mutex_unlock(&priv->lock); in quad8_count_preset_enable_write()
779 struct quad8 *const priv = counter->priv; in quad8_signal_cable_fault_read()
780 const size_t channel_id = signal->id / 2; in quad8_signal_cable_fault_read()
785 mutex_lock(&priv->lock); in quad8_signal_cable_fault_read()
787 disabled = !(priv->cable_fault_enable & BIT(channel_id)); in quad8_signal_cable_fault_read()
790 mutex_unlock(&priv->lock); in quad8_signal_cable_fault_read()
791 return -EINVAL; in quad8_signal_cable_fault_read()
795 status = inb(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS); in quad8_signal_cable_fault_read()
797 mutex_unlock(&priv->lock); in quad8_signal_cable_fault_read()
809 const struct quad8 *const priv = counter->priv; in quad8_signal_cable_fault_enable_read()
810 const size_t channel_id = signal->id / 2; in quad8_signal_cable_fault_enable_read()
811 const unsigned int enb = !!(priv->cable_fault_enable & BIT(channel_id)); in quad8_signal_cable_fault_enable_read()
820 struct quad8 *const priv = counter->priv; in quad8_signal_cable_fault_enable_write()
821 const size_t channel_id = signal->id / 2; in quad8_signal_cable_fault_enable_write()
830 mutex_lock(&priv->lock); in quad8_signal_cable_fault_enable_write()
833 priv->cable_fault_enable |= BIT(channel_id); in quad8_signal_cable_fault_enable_write()
835 priv->cable_fault_enable &= ~BIT(channel_id); in quad8_signal_cable_fault_enable_write()
838 cable_fault_enable = ~priv->cable_fault_enable; in quad8_signal_cable_fault_enable_write()
840 outb(cable_fault_enable, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS); in quad8_signal_cable_fault_enable_write()
842 mutex_unlock(&priv->lock); in quad8_signal_cable_fault_enable_write()
850 const struct quad8 *const priv = counter->priv; in quad8_signal_fck_prescaler_read()
851 const size_t channel_id = signal->id / 2; in quad8_signal_fck_prescaler_read()
853 return sprintf(buf, "%u\n", priv->fck_prescaler[channel_id]); in quad8_signal_fck_prescaler_read()
860 struct quad8 *const priv = counter->priv; in quad8_signal_fck_prescaler_write()
861 const size_t channel_id = signal->id / 2; in quad8_signal_fck_prescaler_write()
862 const int base_offset = priv->base + 2 * channel_id; in quad8_signal_fck_prescaler_write()
870 mutex_lock(&priv->lock); in quad8_signal_fck_prescaler_write()
872 priv->fck_prescaler[channel_id] = prescaler; in quad8_signal_fck_prescaler_write()
874 /* Reset Byte Pointer */ in quad8_signal_fck_prescaler_write()
882 mutex_unlock(&priv->lock); in quad8_signal_fck_prescaler_write()
914 .ext = quad8_signal_ext, \
921 .ext = quad8_index_ext, \
1019 .ext = quad8_count_ext, \
1041 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", in quad8_probe()
1043 return -EBUSY; in quad8_probe()
1048 return -ENOMEM; in quad8_probe()
1051 priv->counter.name = dev_name(dev); in quad8_probe()
1052 priv->counter.parent = dev; in quad8_probe()
1053 priv->counter.ops = &quad8_ops; in quad8_probe()
1054 priv->counter.counts = quad8_counts; in quad8_probe()
1055 priv->counter.num_counts = ARRAY_SIZE(quad8_counts); in quad8_probe()
1056 priv->counter.signals = quad8_signals; in quad8_probe()
1057 priv->counter.num_signals = ARRAY_SIZE(quad8_signals); in quad8_probe()
1058 priv->counter.priv = priv; in quad8_probe()
1059 priv->base = base[id]; in quad8_probe()
1062 mutex_init(&priv->lock); in quad8_probe()
1064 /* Reset all counters and disable interrupt function */ in quad8_probe()
1069 /* Reset Byte Pointer */ in quad8_probe()
1071 /* Reset filter clock factor */ in quad8_probe()
1075 /* Reset Byte Pointer */ in quad8_probe()
1077 /* Reset Preset Register */ in quad8_probe()
1080 /* Reset Borrow, Carry, Compare, and Sign flags */ in quad8_probe()
1082 /* Reset Error flag */ in quad8_probe()
1084 /* Binary encoding; Normal count; non-quadrature mode */ in quad8_probe()
1096 return devm_counter_register(dev, &priv->counter); in quad8_probe()
1102 .name = "104-quad-8"
1109 MODULE_DESCRIPTION("ACCES 104-QUAD-8 driver");