counter: 104-quad-8: Support Differential Encoder Cable Status
The ACCES 104-QUAD-8 series provides status information about the connection state of the differential encoder cable inputs. This patch implements support to expose such information from these devices. Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
parent
de65d05563
commit
954ab5cc5f
|
@ -1,3 +1,21 @@
|
||||||
|
What: /sys/bus/counter/devices/counterX/signalY/cable_fault
|
||||||
|
KernelVersion: 5.7
|
||||||
|
Contact: linux-iio@vger.kernel.org
|
||||||
|
Description:
|
||||||
|
Read-only attribute that indicates whether a differential
|
||||||
|
encoder cable fault (not connected or loose wires) is detected
|
||||||
|
for the respective channel of Signal Y. Valid attribute values
|
||||||
|
are boolean. Detection must first be enabled via the
|
||||||
|
corresponding cable_fault_enable attribute.
|
||||||
|
|
||||||
|
What: /sys/bus/counter/devices/counterX/signalY/cable_fault_enable
|
||||||
|
KernelVersion: 5.7
|
||||||
|
Contact: linux-iio@vger.kernel.org
|
||||||
|
Description:
|
||||||
|
Whether detection of differential encoder cable faults for the
|
||||||
|
respective channel of Signal Y is enabled. Valid attribute
|
||||||
|
values are boolean.
|
||||||
|
|
||||||
What: /sys/bus/counter/devices/counterX/signalY/filter_clock_prescaler
|
What: /sys/bus/counter/devices/counterX/signalY/filter_clock_prescaler
|
||||||
KernelVersion: 5.7
|
KernelVersion: 5.7
|
||||||
Contact: linux-iio@vger.kernel.org
|
Contact: linux-iio@vger.kernel.org
|
||||||
|
|
|
@ -31,6 +31,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
|
||||||
/**
|
/**
|
||||||
* struct quad8_iio - IIO device private data structure
|
* struct quad8_iio - IIO device private data structure
|
||||||
* @counter: instance of the counter_device
|
* @counter: instance of the counter_device
|
||||||
|
* @fck_prescaler: array of filter clock prescaler configurations
|
||||||
* @preset: array of preset values
|
* @preset: array of preset values
|
||||||
* @count_mode: array of count mode configurations
|
* @count_mode: array of count mode configurations
|
||||||
* @quadrature_mode: array of quadrature mode configurations
|
* @quadrature_mode: array of quadrature mode configurations
|
||||||
|
@ -39,6 +40,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
|
||||||
* @preset_enable: array of set_to_preset_on_index attribute configurations
|
* @preset_enable: array of set_to_preset_on_index attribute configurations
|
||||||
* @synchronous_mode: array of index function synchronous mode configurations
|
* @synchronous_mode: array of index function synchronous mode configurations
|
||||||
* @index_polarity: array of index function polarity configurations
|
* @index_polarity: array of index function polarity configurations
|
||||||
|
* @cable_fault_enable: differential encoder cable status enable configurations
|
||||||
* @base: base port address of the IIO device
|
* @base: base port address of the IIO device
|
||||||
*/
|
*/
|
||||||
struct quad8_iio {
|
struct quad8_iio {
|
||||||
|
@ -52,11 +54,13 @@ struct quad8_iio {
|
||||||
unsigned int preset_enable[QUAD8_NUM_COUNTERS];
|
unsigned int preset_enable[QUAD8_NUM_COUNTERS];
|
||||||
unsigned int synchronous_mode[QUAD8_NUM_COUNTERS];
|
unsigned int synchronous_mode[QUAD8_NUM_COUNTERS];
|
||||||
unsigned int index_polarity[QUAD8_NUM_COUNTERS];
|
unsigned int index_polarity[QUAD8_NUM_COUNTERS];
|
||||||
|
unsigned int cable_fault_enable;
|
||||||
unsigned int base;
|
unsigned int base;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QUAD8_REG_CHAN_OP 0x11
|
#define QUAD8_REG_CHAN_OP 0x11
|
||||||
#define QUAD8_REG_INDEX_INPUT_LEVELS 0x16
|
#define QUAD8_REG_INDEX_INPUT_LEVELS 0x16
|
||||||
|
#define QUAD8_DIFF_ENCODER_CABLE_STATUS 0x17
|
||||||
/* Borrow Toggle flip-flop */
|
/* Borrow Toggle flip-flop */
|
||||||
#define QUAD8_FLAG_BT BIT(0)
|
#define QUAD8_FLAG_BT BIT(0)
|
||||||
/* Carry Toggle flip-flop */
|
/* Carry Toggle flip-flop */
|
||||||
|
@ -1143,6 +1147,66 @@ static ssize_t quad8_count_preset_enable_write(struct counter_device *counter,
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t quad8_signal_cable_fault_read(struct counter_device *counter,
|
||||||
|
struct counter_signal *signal,
|
||||||
|
void *private, char *buf)
|
||||||
|
{
|
||||||
|
const struct quad8_iio *const priv = counter->priv;
|
||||||
|
const size_t channel_id = signal->id / 2;
|
||||||
|
const bool disabled = !(priv->cable_fault_enable & BIT(channel_id));
|
||||||
|
unsigned int status;
|
||||||
|
unsigned int fault;
|
||||||
|
|
||||||
|
if (disabled)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Logic 0 = cable fault */
|
||||||
|
status = inb(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
|
||||||
|
|
||||||
|
/* Mask respective channel and invert logic */
|
||||||
|
fault = !(status & BIT(channel_id));
|
||||||
|
|
||||||
|
return sprintf(buf, "%u\n", fault);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t quad8_signal_cable_fault_enable_read(
|
||||||
|
struct counter_device *counter, struct counter_signal *signal,
|
||||||
|
void *private, char *buf)
|
||||||
|
{
|
||||||
|
const struct quad8_iio *const priv = counter->priv;
|
||||||
|
const size_t channel_id = signal->id / 2;
|
||||||
|
const unsigned int enb = !!(priv->cable_fault_enable & BIT(channel_id));
|
||||||
|
|
||||||
|
return sprintf(buf, "%u\n", enb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t quad8_signal_cable_fault_enable_write(
|
||||||
|
struct counter_device *counter, struct counter_signal *signal,
|
||||||
|
void *private, const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
struct quad8_iio *const priv = counter->priv;
|
||||||
|
const size_t channel_id = signal->id / 2;
|
||||||
|
bool enable;
|
||||||
|
int ret;
|
||||||
|
unsigned int cable_fault_enable;
|
||||||
|
|
||||||
|
ret = kstrtobool(buf, &enable);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
priv->cable_fault_enable |= BIT(channel_id);
|
||||||
|
else
|
||||||
|
priv->cable_fault_enable &= ~BIT(channel_id);
|
||||||
|
|
||||||
|
/* Enable is active low in Differential Encoder Cable Status register */
|
||||||
|
cable_fault_enable = ~priv->cable_fault_enable;
|
||||||
|
|
||||||
|
outb(cable_fault_enable, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t quad8_signal_fck_prescaler_read(struct counter_device *counter,
|
static ssize_t quad8_signal_fck_prescaler_read(struct counter_device *counter,
|
||||||
struct counter_signal *signal, void *private, char *buf)
|
struct counter_signal *signal, void *private, char *buf)
|
||||||
{
|
{
|
||||||
|
@ -1180,6 +1244,15 @@ static ssize_t quad8_signal_fck_prescaler_write(struct counter_device *counter,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct counter_signal_ext quad8_signal_ext[] = {
|
static const struct counter_signal_ext quad8_signal_ext[] = {
|
||||||
|
{
|
||||||
|
.name = "cable_fault",
|
||||||
|
.read = quad8_signal_cable_fault_read
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "cable_fault_enable",
|
||||||
|
.read = quad8_signal_cable_fault_enable_read,
|
||||||
|
.write = quad8_signal_cable_fault_enable_write
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "filter_clock_prescaler",
|
.name = "filter_clock_prescaler",
|
||||||
.read = quad8_signal_fck_prescaler_read,
|
.read = quad8_signal_fck_prescaler_read,
|
||||||
|
@ -1383,6 +1456,8 @@ static int quad8_probe(struct device *dev, unsigned int id)
|
||||||
/* Disable index function; negative index polarity */
|
/* Disable index function; negative index polarity */
|
||||||
outb(QUAD8_CTR_IDR, base_offset + 1);
|
outb(QUAD8_CTR_IDR, base_offset + 1);
|
||||||
}
|
}
|
||||||
|
/* Disable Differential Encoder Cable Status for all channels */
|
||||||
|
outb(0xFF, base[id] + QUAD8_DIFF_ENCODER_CABLE_STATUS);
|
||||||
/* Enable all counters */
|
/* Enable all counters */
|
||||||
outb(QUAD8_CHAN_OP_ENABLE_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
|
outb(QUAD8_CHAN_OP_ENABLE_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue