diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-02-03 07:10:41 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-02-03 07:10:41 -0500 |
commit | 6d923f8fe821c0c6b5378635cbcc9da5f5ec520a (patch) | |
tree | 989514e51f10fd95713ef312a2ed8cd5d563db1a | |
parent | 798badf8467f41af6dfbf5621e1fc966c80446fd (diff) | |
parent | f214ff521fb1f861c8d7f7d0af98b06bf61b3369 (diff) |
Merge tag 'iio-fixes-5.0a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus
Jonathan writes:
First set of IIO fixes for the 5.0 cycle.
Been a busy month, so these are rather later than they should have been.
* atlas-ph-sensor:
- Temperature scale didn't correspond to the ABI.
* axp288:
- A few different fixes around the TS-pin handling.
* ti-ads8688
- Not enough space in the buffer used to build the scan to allow for
the timestamp.
* tools - iio_generic_buffer
- Make num_loops signed so that we really are running for ever
rather than just a long time when we specify -1.
* tag 'iio-fixes-5.0a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio:
iio: ti-ads8688: Update buffer allocation for timestamps
tools: iio: iio_generic_buffer: make num_loops signed
iio: adc: axp288: Fix TS-pin handling
iio: chemical: atlas-ph-sensor: correct IIO_TEMP values to millicelsius
-rw-r--r-- | drivers/iio/adc/axp288_adc.c | 76 | ||||
-rw-r--r-- | drivers/iio/adc/ti-ads8688.c | 3 | ||||
-rw-r--r-- | drivers/iio/chemical/atlas-ph-sensor.c | 7 | ||||
-rw-r--r-- | tools/iio/iio_generic_buffer.c | 2 |
4 files changed, 66 insertions, 22 deletions
diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c index 031d568b4972..4e339cfd0c54 100644 --- a/drivers/iio/adc/axp288_adc.c +++ b/drivers/iio/adc/axp288_adc.c | |||
@@ -27,9 +27,18 @@ | |||
27 | #include <linux/iio/machine.h> | 27 | #include <linux/iio/machine.h> |
28 | #include <linux/iio/driver.h> | 28 | #include <linux/iio/driver.h> |
29 | 29 | ||
30 | #define AXP288_ADC_EN_MASK 0xF1 | 30 | /* |
31 | #define AXP288_ADC_TS_PIN_GPADC 0xF2 | 31 | * This mask enables all ADCs except for the battery temp-sensor (TS), that is |
32 | #define AXP288_ADC_TS_PIN_ON 0xF3 | 32 | * left as-is to avoid breaking charging on devices without a temp-sensor. |
33 | */ | ||
34 | #define AXP288_ADC_EN_MASK 0xF0 | ||
35 | #define AXP288_ADC_TS_ENABLE 0x01 | ||
36 | |||
37 | #define AXP288_ADC_TS_CURRENT_ON_OFF_MASK GENMASK(1, 0) | ||
38 | #define AXP288_ADC_TS_CURRENT_OFF (0 << 0) | ||
39 | #define AXP288_ADC_TS_CURRENT_ON_WHEN_CHARGING (1 << 0) | ||
40 | #define AXP288_ADC_TS_CURRENT_ON_ONDEMAND (2 << 0) | ||
41 | #define AXP288_ADC_TS_CURRENT_ON (3 << 0) | ||
33 | 42 | ||
34 | enum axp288_adc_id { | 43 | enum axp288_adc_id { |
35 | AXP288_ADC_TS, | 44 | AXP288_ADC_TS, |
@@ -44,6 +53,7 @@ enum axp288_adc_id { | |||
44 | struct axp288_adc_info { | 53 | struct axp288_adc_info { |
45 | int irq; | 54 | int irq; |
46 | struct regmap *regmap; | 55 | struct regmap *regmap; |
56 | bool ts_enabled; | ||
47 | }; | 57 | }; |
48 | 58 | ||
49 | static const struct iio_chan_spec axp288_adc_channels[] = { | 59 | static const struct iio_chan_spec axp288_adc_channels[] = { |
@@ -115,21 +125,33 @@ static int axp288_adc_read_channel(int *val, unsigned long address, | |||
115 | return IIO_VAL_INT; | 125 | return IIO_VAL_INT; |
116 | } | 126 | } |
117 | 127 | ||
118 | static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode, | 128 | /* |
119 | unsigned long address) | 129 | * The current-source used for the battery temp-sensor (TS) is shared |
130 | * with the GPADC. For proper fuel-gauge and charger operation the TS | ||
131 | * current-source needs to be permanently on. But to read the GPADC we | ||
132 | * need to temporary switch the TS current-source to ondemand, so that | ||
133 | * the GPADC can use it, otherwise we will always read an all 0 value. | ||
134 | */ | ||
135 | static int axp288_adc_set_ts(struct axp288_adc_info *info, | ||
136 | unsigned int mode, unsigned long address) | ||
120 | { | 137 | { |
121 | int ret; | 138 | int ret; |
122 | 139 | ||
123 | /* channels other than GPADC do not need to switch TS pin */ | 140 | /* No need to switch the current-source if the TS pin is disabled */ |
141 | if (!info->ts_enabled) | ||
142 | return 0; | ||
143 | |||
144 | /* Channels other than GPADC do not need the current source */ | ||
124 | if (address != AXP288_GP_ADC_H) | 145 | if (address != AXP288_GP_ADC_H) |
125 | return 0; | 146 | return 0; |
126 | 147 | ||
127 | ret = regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode); | 148 | ret = regmap_update_bits(info->regmap, AXP288_ADC_TS_PIN_CTRL, |
149 | AXP288_ADC_TS_CURRENT_ON_OFF_MASK, mode); | ||
128 | if (ret) | 150 | if (ret) |
129 | return ret; | 151 | return ret; |
130 | 152 | ||
131 | /* When switching to the GPADC pin give things some time to settle */ | 153 | /* When switching to the GPADC pin give things some time to settle */ |
132 | if (mode == AXP288_ADC_TS_PIN_GPADC) | 154 | if (mode == AXP288_ADC_TS_CURRENT_ON_ONDEMAND) |
133 | usleep_range(6000, 10000); | 155 | usleep_range(6000, 10000); |
134 | 156 | ||
135 | return 0; | 157 | return 0; |
@@ -145,14 +167,14 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, | |||
145 | mutex_lock(&indio_dev->mlock); | 167 | mutex_lock(&indio_dev->mlock); |
146 | switch (mask) { | 168 | switch (mask) { |
147 | case IIO_CHAN_INFO_RAW: | 169 | case IIO_CHAN_INFO_RAW: |
148 | if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC, | 170 | if (axp288_adc_set_ts(info, AXP288_ADC_TS_CURRENT_ON_ONDEMAND, |
149 | chan->address)) { | 171 | chan->address)) { |
150 | dev_err(&indio_dev->dev, "GPADC mode\n"); | 172 | dev_err(&indio_dev->dev, "GPADC mode\n"); |
151 | ret = -EINVAL; | 173 | ret = -EINVAL; |
152 | break; | 174 | break; |
153 | } | 175 | } |
154 | ret = axp288_adc_read_channel(val, chan->address, info->regmap); | 176 | ret = axp288_adc_read_channel(val, chan->address, info->regmap); |
155 | if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON, | 177 | if (axp288_adc_set_ts(info, AXP288_ADC_TS_CURRENT_ON, |
156 | chan->address)) | 178 | chan->address)) |
157 | dev_err(&indio_dev->dev, "TS pin restore\n"); | 179 | dev_err(&indio_dev->dev, "TS pin restore\n"); |
158 | break; | 180 | break; |
@@ -164,13 +186,35 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, | |||
164 | return ret; | 186 | return ret; |
165 | } | 187 | } |
166 | 188 | ||
167 | static int axp288_adc_set_state(struct regmap *regmap) | 189 | static int axp288_adc_initialize(struct axp288_adc_info *info) |
168 | { | 190 | { |
169 | /* ADC should be always enabled for internal FG to function */ | 191 | int ret, adc_enable_val; |
170 | if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON)) | 192 | |
171 | return -EIO; | 193 | /* |
194 | * Determine if the TS pin is enabled and set the TS current-source | ||
195 | * accordingly. | ||
196 | */ | ||
197 | ret = regmap_read(info->regmap, AXP20X_ADC_EN1, &adc_enable_val); | ||
198 | if (ret) | ||
199 | return ret; | ||
200 | |||
201 | if (adc_enable_val & AXP288_ADC_TS_ENABLE) { | ||
202 | info->ts_enabled = true; | ||
203 | ret = regmap_update_bits(info->regmap, AXP288_ADC_TS_PIN_CTRL, | ||
204 | AXP288_ADC_TS_CURRENT_ON_OFF_MASK, | ||
205 | AXP288_ADC_TS_CURRENT_ON); | ||
206 | } else { | ||
207 | info->ts_enabled = false; | ||
208 | ret = regmap_update_bits(info->regmap, AXP288_ADC_TS_PIN_CTRL, | ||
209 | AXP288_ADC_TS_CURRENT_ON_OFF_MASK, | ||
210 | AXP288_ADC_TS_CURRENT_OFF); | ||
211 | } | ||
212 | if (ret) | ||
213 | return ret; | ||
172 | 214 | ||
173 | return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK); | 215 | /* Turn on the ADC for all channels except TS, leave TS as is */ |
216 | return regmap_update_bits(info->regmap, AXP20X_ADC_EN1, | ||
217 | AXP288_ADC_EN_MASK, AXP288_ADC_EN_MASK); | ||
174 | } | 218 | } |
175 | 219 | ||
176 | static const struct iio_info axp288_adc_iio_info = { | 220 | static const struct iio_info axp288_adc_iio_info = { |
@@ -200,7 +244,7 @@ static int axp288_adc_probe(struct platform_device *pdev) | |||
200 | * Set ADC to enabled state at all time, including system suspend. | 244 | * Set ADC to enabled state at all time, including system suspend. |
201 | * otherwise internal fuel gauge functionality may be affected. | 245 | * otherwise internal fuel gauge functionality may be affected. |
202 | */ | 246 | */ |
203 | ret = axp288_adc_set_state(axp20x->regmap); | 247 | ret = axp288_adc_initialize(info); |
204 | if (ret) { | 248 | if (ret) { |
205 | dev_err(&pdev->dev, "unable to enable ADC device\n"); | 249 | dev_err(&pdev->dev, "unable to enable ADC device\n"); |
206 | return ret; | 250 | return ret; |
diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c index 184d686ebd99..8b4568edd5cb 100644 --- a/drivers/iio/adc/ti-ads8688.c +++ b/drivers/iio/adc/ti-ads8688.c | |||
@@ -41,6 +41,7 @@ | |||
41 | 41 | ||
42 | #define ADS8688_VREF_MV 4096 | 42 | #define ADS8688_VREF_MV 4096 |
43 | #define ADS8688_REALBITS 16 | 43 | #define ADS8688_REALBITS 16 |
44 | #define ADS8688_MAX_CHANNELS 8 | ||
44 | 45 | ||
45 | /* | 46 | /* |
46 | * enum ads8688_range - ADS8688 reference voltage range | 47 | * enum ads8688_range - ADS8688 reference voltage range |
@@ -385,7 +386,7 @@ static irqreturn_t ads8688_trigger_handler(int irq, void *p) | |||
385 | { | 386 | { |
386 | struct iio_poll_func *pf = p; | 387 | struct iio_poll_func *pf = p; |
387 | struct iio_dev *indio_dev = pf->indio_dev; | 388 | struct iio_dev *indio_dev = pf->indio_dev; |
388 | u16 buffer[8]; | 389 | u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)]; |
389 | int i, j = 0; | 390 | int i, j = 0; |
390 | 391 | ||
391 | for (i = 0; i < indio_dev->masklength; i++) { | 392 | for (i = 0; i < indio_dev->masklength; i++) { |
diff --git a/drivers/iio/chemical/atlas-ph-sensor.c b/drivers/iio/chemical/atlas-ph-sensor.c index a406ad31b096..3a20cb5d9bff 100644 --- a/drivers/iio/chemical/atlas-ph-sensor.c +++ b/drivers/iio/chemical/atlas-ph-sensor.c | |||
@@ -444,9 +444,8 @@ static int atlas_read_raw(struct iio_dev *indio_dev, | |||
444 | case IIO_CHAN_INFO_SCALE: | 444 | case IIO_CHAN_INFO_SCALE: |
445 | switch (chan->type) { | 445 | switch (chan->type) { |
446 | case IIO_TEMP: | 446 | case IIO_TEMP: |
447 | *val = 1; /* 0.01 */ | 447 | *val = 10; |
448 | *val2 = 100; | 448 | return IIO_VAL_INT; |
449 | break; | ||
450 | case IIO_PH: | 449 | case IIO_PH: |
451 | *val = 1; /* 0.001 */ | 450 | *val = 1; /* 0.001 */ |
452 | *val2 = 1000; | 451 | *val2 = 1000; |
@@ -477,7 +476,7 @@ static int atlas_write_raw(struct iio_dev *indio_dev, | |||
477 | int val, int val2, long mask) | 476 | int val, int val2, long mask) |
478 | { | 477 | { |
479 | struct atlas_data *data = iio_priv(indio_dev); | 478 | struct atlas_data *data = iio_priv(indio_dev); |
480 | __be32 reg = cpu_to_be32(val); | 479 | __be32 reg = cpu_to_be32(val / 10); |
481 | 480 | ||
482 | if (val2 != 0 || val < 0 || val > 20000) | 481 | if (val2 != 0 || val < 0 || val > 20000) |
483 | return -EINVAL; | 482 | return -EINVAL; |
diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c index 3040830d7797..84545666a09c 100644 --- a/tools/iio/iio_generic_buffer.c +++ b/tools/iio/iio_generic_buffer.c | |||
@@ -330,7 +330,7 @@ static const struct option longopts[] = { | |||
330 | 330 | ||
331 | int main(int argc, char **argv) | 331 | int main(int argc, char **argv) |
332 | { | 332 | { |
333 | unsigned long long num_loops = 2; | 333 | long long num_loops = 2; |
334 | unsigned long timedelay = 1000000; | 334 | unsigned long timedelay = 1000000; |
335 | unsigned long buf_len = 128; | 335 | unsigned long buf_len = 128; |
336 | 336 | ||