aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/industrialio-core.c
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2012-06-04 05:36:11 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-06-05 00:47:29 -0400
commit5212cc8a9d833791a7aec566db136e78951f203d (patch)
tree3c823a04bb8b5c1e001bdf4e26f5413c26de7bd7 /drivers/iio/industrialio-core.c
parent1875ffd218ddafd78f0f8e78198c137cef97fd8a (diff)
iio: Add helper functions for enum style channel attributes
We often have the case were we do have a enum style channel attribute. These attributes have in common that they are a list of string values which usually map in a 1-to-1 fashion to integer values. This patch implements some common helper code for implementing enum style channel attributes using extended channel attributes. The helper functions take care of converting between the string and integer values, as well providing a function for "_available" attributes which list all available enum items. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Acked-by: Jonathan Cameron <jic23@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/iio/industrialio-core.c')
-rw-r--r--drivers/iio/industrialio-core.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 1ddd8861c71b..56a3c0bc996c 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -289,6 +289,69 @@ static ssize_t iio_write_channel_ext_info(struct device *dev,
289 this_attr->c, buf, len); 289 this_attr->c, buf, len);
290} 290}
291 291
292ssize_t iio_enum_available_read(struct iio_dev *indio_dev,
293 uintptr_t priv, const struct iio_chan_spec *chan, char *buf)
294{
295 const struct iio_enum *e = (const struct iio_enum *)priv;
296 unsigned int i;
297 size_t len = 0;
298
299 if (!e->num_items)
300 return 0;
301
302 for (i = 0; i < e->num_items; ++i)
303 len += snprintf(buf + len, PAGE_SIZE - len, "%s ", e->items[i]);
304
305 /* replace last space with a newline */
306 buf[len - 1] = '\n';
307
308 return len;
309}
310EXPORT_SYMBOL_GPL(iio_enum_available_read);
311
312ssize_t iio_enum_read(struct iio_dev *indio_dev,
313 uintptr_t priv, const struct iio_chan_spec *chan, char *buf)
314{
315 const struct iio_enum *e = (const struct iio_enum *)priv;
316 int i;
317
318 if (!e->get)
319 return -EINVAL;
320
321 i = e->get(indio_dev, chan);
322 if (i < 0)
323 return i;
324 else if (i >= e->num_items)
325 return -EINVAL;
326
327 return sprintf(buf, "%s\n", e->items[i]);
328}
329EXPORT_SYMBOL_GPL(iio_enum_read);
330
331ssize_t iio_enum_write(struct iio_dev *indio_dev,
332 uintptr_t priv, const struct iio_chan_spec *chan, const char *buf,
333 size_t len)
334{
335 const struct iio_enum *e = (const struct iio_enum *)priv;
336 unsigned int i;
337 int ret;
338
339 if (!e->set)
340 return -EINVAL;
341
342 for (i = 0; i < e->num_items; i++) {
343 if (sysfs_streq(buf, e->items[i]))
344 break;
345 }
346
347 if (i == e->num_items)
348 return -EINVAL;
349
350 ret = e->set(indio_dev, chan, i);
351 return ret ? ret : len;
352}
353EXPORT_SYMBOL_GPL(iio_enum_write);
354
292static ssize_t iio_read_channel_info(struct device *dev, 355static ssize_t iio_read_channel_info(struct device *dev,
293 struct device_attribute *attr, 356 struct device_attribute *attr,
294 char *buf) 357 char *buf)