IIO: Refactor info_mask* handling and introduce info_mask_shared_[by_all/by_type]
Subsystems (3)
Jonathan Cameron
maintainercover IIO: Refactor info_mask* handling and introduce info_mask_shared_[by_all/by_type]
This series first performs a bit of refactoring of the core handling of info_mask_separate and info_mask_shared_by_type.
Next we introduce info_mask_shared_by_dir and info_mask_shared_by_all to allow for attributes of the form
in_sampling_frequency or sampling_frequency as appropriate.
Most existing drivers will make no use of the shared_by_dir case, but it is there to handle devices with both and input and output channels.
There are two main reasons for adding these two cases.
1) Should result in shorter code, particularly for complex drivers.
2) Allows for in kernel consumers accessing this functionality.
The intent is to follow this series with one providing a standard way of providing 'available' attributes. The combination of the two should mean that very few things are still handled via direct registration of attributes.
Thanks,
Jonathan
Jonathan Cameron (5):
iio: drop info_mask from struct iio_dev
iio: refactor info mask attribute creation.
iio: add info_mask_[shared_by_dir/shared_by_all] staging:iio: dummy driver additions to show shared_by_dir infomask
usage
iio:temperature:tmp006 put sampling_frequency in
info_mask_shared_by_all
drivers/iio/iio_core.h | 7 +- drivers/iio/industrialio-buffer.c | 2 +- drivers/iio/industrialio-core.c | 179 ++++++++++++++++++++------------- drivers/iio/temperature/tmp006.c | 57 +++++------ drivers/staging/iio/iio_simple_dummy.c | 16 +++ include/linux/iio/iio.h | 14 ++- 6 files changed, 169 insertions(+), 106 deletions(-)
Signature · 1 line
1.8.3.4
Jonathan Cameron
maintainerPATCH 1/5 iio: drop info_mask from struct iio_dev
Somehow this got missed when dropping all the code that used it prior to the split. Remove it now, there are no users.
--- include/linux/iio/iio.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
include/linux/iio/iio.h +1 -4
@@ -146,12 +146,10 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev,* shift: Shift right by this before masking out * realbits. * endianness: little or big endian -* @info_mask: What information is to be exported about this channel. -* This includes calibbias, scale etc. * @info_mask_separate: What information is to be exported that is specific to * this channel. * @info_mask_shared_by_type: What information is to be exported that is shared -* by all channels of the same type. +* by all channels of the same type. * @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
@@ -186,7 +184,6 @@ struct iio_chan_spec {u8 shift;enum iio_endian endianness; } scan_type; -long info_mask;long info_mask_separate;long info_mask_shared_by_type;long event_mask;
Signature · 1 line
1.8.3.4
Jonathan Cameron
maintainerPATCH 2/5 iio: refactor info mask attribute creation.
In reply to Jonathan CameronIntroduce an enum to specify whether the attribute is separate or shared.
Factor out the bitmap handling for loop into a separate function.
Tidy up error handling and add a NULL assignment to squish a false positive warning from GCC.
--- drivers/iio/iio_core.h | 5 +- drivers/iio/industrialio-buffer.c | 2 +- drivers/iio/industrialio-core.c | 148 ++++++++++++++++++++------------------ 3 files changed, 84 insertions(+), 71 deletions(-)
drivers/iio/iio_core.h +4 -1
@@ -20,6 +20,9 @@ struct iio_dev;extern struct device_type iio_device_type; +enum iio_shared_by { __IIO_SEPARATE, + __IIO_SHARED_BY_TYPE }; + int __iio_add_chan_devattr(const char *postfix, struct iio_chan_spec const *chan, ssize_t (*func)(struct device *dev,
@@ -30,7 +33,7 @@ int __iio_add_chan_devattr(const char *postfix,const char *buf, size_t len), u64 mask, - bool generic, + enum iio_shared_by generic, struct device *dev, struct list_head *attr_list);
drivers/iio/industrialio-buffer.c +1 -1
@@ -214,7 +214,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev, &iio_show_scan_index,NULL ,0 , -0 , + __IIO_SEPARATE, &indio_dev->dev, &buffer->scan_el_dev_attr_list);if (ret)
drivers/iio/industrialio-core.c +79 -69
244 lines not on this page · raw message
Signature · 1 line
1.8.3.4
Jonathan Cameron
maintainerRe: [PATCH 2/5] iio: refactor info mask attribute creation.
Quoted 7 lines · Jonathan Cameron
Introduce an enum to specify whether the attribute is separate or shared.
Factor out the bitmap handling for loop into a separate function.
Tidy up error handling and add a NULL assignment to squish a false positive warning from GCC.
Ooops. This doesn't handle the ext_info case properly as that just passes a boolean. Will fix up and repost...
Quoted 301 lines
Signed-off-by Jonathan Cameron <[email protected]>--- drivers/iio/iio_core.h | 5 +- drivers/iio/industrialio-buffer.c | 2 +- drivers/iio/industrialio-core.c | 148 ++++++++++++++++++++------------------ 3 files changed, 84 insertions(+), 71 deletions(-)drivers/iio/iio_core.h +4
-1@@ -20,6 +20,9 @@ struct iio_dev;extern struct device_type iio_device_type; +enum iio_shared_by { __IIO_SEPARATE, + __IIO_SHARED_BY_TYPE }; + int __iio_add_chan_devattr(const char *postfix, struct iio_chan_spec const *chan, ssize_t (*func)(struct device *dev,@@ -30,7 +33,7 @@ int __iio_add_chan_devattr(const char *postfix,const char *buf, size_t len), u64 mask, - bool generic, + enum iio_shared_by generic, struct device *dev, struct list_head *attr_list);drivers/iio/industrialio-buffer.c +1
-1@@ -214,7 +214,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev, &iio_show_scan_index,NULL ,0 , -0 , + __IIO_SEPARATE, &indio_dev->dev, &buffer->scan_el_dev_attr_list);if (ret)drivers/iio/industrialio-core.c +79
-69@@ -516,14 +516,15 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,struct device_attribute *attr, const char *buf, size_t len), - bool generic) + enum iio_shared_by shared_by) { - int ret; -char *name_format, *full_postfix; + int ret = 0; +char *name_format =NULL ; +char *full_postfix;sysfs_attr_init (&dev_attr->attr);/* Build up postfix of <extend_name>_<modifier>_postfix */ - if (chan->modified && !generic) { + if (chan->modified && (shared_by == __IIO_SEPARATE)) { if (chan->extend_name) full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s", iio_modifier_names[chan@@ -544,53 +545,62 @@ int __iio_device_attr_init(struct device_attribute *dev_attr, chan->extend_name, postfix); } -if (full_postfix ==NULL ) { - ret = -ENOMEM ; - goto error_ret; - } +if (full_postfix ==NULL ) +return -ENOMEM ;if (chan->differential) {/* Differential can not have modifier */ -if (generic) +switch (shared_by) { +case __IIO_SHARED_BY_TYPE: name_format =kasprintf (GFP_KERNEL ,"%s_%s-%s_%s" , iio_direction[chan->output], iio_chan_type_name_spec[chan->type], iio_chan_type_name_spec[chan->type], full_postfix); -else if (chan->indexed) +break ; +case __IIO_SEPARATE: +if (!chan->indexed) { +WARN_ON ("Differential channels must be indexed\n" ); + ret = -EINVAL ; + goto error_free_full_postfix; + } name_format - =kasprintf (GFP_KERNEL ,"%s_%s%d-%s%d_%s" , + =kasprintf (GFP_KERNEL , +"%s_%s%d-%s%d_%s" , iio_direction[chan->output], iio_chan_type_name_spec[chan->type], chan->channel, iio_chan_type_name_spec[chan->type], chan->channel2, full_postfix); -else { -WARN_ON ("Differential channels must be indexed\n" ); - ret = -EINVAL ; - goto error_free_full_postfix; +break ; } }else {/* Single ended */ -if (generic) - name_format - =kasprintf (GFP_KERNEL ,"%s_%s_%s" , - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - full_postfix); -else if (chan->indexed) - name_format - =kasprintf (GFP_KERNEL ,"%s_%s%d_%s" , - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - chan->channel, - full_postfix); -else +switch (shared_by) { +case __IIO_SHARED_BY_TYPE: name_format =kasprintf (GFP_KERNEL ,"%s_%s_%s" , iio_direction[chan->output], iio_chan_type_name_spec[chan->type], full_postfix); +break ; + +case __IIO_SEPARATE: +if (chan->indexed) + name_format + =kasprintf (GFP_KERNEL ,"%s_%s%d_%s" , + iio_direction[chan->output], + iio_chan_type_name_spec[chan->type], + chan->channel, + full_postfix); +else + name_format + =kasprintf (GFP_KERNEL ,"%s_%s_%s" , + iio_direction[chan->output], + iio_chan_type_name_spec[chan->type], + full_postfix); +break ; + } }if (name_format ==NULL ) { ret = -ENOMEM ;@@ -614,16 +624,11 @@ int __iio_device_attr_init(struct device_attribute *dev_attr, dev_attr->attr.mode |=S_IWUSR ; dev_attr->store = writefunc; } -kfree (name_format); -kfree (full_postfix); - -return 0 ; - error_free_name_format:kfree (name_format); error_free_full_postfix:kfree (full_postfix); -error_ret: +return ret; }@@ -642,7 +647,7 @@ int __iio_add_chan_devattr(const char *postfix,const char *buf, size_t len), u64 mask, - bool generic, + enum iio_shared_by shared_by, struct device *dev, struct list_head *attr_list) {@@ -656,7 +661,7 @@ int __iio_add_chan_devattr(const char *postfix, } ret =__iio_device_attr_init (&iio_attr->dev_attr, postfix, chan, - readfunc, writefunc, generic); + readfunc, writefunc, shared_by);if (ret) goto error_iio_dev_attr_free; iio_attr->c = chan;@@ -664,7 +669,7 @@ int __iio_add_chan_devattr(const char *postfix,list_for_each_entry (t, attr_list, l)if (strcmp (t->dev_attr.attr.name, iio_attr->dev_attr.attr.name) ==0 ) { -if (!generic) +if (shared_by == __IIO_SEPARATE)dev_err (dev,"tried to double register : %s\n" , t->dev_attr.attr.name); ret = -EBUSY ;@@ -682,46 +687,53 @@ error_ret:return ret; } -static int iio_device_add_channel_sysfs (struct iio_dev *indio_dev, -struct iio_chan_spec const *chan) +static int iio_device_add_info_mask_type (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +enum iio_shared_by shared_by, +const long *infomask) { -int ret, attrcount =0 ; -int i; -const struct iio_chan_spec_ext_info *ext_info; +int i, ret, attrcount =0 ; -if (chan->channel <0 ) -return 0 ; -for_each_set_bit (i, &chan->info_mask_separate,sizeof (long )*8 ) { +for_each_set_bit (i, infomask,sizeof (infomask)*8 ) { ret =__iio_add_chan_devattr (iio_chan_info_postfix[i], chan, &iio_read_channel_info, &iio_write_channel_info, i, -0 , + shared_by, &indio_dev->dev, &indio_dev->channel_attr_list); -if (ret <0 ) - goto error_ret; - attrcount++; - } -for_each_set_bit (i, &chan->info_mask_shared_by_type,sizeof (long )*8 ) { - ret =__iio_add_chan_devattr (iio_chan_info_postfix[i], - chan, - &iio_read_channel_info, - &iio_write_channel_info, - i, -1 , - &indio_dev->dev, - &indio_dev->channel_attr_list); -if (ret == -EBUSY ) { - ret =0 ; +if ((ret == -EBUSY ) && (shared_by != __IIO_SEPARATE))continue ; - }else if (ret <0 ) { - goto error_ret; - } +else if (ret <0 ) +return ret; attrcount++; } +return attrcount; +} + +static int iio_device_add_channel_sysfs (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan) +{ +int ret, attrcount =0 ; +const struct iio_chan_spec_ext_info *ext_info; + +if (chan->channel <0 ) +return 0 ; + ret =iio_device_add_info_mask_type (indio_dev, chan, + __IIO_SEPARATE, + &chan->info_mask_separate); +if (ret <0 ) +return ret; + attrcount += ret; + + ret =iio_device_add_info_mask_type (indio_dev, chan, + __IIO_SHARED_BY_TYPE, + &chan->info_mask_shared_by_type); +if (ret <0 ) +return ret; + attrcount += ret;if (chan->ext_info) {unsigned int i =0 ;for (ext_info = chan->ext_info; ext_info->name; ext_info++) {@@ -740,15 +752,13 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,continue ;if (ret) - goto error_ret; +return ret; attrcount++; } } - ret = attrcount; -error_ret: -return ret; +return attrcount; } static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev,
Jonathan Cameron
maintainerPATCH 3/5 iio: add info_mask_[shared_by_dir/shared_by_all]
In reply to Jonathan CameronThese two additional info_mask bitmaps should allow all 'standard' numeric attributes to be handled using the read_raw and write_raw callbacks. Whilst this should reduce code, the more important element is that this makes these values easily accessible to in kernel users of IIO devices.
--- drivers/iio/iio_core.h | 4 +++- drivers/iio/industrialio-core.c | 31 +++++++++++++++++++++++++++++++ include/linux/iio/iio.h | 9 ++++++++- 3 files changed, 42 insertions(+), 2 deletions(-)
drivers/iio/iio_core.h +3 -1
@@ -21,7 +21,9 @@ struct iio_dev;extern struct device_type iio_device_type;enum iio_shared_by { __IIO_SEPARATE, - __IIO_SHARED_BY_TYPE }; + __IIO_SHARED_BY_TYPE, + __IIO_SHARED_BY_DIR, + __IIO_SHARED_BY_ALL }; int __iio_add_chan_devattr(const char *postfix, struct iio_chan_spec const *chan,
drivers/iio/industrialio-core.c +31 -0
@@ -550,6 +550,14 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,if (chan->differential) {/* Differential can not have modifier */ switch (shared_by) { +case __IIO_SHARED_BY_ALL: + name_format =kasprintf (GFP_KERNEL ,"%s" , full_postfix); +break ; +case __IIO_SHARED_BY_DIR: + name_format =kasprintf (GFP_KERNEL ,"%s_%s" , + iio_direction[chan->output], + full_postfix); +break ;case __IIO_SHARED_BY_TYPE: name_format = kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
@@ -577,6 +585,14 @@ int __iio_device_attr_init(struct device_attribute *dev_attr, } }else {/* Single ended */ switch (shared_by) { +case __IIO_SHARED_BY_ALL: + name_format =kasprintf (GFP_KERNEL ,"%s" , full_postfix); +break ; +case __IIO_SHARED_BY_DIR: + name_format =kasprintf (GFP_KERNEL ,"%s_%s" , + iio_direction[chan->output], + full_postfix); +break ;case __IIO_SHARED_BY_TYPE: name_format = kasprintf(GFP_KERNEL, "%s_%s_%s",
@@ -734,6 +750,21 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,if (ret <0 )return ret; attrcount += ret; + + ret =iio_device_add_info_mask_type (indio_dev, chan, + __IIO_SHARED_BY_DIR, + &chan->info_mask_shared_by_dir); +if (ret <0 ) +return ret; + attrcount += ret; + + ret =iio_device_add_info_mask_type (indio_dev, chan, + __IIO_SHARED_BY_ALL, + &chan->info_mask_shared_by_all); +if (ret <0 ) +return ret; + attrcount += ret; +if (chan->ext_info) {unsigned int i =0 ;for (ext_info = chan->ext_info; ext_info->name; ext_info++) {
include/linux/iio/iio.h +8 -1
@@ -150,6 +150,10 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev,* this channel. * @info_mask_shared_by_type: What information is to be exported that is shared * by all channels of the same type. +* @info_mask_shared_by_dir: What information is to be exported that is shared +* by all channels of the same direction. +* @info_mask_shared_by_all: What information is to be exported that is shared +* by all channels. * @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
@@ -186,6 +190,8 @@ struct iio_chan_spec { } scan_type;long info_mask_separate;long info_mask_shared_by_type; +long info_mask_shared_by_dir; +long info_mask_shared_by_all;long event_mask;const struct iio_chan_spec_ext_info *ext_info;const char *extend_name;
@@ -209,7 +215,8 @@ static inline bool iio_channel_has_info(const struct iio_chan_spec *chan, enum iio_chan_info_enum type) {return (chan->info_mask_separate &BIT (type)) | - (chan->info_mask_shared_by_type &BIT (type)); + (chan->info_mask_shared_by_type &BIT (type)) | + (chan->info_mask_shared_by_all &BIT (type)); }#define IIO_ST (si, rb, sb, sh) \
Signature · 1 line
1.8.3.4
Jonathan Cameron
maintainerPATCH 4/5 staging:iio: dummy driver additions to show shared_by_dir infomask usage
In reply to Jonathan CameronNote that as this driver has output as well as output channels an example of info_mask_shared_by_all that makes any sense does not exist.
--- drivers/staging/iio/iio_simple_dummy.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/staging/iio/iio_simple_dummy.c +16 -0
@@ -90,6 +90,11 @@ static const struct iio_chan_spec iio_dummy_channels[] = {* when converting to standard units (microvolts) */ BIT (IIO_CHAN_INFO_SCALE ), +/* +* sampling_frequency +* The frequency in Hz at which the channels are sampled +*/ + .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),/* The ordering of elements in the buffer via an enum */ .scan_index = voltage0, .scan_type = { /* Description of storage in buffer */
@@ -130,6 +135,10 @@ static const struct iio_chan_spec iio_dummy_channels[] = {* input channels of type IIO_VOLTAGE. */ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), + /* + * sampling_frequency + * The frequency in Hz at which the channels are sampled + */ .scan_index = diffvoltage1m2, .scan_type = { /* Description of storage in buffer */ .sign = 's', /* signed */
@@ -147,6 +156,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = { .channel2 = 4, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ), .scan_index = diffvoltage3m4, .scan_type = { .sign = 's',
@@ -173,6 +183,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {*/ BIT (IIO_CHAN_INFO_CALIBSCALE ) | BIT(IIO_CHAN_INFO_CALIBBIAS), + .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ), .scan_index = accelx, .scan_type = { /* Description of storage in buffer */ .sign = 's', /* signed */
@@ -272,6 +283,11 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev, *val2 = st->accel_calibscale->val2; ret =IIO_VAL_INT_PLUS_MICRO ;break ; +case IIO_CHAN_INFO_SAMP_FREQ : + *val =3 ; + *val2 =33 ; + ret =IIO_VAL_INT_PLUS_NANO ; +break ;default :break ; }
Signature · 1 line
1.8.3.4
Jonathan Cameron
maintainerPATCH 5/5 iio:temperature:tmp006 put sampling_frequency in info_mask_shared_by_all
In reply to Jonathan CameronDoing this makes it possible to access this control from within the kernel.
--- drivers/iio/temperature/tmp006.c | 57 +++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 30 deletions(-)
drivers/iio/temperature/tmp006.c +27 -30
@@ -70,12 +70,16 @@ static int tmp006_read_measurement(struct tmp006_data *data, u8 reg)return i2c_smbus_read_word_swapped (data->client, reg); } +static const int const tmp006_freqs[5 ][2 ] = { {4 ,0 }, {2 ,0 }, {1 ,0 }, + {0 ,500000 }, {0 ,250000 } }; +static int tmp006_read_raw (struct iio_dev *indio_dev,struct iio_chan_spec const *channel,int *val,int *val2,long mask) {struct tmp006_data *data =iio_priv (indio_dev);s32 ret; +int cr;switch (mask) {case IIO_CHAN_INFO_RAW :
@@ -106,6 +110,12 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,break ; }return IIO_VAL_INT_PLUS_MICRO ; +case IIO_CHAN_INFO_SAMP_FREQ : + cr = (data->config &TMP006_CONFIG_CR_MASK ) + >>TMP006_CONFIG_CR_SHIFT ; + *val = tmp006_freqs[cr][0 ]; + *val2 = tmp006_freqs[cr][1 ]; +return IIO_VAL_INT_PLUS_MICRO ;default :break ; }
@@ -113,48 +123,32 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,return -EINVAL ; } -static const char *const tmp006_freqs[] = {"4" ,"2" ,"1" ,"0.5" ,"0.25" }; - -static ssize_t tmp006_show_freq (struct device *dev, -struct device_attribute *attr,char *buf) -{ -struct tmp006_data *data =iio_priv (dev_to_iio_dev (dev)); -int cr = (data->config &TMP006_CONFIG_CR_MASK ) - >>TMP006_CONFIG_CR_SHIFT ; -return sprintf (buf,"%s\n" , tmp006_freqs[cr]); -} - -static ssize_t tmp006_store_freq (struct device *dev, -struct device_attribute *attr, -const char *buf,size_t len) +static int tmp006_write_raw (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +int val, +int val2, +long mask) { -struct iio_dev *indio_dev =dev_to_iio_dev (dev);struct tmp006_data *data =iio_priv (indio_dev);int i; -bool found = false;for (i =0 ; i <ARRAY_SIZE (tmp006_freqs); i++) -if (sysfs_streq (buf, tmp006_freqs[i])) { - found = true; -break ; - } -if (!found) -return -EINVAL ; +if ((val == tmp006_freqs[i][0 ]) && + (val2 == tmp006_freqs[i][1 ])) { + data->config &= ~TMP006_CONFIG_CR_MASK ; + data->config |= i <<TMP006_CONFIG_CR_SHIFT ; - data->config &= ~TMP006_CONFIG_CR_MASK ; - data->config |= i <<TMP006_CONFIG_CR_SHIFT ; +return i2c_smbus_write_word_swapped (data->client, +TMP006_CONFIG , + data->config); -return i2c_smbus_write_word_swapped (data->client,TMP006_CONFIG , - data->config); + } +return -EINVAL ; } -static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, - tmp006_show_freq, tmp006_store_freq); - static IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25");static struct attribute *tmp006_attributes[] = { - &iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_const_attr_sampling_frequency_available.dev_attr.attr,NULL };
@@ -168,16 +162,19 @@ static const struct iio_chan_spec tmp006_channels[] = { .type = IIO_VOLTAGE, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), }, { .type = IIO_TEMP, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), } };static const struct iio_info tmp006_info = { .read_raw = tmp006_read_raw, + .write_raw = tmp006_write_raw, .attrs = &tmp006_attribute_group, .driver_module =THIS_MODULE , };
Signature · 1 line
1.8.3.4
Re: [PATCH 5/5] iio:temperature:tmp006 put sampling_frequency in info_mask_shared_by_all
Hello Jonathan,
Quoted 1 line
Doing this makes it possible to access this control from within the kernel.
I noticed this shortcoming as well after submitting;
so the plan is to remove IIO_DEV_ATTR_SAMP_FREQ() sometimes, right?
patch looks good!
regards, p.
Quoted 123 lines
Signed-off-by Jonathan Cameron <[email protected]>--- drivers/iio/temperature/tmp006.c | 57 +++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 30 deletions(-)drivers/iio/temperature/tmp006.c +27
-30@@ -70,12 +70,16 @@ static int tmp006_read_measurement(struct tmp006_data *data, u8 reg)return i2c_smbus_read_word_swapped (data->client, reg); } +static const int const tmp006_freqs[5 ][2 ] = { {4 ,0 }, {2 ,0 }, {1 ,0 }, + {0 ,500000 }, {0 ,250000 } }; +static int tmp006_read_raw (struct iio_dev *indio_dev,struct iio_chan_spec const *channel,int *val,int *val2,long mask) {struct tmp006_data *data =iio_priv (indio_dev);s32 ret; +int cr;switch (mask) {case IIO_CHAN_INFO_RAW :@@ -106,6 +110,12 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,break ; }return IIO_VAL_INT_PLUS_MICRO ; +case IIO_CHAN_INFO_SAMP_FREQ : + cr = (data->config &TMP006_CONFIG_CR_MASK ) + >>TMP006_CONFIG_CR_SHIFT ; + *val = tmp006_freqs[cr][0 ]; + *val2 = tmp006_freqs[cr][1 ]; +return IIO_VAL_INT_PLUS_MICRO ;default :break ; }@@ -113,48 +123,32 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,return -EINVAL ; } -static const char *const tmp006_freqs[] = {"4" ,"2" ,"1" ,"0.5" ,"0.25" }; - -static ssize_t tmp006_show_freq (struct device *dev, -struct device_attribute *attr,char *buf) -{ -struct tmp006_data *data =iio_priv (dev_to_iio_dev (dev)); -int cr = (data->config &TMP006_CONFIG_CR_MASK ) - >>TMP006_CONFIG_CR_SHIFT ; -return sprintf (buf,"%s\n" , tmp006_freqs[cr]); -} - -static ssize_t tmp006_store_freq (struct device *dev, -struct device_attribute *attr, -const char *buf,size_t len) +static int tmp006_write_raw (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +int val, +int val2, +long mask) { -struct iio_dev *indio_dev =dev_to_iio_dev (dev);struct tmp006_data *data =iio_priv (indio_dev);int i; -bool found = false;for (i =0 ; i <ARRAY_SIZE (tmp006_freqs); i++) -if (sysfs_streq (buf, tmp006_freqs[i])) { - found = true; -break ; - } -if (!found) -return -EINVAL ; +if ((val == tmp006_freqs[i][0 ]) && + (val2 == tmp006_freqs[i][1 ])) { + data->config &= ~TMP006_CONFIG_CR_MASK ; + data->config |= i <<TMP006_CONFIG_CR_SHIFT ; - data->config &= ~TMP006_CONFIG_CR_MASK ; - data->config |= i <<TMP006_CONFIG_CR_SHIFT ; +return i2c_smbus_write_word_swapped (data->client, +TMP006_CONFIG , + data->config); -return i2c_smbus_write_word_swapped (data->client,TMP006_CONFIG , - data->config); + } +return -EINVAL ; } -static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, - tmp006_show_freq, tmp006_store_freq); - static IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25");static struct attribute *tmp006_attributes[] = { - &iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_const_attr_sampling_frequency_available.dev_attr.attr,NULL };@@ -168,16 +162,19 @@ static const struct iio_chan_spec tmp006_channels[] = { .type = IIO_VOLTAGE, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), }, { .type = IIO_TEMP, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), } };static const struct iio_info tmp006_info = { .read_raw = tmp006_read_raw, + .write_raw = tmp006_write_raw, .attrs = &tmp006_attribute_group, .driver_module =THIS_MODULE , };
Signature · 2 lines
Peter Meerwald +43-664-2444418 (mobile)
Jonathan Cameron
maintainerRe: [PATCH 5/5] iio:temperature:tmp006 put sampling_frequency in info_mask_shared_by_all
Quoted 6 lines · Peter Meerwald
Hello Jonathan,
Quoted 1 line
Doing this makes it possible to access this control from within the kernel.
I noticed this shortcoming as well after submitting;
so the plan is to removeIIO_DEV_ATTR_SAMP_FREQ()sometimes, right?
Definititely .
Quoted 3 lines
patch looks good!
Acked-by Peter Meerwald <[email protected]>
Thanks,
Jonathan
Quoted 127 lines
regards, p.
Quoted 123 lines
Signed-off-by Jonathan Cameron <[email protected]>--- drivers/iio/temperature/tmp006.c | 57 +++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 30 deletions(-)drivers/iio/temperature/tmp006.c +27
-30@@ -70,12 +70,16 @@ static int tmp006_read_measurement(struct tmp006_data *data, u8 reg)return i2c_smbus_read_word_swapped (data->client, reg); } +static const int const tmp006_freqs[5 ][2 ] = { {4 ,0 }, {2 ,0 }, {1 ,0 }, + {0 ,500000 }, {0 ,250000 } }; +static int tmp006_read_raw (struct iio_dev *indio_dev,struct iio_chan_spec const *channel,int *val,int *val2,long mask) {struct tmp006_data *data =iio_priv (indio_dev);s32 ret; +int cr;switch (mask) {case IIO_CHAN_INFO_RAW :@@ -106,6 +110,12 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,break ; }return IIO_VAL_INT_PLUS_MICRO ; +case IIO_CHAN_INFO_SAMP_FREQ : + cr = (data->config &TMP006_CONFIG_CR_MASK ) + >>TMP006_CONFIG_CR_SHIFT ; + *val = tmp006_freqs[cr][0 ]; + *val2 = tmp006_freqs[cr][1 ]; +return IIO_VAL_INT_PLUS_MICRO ;default :break ; }@@ -113,48 +123,32 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,return -EINVAL ; } -static const char *const tmp006_freqs[] = {"4" ,"2" ,"1" ,"0.5" ,"0.25" }; - -static ssize_t tmp006_show_freq (struct device *dev, -struct device_attribute *attr,char *buf) -{ -struct tmp006_data *data =iio_priv (dev_to_iio_dev (dev)); -int cr = (data->config &TMP006_CONFIG_CR_MASK ) - >>TMP006_CONFIG_CR_SHIFT ; -return sprintf (buf,"%s\n" , tmp006_freqs[cr]); -} - -static ssize_t tmp006_store_freq (struct device *dev, -struct device_attribute *attr, -const char *buf,size_t len) +static int tmp006_write_raw (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +int val, +int val2, +long mask) { -struct iio_dev *indio_dev =dev_to_iio_dev (dev);struct tmp006_data *data =iio_priv (indio_dev);int i; -bool found = false;for (i =0 ; i <ARRAY_SIZE (tmp006_freqs); i++) -if (sysfs_streq (buf, tmp006_freqs[i])) { - found = true; -break ; - } -if (!found) -return -EINVAL ; +if ((val == tmp006_freqs[i][0 ]) && + (val2 == tmp006_freqs[i][1 ])) { + data->config &= ~TMP006_CONFIG_CR_MASK ; + data->config |= i <<TMP006_CONFIG_CR_SHIFT ; - data->config &= ~TMP006_CONFIG_CR_MASK ; - data->config |= i <<TMP006_CONFIG_CR_SHIFT ; +return i2c_smbus_write_word_swapped (data->client, +TMP006_CONFIG , + data->config); -return i2c_smbus_write_word_swapped (data->client,TMP006_CONFIG , - data->config); + } +return -EINVAL ; } -static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, - tmp006_show_freq, tmp006_store_freq); - static IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25");static struct attribute *tmp006_attributes[] = { - &iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_const_attr_sampling_frequency_available.dev_attr.attr,NULL };@@ -168,16 +162,19 @@ static const struct iio_chan_spec tmp006_channels[] = { .type = IIO_VOLTAGE, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), }, { .type = IIO_TEMP, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), } };static const struct iio_info tmp006_info = { .read_raw = tmp006_read_raw, + .write_raw = tmp006_write_raw, .attrs = &tmp006_attribute_group, .driver_module =THIS_MODULE , };