This allows controlling the current trigger by numeric ID rather than name. Signed-off-by: Crestez Dan Leonard <leonard.crestez@xxxxxxxxx> --- Documentation/ABI/testing/sysfs-bus-iio | 9 +++ Documentation/DocBook/iio.tmpl | 4 +- drivers/iio/industrialio-trigger.c | 115 ++++++++++++++++++++++++-------- 3 files changed, 98 insertions(+), 30 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index df44998..e276032 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -1038,6 +1038,15 @@ Description: The name of the trigger source being used, as per string given in /sys/class/iio/triggerY/name. +What: /sys/bus/iio/devices/iio:deviceX/trigger/current_trigger_id +KernelVersion: 4.7 +Contact: linux-iio@xxxxxxxxxxxxxxx +Description: + The id of the trigger source being used. This is the Y from + /sys/class/iio/triggerY. This is an alternative to + /sys/bus/iio/devices/iio:deviceX/trigger/current_trigger. + Write a negative number to clear. + What: /sys/bus/iio/devices/iio:deviceX/buffer/length KernelVersion: 2.6.35 Contact: linux-iio@xxxxxxxxxxxxxxx diff --git a/Documentation/DocBook/iio.tmpl b/Documentation/DocBook/iio.tmpl index f525bf5..599eff0 100644 --- a/Documentation/DocBook/iio.tmpl +++ b/Documentation/DocBook/iio.tmpl @@ -523,7 +523,9 @@ <filename>/sys/bus/iio/devices/iio:deviceX/trigger/</filename>, this directory is created once the device supports a triggered buffer. We can associate a trigger with our device by writing - the trigger's name in the <filename>current_trigger</filename> file. + the trigger's name in the <filename>current_trigger</filename> + file. Alternatively we can write the numeric id Y from + triggerY into <filename>current_trigger_id</filename> </listitem> </itemizedlist> </sect2> diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index ae2806a..e79c64c 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -121,6 +121,21 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name, return trig; } +static struct iio_trigger *iio_trigger_find_by_id(int id) +{ + struct iio_trigger *trig = NULL, *iter; + + mutex_lock(&iio_trigger_list_lock); + list_for_each_entry(iter, &iio_trigger_list, list) + if (iter->id == id) { + trig = iter; + break; + } + mutex_unlock(&iio_trigger_list_lock); + + return trig; +} + void iio_trigger_poll(struct iio_trigger *trig) { int i; @@ -294,7 +309,7 @@ void iio_dealloc_pollfunc(struct iio_poll_func *pf) EXPORT_SYMBOL_GPL(iio_dealloc_pollfunc); /** - * iio_trigger_read_current() - trigger consumer sysfs query current trigger + * iio_trigger_read_current_name() - trigger consumer sysfs query current trigger * @dev: device associated with an industrial I/O device * @attr: pointer to the device_attribute structure that * is being processed @@ -306,9 +321,9 @@ EXPORT_SYMBOL_GPL(iio_dealloc_pollfunc); * Return: a negative number on failure, the number of characters written * on success or 0 if no trigger is available */ -static ssize_t iio_trigger_read_current(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t iio_trigger_read_current_name(struct device *dev, + struct device_attribute *attr, + char *buf) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); @@ -317,28 +332,22 @@ static ssize_t iio_trigger_read_current(struct device *dev, return 0; } -/** - * iio_trigger_write_current() - trigger consumer sysfs set current trigger - * @dev: device associated with an industrial I/O device - * @attr: device attribute that is being processed - * @buf: string buffer that holds the name of the trigger - * @len: length of the trigger name held by buf - * - * For trigger consumers the current_trigger interface allows the trigger - * used for this device to be specified at run time based on the trigger's - * name. - * - * Return: negative error code on failure or length of the buffer - * on success - */ -static ssize_t iio_trigger_write_current(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) +static ssize_t iio_trigger_read_current_id(struct device *dev, + struct device_attribute *attr, + char *buf) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); + + if (indio_dev->trig) + return sprintf(buf, "%d\n", indio_dev->trig->id); + return 0; +} + +/* Set current trigger. Returns -errno or 0 on success */ +static int iio_trigger_set_current(struct iio_dev *indio_dev, + struct iio_trigger *trig) +{ struct iio_trigger *oldtrig = indio_dev->trig; - struct iio_trigger *trig; int ret; mutex_lock(&indio_dev->mlock); @@ -348,18 +357,24 @@ static ssize_t iio_trigger_write_current(struct device *dev, } mutex_unlock(&indio_dev->mlock); - trig = iio_trigger_find_by_name(buf, len); - if (oldtrig == trig) - return len; - if (trig && indio_dev->info->validate_trigger) { ret = indio_dev->info->validate_trigger(indio_dev, trig); + if (ret > 0) { + dev_err(&indio_dev->dev, "validate_trigger %ps incorrectly returned positive %d\n", + indio_dev->info->validate_trigger, ret); + return -EINVAL; + } if (ret) return ret; } if (trig && trig->ops && trig->ops->validate_device) { ret = trig->ops->validate_device(trig, indio_dev); + if (ret > 0) { + dev_err(&indio_dev->dev, "validate_device %ps incorrectly returned positive %d\n", + trig->ops->validate_device, ret); + return -EINVAL; + } if (ret) return ret; } @@ -379,15 +394,57 @@ static ssize_t iio_trigger_write_current(struct device *dev, indio_dev->pollfunc_event); } + return 0; +} + +static ssize_t iio_trigger_write_current_name(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_trigger *trig; + int ret; + + trig = iio_trigger_find_by_name(buf, len); + ret = iio_trigger_set_current(indio_dev, trig); + + return ret ? ret : len; +} + +static ssize_t iio_trigger_write_current_id(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_trigger *trig; + int ret, id; + + ret = kstrtoint(buf, 10, &id); + if (ret) + return ret; + if (id >= 0) { + trig = iio_trigger_find_by_id(id); + if (!trig) + return -ENOENT; + } else + trig = NULL; + ret = iio_trigger_set_current(indio_dev, trig); + return len; } static DEVICE_ATTR(current_trigger, S_IRUGO | S_IWUSR, - iio_trigger_read_current, - iio_trigger_write_current); + iio_trigger_read_current_name, + iio_trigger_write_current_name); +static DEVICE_ATTR(current_trigger_id, S_IRUGO | S_IWUSR, + iio_trigger_read_current_id, + iio_trigger_write_current_id); static struct attribute *iio_trigger_consumer_attrs[] = { &dev_attr_current_trigger.attr, + &dev_attr_current_trigger_id.attr, NULL, }; -- 2.5.5 -- To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html