All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 1/8] iio: Add helper functions for enum style channel attributes
@ 2012-05-11 15:53 Lars-Peter Clausen
  2012-05-11 15:53 ` [RFC 2/8] staging:iio:dac:ad5064: Use iio_enum for powerdown modes Lars-Peter Clausen
                   ` (7 more replies)
  0 siblings, 8 replies; 17+ messages in thread
From: Lars-Peter Clausen @ 2012-05-11 15:53 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Lars-Peter Clausen

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>
---
 drivers/iio/industrialio-core.c |   57 +++++++++++++++++++++++++++++++++++++++
 include/linux/iio/iio.h         |   32 ++++++++++++++++++++++
 2 files changed, 89 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index b39a587..241be03 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -288,6 +288,63 @@ static ssize_t iio_write_channel_ext_info(struct device *dev,
 			       this_attr->c, buf, len);
 }
 
+ssize_t iio_enum_available_read(struct iio_dev *indio_dev,
+	uintptr_t priv, const struct iio_chan_spec *chan, char *buf)
+{
+	const struct iio_enum *e = (const struct iio_enum *)priv;
+	char *tmp = buf;
+	unsigned int i;
+
+	if (!e->num_items)
+		return 0;
+
+	for (i = 0; i < e->num_items; ++i)
+		tmp += sprintf(tmp, "%s ", e->items[i]);
+
+	/* replace last space with a newline */
+	*(tmp - 1) = '\n';
+
+	return tmp - buf;
+}
+EXPORT_SYMBOL_GPL(iio_enum_available_read);
+
+ssize_t iio_enum_read(struct iio_dev *indio_dev,
+	uintptr_t priv, const struct iio_chan_spec *chan, char *buf)
+{
+	const struct iio_enum *e = (const struct iio_enum *)priv;
+	int i;
+
+	i = e->get(indio_dev, chan);
+	if (i < 0)
+		return i;
+	else if (i >= e->num_items)
+		return -EINVAL;
+
+	return sprintf(buf, "%s\n", e->items[i]);
+}
+EXPORT_SYMBOL_GPL(iio_enum_read);
+
+ssize_t iio_enum_write(struct iio_dev *indio_dev,
+	uintptr_t priv, const struct iio_chan_spec *chan, const char *buf,
+	size_t len)
+{
+	const struct iio_enum *e = (const struct iio_enum *)priv;
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < e->num_items; i++) {
+		if (sysfs_streq(buf, e->items[i]))
+			break;
+	}
+
+	if (i == e->num_items)
+		return -EINVAL;
+
+	ret = e->set(indio_dev, chan, i);
+	return ret ? ret : len;
+}
+EXPORT_SYMBOL_GPL(iio_enum_write);
+
 static ssize_t iio_read_channel_info(struct device *dev,
 				     struct device_attribute *attr,
 				     char *buf)
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 6fdbdb8..602f118 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -124,6 +124,38 @@ struct iio_chan_spec_ext_info {
 	uintptr_t private;
 };
 
+struct iio_enum {
+	const char * const *items;
+	unsigned int num_items;
+	int (*set)(struct iio_dev *, const struct iio_chan_spec *, unsigned int);
+	int (*get)(struct iio_dev *, const struct iio_chan_spec *);
+};
+
+ssize_t iio_enum_available_read(struct iio_dev *indio_dev,
+	uintptr_t priv, const struct iio_chan_spec *chan, char *buf);
+ssize_t iio_enum_read(struct iio_dev *indio_dev,
+	uintptr_t priv, const struct iio_chan_spec *chan, char *buf);
+ssize_t iio_enum_write(struct iio_dev *indio_dev,
+	uintptr_t priv, const struct iio_chan_spec *chan, const char *buf,
+	size_t len);
+
+#define IIO_ENUM(_name, _shared, _e) \
+{ \
+	.name = (_name), \
+	.shared = (_shared), \
+	.read = iio_enum_read, \
+	.write = iio_enum_write, \
+	.private = (uintptr_t)(_e), \
+}
+
+#define IIO_ENUM_AVAILABLE(_name, _e) \
+{ \
+	.name = (_name "_available"), \
+	.shared = true, \
+	.read = iio_enum_available_read, \
+	.private = (uintptr_t)(_e), \
+}
+
 /**
  * struct iio_chan_spec - specification of a single channel
  * @type:		What type of measurement is the channel making.
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2012-05-14 18:21 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-11 15:53 [RFC 1/8] iio: Add helper functions for enum style channel attributes Lars-Peter Clausen
2012-05-11 15:53 ` [RFC 2/8] staging:iio:dac:ad5064: Use iio_enum for powerdown modes Lars-Peter Clausen
2012-05-14 17:48   ` Jonathan Cameron
2012-05-11 15:53 ` [RFC 3/8] staging:iio:dac:ad5446: " Lars-Peter Clausen
2012-05-14 17:55   ` Jonathan Cameron
2012-05-11 15:53 ` [RFC 4/8] staging:iio:dac:ad5380: Convert to extended channel attributes Lars-Peter Clausen
2012-05-14 18:11   ` Jonathan Cameron
2012-05-11 15:53 ` [RFC 5/8] staging:iio:dac:ad5504: " Lars-Peter Clausen
2012-05-14 18:14   ` Jonathan Cameron
2012-05-11 15:53 ` [RFC 6/8] staging:iio:dac:ad5624r: " Lars-Peter Clausen
2012-05-14 18:16   ` Jonathan Cameron
2012-05-11 15:53 ` [RFC 7/8] staging:iio:dac:ad5686: " Lars-Peter Clausen
2012-05-14 18:18   ` Jonathan Cameron
2012-05-11 15:53 ` [RFC 8/8] staging:iio:dac:ad5791: " Lars-Peter Clausen
2012-05-14 18:21   ` Jonathan Cameron
2012-05-14 17:42 ` [RFC 1/8] iio: Add helper functions for enum style " Jonathan Cameron
2012-05-14 18:15   ` Lars-Peter Clausen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.