IIO_LE,
};
+struct iio_chan_spec;
+struct iio_dev;
+
+/**
+ * struct iio_chan_spec_ext_info - Extended channel info attribute
+ * @name: Info attribute name
+ * @shared: Whether this attribute is shared between all channels.
+ * @read: Read callback for this info attribute, may be NULL.
+ * @write: Write callback for this info attribute, may be NULL.
+ */
+struct iio_chan_spec_ext_info {
+ const char *name;
+ bool shared;
+ ssize_t (*read)(struct iio_dev *, struct iio_chan_spec const *,
+ char *buf);
+ ssize_t (*write)(struct iio_dev *, struct iio_chan_spec const *,
+ const char *buf, size_t len);
+};
+
/**
* struct iio_chan_spec - specification of a single channel
* @type: What type of measurement is the channel making.
* @info_mask: What information is to be exported about this channel.
* This includes calibbias, scale etc.
* @event_mask: What events can this channel produce.
+ * @ext_info: Array of extended info attributes for this channel.
+ * The array is NULL terminated, the last element should
+ * have it's name field set to NULL.
* @extend_name: Allows labeling of channel attributes with an
* informative name. Note this has no effect codes etc,
* unlike modifiers.
} scan_type;
long info_mask;
long event_mask;
+ const struct iio_chan_spec_ext_info *ext_info;
char *extend_name;
const char *datasheet_name;
unsigned processed_val:1;
bus_unregister(&iio_bus_type);
}
+static ssize_t iio_read_channel_ext_info(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ const struct iio_chan_spec_ext_info *ext_info;
+
+ ext_info = &this_attr->c->ext_info[this_attr->address];
+
+ return ext_info->read(indio_dev, this_attr->c, buf);
+}
+
+static ssize_t iio_write_channel_ext_info(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ const struct iio_chan_spec_ext_info *ext_info;
+
+ ext_info = &this_attr->c->ext_info[this_attr->address];
+
+ return ext_info->write(indio_dev, this_attr->c, buf, len);
+}
+
static ssize_t iio_read_channel_info(struct device *dev,
struct device_attribute *attr,
char *buf)
struct iio_chan_spec const *chan)
{
int ret, i, attrcount = 0;
+ const struct iio_chan_spec_ext_info *ext_info;
if (chan->channel < 0)
return 0;
goto error_ret;
attrcount++;
}
+
+ if (chan->ext_info) {
+ unsigned int i = 0;
+ for (ext_info = chan->ext_info; ext_info->name; ext_info++) {
+ ret = __iio_add_chan_devattr(ext_info->name,
+ chan,
+ ext_info->read ?
+ &iio_read_channel_ext_info : NULL,
+ ext_info->write ?
+ &iio_write_channel_ext_info : NULL,
+ i,
+ ext_info->shared,
+ &indio_dev->dev,
+ &indio_dev->channel_attr_list);
+ i++;
+ if (ret == -EBUSY && ext_info->shared)
+ continue;
+
+ if (ret)
+ goto error_ret;
+
+ attrcount++;
+ }
+ }
+
ret = attrcount;
error_ret:
return ret;