mirror of https://gitee.com/openkylin/linux.git
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
|
||||
KernelVersion: 5.7
|
||||
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
|
||||
* @counter: instance of the counter_device
|
||||
* @fck_prescaler: array of filter clock prescaler configurations
|
||||
* @preset: array of preset values
|
||||
* @count_mode: array of count 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
|
||||
* @synchronous_mode: array of index function synchronous mode 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
|
||||
*/
|
||||
struct quad8_iio {
|
||||
|
@ -52,11 +54,13 @@ struct quad8_iio {
|
|||
unsigned int preset_enable[QUAD8_NUM_COUNTERS];
|
||||
unsigned int synchronous_mode[QUAD8_NUM_COUNTERS];
|
||||
unsigned int index_polarity[QUAD8_NUM_COUNTERS];
|
||||
unsigned int cable_fault_enable;
|
||||
unsigned int base;
|
||||
};
|
||||
|
||||
#define QUAD8_REG_CHAN_OP 0x11
|
||||
#define QUAD8_REG_INDEX_INPUT_LEVELS 0x16
|
||||
#define QUAD8_DIFF_ENCODER_CABLE_STATUS 0x17
|
||||
/* Borrow Toggle flip-flop */
|
||||
#define QUAD8_FLAG_BT BIT(0)
|
||||
/* Carry Toggle flip-flop */
|
||||
|
@ -1143,6 +1147,66 @@ static ssize_t quad8_count_preset_enable_write(struct counter_device *counter,
|
|||
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,
|
||||
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[] = {
|
||||
{
|
||||
.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",
|
||||
.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 */
|
||||
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 */
|
||||
outb(QUAD8_CHAN_OP_ENABLE_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
|
||||
|
||||
|
|
Loading…
Reference in New Issue