Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: adc: cc10001: Power-up the ADC at probe time when used remotely

The ADC is typically shared with remote CPUs not running Linux.
However, there is only one register to power-up/power-down. Remote CPUs
aren't able to power-up the ADC, and rely in Linux doing it instead.

This commit uses the adc-reserved-channels devicetree property to
distinguish shared usage. In this case, the ADC is powered up at
probe time.

If the ADC is used only by the CPU running Linux, power-up/down
at runtime, only when neeeded.

Signed-off-by: Naidu Tellapati <naidu.tellapati@imgtec.com>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Naidu Tellapati and committed by
Jonathan Cameron
ae354962 eb2c9ce2

+21 -5
+21 -5
drivers/iio/adc/cc10001_adc.c
··· 62 62 struct regulator *reg; 63 63 u16 *buf; 64 64 65 + bool shared; 65 66 struct mutex lock; 66 67 unsigned int start_delay_ns; 67 68 unsigned int eoc_delay_ns; ··· 154 153 155 154 mutex_lock(&adc_dev->lock); 156 155 157 - cc10001_adc_power_up(adc_dev); 156 + if (!adc_dev->shared) 157 + cc10001_adc_power_up(adc_dev); 158 158 159 159 /* Calculate delay step for eoc and sampled data */ 160 160 delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; ··· 179 177 } 180 178 181 179 done: 182 - cc10001_adc_power_down(adc_dev); 180 + if (!adc_dev->shared) 181 + cc10001_adc_power_down(adc_dev); 183 182 184 183 mutex_unlock(&adc_dev->lock); 185 184 ··· 199 196 unsigned int delay_ns; 200 197 u16 val; 201 198 202 - cc10001_adc_power_up(adc_dev); 199 + if (!adc_dev->shared) 200 + cc10001_adc_power_up(adc_dev); 203 201 204 202 /* Calculate delay step for eoc and sampled data */ 205 203 delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; ··· 209 205 210 206 val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns); 211 207 212 - cc10001_adc_power_down(adc_dev); 208 + if (!adc_dev->shared) 209 + cc10001_adc_power_down(adc_dev); 213 210 214 211 return val; 215 212 } ··· 327 322 adc_dev = iio_priv(indio_dev); 328 323 329 324 channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0); 330 - if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) 325 + if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) { 326 + adc_dev->shared = true; 331 327 channel_map &= ~ret; 328 + } 332 329 333 330 adc_dev->reg = devm_regulator_get(&pdev->dev, "vref"); 334 331 if (IS_ERR(adc_dev->reg)) ··· 375 368 adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate; 376 369 adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES; 377 370 371 + /* 372 + * There is only one register to power-up/power-down the AUX ADC. 373 + * If the ADC is shared among multiple CPUs, always power it up here. 374 + * If the ADC is used only by the MIPS, power-up/power-down at runtime. 375 + */ 376 + if (adc_dev->shared) 377 + cc10001_adc_power_up(adc_dev); 378 + 378 379 /* Setup the ADC channels available on the device */ 379 380 ret = cc10001_adc_channel_init(indio_dev, channel_map); 380 381 if (ret < 0) ··· 417 402 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 418 403 struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 419 404 405 + cc10001_adc_power_down(adc_dev); 420 406 iio_device_unregister(indio_dev); 421 407 iio_triggered_buffer_cleanup(indio_dev); 422 408 clk_disable_unprepare(adc_dev->adc_clk);