aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/iio/dac
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2011-10-19 11:47:50 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-10-19 16:57:01 -0400
commit9dc9961dca37379fd128508aac37e9f4928ee18f (patch)
tree5070cc6955f9b060985a4c45fa89f33b57964ca5 /drivers/staging/iio/dac
parent021c0a381c5c1ae457bb9316669736d2ec66f972 (diff)
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: Lars-Peter Clausen <lars@metafoo.de> Acked-by: Jonathan Cameron <jic23@cam.ac.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/iio/dac')
-rw-r--r--drivers/staging/iio/dac/ad5791.c24
-rw-r--r--drivers/staging/iio/dac/ad5791.h2
2 files changed, 18 insertions, 8 deletions
diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c
index 9a76c4311f9..c465fcfdac4 100644
--- a/drivers/staging/iio/dac/ad5791.c
+++ b/drivers/staging/iio/dac/ad5791.c
@@ -77,7 +77,8 @@ static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val)
77 .indexed = 1, \ 77 .indexed = 1, \
78 .address = AD5791_ADDR_DAC0, \ 78 .address = AD5791_ADDR_DAC0, \
79 .channel = 0, \ 79 .channel = 0, \
80 .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), \ 80 .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED) | \
81 (1 << IIO_CHAN_INFO_OFFSET_SHARED), \
81 .scan_type = IIO_ST('u', bits, 24, shift) \ 82 .scan_type = IIO_ST('u', bits, 24, shift) \
82} 83}
83 84
@@ -225,6 +226,7 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
225 long m) 226 long m)
226{ 227{
227 struct ad5791_state *st = iio_priv(indio_dev); 228 struct ad5791_state *st = iio_priv(indio_dev);
229 u64 val64;
228 int ret; 230 int ret;
229 231
230 switch (m) { 232 switch (m) {
@@ -234,12 +236,16 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
234 return ret; 236 return ret;
235 *val &= AD5791_DAC_MASK; 237 *val &= AD5791_DAC_MASK;
236 *val >>= chan->scan_type.shift; 238 *val >>= chan->scan_type.shift;
237 *val -= (1 << (chan->scan_type.realbits - 1));
238 return IIO_VAL_INT; 239 return IIO_VAL_INT;
239 case (1 << IIO_CHAN_INFO_SCALE_SHARED): 240 case (1 << IIO_CHAN_INFO_SCALE_SHARED):
240 *val = 0; 241 *val = 0;
241 *val2 = (st->vref_mv * 1000) >> chan->scan_type.realbits; 242 *val2 = (st->vref_mv * 1000) >> chan->scan_type.realbits;
242 return IIO_VAL_INT_PLUS_MICRO; 243 return IIO_VAL_INT_PLUS_MICRO;
244 case (1 << IIO_CHAN_INFO_OFFSET_SHARED):
245 val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
246 do_div(val64, st->vref_mv);
247 *val = -val64;
248 return IIO_VAL_INT;
243 default: 249 default:
244 return -EINVAL; 250 return -EINVAL;
245 } 251 }
@@ -257,7 +263,6 @@ static int ad5791_write_raw(struct iio_dev *indio_dev,
257 263
258 switch (mask) { 264 switch (mask) {
259 case 0: 265 case 0:
260 val += (1 << (chan->scan_type.realbits - 1));
261 val &= AD5791_RES_MASK(chan->scan_type.realbits); 266 val &= AD5791_RES_MASK(chan->scan_type.realbits);
262 val <<= chan->scan_type.shift; 267 val <<= chan->scan_type.shift;
263 268
@@ -309,12 +314,15 @@ static int __devinit ad5791_probe(struct spi_device *spi)
309 st->pwr_down = true; 314 st->pwr_down = true;
310 st->spi = spi; 315 st->spi = spi;
311 316
312 if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) 317 if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) {
313 st->vref_mv = (pos_voltage_uv - neg_voltage_uv) / 1000; 318 st->vref_mv = (pos_voltage_uv + neg_voltage_uv) / 1000;
314 else if (pdata) 319 st->vref_neg_mv = neg_voltage_uv / 1000;
315 st->vref_mv = pdata->vref_pos_mv - pdata->vref_neg_mv; 320 } else if (pdata) {
316 else 321 st->vref_mv = pdata->vref_pos_mv + pdata->vref_neg_mv;
322 st->vref_neg_mv = pdata->vref_neg_mv;
323 } else {
317 dev_warn(&spi->dev, "reference voltage unspecified\n"); 324 dev_warn(&spi->dev, "reference voltage unspecified\n");
325 }
318 326
319 ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET); 327 ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
320 if (ret) 328 if (ret)
diff --git a/drivers/staging/iio/dac/ad5791.h b/drivers/staging/iio/dac/ad5791.h
index 2a50a112b96..fd7edbdb4ec 100644
--- a/drivers/staging/iio/dac/ad5791.h
+++ b/drivers/staging/iio/dac/ad5791.h
@@ -82,6 +82,7 @@ struct ad5791_chip_info {
82 * @reg_vss: negative supply regulator 82 * @reg_vss: negative supply regulator
83 * @chip_info: chip model specific constants 83 * @chip_info: chip model specific constants
84 * @vref_mv: actual reference voltage used 84 * @vref_mv: actual reference voltage used
85 * @vref_neg_mv: voltage of the negative supply
85 * @pwr_down_mode current power down mode 86 * @pwr_down_mode current power down mode
86 */ 87 */
87 88
@@ -91,6 +92,7 @@ struct ad5791_state {
91 struct regulator *reg_vss; 92 struct regulator *reg_vss;
92 const struct ad5791_chip_info *chip_info; 93 const struct ad5791_chip_info *chip_info;
93 unsigned short vref_mv; 94 unsigned short vref_mv;
95 unsigned int vref_neg_mv;
94 unsigned ctrl; 96 unsigned ctrl;
95 unsigned pwr_down_mode; 97 unsigned pwr_down_mode;
96 bool pwr_down; 98 bool pwr_down;