Commit 9dc9961d authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Greg Kroah-Hartman

staging:iio:dac:ad5791: Allow asymmetrical reference voltages

The ad5791 currently assumes that the negative and positive supply have the
same absolute value, which is not necessarily true. This patch introduces a
offset attribute which will contain the negative supply voltage scaled
according to the iio spec. The raw attribute now accepts values in the range
of 0 to max instead of -max/2 to max/2.

While we are at it also fix the vref span calculation. Since both positive and
negative reference voltages are specificed as absolute values we need to add
them and not subtract them to get the reference voltage span.
Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Acked-by: default avatarJonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 021c0a38
...@@ -77,7 +77,8 @@ static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val) ...@@ -77,7 +77,8 @@ static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val)
.indexed = 1, \ .indexed = 1, \
.address = AD5791_ADDR_DAC0, \ .address = AD5791_ADDR_DAC0, \
.channel = 0, \ .channel = 0, \
.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), \ .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED) | \
(1 << IIO_CHAN_INFO_OFFSET_SHARED), \
.scan_type = IIO_ST('u', bits, 24, shift) \ .scan_type = IIO_ST('u', bits, 24, shift) \
} }
...@@ -225,6 +226,7 @@ static int ad5791_read_raw(struct iio_dev *indio_dev, ...@@ -225,6 +226,7 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
long m) long m)
{ {
struct ad5791_state *st = iio_priv(indio_dev); struct ad5791_state *st = iio_priv(indio_dev);
u64 val64;
int ret; int ret;
switch (m) { switch (m) {
...@@ -234,12 +236,16 @@ static int ad5791_read_raw(struct iio_dev *indio_dev, ...@@ -234,12 +236,16 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
return ret; return ret;
*val &= AD5791_DAC_MASK; *val &= AD5791_DAC_MASK;
*val >>= chan->scan_type.shift; *val >>= chan->scan_type.shift;
*val -= (1 << (chan->scan_type.realbits - 1));
return IIO_VAL_INT; return IIO_VAL_INT;
case (1 << IIO_CHAN_INFO_SCALE_SHARED): case (1 << IIO_CHAN_INFO_SCALE_SHARED):
*val = 0; *val = 0;
*val2 = (st->vref_mv * 1000) >> chan->scan_type.realbits; *val2 = (st->vref_mv * 1000) >> chan->scan_type.realbits;
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
case (1 << IIO_CHAN_INFO_OFFSET_SHARED):
val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
do_div(val64, st->vref_mv);
*val = -val64;
return IIO_VAL_INT;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -257,7 +263,6 @@ static int ad5791_write_raw(struct iio_dev *indio_dev, ...@@ -257,7 +263,6 @@ static int ad5791_write_raw(struct iio_dev *indio_dev,
switch (mask) { switch (mask) {
case 0: case 0:
val += (1 << (chan->scan_type.realbits - 1));
val &= AD5791_RES_MASK(chan->scan_type.realbits); val &= AD5791_RES_MASK(chan->scan_type.realbits);
val <<= chan->scan_type.shift; val <<= chan->scan_type.shift;
...@@ -309,12 +314,15 @@ static int __devinit ad5791_probe(struct spi_device *spi) ...@@ -309,12 +314,15 @@ static int __devinit ad5791_probe(struct spi_device *spi)
st->pwr_down = true; st->pwr_down = true;
st->spi = spi; st->spi = spi;
if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) {
st->vref_mv = (pos_voltage_uv - neg_voltage_uv) / 1000; st->vref_mv = (pos_voltage_uv + neg_voltage_uv) / 1000;
else if (pdata) st->vref_neg_mv = neg_voltage_uv / 1000;
st->vref_mv = pdata->vref_pos_mv - pdata->vref_neg_mv; } else if (pdata) {
else st->vref_mv = pdata->vref_pos_mv + pdata->vref_neg_mv;
st->vref_neg_mv = pdata->vref_neg_mv;
} else {
dev_warn(&spi->dev, "reference voltage unspecified\n"); dev_warn(&spi->dev, "reference voltage unspecified\n");
}
ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET); ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
if (ret) if (ret)
......
...@@ -82,6 +82,7 @@ struct ad5791_chip_info { ...@@ -82,6 +82,7 @@ struct ad5791_chip_info {
* @reg_vss: negative supply regulator * @reg_vss: negative supply regulator
* @chip_info: chip model specific constants * @chip_info: chip model specific constants
* @vref_mv: actual reference voltage used * @vref_mv: actual reference voltage used
* @vref_neg_mv: voltage of the negative supply
* @pwr_down_mode current power down mode * @pwr_down_mode current power down mode
*/ */
...@@ -91,6 +92,7 @@ struct ad5791_state { ...@@ -91,6 +92,7 @@ struct ad5791_state {
struct regulator *reg_vss; struct regulator *reg_vss;
const struct ad5791_chip_info *chip_info; const struct ad5791_chip_info *chip_info;
unsigned short vref_mv; unsigned short vref_mv;
unsigned int vref_neg_mv;
unsigned ctrl; unsigned ctrl;
unsigned pwr_down_mode; unsigned pwr_down_mode;
bool pwr_down; bool pwr_down;
......
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