Lines Matching +full:signal +full:- +full:id

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 */
101 struct counter_signal *signal, in quad8_signal_read() argument
104 const struct quad8 *const priv = counter->priv; in quad8_signal_read()
107 /* Only Index signal levels can be read */ 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()
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()
177 val = priv->preset[count->id]; 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() local
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() local
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()
397 struct counter_signal *signal, size_t *index_polarity) in quad8_index_polarity_get() argument
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()
408 struct counter_signal *signal, size_t index_polarity) in quad8_index_polarity_set() argument
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",
442 struct counter_signal *signal, size_t *synchronous_mode) in quad8_synchronous_mode_get() argument
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()
453 struct counter_signal *signal, size_t synchronous_mode) in quad8_synchronous_mode_set() argument
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()
645 static void quad8_preset_register_set(struct quad8 *const priv, const int id, in quad8_preset_register_set() argument
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()
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()
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()
770 mutex_unlock(&priv->lock); in quad8_count_preset_enable_write()
776 struct counter_signal *signal, in quad8_signal_cable_fault_read() argument
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()
806 struct counter_device *counter, struct counter_signal *signal, in quad8_signal_cable_fault_enable_read() argument
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()
817 struct counter_device *counter, struct counter_signal *signal, in quad8_signal_cable_fault_enable_write() argument
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()
848 struct counter_signal *signal, void *private, char *buf) in quad8_signal_fck_prescaler_read() argument
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()
857 struct counter_signal *signal, void *private, const char *buf, in quad8_signal_fck_prescaler_write() argument
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()
882 mutex_unlock(&priv->lock); in quad8_signal_fck_prescaler_write()
912 .id = (_id), \
919 .id = (_id), \
956 .signal = quad8_signals + 2 * (_id) \
961 .signal = quad8_signals + 2 * (_id) + 1 \
966 .signal = quad8_signals + 2 * (_id) + 16 \
1013 .id = (_id), \
1034 static int quad8_probe(struct device *dev, unsigned int id) in quad8_probe() argument
1040 if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) { in quad8_probe()
1041 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", in quad8_probe()
1042 base[id], base[id] + QUAD8_EXTENT); 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()
1065 outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP); in quad8_probe()
1068 base_offset = base[id] + 2 * i; in quad8_probe()
1084 /* Binary encoding; Normal count; non-quadrature mode */ in quad8_probe()
1092 outb(0xFF, base[id] + QUAD8_DIFF_ENCODER_CABLE_STATUS); in quad8_probe()
1094 outb(QUAD8_CHAN_OP_ENABLE_COUNTERS, base[id] + QUAD8_REG_CHAN_OP); 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");