aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2015-10-13 12:15:38 -0400
committerJonathan Cameron <jic23@kernel.org>2015-10-25 08:30:42 -0400
commit5dcbe97bedd6ba4b0f574a96cc2e293d26f3d857 (patch)
tree7aa8d91b321d07d8b2a229beb2bb458109102e22
parent03fe472ef33b7f31fbd11d300dbb3fdab9c00fd4 (diff)
iio: ad5064: Fix ad5629/ad5669 shift
The ad5629/ad5669 are the I2C variant of the ad5628/ad5668, which has a SPI interface. They are mostly identical with the exception that the shift factor is different. Currently the driver does not take care of this difference which leads to incorrect DAC output values. Fix this by introducing a custom channel spec for the ad5629/ad5669 with the correct shift factor. Fixes: commit 6a17a0768f77 ("iio:dac:ad5064: Add support for the ad5629r and ad5669r") Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Cc: <Stable@vger.kernel.org> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/iio/dac/ad5064.c83
1 files changed, 57 insertions, 26 deletions
diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c
index 7e7ebf30e954..978f130ca678 100644
--- a/drivers/iio/dac/ad5064.c
+++ b/drivers/iio/dac/ad5064.c
@@ -113,12 +113,16 @@ enum ad5064_type {
113 ID_AD5065, 113 ID_AD5065,
114 ID_AD5628_1, 114 ID_AD5628_1,
115 ID_AD5628_2, 115 ID_AD5628_2,
116 ID_AD5629_1,
117 ID_AD5629_2,
116 ID_AD5648_1, 118 ID_AD5648_1,
117 ID_AD5648_2, 119 ID_AD5648_2,
118 ID_AD5666_1, 120 ID_AD5666_1,
119 ID_AD5666_2, 121 ID_AD5666_2,
120 ID_AD5668_1, 122 ID_AD5668_1,
121 ID_AD5668_2, 123 ID_AD5668_2,
124 ID_AD5669_1,
125 ID_AD5669_2,
122}; 126};
123 127
124static int ad5064_write(struct ad5064_state *st, unsigned int cmd, 128static int ad5064_write(struct ad5064_state *st, unsigned int cmd,
@@ -291,7 +295,7 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
291 { }, 295 { },
292}; 296};
293 297
294#define AD5064_CHANNEL(chan, addr, bits) { \ 298#define AD5064_CHANNEL(chan, addr, bits, _shift) { \
295 .type = IIO_VOLTAGE, \ 299 .type = IIO_VOLTAGE, \
296 .indexed = 1, \ 300 .indexed = 1, \
297 .output = 1, \ 301 .output = 1, \
@@ -303,36 +307,39 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
303 .sign = 'u', \ 307 .sign = 'u', \
304 .realbits = (bits), \ 308 .realbits = (bits), \
305 .storagebits = 16, \ 309 .storagebits = 16, \
306 .shift = 20 - bits, \ 310 .shift = (_shift), \
307 }, \ 311 }, \
308 .ext_info = ad5064_ext_info, \ 312 .ext_info = ad5064_ext_info, \
309} 313}
310 314
311#define DECLARE_AD5064_CHANNELS(name, bits) \ 315#define DECLARE_AD5064_CHANNELS(name, bits, shift) \
312const struct iio_chan_spec name[] = { \ 316const struct iio_chan_spec name[] = { \
313 AD5064_CHANNEL(0, 0, bits), \ 317 AD5064_CHANNEL(0, 0, bits, shift), \
314 AD5064_CHANNEL(1, 1, bits), \ 318 AD5064_CHANNEL(1, 1, bits, shift), \
315 AD5064_CHANNEL(2, 2, bits), \ 319 AD5064_CHANNEL(2, 2, bits, shift), \
316 AD5064_CHANNEL(3, 3, bits), \ 320 AD5064_CHANNEL(3, 3, bits, shift), \
317 AD5064_CHANNEL(4, 4, bits), \ 321 AD5064_CHANNEL(4, 4, bits, shift), \
318 AD5064_CHANNEL(5, 5, bits), \ 322 AD5064_CHANNEL(5, 5, bits, shift), \
319 AD5064_CHANNEL(6, 6, bits), \ 323 AD5064_CHANNEL(6, 6, bits, shift), \
320 AD5064_CHANNEL(7, 7, bits), \ 324 AD5064_CHANNEL(7, 7, bits, shift), \
321} 325}
322 326
323#define DECLARE_AD5065_CHANNELS(name, bits) \ 327#define DECLARE_AD5065_CHANNELS(name, bits, shift) \
324const struct iio_chan_spec name[] = { \ 328const struct iio_chan_spec name[] = { \
325 AD5064_CHANNEL(0, 0, bits), \ 329 AD5064_CHANNEL(0, 0, bits, shift), \
326 AD5064_CHANNEL(1, 3, bits), \ 330 AD5064_CHANNEL(1, 3, bits, shift), \
327} 331}
328 332
329static DECLARE_AD5064_CHANNELS(ad5024_channels, 12); 333static DECLARE_AD5064_CHANNELS(ad5024_channels, 12, 8);
330static DECLARE_AD5064_CHANNELS(ad5044_channels, 14); 334static DECLARE_AD5064_CHANNELS(ad5044_channels, 14, 6);
331static DECLARE_AD5064_CHANNELS(ad5064_channels, 16); 335static DECLARE_AD5064_CHANNELS(ad5064_channels, 16, 4);
332 336
333static DECLARE_AD5065_CHANNELS(ad5025_channels, 12); 337static DECLARE_AD5065_CHANNELS(ad5025_channels, 12, 8);
334static DECLARE_AD5065_CHANNELS(ad5045_channels, 14); 338static DECLARE_AD5065_CHANNELS(ad5045_channels, 14, 6);
335static DECLARE_AD5065_CHANNELS(ad5065_channels, 16); 339static DECLARE_AD5065_CHANNELS(ad5065_channels, 16, 4);
340
341static DECLARE_AD5064_CHANNELS(ad5629_channels, 12, 4);
342static DECLARE_AD5064_CHANNELS(ad5669_channels, 16, 0);
336 343
337static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { 344static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
338 [ID_AD5024] = { 345 [ID_AD5024] = {
@@ -382,6 +389,18 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
382 .channels = ad5024_channels, 389 .channels = ad5024_channels,
383 .num_channels = 8, 390 .num_channels = 8,
384 }, 391 },
392 [ID_AD5629_1] = {
393 .shared_vref = true,
394 .internal_vref = 2500000,
395 .channels = ad5629_channels,
396 .num_channels = 8,
397 },
398 [ID_AD5629_2] = {
399 .shared_vref = true,
400 .internal_vref = 5000000,
401 .channels = ad5629_channels,
402 .num_channels = 8,
403 },
385 [ID_AD5648_1] = { 404 [ID_AD5648_1] = {
386 .shared_vref = true, 405 .shared_vref = true,
387 .internal_vref = 2500000, 406 .internal_vref = 2500000,
@@ -418,6 +437,18 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
418 .channels = ad5064_channels, 437 .channels = ad5064_channels,
419 .num_channels = 8, 438 .num_channels = 8,
420 }, 439 },
440 [ID_AD5669_1] = {
441 .shared_vref = true,
442 .internal_vref = 2500000,
443 .channels = ad5669_channels,
444 .num_channels = 8,
445 },
446 [ID_AD5669_2] = {
447 .shared_vref = true,
448 .internal_vref = 5000000,
449 .channels = ad5669_channels,
450 .num_channels = 8,
451 },
421}; 452};
422 453
423static inline unsigned int ad5064_num_vref(struct ad5064_state *st) 454static inline unsigned int ad5064_num_vref(struct ad5064_state *st)
@@ -623,12 +654,12 @@ static int ad5064_i2c_remove(struct i2c_client *i2c)
623} 654}
624 655
625static const struct i2c_device_id ad5064_i2c_ids[] = { 656static const struct i2c_device_id ad5064_i2c_ids[] = {
626 {"ad5629-1", ID_AD5628_1}, 657 {"ad5629-1", ID_AD5629_1},
627 {"ad5629-2", ID_AD5628_2}, 658 {"ad5629-2", ID_AD5629_2},
628 {"ad5629-3", ID_AD5628_2}, /* similar enough to ad5629-2 */ 659 {"ad5629-3", ID_AD5629_2}, /* similar enough to ad5629-2 */
629 {"ad5669-1", ID_AD5668_1}, 660 {"ad5669-1", ID_AD5669_1},
630 {"ad5669-2", ID_AD5668_2}, 661 {"ad5669-2", ID_AD5669_2},
631 {"ad5669-3", ID_AD5668_2}, /* similar enough to ad5669-2 */ 662 {"ad5669-3", ID_AD5669_2}, /* similar enough to ad5669-2 */
632 {} 663 {}
633}; 664};
634MODULE_DEVICE_TABLE(i2c, ad5064_i2c_ids); 665MODULE_DEVICE_TABLE(i2c, ad5064_i2c_ids);