mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-03 17:14:14 +08:00
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>
This commit is contained in:
parent
eb2c9ce2cc
commit
ae35496230
@ -62,6 +62,7 @@ struct cc10001_adc_device {
|
||||
struct regulator *reg;
|
||||
u16 *buf;
|
||||
|
||||
bool shared;
|
||||
struct mutex lock;
|
||||
unsigned int start_delay_ns;
|
||||
unsigned int eoc_delay_ns;
|
||||
@ -153,7 +154,8 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
|
||||
|
||||
mutex_lock(&adc_dev->lock);
|
||||
|
||||
cc10001_adc_power_up(adc_dev);
|
||||
if (!adc_dev->shared)
|
||||
cc10001_adc_power_up(adc_dev);
|
||||
|
||||
/* Calculate delay step for eoc and sampled data */
|
||||
delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
|
||||
@ -177,7 +179,8 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
|
||||
}
|
||||
|
||||
done:
|
||||
cc10001_adc_power_down(adc_dev);
|
||||
if (!adc_dev->shared)
|
||||
cc10001_adc_power_down(adc_dev);
|
||||
|
||||
mutex_unlock(&adc_dev->lock);
|
||||
|
||||
@ -196,7 +199,8 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
|
||||
unsigned int delay_ns;
|
||||
u16 val;
|
||||
|
||||
cc10001_adc_power_up(adc_dev);
|
||||
if (!adc_dev->shared)
|
||||
cc10001_adc_power_up(adc_dev);
|
||||
|
||||
/* Calculate delay step for eoc and sampled data */
|
||||
delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
|
||||
@ -205,7 +209,8 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
|
||||
|
||||
val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
|
||||
|
||||
cc10001_adc_power_down(adc_dev);
|
||||
if (!adc_dev->shared)
|
||||
cc10001_adc_power_down(adc_dev);
|
||||
|
||||
return val;
|
||||
}
|
||||
@ -322,8 +327,10 @@ static int cc10001_adc_probe(struct platform_device *pdev)
|
||||
adc_dev = iio_priv(indio_dev);
|
||||
|
||||
channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
|
||||
if (!of_property_read_u32(node, "adc-reserved-channels", &ret))
|
||||
if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) {
|
||||
adc_dev->shared = true;
|
||||
channel_map &= ~ret;
|
||||
}
|
||||
|
||||
adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
|
||||
if (IS_ERR(adc_dev->reg))
|
||||
@ -368,6 +375,14 @@ static int cc10001_adc_probe(struct platform_device *pdev)
|
||||
adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate;
|
||||
adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES;
|
||||
|
||||
/*
|
||||
* There is only one register to power-up/power-down the AUX ADC.
|
||||
* If the ADC is shared among multiple CPUs, always power it up here.
|
||||
* If the ADC is used only by the MIPS, power-up/power-down at runtime.
|
||||
*/
|
||||
if (adc_dev->shared)
|
||||
cc10001_adc_power_up(adc_dev);
|
||||
|
||||
/* Setup the ADC channels available on the device */
|
||||
ret = cc10001_adc_channel_init(indio_dev, channel_map);
|
||||
if (ret < 0)
|
||||
@ -402,6 +417,7 @@ static int cc10001_adc_remove(struct platform_device *pdev)
|
||||
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
|
||||
struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
|
||||
|
||||
cc10001_adc_power_down(adc_dev);
|
||||
iio_device_unregister(indio_dev);
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
clk_disable_unprepare(adc_dev->adc_clk);
|
||||
|
Loading…
Reference in New Issue
Block a user