dt-bindings: iio: adc: ti,ads1015: Add missing ADS1115 compatible string
Subsystems (2)
PATCH v4 1/10 dt-bindings: iio: adc: ti,ads1015: Add missing ADS1115 compatible string
Add missing ti,ads1115 compatible string. This compatible string is supported by the Linux kernel driver and the ads1015 is a 12bit ADC while ads1115 is 16bit ADC. Add the missing compatible string.
---
V2: Add AB from Krzysztof
V3: No change
V4: No change
--- Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml +4 -2
@@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/iio/adc/ti,ads1015.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: TI ADS1015 4 channel I2C analog to digital converter +title: TI ADS1015/ADS1115 4 channel I2C analog to digital converter maintainers: - Daniel Baluta <[email protected]>
@@ -15,7 +15,9 @@ description: | properties: compatible: - const: ti,ads1015 + enum: + - ti,ads1015 + - ti,ads1115 reg: maxItems: 1
Signature · 1 line
2.35.1
PATCH v4 2/10 dt-bindings: iio: adc: ti,ads1015: Add TLA2024 compatible string
Add ti,tla2024 compatible string. This device is compatible with ADS1015 except it has no on-chip comparator.
---
V2: Add AB from Krzysztof
V3: No change
V4: No change
--- Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml +1 -0
@@ -18,6 +18,7 @@ properties: enum: - ti,ads1015 - ti,ads1115 + - ti,tla2024 reg: maxItems: 1
Signature · 1 line
2.35.1
PATCH v4 3/10 iio: adc: ti-ads1015: Switch to static const writeable ranges table
In reply to Marek VasutSwitch the driver from code implementing test whether a regmap register is writeable to static const tables describing the test. No functional change.
---
V2: No change
V3: No change
V4: No change
--- drivers/iio/adc/ti-ads1015.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-)
drivers/iio/adc/ti-ads1015.c +9 -12
@@ -273,23 +273,20 @@ static void ads1015_event_channel_disable(struct ads1015_data *data, int chan) data->event_channel =ADS1015_CHANNELS ; } -static bool ads1015_is_writeable_reg (struct device *dev,unsigned int reg) -{ -switch (reg) { -case ADS1015_CFG_REG : -case ADS1015_LO_THRESH_REG : -case ADS1015_HI_THRESH_REG : -return true; -default : -return false; - } -} +static const struct regmap_range ads1015_writeable_ranges[] = { +regmap_reg_range (ADS1015_CFG_REG ,ADS1015_HI_THRESH_REG ), +}; + +static const struct regmap_access_table ads1015_writeable_table = { + .yes_ranges = ads1015_writeable_ranges, + .n_yes_ranges =ARRAY_SIZE (ads1015_writeable_ranges), +};static const struct regmap_config ads1015_regmap_config = { .reg_bits =8 , .val_bits =16 , .max_register =ADS1015_HI_THRESH_REG , - .writeable_reg = ads1015_is_writeable_reg, + .wr_table = &ads1015_writeable_table, };static const struct iio_chan_spec ads1015_channels[] = {
Signature · 1 line
2.35.1
PATCH v4 4/10 iio: adc: ti-ads1015: Deduplicate channel macros
In reply to Marek VasutThese macros differ only in the number of valid bits of each ADC sample and the shift of those bits, i.e. ADS1015 is 12bit ADC shifted by 4 left, ADS1115 is 16bit ADC shifted by 0. No functional change.
---
V2: No change
V3: No change
V4: No change
--- drivers/iio/adc/ti-ads1015.c | 86 +++++++++--------------------------- 1 file changed, 22 insertions(+), 64 deletions(-)
drivers/iio/adc/ti-ads1015.c +22 -64
@@ -134,7 +134,7 @@ static const struct iio_event_spec ads1015_events[] = { }, }; -#define ADS1015_V_CHAN (_chan, _addr) { \ +#define ADS1015_V_CHAN (_chan, _addr, _realbits, _shift) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .address = _addr, \
@@ -145,9 +145,9 @@ static const struct iio_event_spec ads1015_events[] = { .scan_index = _addr, \ .scan_type = { \ .sign = 's', \ - .realbits = 12, \ + .realbits = (_realbits), \ .storagebits = 16, \ - .shift = 4, \ + .shift = (_shift), \ .endianness = IIO_CPU, \ }, \ .event_spec = ads1015_events, \
@@ -155,7 +155,7 @@ static const struct iio_event_spec ads1015_events[] = { .datasheet_name = "AIN"#_chan, \ } -#define ADS1015_V_DIFF_CHAN (_chan, _chan2, _addr) { \ +#define ADS1015_V_DIFF_CHAN (_chan, _chan2, _addr, _realbits, _shift) { \ .type = IIO_VOLTAGE, \ .differential = 1, \ .indexed = 1, \
@@ -168,51 +168,9 @@ static const struct iio_event_spec ads1015_events[] = { .scan_index = _addr, \ .scan_type = { \ .sign = 's', \ - .realbits = 12, \ - .storagebits = 16, \ - .shift = 4, \ - .endianness = IIO_CPU, \ - }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ - .datasheet_name = "AIN"#_chan"-AIN"#_chan2, \ -} - -#define ADS1115_V_CHAN (_chan, _addr) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .address = _addr, \ - .channel = _chan, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ - BIT(IIO_CHAN_INFO_SCALE) | \ - BIT(IIO_CHAN_INFO_SAMP_FREQ), \ - .scan_index = _addr, \ - .scan_type = { \ - .sign = 's', \ - .realbits = 16, \ - .storagebits = 16, \ - .endianness = IIO_CPU, \ - }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ - .datasheet_name = "AIN"#_chan, \ -} - -#define ADS1115_V_DIFF_CHAN (_chan, _chan2, _addr) { \ - .type = IIO_VOLTAGE, \ - .differential = 1, \ - .indexed = 1, \ - .address = _addr, \ - .channel = _chan, \ - .channel2 = _chan2, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ - BIT(IIO_CHAN_INFO_SCALE) | \ - BIT(IIO_CHAN_INFO_SAMP_FREQ), \ - .scan_index = _addr, \ - .scan_type = { \ - .sign = 's', \ - .realbits = 16, \ + .realbits = (_realbits), \ .storagebits = 16, \ + .shift = (_shift), \ .endianness = IIO_CPU, \ }, \ .event_spec = ads1015_events, \
@@ -290,26 +248,26 @@ static const struct regmap_config ads1015_regmap_config = { };static const struct iio_chan_spec ads1015_channels[] = { -ADS1015_V_DIFF_CHAN (0 ,1 ,ADS1015_AIN0_AIN1 ), -ADS1015_V_DIFF_CHAN (0 ,3 ,ADS1015_AIN0_AIN3 ), -ADS1015_V_DIFF_CHAN (1 ,3 ,ADS1015_AIN1_AIN3 ), -ADS1015_V_DIFF_CHAN (2 ,3 ,ADS1015_AIN2_AIN3 ), -ADS1015_V_CHAN (0 ,ADS1015_AIN0 ), -ADS1015_V_CHAN (1 ,ADS1015_AIN1 ), -ADS1015_V_CHAN (2 ,ADS1015_AIN2 ), -ADS1015_V_CHAN (3 ,ADS1015_AIN3 ), +ADS1015_V_DIFF_CHAN (0 ,1 ,ADS1015_AIN0_AIN1 ,12 ,4 ), +ADS1015_V_DIFF_CHAN (0 ,3 ,ADS1015_AIN0_AIN3 ,12 ,4 ), +ADS1015_V_DIFF_CHAN (1 ,3 ,ADS1015_AIN1_AIN3 ,12 ,4 ), +ADS1015_V_DIFF_CHAN (2 ,3 ,ADS1015_AIN2_AIN3 ,12 ,4 ), +ADS1015_V_CHAN (0 ,ADS1015_AIN0 ,12 ,4 ), +ADS1015_V_CHAN (1 ,ADS1015_AIN1 ,12 ,4 ), +ADS1015_V_CHAN (2 ,ADS1015_AIN2 ,12 ,4 ), +ADS1015_V_CHAN (3 ,ADS1015_AIN3 ,12 ,4 ),IIO_CHAN_SOFT_TIMESTAMP (ADS1015_TIMESTAMP ), };static const struct iio_chan_spec ads1115_channels[] = { -ADS1115_V_DIFF_CHAN (0 ,1 ,ADS1015_AIN0_AIN1 ), -ADS1115_V_DIFF_CHAN (0 ,3 ,ADS1015_AIN0_AIN3 ), -ADS1115_V_DIFF_CHAN (1 ,3 ,ADS1015_AIN1_AIN3 ), -ADS1115_V_DIFF_CHAN (2 ,3 ,ADS1015_AIN2_AIN3 ), -ADS1115_V_CHAN (0 ,ADS1015_AIN0 ), -ADS1115_V_CHAN (1 ,ADS1015_AIN1 ), -ADS1115_V_CHAN (2 ,ADS1015_AIN2 ), -ADS1115_V_CHAN (3 ,ADS1015_AIN3 ), +ADS1015_V_DIFF_CHAN (0 ,1 ,ADS1015_AIN0_AIN1 ,16 ,0 ), +ADS1015_V_DIFF_CHAN (0 ,3 ,ADS1015_AIN0_AIN3 ,16 ,0 ), +ADS1015_V_DIFF_CHAN (1 ,3 ,ADS1015_AIN1_AIN3 ,16 ,0 ), +ADS1015_V_DIFF_CHAN (2 ,3 ,ADS1015_AIN2_AIN3 ,16 ,0 ), +ADS1015_V_CHAN (0 ,ADS1015_AIN0 ,16 ,0 ), +ADS1015_V_CHAN (1 ,ADS1015_AIN1 ,16 ,0 ), +ADS1015_V_CHAN (2 ,ADS1015_AIN2 ,16 ,0 ), +ADS1015_V_CHAN (3 ,ADS1015_AIN3 ,16 ,0 ),IIO_CHAN_SOFT_TIMESTAMP (ADS1015_TIMESTAMP ), };
Signature · 1 line
2.35.1
PATCH v4 5/10 iio: adc: ti-ads1015: Make channel event_spec optional
In reply to Marek VasutPass event_spec and num_event_specs to ADS1015_V_CHAN and ADS1015_V_DIFF_CHAN macros, to make it possible to pass no event_spec at all for chips which have no comparator and thus no events. No functional change.
---
V2: No change
V3: No change
V4: No change
--- drivers/iio/adc/ti-ads1015.c | 60 +++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 22 deletions(-)
drivers/iio/adc/ti-ads1015.c +38 -22
@@ -134,7 +134,7 @@ static const struct iio_event_spec ads1015_events[] = { }, }; -#define ADS1015_V_CHAN (_chan, _addr, _realbits, _shift) { \ +#define ADS1015_V_CHAN (_chan, _addr, _realbits, _shift, _event_spec, _num_event_specs) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .address = _addr, \
@@ -150,12 +150,12 @@ static const struct iio_event_spec ads1015_events[] = { .shift = (_shift), \ .endianness = IIO_CPU, \ }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ + .event_spec = (_event_spec), \ + .num_event_specs = (_num_event_specs), \ .datasheet_name = "AIN"#_chan, \ } -#define ADS1015_V_DIFF_CHAN (_chan, _chan2, _addr, _realbits, _shift) { \ +#define ADS1015_V_DIFF_CHAN (_chan, _chan2, _addr, _realbits, _shift, _event_spec, _num_event_specs) { \ .type = IIO_VOLTAGE, \ .differential = 1, \ .indexed = 1, \
@@ -173,8 +173,8 @@ static const struct iio_event_spec ads1015_events[] = { .shift = (_shift), \ .endianness = IIO_CPU, \ }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ + .event_spec = (_event_spec), \ + .num_event_specs = (_num_event_specs), \ .datasheet_name = "AIN"#_chan"-AIN"#_chan2, \ }
@@ -248,26 +248,42 @@ static const struct regmap_config ads1015_regmap_config = { };static const struct iio_chan_spec ads1015_channels[] = { -ADS1015_V_DIFF_CHAN (0 ,1 ,ADS1015_AIN0_AIN1 ,12 ,4 ), -ADS1015_V_DIFF_CHAN (0 ,3 ,ADS1015_AIN0_AIN3 ,12 ,4 ), -ADS1015_V_DIFF_CHAN (1 ,3 ,ADS1015_AIN1_AIN3 ,12 ,4 ), -ADS1015_V_DIFF_CHAN (2 ,3 ,ADS1015_AIN2_AIN3 ,12 ,4 ), -ADS1015_V_CHAN (0 ,ADS1015_AIN0 ,12 ,4 ), -ADS1015_V_CHAN (1 ,ADS1015_AIN1 ,12 ,4 ), -ADS1015_V_CHAN (2 ,ADS1015_AIN2 ,12 ,4 ), -ADS1015_V_CHAN (3 ,ADS1015_AIN3 ,12 ,4 ), +ADS1015_V_DIFF_CHAN (0 ,1 ,ADS1015_AIN0_AIN1 ,12 ,4 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_DIFF_CHAN (0 ,3 ,ADS1015_AIN0_AIN3 ,12 ,4 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_DIFF_CHAN (1 ,3 ,ADS1015_AIN1_AIN3 ,12 ,4 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_DIFF_CHAN (2 ,3 ,ADS1015_AIN2_AIN3 ,12 ,4 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_CHAN (0 ,ADS1015_AIN0 ,12 ,4 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_CHAN (1 ,ADS1015_AIN1 ,12 ,4 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_CHAN (2 ,ADS1015_AIN2 ,12 ,4 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_CHAN (3 ,ADS1015_AIN3 ,12 ,4 , + ads1015_events,ARRAY_SIZE (ads1015_events)),IIO_CHAN_SOFT_TIMESTAMP (ADS1015_TIMESTAMP ), };static const struct iio_chan_spec ads1115_channels[] = { -ADS1015_V_DIFF_CHAN (0 ,1 ,ADS1015_AIN0_AIN1 ,16 ,0 ), -ADS1015_V_DIFF_CHAN (0 ,3 ,ADS1015_AIN0_AIN3 ,16 ,0 ), -ADS1015_V_DIFF_CHAN (1 ,3 ,ADS1015_AIN1_AIN3 ,16 ,0 ), -ADS1015_V_DIFF_CHAN (2 ,3 ,ADS1015_AIN2_AIN3 ,16 ,0 ), -ADS1015_V_CHAN (0 ,ADS1015_AIN0 ,16 ,0 ), -ADS1015_V_CHAN (1 ,ADS1015_AIN1 ,16 ,0 ), -ADS1015_V_CHAN (2 ,ADS1015_AIN2 ,16 ,0 ), -ADS1015_V_CHAN (3 ,ADS1015_AIN3 ,16 ,0 ), +ADS1015_V_DIFF_CHAN (0 ,1 ,ADS1015_AIN0_AIN1 ,16 ,0 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_DIFF_CHAN (0 ,3 ,ADS1015_AIN0_AIN3 ,16 ,0 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_DIFF_CHAN (1 ,3 ,ADS1015_AIN1_AIN3 ,16 ,0 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_DIFF_CHAN (2 ,3 ,ADS1015_AIN2_AIN3 ,16 ,0 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_CHAN (0 ,ADS1015_AIN0 ,16 ,0 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_CHAN (1 ,ADS1015_AIN1 ,16 ,0 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_CHAN (2 ,ADS1015_AIN2 ,16 ,0 , + ads1015_events,ARRAY_SIZE (ads1015_events)), +ADS1015_V_CHAN (3 ,ADS1015_AIN3 ,16 ,0 , + ads1015_events,ARRAY_SIZE (ads1015_events)),IIO_CHAN_SOFT_TIMESTAMP (ADS1015_TIMESTAMP ), };
Signature · 1 line
2.35.1
PATCH v4 6/10 iio: adc: ti-ads1015: Add TLA2024 support
In reply to Marek VasutAdd support for TI TLA2024 ADC. This chip is compatible with ADS1015 except it has no comparator in it, hence the comparator configuration bits are missing in Configuration Register and the Hi_Thresh/Lo_Thresh registers are missing as well and so is event support.
---
V2: No change
V3: Use ADS1015 attr group, that's the correct one for this part
V4: No change
--- drivers/iio/adc/ti-ads1015.c | 53 ++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-)
drivers/iio/adc/ti-ads1015.c +51 -2
@@ -80,6 +80,7 @@ enum chip_ids {ADSXXXX =0 ,ADS1015 ,ADS1115 , + TLA2024, }; enum ads1015_channels {
@@ -247,6 +248,22 @@ static const struct regmap_config ads1015_regmap_config = { .wr_table = &ads1015_writeable_table, }; +static const struct regmap_range tla2024_writeable_ranges[] = { +regmap_reg_range (ADS1015_CFG_REG ,ADS1015_CFG_REG ), +}; + +static const struct regmap_access_table tla2024_writeable_table = { + .yes_ranges = tla2024_writeable_ranges, + .n_yes_ranges =ARRAY_SIZE (tla2024_writeable_ranges), +}; + +static const struct regmap_config tla2024_regmap_config = { + .reg_bits =8 , + .val_bits =16 , + .max_register =ADS1015_CFG_REG , + .wr_table = &tla2024_writeable_table, +}; +static const struct iio_chan_spec ads1015_channels[] = {ADS1015_V_DIFF_CHAN (0 ,1 ,ADS1015_AIN0_AIN1 ,12 ,4 , ads1015_events,ARRAY_SIZE (ads1015_events)),
@@ -287,6 +304,19 @@ static const struct iio_chan_spec ads1115_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP), }; +static const struct iio_chan_spec tla2024_channels[] = { +ADS1015_V_DIFF_CHAN (0 ,1 ,ADS1015_AIN0_AIN1 ,12 ,4 ,NULL ,0 ), +ADS1015_V_DIFF_CHAN (0 ,3 ,ADS1015_AIN0_AIN3 ,12 ,4 ,NULL ,0 ), +ADS1015_V_DIFF_CHAN (1 ,3 ,ADS1015_AIN1_AIN3 ,12 ,4 ,NULL ,0 ), +ADS1015_V_DIFF_CHAN (2 ,3 ,ADS1015_AIN2_AIN3 ,12 ,4 ,NULL ,0 ), +ADS1015_V_CHAN (0 ,ADS1015_AIN0 ,12 ,4 ,NULL ,0 ), +ADS1015_V_CHAN (1 ,ADS1015_AIN1 ,12 ,4 ,NULL ,0 ), +ADS1015_V_CHAN (2 ,ADS1015_AIN2 ,12 ,4 ,NULL ,0 ), +ADS1015_V_CHAN (3 ,ADS1015_AIN3 ,12 ,4 ,NULL ,0 ), +IIO_CHAN_SOFT_TIMESTAMP (ADS1015_TIMESTAMP ), +}; + +#ifdef CONFIG_PM static int ads1015_set_power_state (struct ads1015_data *data,bool on) {
@@ -823,6 +853,12 @@ static const struct iio_info ads1115_info = { .attrs = &ads1115_attribute_group, }; +static const struct iio_info tla2024_info = { + .read_raw = ads1015_read_raw, + .write_raw = ads1015_write_raw, + .attrs = &ads1015_attribute_group, +}; +static int ads1015_client_get_channels_config (struct i2c_client *client) {struct iio_dev *indio_dev =i2c_get_clientdata (client);
@@ -937,6 +973,12 @@ static int ads1015_probe(struct i2c_client *client, indio_dev->info = &ads1115_info; data->data_rate = (unsigned int *) &ads1115_data_rate;break ; +case TLA2024 : + indio_dev->channels = tla2024_channels; + indio_dev->num_channels =ARRAY_SIZE (tla2024_channels); + indio_dev->info = &tla2024_info; + data->data_rate = (unsigned int *) &ads1015_data_rate; +break ;default :dev_err (&client->dev,"Unknown chip %d\n" , chip);return -EINVAL ;
@@ -957,7 +999,9 @@ static int ads1015_probe(struct i2c_client *client,/* we need to keep this ABI the same as used by hwmon ADS1015 driver */ ads1015_get_channels_config (client); - data->regmap =devm_regmap_init_i2c (client, &ads1015_regmap_config); + data->regmap =devm_regmap_init_i2c (client, (chip ==TLA2024 ) ? + &tla2024_regmap_config : + &ads1015_regmap_config);if (IS_ERR (data->regmap)) {dev_err (&client->dev,"Failed to allocate register map\n" );return PTR_ERR (data->regmap);
@@ -971,7 +1015,7 @@ static int ads1015_probe(struct i2c_client *client,return ret; } -if (client->irq) { +if (client->irq && chip !=TLA2024 ) {unsigned long irq_trig =irqd_get_trigger_type (irq_get_irq_data (client->irq)); unsigned int cfg_comp_mask = ADS1015_CFG_COMP_QUE_MASK |
@@ -1073,6 +1117,7 @@ static const struct dev_pm_ops ads1015_pm_ops = {static const struct i2c_device_id ads1015_id[] = { {"ads1015" ,ADS1015 }, {"ads1115" ,ADS1115 }, + {"tla2024" ,TLA2024 }, {} };MODULE_DEVICE_TABLE (i2c, ads1015_id);
@@ -1086,6 +1131,10 @@ static const struct of_device_id ads1015_of_match[] = { .compatible = "ti,ads1115", .data = (void *)ADS1115 }, + { + .compatible = "ti,tla2024", + .data = (void *)TLA2024 + }, {} };MODULE_DEVICE_TABLE (of, ads1015_of_match);
Signature · 1 line
2.35.1
PATCH v4 7/10 iio: adc: ti-ads1015: Add static assert to test if shifted realbits fit into storagebits
In reply to Marek VasutAdd compile-time static_assert wrapper to verify that shifted realbits fit into storagebits. The macro is implemented in a more generic way so it can be used to verify other values if required.
---
V2: New patch
V3: No change
V4: No change
--- drivers/iio/adc/ti-ads1015.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)
drivers/iio/adc/ti-ads1015.c +24 -2
@@ -135,6 +135,28 @@ static const struct iio_event_spec ads1015_events[] = { }, }; +/* +* Compile-time check whether _fitbits can accommodate up to _testbits +* bits. Returns _fitbits on success, fails to compile otherwise. +* +* The test works such that it multiplies constant _fitbits by constant +* double-negation of size of a non-empty structure, i.e. it multiplies +* constant _fitbits by constant 1 in each successful compilation case. +* The non-empty structure may contain C11 _Static_assert(), make use of +* this and place the kernel variant of static assert in there, so that +* it performs the compile-time check for _testbits <= _fitbits. Note +* that it is not possible to directly use static_assert in compound +* statements, hence this convoluted construct. +*/ +#define FIT_CHECK (_testbits, _fitbits) \ + ( \ + (_fitbits) * \ + !!sizeof(struct { \ + static_assert((_testbits) <= (_fitbits)); \ + int pad; \ + }) \ + ) +#define ADS1015_V_CHAN (_chan, _addr, _realbits, _shift, _event_spec, _num_event_specs) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \
@@ -147,7 +169,7 @@ static const struct iio_event_spec ads1015_events[] = { .scan_type = { \ .sign = 's', \ .realbits = (_realbits), \ - .storagebits = 16, \ + .storagebits = FIT_CHECK((_realbits) + (_shift), 16), \ .shift = (_shift), \ .endianness = IIO_CPU, \ }, \
@@ -170,7 +192,7 @@ static const struct iio_event_spec ads1015_events[] = { .scan_type = { \ .sign = 's', \ .realbits = (_realbits), \ - .storagebits = 16, \ + .storagebits = FIT_CHECK((_realbits) + (_shift), 16), \ .shift = (_shift), \ .endianness = IIO_CPU, \ }, \
Signature · 1 line
2.35.1
PATCH v4 8/10 iio: adc: ti-ads1015: Convert to OF match data
In reply to Marek VasutReplace chip type enumeration in match data with pointer to static constant structure which contains all the different chip properties in one place, and then replace handling of chip type in probe() with simple copy of fields in the new match data structure into struct iio_dev.
This reduces code and increases static data.
---
V3: New patch
V4: - Fix contains typo in commit message
- Drop redundant cast of device_get_match_data()
- Return dev_err_probe() if no valid chip data found
--- drivers/iio/adc/ti-ads1015.c | 106 +++++++++++++++++------------------ 1 file changed, 53 insertions(+), 53 deletions(-)
drivers/iio/adc/ti-ads1015.c +53 -53
@@ -76,11 +76,12 @@#define ADS1015_DEFAULT_DATA_RATE 4#define ADS1015_DEFAULT_CHAN 0 -enum chip_ids { -ADSXXXX =0 , -ADS1015 , -ADS1115 , -TLA2024 , +struct ads1015_chip_data { +struct iio_chan_spec const *channels; +int num_channels; +const struct iio_info *info; +const unsigned int *data_rate; +bool has_comparator; };enum ads1015_channels {
@@ -226,7 +227,7 @@ struct ads1015_data {unsigned int comp_mode;struct ads1015_thresh_data thresh_data[ADS1015_CHANNELS ]; -unsigned int *data_rate; +const unsigned int *data_rate;/* * Set to true when the ADC is switched to the continuous-conversion * mode and exits from a power-down state. This flag is used to avoid
@@ -961,12 +962,18 @@ static int ads1015_set_conv_mode(struct ads1015_data *data, int mode)static int ads1015_probe (struct i2c_client *client,const struct i2c_device_id *id) { +const struct ads1015_chip_data *chip;struct iio_dev *indio_dev;struct ads1015_data *data;int ret; -enum chip_ids chip;int i; + chip =device_get_match_data (&client->dev); +if (!chip) + chip = (const struct ads1015_chip_data *)id->driver_data; +if (!chip) +return dev_err_probe (&client->dev, -EINVAL ,"Unknown chip\n" ); + indio_dev =devm_iio_device_alloc (&client->dev,sizeof (*data));if (!indio_dev)return -ENOMEM ;
@@ -979,34 +986,12 @@ static int ads1015_probe(struct i2c_client *client, indio_dev->name =ADS1015_DRV_NAME ; indio_dev->modes =INDIO_DIRECT_MODE ; - chip = (uintptr_t )device_get_match_data (&client->dev); -if (chip ==ADSXXXX ) - chip = id->driver_data; -switch (chip) { -case ADS1015 : - indio_dev->channels = ads1015_channels; - indio_dev->num_channels =ARRAY_SIZE (ads1015_channels); - indio_dev->info = &ads1015_info; - data->data_rate = (unsigned int *) &ads1015_data_rate; -break ; -case ADS1115 : - indio_dev->channels = ads1115_channels; - indio_dev->num_channels =ARRAY_SIZE (ads1115_channels); - indio_dev->info = &ads1115_info; - data->data_rate = (unsigned int *) &ads1115_data_rate; -break ; -case TLA2024 : - indio_dev->channels = tla2024_channels; - indio_dev->num_channels =ARRAY_SIZE (tla2024_channels); - indio_dev->info = &tla2024_info; - data->data_rate = (unsigned int *) &ads1015_data_rate; -break ; -default : -dev_err (&client->dev,"Unknown chip %d\n" , chip); -return -EINVAL ; - } - + indio_dev->channels = chip->channels; + indio_dev->num_channels = chip->num_channels; + indio_dev->info = chip->info; + data->data_rate = chip->data_rate; data->event_channel =ADS1015_CHANNELS ; +/* * Set default lower and upper threshold to min and max value * respectively.
@@ -1021,9 +1006,9 @@ static int ads1015_probe(struct i2c_client *client,/* we need to keep this ABI the same as used by hwmon ADS1015 driver */ ads1015_get_channels_config (client); - data->regmap =devm_regmap_init_i2c (client, (chip ==TLA2024 ) ? - &tla2024_regmap_config : - &ads1015_regmap_config); + data->regmap =devm_regmap_init_i2c (client, chip->has_comparator ? + &ads1015_regmap_config : + &tla2024_regmap_config);if (IS_ERR (data->regmap)) {dev_err (&client->dev,"Failed to allocate register map\n" );return PTR_ERR (data->regmap);
@@ -1037,7 +1022,7 @@ static int ads1015_probe(struct i2c_client *client,return ret; } -if (client->irq && chip !=TLA2024 ) { +if (client->irq && chip->has_comparator) {unsigned long irq_trig =irqd_get_trigger_type (irq_get_irq_data (client->irq)); unsigned int cfg_comp_mask = ADS1015_CFG_COMP_QUE_MASK |
@@ -1136,27 +1121,42 @@ static const struct dev_pm_ops ads1015_pm_ops = { ads1015_runtime_resume, NULL) }; +static const struct ads1015_chip_data ads1015_data = { + .channels = ads1015_channels, + .num_channels =ARRAY_SIZE (ads1015_channels), + .info = &ads1015_info, + .data_rate = ads1015_data_rate, + .has_comparator = true, +}; + +static const struct ads1015_chip_data ads1115_data = { + .channels = ads1115_channels, + .num_channels =ARRAY_SIZE (ads1115_channels), + .info = &ads1115_info, + .data_rate = ads1115_data_rate, + .has_comparator = true, +}; + +static const struct ads1015_chip_data tla2024_data = { + .channels = tla2024_channels, + .num_channels =ARRAY_SIZE (tla2024_channels), + .info = &tla2024_info, + .data_rate = ads1015_data_rate, + .has_comparator = false, +}; +static const struct i2c_device_id ads1015_id[] = { - {"ads1015" ,ADS1015 }, - {"ads1115" ,ADS1115 }, - {"tla2024" ,TLA2024 }, + {"ads1015" , (kernel_ulong_t)&ads1015_data }, + {"ads1115" , (kernel_ulong_t)&ads1115_data }, + {"tla2024" , (kernel_ulong_t)&tla2024_data }, {} };MODULE_DEVICE_TABLE (i2c, ads1015_id);static const struct of_device_id ads1015_of_match[] = { - { - .compatible ="ti,ads1015" , - .data = (void *)ADS1015 - }, - { - .compatible ="ti,ads1115" , - .data = (void *)ADS1115 - }, - { - .compatible ="ti,tla2024" , - .data = (void *)TLA2024 - }, + { .compatible ="ti,ads1015" , .data = &ads1015_data }, + { .compatible ="ti,ads1115" , .data = &ads1115_data }, + { .compatible ="ti,tla2024" , .data = &tla2024_data }, {} };MODULE_DEVICE_TABLE (of, ads1015_of_match);
Signature · 1 line
2.35.1
PATCH v4 9/10 iio: adc: ti-ads1015: Replace data_rate with chip data struct ads1015_data
In reply to Marek VasutInstead of storing only data_rate in private data, store pointer to the whole chip data and use the data_rate from chip data throughout the driver. No functional change. This is done in preparation for switching to read_avail().
---
V3: New patch
V4: Use switching in commit message
--- drivers/iio/adc/ti-ads1015.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/iio/adc/ti-ads1015.c +10 -8
@@ -227,7 +227,7 @@ struct ads1015_data {unsigned int comp_mode;struct ads1015_thresh_data thresh_data[ADS1015_CHANNELS ]; -const unsigned int *data_rate; +const struct ads1015_chip_data *chip;/* * Set to true when the ADC is switched to the continuous-conversion * mode and exits from a power-down state. This flag is used to avoid
@@ -368,6 +368,7 @@ static int ads1015_set_power_state(struct ads1015_data *data, bool on)static int ads1015_get_adc_result (struct ads1015_data *data,int chan,int *val) { +const unsigned int *data_rate = data->chip->data_rate;int ret, pga, dr, dr_old, conv_time;unsigned int old, mask, cfg;
@@ -402,8 +403,8 @@ int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val) }if (data->conv_invalid) { dr_old = (old &ADS1015_CFG_DR_MASK ) >>ADS1015_CFG_DR_SHIFT ; - conv_time =DIV_ROUND_UP (USEC_PER_SEC , data->data_rate[dr_old]); - conv_time +=DIV_ROUND_UP (USEC_PER_SEC , data->data_rate[dr]); + conv_time =DIV_ROUND_UP (USEC_PER_SEC , data_rate[dr_old]); + conv_time +=DIV_ROUND_UP (USEC_PER_SEC , data_rate[dr]); conv_time += conv_time /10 ;/* 10% internal clock inaccuracy */ usleep_range (conv_time, conv_time +1 ); data->conv_invalid = false;
@@ -470,7 +471,7 @@ static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate)int i;for (i =0 ; i <ARRAY_SIZE (ads1015_data_rate); i++) { -if (data->data_rate[i] == rate) { +if (data->chip->data_rate[i] == rate) { data->channel_data[chan].data_rate = i;return 0 ; }
@@ -528,7 +529,7 @@ static int ads1015_read_raw(struct iio_dev *indio_dev,break ;case IIO_CHAN_INFO_SAMP_FREQ : idx = data->channel_data[chan->address].data_rate; - *val = data->data_rate[idx]; + *val = data->chip->data_rate[idx]; ret =IIO_VAL_INT ;break ;default :
@@ -588,7 +589,7 @@ static int ads1015_read_event(struct iio_dev *indio_dev, dr = data->channel_data[chan->address].data_rate; comp_queue = data->thresh_data[chan->address].comp_queue; period = ads1015_comp_queue[comp_queue] * -USEC_PER_SEC / data->data_rate[dr]; +USEC_PER_SEC / data->chip->data_rate[dr]; *val = period /USEC_PER_SEC ; *val2 = period %USEC_PER_SEC ;
@@ -610,6 +611,7 @@ static int ads1015_write_event(struct iio_dev *indio_dev, int val2) {struct ads1015_data *data =iio_priv (indio_dev); +const unsigned int *data_rate = data->chip->data_rate;int realbits = chan->scan_type.realbits;int ret =0 ;long long period;
@@ -635,7 +637,7 @@ static int ads1015_write_event(struct iio_dev *indio_dev,for (i =0 ; i <ARRAY_SIZE (ads1015_comp_queue) -1 ; i++) {if (period <= ads1015_comp_queue[i] * -USEC_PER_SEC / data->data_rate[dr]) +USEC_PER_SEC / data_rate[dr])break ; } data->thresh_data[chan->address].comp_queue = i;
@@ -989,7 +991,7 @@ static int ads1015_probe(struct i2c_client *client, indio_dev->channels = chip->channels; indio_dev->num_channels = chip->num_channels; indio_dev->info = chip->info; - data->data_rate = chip->data_rate; + data->chip = chip; data->event_channel =ADS1015_CHANNELS ;/*
Signature · 1 line
2.35.1
PATCH v4 10/10 iio: adc: ti-ads1015: Switch to read_avail
In reply to Marek VasutReplace sysfs attributes with read_avail() callback. This also permits removal of ads1115_info, since the scale attribute tables are now part of chip data.
---
V3: New patch
V4: - Reformat ads1x15 scale ranges pairwise
- Turn the scale ranges into unsigned int
--- drivers/iio/adc/ti-ads1015.c | 112 +++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 45 deletions(-)
drivers/iio/adc/ti-ads1015.c +67 -45
@@ -81,6 +81,9 @@ struct ads1015_chip_data {int num_channels;const struct iio_info *info;const unsigned int *data_rate; +const unsigned int data_rate_len; +const unsigned int *scale; +const unsigned int scale_len;bool has_comparator; };
@@ -108,10 +111,28 @@ static const unsigned int ads1115_data_rate[] = {* Translation from PGA bits to full-scale positive and negative input voltage * range in mV */ -static int ads1015_fullscale_range[] = { +static const unsigned int ads1015_fullscale_range[] = {6144 ,4096 ,2048 ,1024 ,512 ,256 ,256 ,256 }; +static const unsigned int ads1015_scale[] = {/* 12bit ADC */ +256 ,11 , +512 ,11 , +1024 ,11 , +2048 ,11 , +4096 ,11 , +6144 ,11 +}; + +static const unsigned int ads1115_scale[] = {/* 16bit ADC */ +256 ,15 , +512 ,15 , +1024 ,15 , +2048 ,15 , +4096 ,15 , +6144 ,15 +}; +/* * Translation from COMP_QUE field value to the number of successive readings * exceed the threshold values before an interrupt is generated
@@ -166,6 +187,9 @@ static const struct iio_event_spec ads1015_events[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \BIT (IIO_CHAN_INFO_SCALE ) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = \ +BIT (IIO_CHAN_INFO_SCALE ) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = _addr, \ .scan_type = { \ .sign = 's', \
@@ -189,6 +213,9 @@ static const struct iio_event_spec ads1015_events[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \BIT (IIO_CHAN_INFO_SCALE ) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = \ +BIT (IIO_CHAN_INFO_SCALE ) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = _addr, \ .scan_type = { \ .sign = 's', \
@@ -470,7 +497,7 @@ static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate) {int i; -for (i =0 ; i <ARRAY_SIZE (ads1015_data_rate); i++) { +for (i =0 ; i < data->chip->data_rate_len; i++) {if (data->chip->data_rate[i] == rate) { data->channel_data[chan].data_rate = i;return 0 ;
@@ -480,6 +507,32 @@ static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate)return -EINVAL ; } +static int ads1015_read_avail (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +const int **vals,int *type,int *length, +long mask) +{ +struct ads1015_data *data =iio_priv (indio_dev); + +if (chan->type !=IIO_VOLTAGE ) +return -EINVAL ; + +switch (mask) { +case IIO_CHAN_INFO_SCALE : + *type =IIO_VAL_FRACTIONAL_LOG2 ; + *vals = data->chip->scale; + *length = data->chip->scale_len; +return IIO_AVAIL_LIST ; +case IIO_CHAN_INFO_SAMP_FREQ : + *type =IIO_VAL_INT ; + *vals = data->chip->data_rate; + *length = data->chip->data_rate_len; +return IIO_AVAIL_LIST ; +default : +return -EINVAL ; + } +} +static int ads1015_read_raw (struct iio_dev *indio_dev,struct iio_chan_spec const *chan,int *val,int *val2,long mask)
@@ -828,60 +881,20 @@ static const struct iio_buffer_setup_ops ads1015_buffer_setup_ops = { .validate_scan_mask = &iio_validate_scan_mask_onehot, }; -static IIO_CONST_ATTR_NAMED(ads1015_scale_available, scale_available, - "3 2 1 0.5 0.25 0.125"); -static IIO_CONST_ATTR_NAMED(ads1115_scale_available, scale_available, - "0.1875 0.125 0.0625 0.03125 0.015625 0.007813"); - -static IIO_CONST_ATTR_NAMED(ads1015_sampling_frequency_available, - sampling_frequency_available, "128 250 490 920 1600 2400 3300"); -static IIO_CONST_ATTR_NAMED(ads1115_sampling_frequency_available, - sampling_frequency_available, "8 16 32 64 128 250 475 860"); - -static struct attribute *ads1015_attributes[] = { - &iio_const_attr_ads1015_scale_available.dev_attr.attr, - &iio_const_attr_ads1015_sampling_frequency_available.dev_attr.attr, -NULL , -}; - -static const struct attribute_group ads1015_attribute_group = { - .attrs = ads1015_attributes, -}; - -static struct attribute *ads1115_attributes[] = { - &iio_const_attr_ads1115_scale_available.dev_attr.attr, - &iio_const_attr_ads1115_sampling_frequency_available.dev_attr.attr, -NULL , -}; - -static const struct attribute_group ads1115_attribute_group = { - .attrs = ads1115_attributes, -}; -static const struct iio_info ads1015_info = { + .read_avail = ads1015_read_avail, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, .read_event_value = ads1015_read_event, .write_event_value = ads1015_write_event, .read_event_config = ads1015_read_event_config, .write_event_config = ads1015_write_event_config, - .attrs = &ads1015_attribute_group, -}; - -static const struct iio_info ads1115_info = { - .read_raw = ads1015_read_raw, - .write_raw = ads1015_write_raw, - .read_event_value = ads1015_read_event, - .write_event_value = ads1015_write_event, - .read_event_config = ads1015_read_event_config, - .write_event_config = ads1015_write_event_config, - .attrs = &ads1115_attribute_group, };static const struct iio_info tla2024_info = { + .read_avail = ads1015_read_avail, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, - .attrs = &ads1015_attribute_group, };static int ads1015_client_get_channels_config (struct i2c_client *client)
@@ -1128,14 +1141,20 @@ static const struct ads1015_chip_data ads1015_data = { .num_channels = ARRAY_SIZE(ads1015_channels), .info = &ads1015_info, .data_rate = ads1015_data_rate, + .data_rate_len = ARRAY_SIZE(ads1015_data_rate), + .scale = ads1015_scale, + .scale_len = ARRAY_SIZE(ads1015_scale), .has_comparator = true, };static const struct ads1015_chip_data ads1115_data = { .channels = ads1115_channels, .num_channels =ARRAY_SIZE (ads1115_channels), - .info = &ads1115_info, + .info = &ads1015_info, .data_rate = ads1115_data_rate, + .data_rate_len =ARRAY_SIZE (ads1115_data_rate), + .scale = ads1115_scale, + .scale_len =ARRAY_SIZE (ads1115_scale), .has_comparator = true, };
@@ -1144,6 +1163,9 @@ static const struct ads1015_chip_data tla2024_data = { .num_channels = ARRAY_SIZE(tla2024_channels), .info = &tla2024_info, .data_rate = ads1015_data_rate, + .data_rate_len = ARRAY_SIZE(ads1015_data_rate), + .scale = ads1015_scale, + .scale_len = ARRAY_SIZE(ads1015_scale), .has_comparator = false, };
Signature · 1 line
2.35.1
Jonathan Cameron
maintainerRe: [PATCH v4 10/10] iio: adc: ti-ads1015: Switch to read_avail
Quoted 8 lines · On Tue, 22 Mar 2022 23:02:10 +0100 Marek Vasut <[email protected]> wrote:
Replace sysfs attributes with
read_avail()callback. This also permits removal ofads1115_info, since the scale attribute tables are now part of chip data.Signed-off-by Marek Vasut <[email protected]>Cc Andy Shevchenko <[email protected]>Cc Daniel Baluta <[email protected]>Cc Jonathan Cameron <[email protected]>
Sorry, I didn't catch your question on v3 about why I was advocating signed.
You are passing pointers to those arrays as signed in the read_avail.
Obviously you can 'get away with it' because the values are small positive numbers and hence in 2's complement the data representation will be the same. Not pretty though so my inclination would be to keep them signed everywhere.
If you are fine with that change I can change it whilst applying if nothing else comes up in review.
Given there are some (admittedly trivial) dt binding additions, I'll leave this on list until Rob has had a chance to take a look at them. Also, Andy might want to take another glance or give a tag given his previous interest in this series.
Thanks,
Jonathan
Quoted 209 lines
---
V3: New patch
V4: - Reformat ads1x15 scale ranges pairwise
- Turn the scale ranges into unsigned int--- drivers/iio/adc/ti-ads1015.c | 112 +++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 45 deletions(-)drivers/iio/adc/ti-ads1015.c +67
-45@@ -81,6 +81,9 @@ struct ads1015_chip_data {int num_channels;const struct iio_info *info;const unsigned int *data_rate; +const unsigned int data_rate_len; +const unsigned int *scale; +const unsigned int scale_len;bool has_comparator; };@@ -108,10 +111,28 @@ static const unsigned int ads1115_data_rate[] = {* Translation from PGA bits to full-scale positive and negative input voltage * range in mV */ -static int ads1015_fullscale_range[] = { +static const unsigned int ads1015_fullscale_range[] = {6144 ,4096 ,2048 ,1024 ,512 ,256 ,256 ,256 }; +static const unsigned int ads1015_scale[] = {/* 12bit ADC */ +256 ,11 , +512 ,11 , +1024 ,11 , +2048 ,11 , +4096 ,11 , +6144 ,11 +}; + +static const unsigned int ads1115_scale[] = {/* 16bit ADC */ +256 ,15 , +512 ,15 , +1024 ,15 , +2048 ,15 , +4096 ,15 , +6144 ,15 +}; +/* * Translation from COMP_QUE field value to the number of successive readings * exceed the threshold values before an interrupt is generated @@ -166,6 +187,9 @@ static const struct iio_event_spec ads1015_events[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \BIT (IIO_CHAN_INFO_SCALE ) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = \ +BIT (IIO_CHAN_INFO_SCALE ) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = _addr, \ .scan_type = { \ .sign = 's', \@@ -189,6 +213,9 @@ static const struct iio_event_spec ads1015_events[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \BIT (IIO_CHAN_INFO_SCALE ) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = \ +BIT (IIO_CHAN_INFO_SCALE ) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = _addr, \ .scan_type = { \ .sign = 's', \@@ -470,7 +497,7 @@ static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate) {int i; -for (i =0 ; i <ARRAY_SIZE (ads1015_data_rate); i++) { +for (i =0 ; i < data->chip->data_rate_len; i++) {if (data->chip->data_rate[i] == rate) { data->channel_data[chan].data_rate = i;return 0 ;@@ -480,6 +507,32 @@ static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate)return -EINVAL ; } +static int ads1015_read_avail (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +const int **vals,int *type,int *length, +long mask) +{ +struct ads1015_data *data =iio_priv (indio_dev); + +if (chan->type !=IIO_VOLTAGE ) +return -EINVAL ; + +switch (mask) { +case IIO_CHAN_INFO_SCALE : + *type =IIO_VAL_FRACTIONAL_LOG2 ; + *vals = data->chip->scale; + *length = data->chip->scale_len; +return IIO_AVAIL_LIST ; +case IIO_CHAN_INFO_SAMP_FREQ : + *type =IIO_VAL_INT ; + *vals = data->chip->data_rate; + *length = data->chip->data_rate_len; +return IIO_AVAIL_LIST ; +default : +return -EINVAL ; + } +} +static int ads1015_read_raw (struct iio_dev *indio_dev,struct iio_chan_spec const *chan,int *val,int *val2,long mask)@@ -828,60 +881,20 @@ static const struct iio_buffer_setup_ops ads1015_buffer_setup_ops = { .validate_scan_mask = &iio_validate_scan_mask_onehot, }; -static IIO_CONST_ATTR_NAMED(ads1015_scale_available, scale_available, - "3 2 1 0.5 0.25 0.125"); -static IIO_CONST_ATTR_NAMED(ads1115_scale_available, scale_available, - "0.1875 0.125 0.0625 0.03125 0.015625 0.007813"); - -static IIO_CONST_ATTR_NAMED(ads1015_sampling_frequency_available, - sampling_frequency_available, "128 250 490 920 1600 2400 3300"); -static IIO_CONST_ATTR_NAMED(ads1115_sampling_frequency_available, - sampling_frequency_available, "8 16 32 64 128 250 475 860"); - -static struct attribute *ads1015_attributes[] = { - &iio_const_attr_ads1015_scale_available.dev_attr.attr, - &iio_const_attr_ads1015_sampling_frequency_available.dev_attr.attr, -NULL , -}; - -static const struct attribute_group ads1015_attribute_group = { - .attrs = ads1015_attributes, -}; - -static struct attribute *ads1115_attributes[] = { - &iio_const_attr_ads1115_scale_available.dev_attr.attr, - &iio_const_attr_ads1115_sampling_frequency_available.dev_attr.attr, -NULL , -}; - -static const struct attribute_group ads1115_attribute_group = { - .attrs = ads1115_attributes, -}; -static const struct iio_info ads1015_info = { + .read_avail = ads1015_read_avail, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, .read_event_value = ads1015_read_event, .write_event_value = ads1015_write_event, .read_event_config = ads1015_read_event_config, .write_event_config = ads1015_write_event_config, - .attrs = &ads1015_attribute_group, -}; - -static const struct iio_info ads1115_info = { - .read_raw = ads1015_read_raw, - .write_raw = ads1015_write_raw, - .read_event_value = ads1015_read_event, - .write_event_value = ads1015_write_event, - .read_event_config = ads1015_read_event_config, - .write_event_config = ads1015_write_event_config, - .attrs = &ads1115_attribute_group, };static const struct iio_info tla2024_info = { + .read_avail = ads1015_read_avail, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, - .attrs = &ads1015_attribute_group, };static int ads1015_client_get_channels_config (struct i2c_client *client)@@ -1128,14 +1141,20 @@ static const struct ads1015_chip_data ads1015_data = { .num_channels = ARRAY_SIZE(ads1015_channels), .info = &ads1015_info, .data_rate = ads1015_data_rate, + .data_rate_len = ARRAY_SIZE(ads1015_data_rate), + .scale = ads1015_scale, + .scale_len = ARRAY_SIZE(ads1015_scale), .has_comparator = true, };static const struct ads1015_chip_data ads1115_data = { .channels = ads1115_channels, .num_channels =ARRAY_SIZE (ads1115_channels), - .info = &ads1115_info, + .info = &ads1015_info, .data_rate = ads1115_data_rate, + .data_rate_len =ARRAY_SIZE (ads1115_data_rate), + .scale = ads1115_scale, + .scale_len =ARRAY_SIZE (ads1115_scale), .has_comparator = true, };@@ -1144,6 +1163,9 @@ static const struct ads1015_chip_data tla2024_data = { .num_channels = ARRAY_SIZE(tla2024_channels), .info = &tla2024_info, .data_rate = ads1015_data_rate, + .data_rate_len = ARRAY_SIZE(ads1015_data_rate), + .scale = ads1015_scale, + .scale_len = ARRAY_SIZE(ads1015_scale), .has_comparator = false, };
Re: [PATCH v4 10/10] iio: adc: ti-ads1015: Switch to read_avail
Quoted 5 lines · Jonathan Cameron
On Tue, 22 Mar 2022 23:02:10 +0100
Marek Vasut <[email protected]> wrote:Also, Andy might want to take another glance
or give a tag given his previous interest in this series.
Thanks for letting me know. I have no strong remarks on the series, the commas at the end of the line are good to have from my point of view, but I understand Marek's argument that they are from hardware and shouldn't be ever bigger. So, I consider this is kinda nit-pick which I may live with (since I'm not a maintainer here). That being said, if you feel stronger about this, ask for it :-)
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH v4 10/10] iio: adc: ti-ads1015: Switch to read_avail
In reply to Jonathan CameronQuoted 18 lines · Jonathan Cameron
Quoted 8 lines · On Tue, 22 Mar 2022 23:02:10 +0100 Marek Vasut <[email protected]> wrote:
Replace sysfs attributes with
read_avail()callback. This also permits removal ofads1115_info, since the scale attribute tables are now part of chip data.Signed-off-by Marek Vasut <[email protected]>Cc Andy Shevchenko <[email protected]>Cc Daniel Baluta <[email protected]>Cc Jonathan Cameron <[email protected]>Sorry, I didn't catch your question on v3 about why I was advocating signed.
You are passing pointers to those arrays as signed in the
read_avail.
Quoted 7 lines
Obviously you can 'get away with it' because the values are small positive numbers and hence in 2's complement the data representation will be the same. Not pretty though so my inclination would be to keep them signed everywhere.
If you are fine with that change I can change it whilst applying if nothing else comes up in review.
I'm fine with it, although I did switch them all to unsigned int in this V4 (unless I'm missing something still).
Jonathan Cameron
maintainerRe: [PATCH v4 10/10] iio: adc: ti-ads1015: Switch to read_avail
Quoted 24 lines · On Mon, 28 Mar 2022 02:31:32 +0200 Marek Vasut <[email protected]> wrote:
Quoted 23 lines · Jonathan Cameron
Quoted 8 lines · On Tue, 22 Mar 2022 23:02:10 +0100 Marek Vasut <[email protected]> wrote:
Replace sysfs attributes with
read_avail()callback. This also permits removal ofads1115_info, since the scale attribute tables are now part of chip data.Signed-off-by Marek Vasut <[email protected]>Cc Andy Shevchenko <[email protected]>Cc Daniel Baluta <[email protected]>Cc Jonathan Cameron <[email protected]>Sorry, I didn't catch your question on v3 about why I was advocating signed.
You are passing pointers to those arrays as signed in the
read_avail.Obviously you can 'get away with it' because the values are small positive numbers and hence in 2's complement the data representation will be the same. Not pretty though so my inclination would be to keep them signed everywhere.
Quoted 5 lines
Quoted 2 lines
If you are fine with that change I can change it whilst applying if nothing else comes up in review.
I'm fine with it, although I did switch them all to unsigned int in this V4 (unless I'm missing something still).
You switched to unsigned int, but...
+static int ads1015_read_avail(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask)
+{
+ struct ads1015_data *data = iio_priv(indio_dev);
+
+ if (chan->type != IIO_VOLTAGE)
+ return -EINVAL;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ *type = IIO_VAL_FRACTIONAL_LOG2;
+ *vals = data->chip->scale;
This then uses them as signed integers. Which as mentioned is technically not a bug, but that's only because the numbers are small.. So better to go signed throughout.
+ *length = data->chip->scale_len;
+ return IIO_AVAIL_LIST;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *type = IIO_VAL_INT;
+ *vals = data->chip->data_rate;
+ *length = data->chip->data_rate_len;
+ return IIO_AVAIL_LIST;
+ default:
+ return -EINVAL;
+ }
+}
+
Re: [PATCH v4 10/10] iio: adc: ti-ads1015: Switch to read_avail
Quoted 50 lines · Jonathan Cameron
Quoted 24 lines · On Mon, 28 Mar 2022 02:31:32 +0200 Marek Vasut <[email protected]> wrote:
Quoted 23 lines · Jonathan Cameron
Quoted 8 lines · On Tue, 22 Mar 2022 23:02:10 +0100 Marek Vasut <[email protected]> wrote:
Replace sysfs attributes with
read_avail()callback. This also permits removal ofads1115_info, since the scale attribute tables are now part of chip data.Signed-off-by Marek Vasut <[email protected]>Cc Andy Shevchenko <[email protected]>Cc Daniel Baluta <[email protected]>Cc Jonathan Cameron <[email protected]>Sorry, I didn't catch your question on v3 about why I was advocating signed.
You are passing pointers to those arrays as signed in the
read_avail.Obviously you can 'get away with it' because the values are small positive numbers and hence in 2's complement the data representation will be the same. Not pretty though so my inclination would be to keep them signed everywhere.
Quoted 5 lines
Quoted 2 lines
If you are fine with that change I can change it whilst applying if nothing else comes up in review.
I'm fine with it, although I did switch them all to unsigned int in this V4 (unless I'm missing something still).
You switched to unsigned int, but...
drivers/iio/adc/ti-ads1015.c +14
-0+static int ads1015_read_avail (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +const int **vals,int *type,int *length, +long mask) +{ +struct ads1015_data *data =iio_priv (indio_dev); + +if (chan->type !=IIO_VOLTAGE ) +return -EINVAL ; + +switch (mask) { +case IIO_CHAN_INFO_SCALE : + *type =IIO_VAL_FRACTIONAL_LOG2 ; + *vals = data->chip->scale;
Quoted 3 lines
This then uses them as signed integers. Which as mentioned is technically not a bug, but that's only because the numbers are small.. So better to go signed throughout.
Ah, I see.