Commit cb093e44 authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Jonathan Cameron

staging:iio:ad7476: Rework reference voltage handling

Slightly rework the reference voltage handling for the ad7476 driver. Now the only
way to specify a external reference voltage is to use the regulator API,
previously it was possible to use either platform_data or the regulator API. The
new way is more consistent with what other drivers do.

Also do not ignore errors when requesting the regulator, since this will cope
very poorly with e.g. deferred probing.
Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 93e33d70
...@@ -10,16 +10,8 @@ ...@@ -10,16 +10,8 @@
#define RES_MASK(bits) ((1 << (bits)) - 1) #define RES_MASK(bits) ((1 << (bits)) - 1)
/*
* TODO: struct ad7476_platform_data needs to go into include/linux/iio
*/
struct ad7476_platform_data {
u16 vref_mv;
};
struct ad7476_chip_info { struct ad7476_chip_info {
u16 int_vref_mv; unsigned int int_vref_uv;
struct iio_chan_spec channel[2]; struct iio_chan_spec channel[2];
}; };
...@@ -27,7 +19,6 @@ struct ad7476_state { ...@@ -27,7 +19,6 @@ struct ad7476_state {
struct spi_device *spi; struct spi_device *spi;
const struct ad7476_chip_info *chip_info; const struct ad7476_chip_info *chip_info;
struct regulator *reg; struct regulator *reg;
u16 int_vref_mv;
struct spi_transfer xfer; struct spi_transfer xfer;
struct spi_message msg; struct spi_message msg;
/* /*
......
...@@ -40,7 +40,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, ...@@ -40,7 +40,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
{ {
int ret; int ret;
struct ad7476_state *st = iio_priv(indio_dev); struct ad7476_state *st = iio_priv(indio_dev);
unsigned int scale_uv; int scale_uv;
switch (m) { switch (m) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
...@@ -57,10 +57,16 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, ...@@ -57,10 +57,16 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
RES_MASK(st->chip_info->channel[0].scan_type.realbits); RES_MASK(st->chip_info->channel[0].scan_type.realbits);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = (st->int_vref_mv * 1000) if (!st->chip_info->int_vref_uv) {
>> st->chip_info->channel[0].scan_type.realbits; scale_uv = regulator_get_voltage(st->reg);
*val = scale_uv/1000; if (scale_uv < 0)
*val2 = (scale_uv%1000)*1000; return scale_uv;
} else {
scale_uv = st->chip_info->int_vref_uv;
}
scale_uv >>= chan->scan_type.realbits;
*val = scale_uv / 1000;
*val2 = (scale_uv % 1000) * 1000;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
} }
return -EINVAL; return -EINVAL;
...@@ -96,7 +102,7 @@ static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { ...@@ -96,7 +102,7 @@ static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
[ID_AD7495] = { [ID_AD7495] = {
.channel[0] = AD7476_CHAN(12), .channel[0] = AD7476_CHAN(12),
.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
.int_vref_mv = 2500, .int_vref_uv = 2500000,
}, },
}; };
...@@ -107,10 +113,9 @@ static const struct iio_info ad7476_info = { ...@@ -107,10 +113,9 @@ static const struct iio_info ad7476_info = {
static int __devinit ad7476_probe(struct spi_device *spi) static int __devinit ad7476_probe(struct spi_device *spi)
{ {
struct ad7476_platform_data *pdata = spi->dev.platform_data;
struct ad7476_state *st; struct ad7476_state *st;
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
int ret, voltage_uv = 0; int ret;
indio_dev = iio_device_alloc(sizeof(*st)); indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) { if (indio_dev == NULL) {
...@@ -118,25 +123,18 @@ static int __devinit ad7476_probe(struct spi_device *spi) ...@@ -118,25 +123,18 @@ static int __devinit ad7476_probe(struct spi_device *spi)
goto error_ret; goto error_ret;
} }
st = iio_priv(indio_dev); st = iio_priv(indio_dev);
st->reg = regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
voltage_uv = regulator_get_voltage(st->reg);
}
st->chip_info = st->chip_info =
&ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data]; &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];
if (st->chip_info->int_vref_mv) st->reg = regulator_get(&spi->dev, "vcc");
st->int_vref_mv = st->chip_info->int_vref_mv; if (IS_ERR(st->reg)) {
else if (pdata && pdata->vref_mv) ret = PTR_ERR(st->reg);
st->int_vref_mv = pdata->vref_mv; goto error_free_dev;
else if (voltage_uv) }
st->int_vref_mv = voltage_uv / 1000;
else ret = regulator_enable(st->reg);
dev_warn(&spi->dev, "reference voltage unspecified\n"); if (ret)
goto error_put_reg;
spi_set_drvdata(spi, indio_dev); spi_set_drvdata(spi, indio_dev);
...@@ -169,11 +167,10 @@ static int __devinit ad7476_probe(struct spi_device *spi) ...@@ -169,11 +167,10 @@ static int __devinit ad7476_probe(struct spi_device *spi)
error_ring_unregister: error_ring_unregister:
ad7476_ring_cleanup(indio_dev); ad7476_ring_cleanup(indio_dev);
error_disable_reg: error_disable_reg:
if (!IS_ERR(st->reg)) regulator_disable(st->reg);
regulator_disable(st->reg);
error_put_reg: error_put_reg:
if (!IS_ERR(st->reg)) regulator_put(st->reg);
regulator_put(st->reg); error_free_dev:
iio_device_free(indio_dev); iio_device_free(indio_dev);
error_ret: error_ret:
...@@ -187,10 +184,8 @@ static int __devexit ad7476_remove(struct spi_device *spi) ...@@ -187,10 +184,8 @@ static int __devexit ad7476_remove(struct spi_device *spi)
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
ad7476_ring_cleanup(indio_dev); ad7476_ring_cleanup(indio_dev);
if (!IS_ERR(st->reg)) { regulator_disable(st->reg);
regulator_disable(st->reg); regulator_put(st->reg);
regulator_put(st->reg);
}
iio_device_free(indio_dev); iio_device_free(indio_dev);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment