* [PATCH 0/2] Introduce new iio resolution standard attribute
@ 2023-12-15 12:43 Mårten Lindahl
2023-12-15 12:43 ` [PATCH 1/2] iio: core: Introduce " Mårten Lindahl
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Mårten Lindahl @ 2023-12-15 12:43 UTC (permalink / raw)
To: Jonathan Cameron, Lars-Peter Clausen
Cc: linux-iio, linux-kernel, kernel, Mårten Lindahl
This patch introduces a new IIO standard attribute to set the bit
resolution of the data *_raw readings dynamically using sysfs.
The VCNL4040/4200 proximity/ambient light sensors support 12-bit
(default) and 16-bit ADC resolutions. This can be dynamically changed,
so to support this with the standard iio channel configuration a new iio
attribute should be added.
The VCNL4040 devices will use this for setting proximity high definition
(16-bit resolution).
Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com>
---
Mårten Lindahl (2):
iio: core: Introduce resolution standard attribute
iio: light: vcnl4000: Add ps high definition for vcnl4040
drivers/iio/industrialio-core.c | 1 +
drivers/iio/light/vcnl4000.c | 87 ++++++++++++++++++++++++++++++++++++++++-
include/linux/iio/types.h | 1 +
3 files changed, 87 insertions(+), 2 deletions(-)
---
base-commit: a39b6ac3781d46ba18193c9dbb2110f31e9bffe9
change-id: 20231212-vcnl4000-ps-hd-38d42abf9095
Best regards,
--
Mårten Lindahl <marten.lindahl@axis.com>
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 1/2] iio: core: Introduce resolution standard attribute 2023-12-15 12:43 [PATCH 0/2] Introduce new iio resolution standard attribute Mårten Lindahl @ 2023-12-15 12:43 ` Mårten Lindahl 2023-12-15 12:43 ` [PATCH 2/2] iio: light: vcnl4000: Add ps high definition for vcnl4040 Mårten Lindahl 2023-12-17 14:10 ` [PATCH 0/2] Introduce new iio resolution standard attribute Jonathan Cameron 2 siblings, 0 replies; 9+ messages in thread From: Mårten Lindahl @ 2023-12-15 12:43 UTC (permalink / raw) To: Jonathan Cameron, Lars-Peter Clausen Cc: linux-iio, linux-kernel, kernel, Mårten Lindahl Introduce a new IIO standard attribute to set bit resolution of the data *_raw readings dynamically using sysfs. Needed to set 16 bit data width (high definition) with the VCNL4040 driver. Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com> --- drivers/iio/industrialio-core.c | 1 + include/linux/iio/types.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index c77745b594bd..4316e0290404 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -182,6 +182,7 @@ static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_THERMOCOUPLE_TYPE] = "thermocouple_type", [IIO_CHAN_INFO_CALIBAMBIENT] = "calibambient", [IIO_CHAN_INFO_ZEROPOINT] = "zeropoint", + [IIO_CHAN_INFO_RESOLUTION] = "resolution", }; /** * iio_device_id() - query the unique ID for the device diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index 117bde7d6ad7..7de4d83ca105 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -68,6 +68,7 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_THERMOCOUPLE_TYPE, IIO_CHAN_INFO_CALIBAMBIENT, IIO_CHAN_INFO_ZEROPOINT, + IIO_CHAN_INFO_RESOLUTION, }; #endif /* _IIO_TYPES_H_ */ -- 2.30.2 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] iio: light: vcnl4000: Add ps high definition for vcnl4040 2023-12-15 12:43 [PATCH 0/2] Introduce new iio resolution standard attribute Mårten Lindahl 2023-12-15 12:43 ` [PATCH 1/2] iio: core: Introduce " Mårten Lindahl @ 2023-12-15 12:43 ` Mårten Lindahl 2023-12-17 14:15 ` Jonathan Cameron 2023-12-17 14:10 ` [PATCH 0/2] Introduce new iio resolution standard attribute Jonathan Cameron 2 siblings, 1 reply; 9+ messages in thread From: Mårten Lindahl @ 2023-12-15 12:43 UTC (permalink / raw) To: Jonathan Cameron, Lars-Peter Clausen Cc: linux-iio, linux-kernel, kernel, Mårten Lindahl The vcnl4040 proximity sensor defaults to 12 bit data resolution, but the chip also supports 16 bit data resolution, which is called proximity high definition (PS_HD). Add read/write attribute for proximity resolution, and read attribute for available proximity resolution values for the vcnl4040 chip. Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com> --- drivers/iio/light/vcnl4000.c | 87 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index fdf763a04b0b..2addff635b79 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -90,6 +90,7 @@ #define VCNL4040_PS_CONF1_PS_SHUTDOWN BIT(0) #define VCNL4040_PS_CONF2_PS_IT GENMASK(3, 1) /* Proximity integration time */ #define VCNL4040_CONF1_PS_PERS GENMASK(5, 4) /* Proximity interrupt persistence setting */ +#define VCNL4040_PS_CONF2_PS_HD BIT(11) /* Proximity high definition */ #define VCNL4040_PS_CONF2_PS_INT GENMASK(9, 8) /* Proximity interrupt mode */ #define VCNL4040_PS_CONF3_MPS GENMASK(6, 5) /* Proximity multi pulse number */ #define VCNL4040_PS_MS_LED_I GENMASK(10, 8) /* Proximity current */ @@ -170,6 +171,11 @@ static const int vcnl4040_ps_calibbias_ua[][2] = { {0, 200000}, }; +static const int vcnl4040_ps_resolutions[2] = { + 12, + 16 +}; + static const int vcnl4040_als_persistence[] = {1, 2, 4, 8}; static const int vcnl4040_ps_persistence[] = {1, 2, 3, 4}; static const int vcnl4040_ps_oversampling_ratio[] = {1, 2, 4, 8}; @@ -880,6 +886,54 @@ static ssize_t vcnl4040_write_ps_calibbias(struct vcnl4000_data *data, int val) return ret; } +static ssize_t vcnl4040_read_ps_resolution(struct vcnl4000_data *data, int *val, int *val2) +{ + int ret; + + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); + if (ret < 0) + return ret; + + ret = FIELD_GET(VCNL4040_PS_CONF2_PS_HD, ret); + if (ret >= ARRAY_SIZE(vcnl4040_ps_resolutions)) + return -EINVAL; + + *val = vcnl4040_ps_resolutions[ret]; + *val2 = 0; + + return ret; +} + +static ssize_t vcnl4040_write_ps_resolution(struct vcnl4000_data *data, int val) +{ + unsigned int i; + int ret; + u16 regval; + + for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_resolutions); i++) { + if (val == vcnl4040_ps_resolutions[i]) + break; + } + + if (i >= ARRAY_SIZE(vcnl4040_ps_resolutions)) + return -EINVAL; + + mutex_lock(&data->vcnl4000_lock); + + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); + if (ret < 0) + goto out_unlock; + + regval = (ret & ~VCNL4040_PS_CONF2_PS_HD); + regval |= FIELD_PREP(VCNL4040_PS_CONF2_PS_HD, i); + ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, + regval); + +out_unlock: + mutex_unlock(&data->vcnl4000_lock); + return ret; +} + static int vcnl4000_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -950,6 +1004,16 @@ static int vcnl4000_read_raw(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_CHAN_INFO_RESOLUTION: + switch (chan->type) { + case IIO_PROXIMITY: + ret = vcnl4040_read_ps_resolution(data, val, val2); + if (ret < 0) + return ret; + return IIO_VAL_INT; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -987,6 +1051,13 @@ static int vcnl4040_write_raw(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_CHAN_INFO_RESOLUTION: + switch (chan->type) { + case IIO_PROXIMITY: + return vcnl4040_write_ps_resolution(data, val); + default: + return -EINVAL; + } default: return -EINVAL; } @@ -1035,6 +1106,16 @@ static int vcnl4040_read_avail(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_CHAN_INFO_RESOLUTION: + switch (chan->type) { + case IIO_PROXIMITY: + *vals = (int *)vcnl4040_ps_resolutions; + *length = ARRAY_SIZE(vcnl4040_ps_resolutions); + *type = IIO_VAL_INT; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -1808,10 +1889,12 @@ static const struct iio_chan_spec vcnl4040_channels[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | - BIT(IIO_CHAN_INFO_CALIBBIAS), + BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_RESOLUTION), .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | - BIT(IIO_CHAN_INFO_CALIBBIAS), + BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_RESOLUTION), .ext_info = vcnl4000_ext_info, .event_spec = vcnl4040_event_spec, .num_event_specs = ARRAY_SIZE(vcnl4040_event_spec), -- 2.30.2 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] iio: light: vcnl4000: Add ps high definition for vcnl4040 2023-12-15 12:43 ` [PATCH 2/2] iio: light: vcnl4000: Add ps high definition for vcnl4040 Mårten Lindahl @ 2023-12-17 14:15 ` Jonathan Cameron 2023-12-18 15:19 ` Mårten Lindahl 0 siblings, 1 reply; 9+ messages in thread From: Jonathan Cameron @ 2023-12-17 14:15 UTC (permalink / raw) To: Mårten Lindahl; +Cc: Lars-Peter Clausen, linux-iio, linux-kernel, kernel On Fri, 15 Dec 2023 13:43:05 +0100 Mårten Lindahl <marten.lindahl@axis.com> wrote: > The vcnl4040 proximity sensor defaults to 12 bit data resolution, but > the chip also supports 16 bit data resolution, which is called proximity > high definition (PS_HD). > > Add read/write attribute for proximity resolution, and read attribute > for available proximity resolution values for the vcnl4040 chip. > > Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com> I'll review this on basis the usecase is clear (see reply to cover letter) The manipulation of the CONF1 and CONF2 registers in a pair is rather odd given you only want to change one bit here. Why is that done? > --- > drivers/iio/light/vcnl4000.c | 87 +++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 85 insertions(+), 2 deletions(-) > > diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c > index fdf763a04b0b..2addff635b79 100644 > --- a/drivers/iio/light/vcnl4000.c > +++ b/drivers/iio/light/vcnl4000.c > @@ -90,6 +90,7 @@ > #define VCNL4040_PS_CONF1_PS_SHUTDOWN BIT(0) > #define VCNL4040_PS_CONF2_PS_IT GENMASK(3, 1) /* Proximity integration time */ > #define VCNL4040_CONF1_PS_PERS GENMASK(5, 4) /* Proximity interrupt persistence setting */ > +#define VCNL4040_PS_CONF2_PS_HD BIT(11) /* Proximity high definition */ > #define VCNL4040_PS_CONF2_PS_INT GENMASK(9, 8) /* Proximity interrupt mode */ > #define VCNL4040_PS_CONF3_MPS GENMASK(6, 5) /* Proximity multi pulse number */ > #define VCNL4040_PS_MS_LED_I GENMASK(10, 8) /* Proximity current */ > @@ -170,6 +171,11 @@ static const int vcnl4040_ps_calibbias_ua[][2] = { > {0, 200000}, > }; > > +static const int vcnl4040_ps_resolutions[2] = { > + 12, > + 16 > +}; > + > static const int vcnl4040_als_persistence[] = {1, 2, 4, 8}; > static const int vcnl4040_ps_persistence[] = {1, 2, 3, 4}; > static const int vcnl4040_ps_oversampling_ratio[] = {1, 2, 4, 8}; > @@ -880,6 +886,54 @@ static ssize_t vcnl4040_write_ps_calibbias(struct vcnl4000_data *data, int val) > return ret; > } > > +static ssize_t vcnl4040_read_ps_resolution(struct vcnl4000_data *data, int *val, int *val2) > +{ > + int ret; > + > + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); The field seems to be in PS_CONF2. So you are reading a word and I guess that gets you two registers. Can we not do a byte read to get just CONF2? > + if (ret < 0) > + return ret; > + > + ret = FIELD_GET(VCNL4040_PS_CONF2_PS_HD, ret); > + if (ret >= ARRAY_SIZE(vcnl4040_ps_resolutions)) > + return -EINVAL; > + > + *val = vcnl4040_ps_resolutions[ret]; > + *val2 = 0; > + > + return ret; > +} > + > +static ssize_t vcnl4040_write_ps_resolution(struct vcnl4000_data *data, int val) > +{ > + unsigned int i; > + int ret; > + u16 regval; > + > + for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_resolutions); i++) { > + if (val == vcnl4040_ps_resolutions[i]) > + break; > + } > + > + if (i >= ARRAY_SIZE(vcnl4040_ps_resolutions)) > + return -EINVAL; > + > + mutex_lock(&data->vcnl4000_lock); > + > + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); > + if (ret < 0) > + goto out_unlock; > + > + regval = (ret & ~VCNL4040_PS_CONF2_PS_HD); > + regval |= FIELD_PREP(VCNL4040_PS_CONF2_PS_HD, i); > + ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, > + regval); > + > +out_unlock: > + mutex_unlock(&data->vcnl4000_lock); > + return ret; > +} c), > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] iio: light: vcnl4000: Add ps high definition for vcnl4040 2023-12-17 14:15 ` Jonathan Cameron @ 2023-12-18 15:19 ` Mårten Lindahl 2023-12-18 16:00 ` Mårten Lindahl 0 siblings, 1 reply; 9+ messages in thread From: Mårten Lindahl @ 2023-12-18 15:19 UTC (permalink / raw) To: Jonathan Cameron; +Cc: Lars-Peter Clausen, linux-iio, linux-kernel, kernel On 12/17/23 15:15, Jonathan Cameron wrote: > On Fri, 15 Dec 2023 13:43:05 +0100 > Mårten Lindahl <marten.lindahl@axis.com> wrote: > >> The vcnl4040 proximity sensor defaults to 12 bit data resolution, but >> the chip also supports 16 bit data resolution, which is called proximity >> high definition (PS_HD). >> >> Add read/write attribute for proximity resolution, and read attribute >> for available proximity resolution values for the vcnl4040 chip. >> >> Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com> Hi Jonathan! > I'll review this on basis the usecase is clear (see reply to cover letter) I'll skip this patch (see reply to cover letter comment) Your are right about the paired register manipulation. Better to read/write byte instead of word. Kind regards Mårten > > The manipulation of the CONF1 and CONF2 registers in a pair is rather odd given you > only want to change one bit here. > > Why is that done? >> --- >> drivers/iio/light/vcnl4000.c | 87 +++++++++++++++++++++++++++++++++++++++++++- >> 1 file changed, 85 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c >> index fdf763a04b0b..2addff635b79 100644 >> --- a/drivers/iio/light/vcnl4000.c >> +++ b/drivers/iio/light/vcnl4000.c >> @@ -90,6 +90,7 @@ >> #define VCNL4040_PS_CONF1_PS_SHUTDOWN BIT(0) >> #define VCNL4040_PS_CONF2_PS_IT GENMASK(3, 1) /* Proximity integration time */ >> #define VCNL4040_CONF1_PS_PERS GENMASK(5, 4) /* Proximity interrupt persistence setting */ >> +#define VCNL4040_PS_CONF2_PS_HD BIT(11) /* Proximity high definition */ >> #define VCNL4040_PS_CONF2_PS_INT GENMASK(9, 8) /* Proximity interrupt mode */ >> #define VCNL4040_PS_CONF3_MPS GENMASK(6, 5) /* Proximity multi pulse number */ >> #define VCNL4040_PS_MS_LED_I GENMASK(10, 8) /* Proximity current */ >> @@ -170,6 +171,11 @@ static const int vcnl4040_ps_calibbias_ua[][2] = { >> {0, 200000}, >> }; >> >> +static const int vcnl4040_ps_resolutions[2] = { >> + 12, >> + 16 >> +}; >> + >> static const int vcnl4040_als_persistence[] = {1, 2, 4, 8}; >> static const int vcnl4040_ps_persistence[] = {1, 2, 3, 4}; >> static const int vcnl4040_ps_oversampling_ratio[] = {1, 2, 4, 8}; >> @@ -880,6 +886,54 @@ static ssize_t vcnl4040_write_ps_calibbias(struct vcnl4000_data *data, int val) >> return ret; >> } >> >> +static ssize_t vcnl4040_read_ps_resolution(struct vcnl4000_data *data, int *val, int *val2) >> +{ >> + int ret; >> + >> + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); > The field seems to be in PS_CONF2. So you are reading a word and I guess that > gets you two registers. Can we not do a byte read to get just CONF2? >> + if (ret < 0) >> + return ret; >> + >> + ret = FIELD_GET(VCNL4040_PS_CONF2_PS_HD, ret); >> + if (ret >= ARRAY_SIZE(vcnl4040_ps_resolutions)) >> + return -EINVAL; >> + >> + *val = vcnl4040_ps_resolutions[ret]; >> + *val2 = 0; >> + >> + return ret; >> +} >> + >> +static ssize_t vcnl4040_write_ps_resolution(struct vcnl4000_data *data, int val) >> +{ >> + unsigned int i; >> + int ret; >> + u16 regval; >> + >> + for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_resolutions); i++) { >> + if (val == vcnl4040_ps_resolutions[i]) >> + break; >> + } >> + >> + if (i >= ARRAY_SIZE(vcnl4040_ps_resolutions)) >> + return -EINVAL; >> + >> + mutex_lock(&data->vcnl4000_lock); >> + >> + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); >> + if (ret < 0) >> + goto out_unlock; >> + >> + regval = (ret & ~VCNL4040_PS_CONF2_PS_HD); >> + regval |= FIELD_PREP(VCNL4040_PS_CONF2_PS_HD, i); >> + ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, >> + regval); >> + >> +out_unlock: >> + mutex_unlock(&data->vcnl4000_lock); >> + return ret; >> +} > c), ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] iio: light: vcnl4000: Add ps high definition for vcnl4040 2023-12-18 15:19 ` Mårten Lindahl @ 2023-12-18 16:00 ` Mårten Lindahl 2023-12-18 18:14 ` Jonathan Cameron 0 siblings, 1 reply; 9+ messages in thread From: Mårten Lindahl @ 2023-12-18 16:00 UTC (permalink / raw) To: Jonathan Cameron; +Cc: linux-iio, Lars-Peter Clausen, kernel, linux-kernel On 12/18/23 16:19, Mårten Lindahl wrote: > On 12/17/23 15:15, Jonathan Cameron wrote: >> On Fri, 15 Dec 2023 13:43:05 +0100 >> Mårten Lindahl <marten.lindahl@axis.com> wrote: >> >>> The vcnl4040 proximity sensor defaults to 12 bit data resolution, but >>> the chip also supports 16 bit data resolution, which is called >>> proximity >>> high definition (PS_HD). >>> >>> Add read/write attribute for proximity resolution, and read attribute >>> for available proximity resolution values for the vcnl4040 chip. >>> >>> Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com> > Hi Jonathan! >> I'll review this on basis the usecase is clear (see reply to cover >> letter) > > I'll skip this patch (see reply to cover letter comment) > > Your are right about the paired register manipulation. Better to > read/write byte instead of word. Hi Jonathan! I now remember why the register is read as a word (CONF1/CONF2). It is addressed as one 16 bit register where CONF1 is the low 8 bit field and CONF2 is the high bit field. It is the same address/code for both: Register PS_CONF1 - COMMAND CODE: 0x03_L (0x03 DATA BYTE LOW) Register PS_CONF2 - COMMAND CODE: 0x03_H (0x03 DATA BYTE HIGH) Where in my case (PS_CONF2->PS_HD[3] is the same as PS_CONF1[11]) Kind regards Mårten > > Kind regards > > Mårten > >> >> The manipulation of the CONF1 and CONF2 registers in a pair is rather >> odd given you >> only want to change one bit here. >> >> Why is that done? >>> --- >>> drivers/iio/light/vcnl4000.c | 87 >>> +++++++++++++++++++++++++++++++++++++++++++- >>> 1 file changed, 85 insertions(+), 2 deletions(-) >>> >>> diff --git a/drivers/iio/light/vcnl4000.c >>> b/drivers/iio/light/vcnl4000.c >>> index fdf763a04b0b..2addff635b79 100644 >>> --- a/drivers/iio/light/vcnl4000.c >>> +++ b/drivers/iio/light/vcnl4000.c >>> @@ -90,6 +90,7 @@ >>> #define VCNL4040_PS_CONF1_PS_SHUTDOWN BIT(0) >>> #define VCNL4040_PS_CONF2_PS_IT GENMASK(3, 1) /* Proximity >>> integration time */ >>> #define VCNL4040_CONF1_PS_PERS GENMASK(5, 4) /* Proximity >>> interrupt persistence setting */ >>> +#define VCNL4040_PS_CONF2_PS_HD BIT(11) /* Proximity high >>> definition */ >>> #define VCNL4040_PS_CONF2_PS_INT GENMASK(9, 8) /* Proximity >>> interrupt mode */ >>> #define VCNL4040_PS_CONF3_MPS GENMASK(6, 5) /* Proximity >>> multi pulse number */ >>> #define VCNL4040_PS_MS_LED_I GENMASK(10, 8) /* Proximity >>> current */ >>> @@ -170,6 +171,11 @@ static const int vcnl4040_ps_calibbias_ua[][2] = { >>> {0, 200000}, >>> }; >>> +static const int vcnl4040_ps_resolutions[2] = { >>> + 12, >>> + 16 >>> +}; >>> + >>> static const int vcnl4040_als_persistence[] = {1, 2, 4, 8}; >>> static const int vcnl4040_ps_persistence[] = {1, 2, 3, 4}; >>> static const int vcnl4040_ps_oversampling_ratio[] = {1, 2, 4, 8}; >>> @@ -880,6 +886,54 @@ static ssize_t >>> vcnl4040_write_ps_calibbias(struct vcnl4000_data *data, int val) >>> return ret; >>> } >>> +static ssize_t vcnl4040_read_ps_resolution(struct vcnl4000_data >>> *data, int *val, int *val2) >>> +{ >>> + int ret; >>> + >>> + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); >> The field seems to be in PS_CONF2. So you are reading a word and I >> guess that >> gets you two registers. Can we not do a byte read to get just CONF2? >>> + if (ret < 0) >>> + return ret; >>> + >>> + ret = FIELD_GET(VCNL4040_PS_CONF2_PS_HD, ret); >>> + if (ret >= ARRAY_SIZE(vcnl4040_ps_resolutions)) >>> + return -EINVAL; >>> + >>> + *val = vcnl4040_ps_resolutions[ret]; >>> + *val2 = 0; >>> + >>> + return ret; >>> +} >>> + >>> +static ssize_t vcnl4040_write_ps_resolution(struct vcnl4000_data >>> *data, int val) >>> +{ >>> + unsigned int i; >>> + int ret; >>> + u16 regval; >>> + >>> + for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_resolutions); i++) { >>> + if (val == vcnl4040_ps_resolutions[i]) >>> + break; >>> + } >>> + >>> + if (i >= ARRAY_SIZE(vcnl4040_ps_resolutions)) >>> + return -EINVAL; >>> + >>> + mutex_lock(&data->vcnl4000_lock); >>> + >>> + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); >>> + if (ret < 0) >>> + goto out_unlock; >>> + >>> + regval = (ret & ~VCNL4040_PS_CONF2_PS_HD); >>> + regval |= FIELD_PREP(VCNL4040_PS_CONF2_PS_HD, i); >>> + ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, >>> + regval); >>> + >>> +out_unlock: >>> + mutex_unlock(&data->vcnl4000_lock); >>> + return ret; >>> +} >> c), ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] iio: light: vcnl4000: Add ps high definition for vcnl4040 2023-12-18 16:00 ` Mårten Lindahl @ 2023-12-18 18:14 ` Jonathan Cameron 0 siblings, 0 replies; 9+ messages in thread From: Jonathan Cameron @ 2023-12-18 18:14 UTC (permalink / raw) To: Mårten Lindahl; +Cc: linux-iio, Lars-Peter Clausen, kernel, linux-kernel On Mon, 18 Dec 2023 17:00:10 +0100 Mårten Lindahl <martenli@axis.com> wrote: > On 12/18/23 16:19, Mårten Lindahl wrote: > > On 12/17/23 15:15, Jonathan Cameron wrote: > >> On Fri, 15 Dec 2023 13:43:05 +0100 > >> Mårten Lindahl <marten.lindahl@axis.com> wrote: > >> > >>> The vcnl4040 proximity sensor defaults to 12 bit data resolution, but > >>> the chip also supports 16 bit data resolution, which is called > >>> proximity > >>> high definition (PS_HD). > >>> > >>> Add read/write attribute for proximity resolution, and read attribute > >>> for available proximity resolution values for the vcnl4040 chip. > >>> > >>> Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com> > > Hi Jonathan! > >> I'll review this on basis the usecase is clear (see reply to cover > >> letter) > > > > I'll skip this patch (see reply to cover letter comment) > > > > Your are right about the paired register manipulation. Better to > > read/write byte instead of word. > > Hi Jonathan! > > I now remember why the register is read as a word (CONF1/CONF2). It is > addressed as one 16 bit register where CONF1 is the low 8 bit field and > CONF2 is the high bit field. It is the same address/code for both: > > Register PS_CONF1 - COMMAND CODE: 0x03_L (0x03 DATA BYTE LOW) > > Register PS_CONF2 - COMMAND CODE: 0x03_H (0x03 DATA BYTE HIGH) > > Where in my case (PS_CONF2->PS_HD[3] is the same as PS_CONF1[11]) Ouch. That's a horrible way to define a register map. Jonathan > > Kind regards > > Mårten > > > > > Kind regards > > > > Mårten > > > >> > >> The manipulation of the CONF1 and CONF2 registers in a pair is rather > >> odd given you > >> only want to change one bit here. > >> > >> Why is that done? > >>> --- > >>> drivers/iio/light/vcnl4000.c | 87 > >>> +++++++++++++++++++++++++++++++++++++++++++- > >>> 1 file changed, 85 insertions(+), 2 deletions(-) > >>> > >>> diff --git a/drivers/iio/light/vcnl4000.c > >>> b/drivers/iio/light/vcnl4000.c > >>> index fdf763a04b0b..2addff635b79 100644 > >>> --- a/drivers/iio/light/vcnl4000.c > >>> +++ b/drivers/iio/light/vcnl4000.c > >>> @@ -90,6 +90,7 @@ > >>> #define VCNL4040_PS_CONF1_PS_SHUTDOWN BIT(0) > >>> #define VCNL4040_PS_CONF2_PS_IT GENMASK(3, 1) /* Proximity > >>> integration time */ > >>> #define VCNL4040_CONF1_PS_PERS GENMASK(5, 4) /* Proximity > >>> interrupt persistence setting */ > >>> +#define VCNL4040_PS_CONF2_PS_HD BIT(11) /* Proximity high > >>> definition */ > >>> #define VCNL4040_PS_CONF2_PS_INT GENMASK(9, 8) /* Proximity > >>> interrupt mode */ > >>> #define VCNL4040_PS_CONF3_MPS GENMASK(6, 5) /* Proximity > >>> multi pulse number */ > >>> #define VCNL4040_PS_MS_LED_I GENMASK(10, 8) /* Proximity > >>> current */ > >>> @@ -170,6 +171,11 @@ static const int vcnl4040_ps_calibbias_ua[][2] = { > >>> {0, 200000}, > >>> }; > >>> +static const int vcnl4040_ps_resolutions[2] = { > >>> + 12, > >>> + 16 > >>> +}; > >>> + > >>> static const int vcnl4040_als_persistence[] = {1, 2, 4, 8}; > >>> static const int vcnl4040_ps_persistence[] = {1, 2, 3, 4}; > >>> static const int vcnl4040_ps_oversampling_ratio[] = {1, 2, 4, 8}; > >>> @@ -880,6 +886,54 @@ static ssize_t > >>> vcnl4040_write_ps_calibbias(struct vcnl4000_data *data, int val) > >>> return ret; > >>> } > >>> +static ssize_t vcnl4040_read_ps_resolution(struct vcnl4000_data > >>> *data, int *val, int *val2) > >>> +{ > >>> + int ret; > >>> + > >>> + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); > >> The field seems to be in PS_CONF2. So you are reading a word and I > >> guess that > >> gets you two registers. Can we not do a byte read to get just CONF2? > >>> + if (ret < 0) > >>> + return ret; > >>> + > >>> + ret = FIELD_GET(VCNL4040_PS_CONF2_PS_HD, ret); > >>> + if (ret >= ARRAY_SIZE(vcnl4040_ps_resolutions)) > >>> + return -EINVAL; > >>> + > >>> + *val = vcnl4040_ps_resolutions[ret]; > >>> + *val2 = 0; > >>> + > >>> + return ret; > >>> +} > >>> + > >>> +static ssize_t vcnl4040_write_ps_resolution(struct vcnl4000_data > >>> *data, int val) > >>> +{ > >>> + unsigned int i; > >>> + int ret; > >>> + u16 regval; > >>> + > >>> + for (i = 0; i < ARRAY_SIZE(vcnl4040_ps_resolutions); i++) { > >>> + if (val == vcnl4040_ps_resolutions[i]) > >>> + break; > >>> + } > >>> + > >>> + if (i >= ARRAY_SIZE(vcnl4040_ps_resolutions)) > >>> + return -EINVAL; > >>> + > >>> + mutex_lock(&data->vcnl4000_lock); > >>> + > >>> + ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1); > >>> + if (ret < 0) > >>> + goto out_unlock; > >>> + > >>> + regval = (ret & ~VCNL4040_PS_CONF2_PS_HD); > >>> + regval |= FIELD_PREP(VCNL4040_PS_CONF2_PS_HD, i); > >>> + ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1, > >>> + regval); > >>> + > >>> +out_unlock: > >>> + mutex_unlock(&data->vcnl4000_lock); > >>> + return ret; > >>> +} > >> c), ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/2] Introduce new iio resolution standard attribute 2023-12-15 12:43 [PATCH 0/2] Introduce new iio resolution standard attribute Mårten Lindahl 2023-12-15 12:43 ` [PATCH 1/2] iio: core: Introduce " Mårten Lindahl 2023-12-15 12:43 ` [PATCH 2/2] iio: light: vcnl4000: Add ps high definition for vcnl4040 Mårten Lindahl @ 2023-12-17 14:10 ` Jonathan Cameron 2023-12-18 15:08 ` Mårten Lindahl 2 siblings, 1 reply; 9+ messages in thread From: Jonathan Cameron @ 2023-12-17 14:10 UTC (permalink / raw) To: Mårten Lindahl; +Cc: Lars-Peter Clausen, linux-iio, linux-kernel, kernel On Fri, 15 Dec 2023 13:43:03 +0100 Mårten Lindahl <marten.lindahl@axis.com> wrote: > This patch introduces a new IIO standard attribute to set the bit > resolution of the data *_raw readings dynamically using sysfs. > > The VCNL4040/4200 proximity/ambient light sensors support 12-bit > (default) and 16-bit ADC resolutions. This can be dynamically changed, > so to support this with the standard iio channel configuration a new iio > attribute should be added. > > The VCNL4040 devices will use this for setting proximity high definition > (16-bit resolution). > > Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com> Hi Mårten, What is the use case? We've had lots of devices capable of doing this sort of resolution change, but never yet come up with a reason to do so for the sysfs interfaces on the basis the overhead of the sysfs interfaces is high enough the best bet is almost always to use the highest available resolution and don't worry that the read takes a little longer. Jonathan > --- > Mårten Lindahl (2): > iio: core: Introduce resolution standard attribute > iio: light: vcnl4000: Add ps high definition for vcnl4040 > > drivers/iio/industrialio-core.c | 1 + > drivers/iio/light/vcnl4000.c | 87 ++++++++++++++++++++++++++++++++++++++++- > include/linux/iio/types.h | 1 + > 3 files changed, 87 insertions(+), 2 deletions(-) > --- > base-commit: a39b6ac3781d46ba18193c9dbb2110f31e9bffe9 > change-id: 20231212-vcnl4000-ps-hd-38d42abf9095 > > Best regards, ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/2] Introduce new iio resolution standard attribute 2023-12-17 14:10 ` [PATCH 0/2] Introduce new iio resolution standard attribute Jonathan Cameron @ 2023-12-18 15:08 ` Mårten Lindahl 0 siblings, 0 replies; 9+ messages in thread From: Mårten Lindahl @ 2023-12-18 15:08 UTC (permalink / raw) To: Jonathan Cameron; +Cc: Lars-Peter Clausen, linux-iio, linux-kernel, kernel On 12/17/23 15:10, Jonathan Cameron wrote: > On Fri, 15 Dec 2023 13:43:03 +0100 > Mårten Lindahl <marten.lindahl@axis.com> wrote: > >> This patch introduces a new IIO standard attribute to set the bit >> resolution of the data *_raw readings dynamically using sysfs. >> >> The VCNL4040/4200 proximity/ambient light sensors support 12-bit >> (default) and 16-bit ADC resolutions. This can be dynamically changed, >> so to support this with the standard iio channel configuration a new iio >> attribute should be added. >> >> The VCNL4040 devices will use this for setting proximity high definition >> (16-bit resolution). >> >> Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com> > Hi Mårten, > > What is the use case? We've had lots of devices capable of doing this > sort of resolution change, but never yet come up with a reason to do so for > the sysfs interfaces on the basis the overhead of the sysfs interfaces is > high enough the best bet is almost always to use the highest available resolution > and don't worry that the read takes a little longer. > > Jonathan Hi Jonathan! My use case probably does not differ from others, in that 12 bits does not give enough precision. So it's just a dynamic feature that the sensor has, but as you suggest to hard code this to the highest works fine for me. I just didn't feel confident enough to do that :) I'll make a single patch for this change instead. Thanks! Kind regards Mårten > >> --- >> Mårten Lindahl (2): >> iio: core: Introduce resolution standard attribute >> iio: light: vcnl4000: Add ps high definition for vcnl4040 >> >> drivers/iio/industrialio-core.c | 1 + >> drivers/iio/light/vcnl4000.c | 87 ++++++++++++++++++++++++++++++++++++++++- >> include/linux/iio/types.h | 1 + >> 3 files changed, 87 insertions(+), 2 deletions(-) >> --- >> base-commit: a39b6ac3781d46ba18193c9dbb2110f31e9bffe9 >> change-id: 20231212-vcnl4000-ps-hd-38d42abf9095 >> >> Best regards, ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2023-12-18 18:14 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-12-15 12:43 [PATCH 0/2] Introduce new iio resolution standard attribute Mårten Lindahl 2023-12-15 12:43 ` [PATCH 1/2] iio: core: Introduce " Mårten Lindahl 2023-12-15 12:43 ` [PATCH 2/2] iio: light: vcnl4000: Add ps high definition for vcnl4040 Mårten Lindahl 2023-12-17 14:15 ` Jonathan Cameron 2023-12-18 15:19 ` Mårten Lindahl 2023-12-18 16:00 ` Mårten Lindahl 2023-12-18 18:14 ` Jonathan Cameron 2023-12-17 14:10 ` [PATCH 0/2] Introduce new iio resolution standard attribute Jonathan Cameron 2023-12-18 15:08 ` Mårten Lindahl
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox