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.
27 MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
32 * struct quad8_iio - IIO device private data structure
65 /* Borrow Toggle flip-flop */
67 /* Carry Toggle flip-flop */
73 /* Reset and Load Signal Decoders */
106 const int base_offset = priv->base + 2 * chan->channel; in quad8_read_raw()
114 if (chan->type == IIO_INDEX) { in quad8_read_raw()
115 *val = !!(inb(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS) in quad8_read_raw()
116 & BIT(chan->channel)); in quad8_read_raw()
127 mutex_lock(&priv->lock); in quad8_read_raw()
136 mutex_unlock(&priv->lock); in quad8_read_raw()
140 *val = priv->ab_enable[chan->channel]; in quad8_read_raw()
144 *val2 = priv->quadrature_scale[chan->channel]; in quad8_read_raw()
148 return -EINVAL; in quad8_read_raw()
155 const int base_offset = priv->base + 2 * chan->channel; in quad8_write_raw()
161 if (chan->type == IIO_INDEX) in quad8_write_raw()
162 return -EINVAL; in quad8_write_raw()
164 /* Only 24-bit values are supported */ in quad8_write_raw()
166 return -EINVAL; in quad8_write_raw()
168 mutex_lock(&priv->lock); in quad8_write_raw()
184 val = priv->preset[chan->channel]; in quad8_write_raw()
193 mutex_unlock(&priv->lock); in quad8_write_raw()
199 return -EINVAL; in quad8_write_raw()
201 mutex_lock(&priv->lock); in quad8_write_raw()
203 priv->ab_enable[chan->channel] = val; in quad8_write_raw()
205 ior_cfg = val | priv->preset_enable[chan->channel] << 1; in quad8_write_raw()
210 mutex_unlock(&priv->lock); in quad8_write_raw()
214 mutex_lock(&priv->lock); in quad8_write_raw()
217 if (!priv->quadrature_mode[chan->channel] && in quad8_write_raw()
219 mutex_unlock(&priv->lock); in quad8_write_raw()
220 return -EINVAL; in quad8_write_raw()
225 priv->quadrature_scale[chan->channel] = 0; in quad8_write_raw()
229 priv->quadrature_scale[chan->channel] = 1; in quad8_write_raw()
232 priv->quadrature_scale[chan->channel] = 2; in quad8_write_raw()
235 mutex_unlock(&priv->lock); in quad8_write_raw()
236 return -EINVAL; in quad8_write_raw()
239 mutex_unlock(&priv->lock); in quad8_write_raw()
240 return -EINVAL; in quad8_write_raw()
243 mutex_unlock(&priv->lock); in quad8_write_raw()
247 return -EINVAL; in quad8_write_raw()
260 return snprintf(buf, PAGE_SIZE, "%u\n", priv->preset[chan->channel]); in quad8_read_preset()
267 const int base_offset = priv->base + 2 * chan->channel; in quad8_write_preset()
276 /* Only 24-bit values are supported */ in quad8_write_preset()
278 return -EINVAL; in quad8_write_preset()
280 mutex_lock(&priv->lock); in quad8_write_preset()
282 priv->preset[chan->channel] = preset; in quad8_write_preset()
291 mutex_unlock(&priv->lock); in quad8_write_preset()
302 !priv->preset_enable[chan->channel]); in quad8_read_set_to_preset_on_index()
310 const int base_offset = priv->base + 2 * chan->channel + 1; in quad8_write_set_to_preset_on_index()
322 mutex_lock(&priv->lock); in quad8_write_set_to_preset_on_index()
324 priv->preset_enable[chan->channel] = preset_enable; in quad8_write_set_to_preset_on_index()
326 ior_cfg = priv->ab_enable[chan->channel] | in quad8_write_set_to_preset_on_index()
332 mutex_unlock(&priv->lock); in quad8_write_set_to_preset_on_index()
346 const int base_offset = priv->base + 2 * chan->channel + 1; in quad8_get_noise_error()
366 const int base_offset = priv->base + 2 * chan->channel + 1; in quad8_get_count_direction()
380 "non-recycle",
381 "modulo-n"
389 const int base_offset = priv->base + 2 * chan->channel + 1; in quad8_set_count_mode()
391 mutex_lock(&priv->lock); in quad8_set_count_mode()
393 priv->count_mode[chan->channel] = cnt_mode; in quad8_set_count_mode()
396 if (priv->quadrature_mode[chan->channel]) in quad8_set_count_mode()
397 mode_cfg |= (priv->quadrature_scale[chan->channel] + 1) << 3; in quad8_set_count_mode()
402 mutex_unlock(&priv->lock); in quad8_set_count_mode()
412 return priv->count_mode[chan->channel]; in quad8_get_count_mode()
423 "non-synchronous",
431 const int base_offset = priv->base + 2 * chan->channel + 1; in quad8_set_synchronous_mode()
434 mutex_lock(&priv->lock); in quad8_set_synchronous_mode()
436 idr_cfg |= priv->index_polarity[chan->channel] << 1; in quad8_set_synchronous_mode()
438 /* Index function must be non-synchronous in non-quadrature mode */ in quad8_set_synchronous_mode()
439 if (synchronous_mode && !priv->quadrature_mode[chan->channel]) { in quad8_set_synchronous_mode()
440 mutex_unlock(&priv->lock); in quad8_set_synchronous_mode()
441 return -EINVAL; in quad8_set_synchronous_mode()
444 priv->synchronous_mode[chan->channel] = synchronous_mode; in quad8_set_synchronous_mode()
449 mutex_unlock(&priv->lock); in quad8_set_synchronous_mode()
459 return priv->synchronous_mode[chan->channel]; in quad8_get_synchronous_mode()
470 "non-quadrature",
478 const int base_offset = priv->base + 2 * chan->channel + 1; in quad8_set_quadrature_mode()
481 mutex_lock(&priv->lock); in quad8_set_quadrature_mode()
483 mode_cfg = priv->count_mode[chan->channel] << 1; in quad8_set_quadrature_mode()
486 mode_cfg |= (priv->quadrature_scale[chan->channel] + 1) << 3; in quad8_set_quadrature_mode()
489 priv->quadrature_scale[chan->channel] = 0; in quad8_set_quadrature_mode()
491 /* Synchronous function not supported in non-quadrature mode */ in quad8_set_quadrature_mode()
492 if (priv->synchronous_mode[chan->channel]) in quad8_set_quadrature_mode()
496 priv->quadrature_mode[chan->channel] = quadrature_mode; in quad8_set_quadrature_mode()
501 mutex_unlock(&priv->lock); in quad8_set_quadrature_mode()
511 return priv->quadrature_mode[chan->channel]; in quad8_get_quadrature_mode()
530 const int base_offset = priv->base + 2 * chan->channel + 1; in quad8_set_index_polarity()
533 mutex_lock(&priv->lock); in quad8_set_index_polarity()
535 idr_cfg |= priv->synchronous_mode[chan->channel]; in quad8_set_index_polarity()
537 priv->index_polarity[chan->channel] = index_polarity; in quad8_set_index_polarity()
542 mutex_unlock(&priv->lock); in quad8_set_index_polarity()
552 return priv->index_polarity[chan->channel]; in quad8_get_index_polarity()
624 struct counter_signal *signal, enum counter_signal_value *val) in quad8_signal_read() argument
626 const struct quad8_iio *const priv = counter->priv; in quad8_signal_read()
629 /* Only Index signal levels can be read */ in quad8_signal_read()
630 if (signal->id < 16) in quad8_signal_read()
631 return -EINVAL; in quad8_signal_read()
633 state = inb(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS) in quad8_signal_read()
634 & BIT(signal->id - 16); in quad8_signal_read()
644 struct quad8_iio *const priv = counter->priv; in quad8_count_read()
645 const int base_offset = priv->base + 2 * count->id; in quad8_count_read()
658 mutex_lock(&priv->lock); in quad8_count_read()
667 mutex_unlock(&priv->lock); in quad8_count_read()
675 struct quad8_iio *const priv = counter->priv; in quad8_count_write()
676 const int base_offset = priv->base + 2 * count->id; in quad8_count_write()
679 /* Only 24-bit values are supported */ in quad8_count_write()
681 return -EINVAL; in quad8_count_write()
683 mutex_lock(&priv->lock); in quad8_count_write()
699 val = priv->preset[count->id]; in quad8_count_write()
708 mutex_unlock(&priv->lock); in quad8_count_write()
730 struct quad8_iio *const priv = counter->priv; in quad8_function_get()
731 const int id = count->id; in quad8_function_get() local
733 mutex_lock(&priv->lock); in quad8_function_get()
735 if (priv->quadrature_mode[id]) in quad8_function_get()
736 switch (priv->quadrature_scale[id]) { in quad8_function_get()
750 mutex_unlock(&priv->lock); in quad8_function_get()
758 struct quad8_iio *const priv = counter->priv; in quad8_function_set()
759 const int id = count->id; in quad8_function_set() local
760 unsigned int *const quadrature_mode = priv->quadrature_mode + id; in quad8_function_set()
761 unsigned int *const scale = priv->quadrature_scale + id; in quad8_function_set()
762 unsigned int *const synchronous_mode = priv->synchronous_mode + id; in quad8_function_set()
763 const int base_offset = priv->base + 2 * id + 1; in quad8_function_set()
767 mutex_lock(&priv->lock); in quad8_function_set()
769 mode_cfg = priv->count_mode[id] << 1; in quad8_function_set()
770 idr_cfg = priv->index_polarity[id] << 1; in quad8_function_set()
778 /* Synchronous function not supported in non-quadrature mode */ in quad8_function_set()
806 mutex_unlock(&priv->lock); in quad8_function_set()
814 const struct quad8_iio *const priv = counter->priv; in quad8_direction_get()
816 const unsigned int flag_addr = priv->base + 2 * count->id + 1; in quad8_direction_get()
848 struct quad8_iio *const priv = counter->priv; in quad8_action_get()
851 const size_t signal_a_id = count->synapses[0].signal->id; in quad8_action_get()
855 if (synapse->signal->id >= 16) { in quad8_action_get()
856 if (priv->preset_enable[count->id]) in quad8_action_get()
874 if (synapse->signal->id == signal_a_id) in quad8_action_get()
878 if (synapse->signal->id == signal_a_id) { in quad8_action_get()
888 if (synapse->signal->id == signal_a_id) in quad8_action_get()
909 struct counter_signal *signal, size_t *index_polarity) in quad8_index_polarity_get() argument
911 const struct quad8_iio *const priv = counter->priv; in quad8_index_polarity_get()
912 const size_t channel_id = signal->id - 16; in quad8_index_polarity_get()
914 *index_polarity = priv->index_polarity[channel_id]; in quad8_index_polarity_get()
920 struct counter_signal *signal, size_t index_polarity) in quad8_index_polarity_set() argument
922 struct quad8_iio *const priv = counter->priv; in quad8_index_polarity_set()
923 const size_t channel_id = signal->id - 16; in quad8_index_polarity_set()
924 const int base_offset = priv->base + 2 * channel_id + 1; in quad8_index_polarity_set()
927 mutex_lock(&priv->lock); in quad8_index_polarity_set()
929 idr_cfg |= priv->synchronous_mode[channel_id]; in quad8_index_polarity_set()
931 priv->index_polarity[channel_id] = index_polarity; in quad8_index_polarity_set()
936 mutex_unlock(&priv->lock); in quad8_index_polarity_set()
949 struct counter_signal *signal, size_t *synchronous_mode) in quad8_synchronous_mode_get() argument
951 const struct quad8_iio *const priv = counter->priv; in quad8_synchronous_mode_get()
952 const size_t channel_id = signal->id - 16; in quad8_synchronous_mode_get()
954 *synchronous_mode = priv->synchronous_mode[channel_id]; in quad8_synchronous_mode_get()
960 struct counter_signal *signal, size_t synchronous_mode) in quad8_synchronous_mode_set() argument
962 struct quad8_iio *const priv = counter->priv; in quad8_synchronous_mode_set()
963 const size_t channel_id = signal->id - 16; in quad8_synchronous_mode_set()
964 const int base_offset = priv->base + 2 * channel_id + 1; in quad8_synchronous_mode_set()
967 mutex_lock(&priv->lock); in quad8_synchronous_mode_set()
969 idr_cfg |= priv->index_polarity[channel_id] << 1; in quad8_synchronous_mode_set()
971 /* Index function must be non-synchronous in non-quadrature mode */ in quad8_synchronous_mode_set()
972 if (synchronous_mode && !priv->quadrature_mode[channel_id]) { in quad8_synchronous_mode_set()
973 mutex_unlock(&priv->lock); in quad8_synchronous_mode_set()
974 return -EINVAL; in quad8_synchronous_mode_set()
977 priv->synchronous_mode[channel_id] = synchronous_mode; in quad8_synchronous_mode_set()
982 mutex_unlock(&priv->lock); in quad8_synchronous_mode_set()
1004 const struct quad8_iio *const priv = counter->priv; in quad8_count_mode_get()
1006 /* Map 104-QUAD-8 count mode to Generic Counter count mode */ in quad8_count_mode_get()
1007 switch (priv->count_mode[count->id]) { in quad8_count_mode_get()
1028 struct quad8_iio *const priv = counter->priv; in quad8_count_mode_set()
1030 const int base_offset = priv->base + 2 * count->id + 1; in quad8_count_mode_set()
1032 /* Map Generic Counter count mode to 104-QUAD-8 count mode */ in quad8_count_mode_set()
1048 mutex_lock(&priv->lock); in quad8_count_mode_set()
1050 priv->count_mode[count->id] = cnt_mode; in quad8_count_mode_set()
1056 if (priv->quadrature_mode[count->id]) in quad8_count_mode_set()
1057 mode_cfg |= (priv->quadrature_scale[count->id] + 1) << 3; in quad8_count_mode_set()
1062 mutex_unlock(&priv->lock); in quad8_count_mode_set()
1087 const struct quad8_iio *const priv = counter->priv; in quad8_count_enable_read()
1089 return sprintf(buf, "%u\n", priv->ab_enable[count->id]); in quad8_count_enable_read()
1095 struct quad8_iio *const priv = counter->priv; in quad8_count_enable_write()
1096 const int base_offset = priv->base + 2 * count->id; in quad8_count_enable_write()
1105 mutex_lock(&priv->lock); in quad8_count_enable_write()
1107 priv->ab_enable[count->id] = ab_enable; in quad8_count_enable_write()
1109 ior_cfg = ab_enable | priv->preset_enable[count->id] << 1; in quad8_count_enable_write()
1114 mutex_unlock(&priv->lock); in quad8_count_enable_write()
1122 const struct quad8_iio *const priv = counter->priv; in quad8_error_noise_get()
1123 const int base_offset = priv->base + 2 * count->id + 1; in quad8_error_noise_get()
1139 const struct quad8_iio *const priv = counter->priv; in quad8_count_preset_read()
1141 return sprintf(buf, "%u\n", priv->preset[count->id]); in quad8_count_preset_read()
1144 static void quad8_preset_register_set(struct quad8_iio *quad8iio, int id, in quad8_preset_register_set() argument
1147 const unsigned int base_offset = quad8iio->base + 2 * id; in quad8_preset_register_set()
1150 quad8iio->preset[id] = preset; in quad8_preset_register_set()
1163 struct quad8_iio *const priv = counter->priv; in quad8_count_preset_write()
1171 /* Only 24-bit values are supported */ in quad8_count_preset_write()
1173 return -EINVAL; in quad8_count_preset_write()
1175 mutex_lock(&priv->lock); in quad8_count_preset_write()
1177 quad8_preset_register_set(priv, count->id, preset); in quad8_count_preset_write()
1179 mutex_unlock(&priv->lock); in quad8_count_preset_write()
1187 struct quad8_iio *const priv = counter->priv; in quad8_count_ceiling_read()
1189 mutex_lock(&priv->lock); in quad8_count_ceiling_read()
1191 /* Range Limit and Modulo-N count modes use preset value as ceiling */ in quad8_count_ceiling_read()
1192 switch (priv->count_mode[count->id]) { in quad8_count_ceiling_read()
1195 mutex_unlock(&priv->lock); in quad8_count_ceiling_read()
1196 return sprintf(buf, "%u\n", priv->preset[count->id]); in quad8_count_ceiling_read()
1199 mutex_unlock(&priv->lock); in quad8_count_ceiling_read()
1208 struct quad8_iio *const priv = counter->priv; in quad8_count_ceiling_write()
1216 /* Only 24-bit values are supported */ in quad8_count_ceiling_write()
1218 return -EINVAL; in quad8_count_ceiling_write()
1220 mutex_lock(&priv->lock); in quad8_count_ceiling_write()
1222 /* Range Limit and Modulo-N count modes use preset value as ceiling */ in quad8_count_ceiling_write()
1223 switch (priv->count_mode[count->id]) { in quad8_count_ceiling_write()
1226 quad8_preset_register_set(priv, count->id, ceiling); in quad8_count_ceiling_write()
1230 mutex_unlock(&priv->lock); in quad8_count_ceiling_write()
1238 const struct quad8_iio *const priv = counter->priv; in quad8_count_preset_enable_read()
1240 return sprintf(buf, "%u\n", !priv->preset_enable[count->id]); in quad8_count_preset_enable_read()
1246 struct quad8_iio *const priv = counter->priv; in quad8_count_preset_enable_write()
1247 const int base_offset = priv->base + 2 * count->id + 1; in quad8_count_preset_enable_write()
1259 mutex_lock(&priv->lock); in quad8_count_preset_enable_write()
1261 priv->preset_enable[count->id] = preset_enable; in quad8_count_preset_enable_write()
1263 ior_cfg = priv->ab_enable[count->id] | (unsigned int)preset_enable << 1; in quad8_count_preset_enable_write()
1268 mutex_unlock(&priv->lock); in quad8_count_preset_enable_write()
1274 struct counter_signal *signal, in quad8_signal_cable_fault_read() argument
1277 struct quad8_iio *const priv = counter->priv; in quad8_signal_cable_fault_read()
1278 const size_t channel_id = signal->id / 2; in quad8_signal_cable_fault_read()
1283 mutex_lock(&priv->lock); in quad8_signal_cable_fault_read()
1285 disabled = !(priv->cable_fault_enable & BIT(channel_id)); in quad8_signal_cable_fault_read()
1288 mutex_unlock(&priv->lock); in quad8_signal_cable_fault_read()
1289 return -EINVAL; in quad8_signal_cable_fault_read()
1293 status = inb(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS); in quad8_signal_cable_fault_read()
1295 mutex_unlock(&priv->lock); in quad8_signal_cable_fault_read()
1304 struct counter_device *counter, struct counter_signal *signal, in quad8_signal_cable_fault_enable_read() argument
1307 const struct quad8_iio *const priv = counter->priv; in quad8_signal_cable_fault_enable_read()
1308 const size_t channel_id = signal->id / 2; in quad8_signal_cable_fault_enable_read()
1309 const unsigned int enb = !!(priv->cable_fault_enable & BIT(channel_id)); in quad8_signal_cable_fault_enable_read()
1315 struct counter_device *counter, struct counter_signal *signal, in quad8_signal_cable_fault_enable_write() argument
1318 struct quad8_iio *const priv = counter->priv; in quad8_signal_cable_fault_enable_write()
1319 const size_t channel_id = signal->id / 2; in quad8_signal_cable_fault_enable_write()
1328 mutex_lock(&priv->lock); in quad8_signal_cable_fault_enable_write()
1331 priv->cable_fault_enable |= BIT(channel_id); in quad8_signal_cable_fault_enable_write()
1333 priv->cable_fault_enable &= ~BIT(channel_id); in quad8_signal_cable_fault_enable_write()
1336 cable_fault_enable = ~priv->cable_fault_enable; in quad8_signal_cable_fault_enable_write()
1338 outb(cable_fault_enable, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS); in quad8_signal_cable_fault_enable_write()
1340 mutex_unlock(&priv->lock); in quad8_signal_cable_fault_enable_write()
1346 struct counter_signal *signal, void *private, char *buf) in quad8_signal_fck_prescaler_read() argument
1348 const struct quad8_iio *const priv = counter->priv; in quad8_signal_fck_prescaler_read()
1349 const size_t channel_id = signal->id / 2; in quad8_signal_fck_prescaler_read()
1351 return sprintf(buf, "%u\n", priv->fck_prescaler[channel_id]); in quad8_signal_fck_prescaler_read()
1355 struct counter_signal *signal, void *private, const char *buf, in quad8_signal_fck_prescaler_write() argument
1358 struct quad8_iio *const priv = counter->priv; in quad8_signal_fck_prescaler_write()
1359 const size_t channel_id = signal->id / 2; in quad8_signal_fck_prescaler_write()
1360 const int base_offset = priv->base + 2 * channel_id; in quad8_signal_fck_prescaler_write()
1368 mutex_lock(&priv->lock); in quad8_signal_fck_prescaler_write()
1370 priv->fck_prescaler[channel_id] = prescaler; in quad8_signal_fck_prescaler_write()
1380 mutex_unlock(&priv->lock); in quad8_signal_fck_prescaler_write()
1410 .id = (_id), \
1417 .id = (_id), \
1454 .signal = quad8_signals + 2 * (_id) \
1459 .signal = quad8_signals + 2 * (_id) + 1 \
1464 .signal = quad8_signals + 2 * (_id) + 16 \
1511 .id = (_id), \
1532 static int quad8_probe(struct device *dev, unsigned int id) in quad8_probe() argument
1540 if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) { in quad8_probe()
1541 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", in quad8_probe()
1542 base[id], base[id] + QUAD8_EXTENT); in quad8_probe()
1543 return -EBUSY; in quad8_probe()
1549 return -ENOMEM; in quad8_probe()
1552 indio_dev->info = &quad8_info; in quad8_probe()
1553 indio_dev->modes = INDIO_DIRECT_MODE; in quad8_probe()
1554 indio_dev->num_channels = ARRAY_SIZE(quad8_channels); in quad8_probe()
1555 indio_dev->channels = quad8_channels; in quad8_probe()
1556 indio_dev->name = dev_name(dev); in quad8_probe()
1560 quad8iio->counter.name = dev_name(dev); in quad8_probe()
1561 quad8iio->counter.parent = dev; in quad8_probe()
1562 quad8iio->counter.ops = &quad8_ops; in quad8_probe()
1563 quad8iio->counter.counts = quad8_counts; in quad8_probe()
1564 quad8iio->counter.num_counts = ARRAY_SIZE(quad8_counts); in quad8_probe()
1565 quad8iio->counter.signals = quad8_signals; in quad8_probe()
1566 quad8iio->counter.num_signals = ARRAY_SIZE(quad8_signals); in quad8_probe()
1567 quad8iio->counter.priv = quad8iio; in quad8_probe()
1568 quad8iio->base = base[id]; in quad8_probe()
1571 mutex_init(&quad8iio->lock); in quad8_probe()
1574 outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP); in quad8_probe()
1577 base_offset = base[id] + 2 * i; in quad8_probe()
1593 /* Binary encoding; Normal count; non-quadrature mode */ in quad8_probe()
1601 outb(0xFF, base[id] + QUAD8_DIFF_ENCODER_CABLE_STATUS); in quad8_probe()
1603 outb(QUAD8_CHAN_OP_ENABLE_COUNTERS, base[id] + QUAD8_REG_CHAN_OP); in quad8_probe()
1611 return devm_counter_register(dev, &quad8iio->counter); in quad8_probe()
1617 .name = "104-quad-8"
1624 MODULE_DESCRIPTION("ACCES 104-QUAD-8 IIO driver");