diff options
Diffstat (limited to 'drivers/iio')
-rw-r--r-- | drivers/iio/dac/Kconfig | 7 | ||||
-rw-r--r-- | drivers/iio/dac/ad5064.c | 192 |
2 files changed, 188 insertions, 11 deletions
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index a56b52dbefa0..3c809e2baecb 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig | |||
@@ -10,9 +10,10 @@ config AD5064 | |||
10 | depends on (SPI_MASTER && I2C!=m) || I2C | 10 | depends on (SPI_MASTER && I2C!=m) || I2C |
11 | help | 11 | help |
12 | Say yes here to build support for Analog Devices AD5024, AD5025, AD5044, | 12 | Say yes here to build support for Analog Devices AD5024, AD5025, AD5044, |
13 | AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5629R, AD5648, AD5666, AD5668, | 13 | AD5045, AD5064, AD5064-1, AD5065, AD5625, AD5625R, AD5627, AD5627R, |
14 | AD5669R, LTC2606, LTC2607, LTC2609, LTC2616, LTC2617, LTC2619, LTC2626, | 14 | AD5628, AD5629R, AD5645R, AD5647R, AD5648, AD5665, AD5665R, AD5666, |
15 | LTC2627, LTC2629 Digital to Analog Converter. | 15 | AD5667, AD5667R, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616, |
16 | LTC2617, LTC2619, LTC2626, LTC2627, LTC2629 Digital to Analog Converter. | ||
16 | 17 | ||
17 | To compile this driver as a module, choose M here: the | 18 | To compile this driver as a module, choose M here: the |
18 | module will be called ad5064. | 19 | module will be called ad5064. |
diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index b7f717cadd0b..6803e4a137cd 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5629R, | 2 | * AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5625, AD5625R, |
3 | * AD5648, AD5666, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616, | 3 | * AD5627, AD5627R, AD5628, AD5629R, AD5645R, AD5647R, AD5648, AD5665, AD5665R, |
4 | * AD5666, AD5667, AD5667R, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616, | ||
4 | * LTC2617, LTC2619, LTC2626, LTC2627, LTC2629 Digital to analog converters | 5 | * LTC2617, LTC2619, LTC2626, LTC2627, LTC2629 Digital to analog converters |
5 | * driver | 6 | * driver |
6 | * | 7 | * |
@@ -41,6 +42,9 @@ | |||
41 | #define AD5064_CMD_RESET 0x7 | 42 | #define AD5064_CMD_RESET 0x7 |
42 | #define AD5064_CMD_CONFIG 0x8 | 43 | #define AD5064_CMD_CONFIG 0x8 |
43 | 44 | ||
45 | #define AD5064_CMD_RESET_V2 0x5 | ||
46 | #define AD5064_CMD_CONFIG_V2 0x7 | ||
47 | |||
44 | #define AD5064_CONFIG_DAISY_CHAIN_ENABLE BIT(1) | 48 | #define AD5064_CONFIG_DAISY_CHAIN_ENABLE BIT(1) |
45 | #define AD5064_CONFIG_INT_VREF_ENABLE BIT(0) | 49 | #define AD5064_CONFIG_INT_VREF_ENABLE BIT(0) |
46 | 50 | ||
@@ -51,11 +55,13 @@ | |||
51 | 55 | ||
52 | /** | 56 | /** |
53 | * enum ad5064_regmap_type - Register layout variant | 57 | * enum ad5064_regmap_type - Register layout variant |
54 | * @AD5064_REGMAP_ADI: Analog Devices register map layout | 58 | * @AD5064_REGMAP_ADI: Old Analog Devices register map layout |
59 | * @AD5064_REGMAP_ADI2: New Analog Devices register map layout | ||
55 | * @AD5064_REGMAP_LTC: LTC register map layout | 60 | * @AD5064_REGMAP_LTC: LTC register map layout |
56 | */ | 61 | */ |
57 | enum ad5064_regmap_type { | 62 | enum ad5064_regmap_type { |
58 | AD5064_REGMAP_ADI, | 63 | AD5064_REGMAP_ADI, |
64 | AD5064_REGMAP_ADI2, | ||
59 | AD5064_REGMAP_LTC, | 65 | AD5064_REGMAP_LTC, |
60 | }; | 66 | }; |
61 | 67 | ||
@@ -125,14 +131,30 @@ enum ad5064_type { | |||
125 | ID_AD5064, | 131 | ID_AD5064, |
126 | ID_AD5064_1, | 132 | ID_AD5064_1, |
127 | ID_AD5065, | 133 | ID_AD5065, |
134 | ID_AD5625, | ||
135 | ID_AD5625R_1V25, | ||
136 | ID_AD5625R_2V5, | ||
137 | ID_AD5627, | ||
138 | ID_AD5627R_1V25, | ||
139 | ID_AD5627R_2V5, | ||
128 | ID_AD5628_1, | 140 | ID_AD5628_1, |
129 | ID_AD5628_2, | 141 | ID_AD5628_2, |
130 | ID_AD5629_1, | 142 | ID_AD5629_1, |
131 | ID_AD5629_2, | 143 | ID_AD5629_2, |
144 | ID_AD5645R_1V25, | ||
145 | ID_AD5645R_2V5, | ||
146 | ID_AD5647R_1V25, | ||
147 | ID_AD5647R_2V5, | ||
132 | ID_AD5648_1, | 148 | ID_AD5648_1, |
133 | ID_AD5648_2, | 149 | ID_AD5648_2, |
150 | ID_AD5665, | ||
151 | ID_AD5665R_1V25, | ||
152 | ID_AD5665R_2V5, | ||
134 | ID_AD5666_1, | 153 | ID_AD5666_1, |
135 | ID_AD5666_2, | 154 | ID_AD5666_2, |
155 | ID_AD5667, | ||
156 | ID_AD5667R_1V25, | ||
157 | ID_AD5667R_2V5, | ||
136 | ID_AD5668_1, | 158 | ID_AD5668_1, |
137 | ID_AD5668_2, | 159 | ID_AD5668_2, |
138 | ID_AD5669_1, | 160 | ID_AD5669_1, |
@@ -160,17 +182,23 @@ static int ad5064_sync_powerdown_mode(struct ad5064_state *st, | |||
160 | const struct iio_chan_spec *chan) | 182 | const struct iio_chan_spec *chan) |
161 | { | 183 | { |
162 | unsigned int val, address; | 184 | unsigned int val, address; |
185 | unsigned int shift; | ||
163 | int ret; | 186 | int ret; |
164 | 187 | ||
165 | if (st->chip_info->regmap_type == AD5064_REGMAP_LTC) { | 188 | if (st->chip_info->regmap_type == AD5064_REGMAP_LTC) { |
166 | val = 0; | 189 | val = 0; |
167 | address = chan->address; | 190 | address = chan->address; |
168 | } else { | 191 | } else { |
169 | address = 0; | 192 | if (st->chip_info->regmap_type == AD5064_REGMAP_ADI2) |
193 | shift = 4; | ||
194 | else | ||
195 | shift = 8; | ||
196 | |||
170 | val = (0x1 << chan->address); | 197 | val = (0x1 << chan->address); |
198 | address = 0; | ||
171 | 199 | ||
172 | if (st->pwr_down[chan->channel]) | 200 | if (st->pwr_down[chan->channel]) |
173 | val |= st->pwr_down_mode[chan->channel] << 8; | 201 | val |= st->pwr_down_mode[chan->channel] << shift; |
174 | } | 202 | } |
175 | 203 | ||
176 | ret = ad5064_write(st, AD5064_CMD_POWERDOWN_DAC, address, val, 0); | 204 | ret = ad5064_write(st, AD5064_CMD_POWERDOWN_DAC, address, val, 0); |
@@ -391,6 +419,7 @@ static DECLARE_AD5065_CHANNELS(ad5045_channels, 14, 6, ad5064_ext_info); | |||
391 | static DECLARE_AD5065_CHANNELS(ad5065_channels, 16, 4, ad5064_ext_info); | 419 | static DECLARE_AD5065_CHANNELS(ad5065_channels, 16, 4, ad5064_ext_info); |
392 | 420 | ||
393 | static DECLARE_AD5064_CHANNELS(ad5629_channels, 12, 4, ad5064_ext_info); | 421 | static DECLARE_AD5064_CHANNELS(ad5629_channels, 12, 4, ad5064_ext_info); |
422 | static DECLARE_AD5064_CHANNELS(ad5645_channels, 14, 2, ad5064_ext_info); | ||
394 | static DECLARE_AD5064_CHANNELS(ad5669_channels, 16, 0, ad5064_ext_info); | 423 | static DECLARE_AD5064_CHANNELS(ad5669_channels, 16, 0, ad5064_ext_info); |
395 | 424 | ||
396 | static DECLARE_AD5064_CHANNELS(ltc2607_channels, 16, 0, ltc2617_ext_info); | 425 | static DECLARE_AD5064_CHANNELS(ltc2607_channels, 16, 0, ltc2617_ext_info); |
@@ -440,6 +469,46 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { | |||
440 | .num_channels = 2, | 469 | .num_channels = 2, |
441 | .regmap_type = AD5064_REGMAP_ADI, | 470 | .regmap_type = AD5064_REGMAP_ADI, |
442 | }, | 471 | }, |
472 | [ID_AD5625] = { | ||
473 | .shared_vref = true, | ||
474 | .channels = ad5629_channels, | ||
475 | .num_channels = 4, | ||
476 | .regmap_type = AD5064_REGMAP_ADI2 | ||
477 | }, | ||
478 | [ID_AD5625R_1V25] = { | ||
479 | .shared_vref = true, | ||
480 | .internal_vref = 1250000, | ||
481 | .channels = ad5629_channels, | ||
482 | .num_channels = 4, | ||
483 | .regmap_type = AD5064_REGMAP_ADI2 | ||
484 | }, | ||
485 | [ID_AD5625R_2V5] = { | ||
486 | .shared_vref = true, | ||
487 | .internal_vref = 2500000, | ||
488 | .channels = ad5629_channels, | ||
489 | .num_channels = 4, | ||
490 | .regmap_type = AD5064_REGMAP_ADI2 | ||
491 | }, | ||
492 | [ID_AD5627] = { | ||
493 | .shared_vref = true, | ||
494 | .channels = ad5629_channels, | ||
495 | .num_channels = 2, | ||
496 | .regmap_type = AD5064_REGMAP_ADI2 | ||
497 | }, | ||
498 | [ID_AD5627R_1V25] = { | ||
499 | .shared_vref = true, | ||
500 | .internal_vref = 1250000, | ||
501 | .channels = ad5629_channels, | ||
502 | .num_channels = 2, | ||
503 | .regmap_type = AD5064_REGMAP_ADI2 | ||
504 | }, | ||
505 | [ID_AD5627R_2V5] = { | ||
506 | .shared_vref = true, | ||
507 | .internal_vref = 2500000, | ||
508 | .channels = ad5629_channels, | ||
509 | .num_channels = 2, | ||
510 | .regmap_type = AD5064_REGMAP_ADI2 | ||
511 | }, | ||
443 | [ID_AD5628_1] = { | 512 | [ID_AD5628_1] = { |
444 | .shared_vref = true, | 513 | .shared_vref = true, |
445 | .internal_vref = 2500000, | 514 | .internal_vref = 2500000, |
@@ -468,6 +537,34 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { | |||
468 | .num_channels = 8, | 537 | .num_channels = 8, |
469 | .regmap_type = AD5064_REGMAP_ADI, | 538 | .regmap_type = AD5064_REGMAP_ADI, |
470 | }, | 539 | }, |
540 | [ID_AD5645R_1V25] = { | ||
541 | .shared_vref = true, | ||
542 | .internal_vref = 1250000, | ||
543 | .channels = ad5645_channels, | ||
544 | .num_channels = 4, | ||
545 | .regmap_type = AD5064_REGMAP_ADI2 | ||
546 | }, | ||
547 | [ID_AD5645R_2V5] = { | ||
548 | .shared_vref = true, | ||
549 | .internal_vref = 2500000, | ||
550 | .channels = ad5645_channels, | ||
551 | .num_channels = 4, | ||
552 | .regmap_type = AD5064_REGMAP_ADI2 | ||
553 | }, | ||
554 | [ID_AD5647R_1V25] = { | ||
555 | .shared_vref = true, | ||
556 | .internal_vref = 1250000, | ||
557 | .channels = ad5645_channels, | ||
558 | .num_channels = 2, | ||
559 | .regmap_type = AD5064_REGMAP_ADI2 | ||
560 | }, | ||
561 | [ID_AD5647R_2V5] = { | ||
562 | .shared_vref = true, | ||
563 | .internal_vref = 2500000, | ||
564 | .channels = ad5645_channels, | ||
565 | .num_channels = 2, | ||
566 | .regmap_type = AD5064_REGMAP_ADI2 | ||
567 | }, | ||
471 | [ID_AD5648_1] = { | 568 | [ID_AD5648_1] = { |
472 | .shared_vref = true, | 569 | .shared_vref = true, |
473 | .internal_vref = 2500000, | 570 | .internal_vref = 2500000, |
@@ -482,6 +579,26 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { | |||
482 | .num_channels = 8, | 579 | .num_channels = 8, |
483 | .regmap_type = AD5064_REGMAP_ADI, | 580 | .regmap_type = AD5064_REGMAP_ADI, |
484 | }, | 581 | }, |
582 | [ID_AD5665] = { | ||
583 | .shared_vref = true, | ||
584 | .channels = ad5669_channels, | ||
585 | .num_channels = 4, | ||
586 | .regmap_type = AD5064_REGMAP_ADI2 | ||
587 | }, | ||
588 | [ID_AD5665R_1V25] = { | ||
589 | .shared_vref = true, | ||
590 | .internal_vref = 1250000, | ||
591 | .channels = ad5669_channels, | ||
592 | .num_channels = 4, | ||
593 | .regmap_type = AD5064_REGMAP_ADI2 | ||
594 | }, | ||
595 | [ID_AD5665R_2V5] = { | ||
596 | .shared_vref = true, | ||
597 | .internal_vref = 2500000, | ||
598 | .channels = ad5669_channels, | ||
599 | .num_channels = 4, | ||
600 | .regmap_type = AD5064_REGMAP_ADI2 | ||
601 | }, | ||
485 | [ID_AD5666_1] = { | 602 | [ID_AD5666_1] = { |
486 | .shared_vref = true, | 603 | .shared_vref = true, |
487 | .internal_vref = 2500000, | 604 | .internal_vref = 2500000, |
@@ -496,6 +613,26 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { | |||
496 | .num_channels = 4, | 613 | .num_channels = 4, |
497 | .regmap_type = AD5064_REGMAP_ADI, | 614 | .regmap_type = AD5064_REGMAP_ADI, |
498 | }, | 615 | }, |
616 | [ID_AD5667] = { | ||
617 | .shared_vref = true, | ||
618 | .channels = ad5669_channels, | ||
619 | .num_channels = 2, | ||
620 | .regmap_type = AD5064_REGMAP_ADI2 | ||
621 | }, | ||
622 | [ID_AD5667R_1V25] = { | ||
623 | .shared_vref = true, | ||
624 | .internal_vref = 1250000, | ||
625 | .channels = ad5669_channels, | ||
626 | .num_channels = 2, | ||
627 | .regmap_type = AD5064_REGMAP_ADI2 | ||
628 | }, | ||
629 | [ID_AD5667R_2V5] = { | ||
630 | .shared_vref = true, | ||
631 | .internal_vref = 2500000, | ||
632 | .channels = ad5669_channels, | ||
633 | .num_channels = 2, | ||
634 | .regmap_type = AD5064_REGMAP_ADI2 | ||
635 | }, | ||
499 | [ID_AD5668_1] = { | 636 | [ID_AD5668_1] = { |
500 | .shared_vref = true, | 637 | .shared_vref = true, |
501 | .internal_vref = 2500000, | 638 | .internal_vref = 2500000, |
@@ -607,6 +744,22 @@ static const char * const ad5064_vref_name(struct ad5064_state *st, | |||
607 | return st->chip_info->shared_vref ? "vref" : ad5064_vref_names[vref]; | 744 | return st->chip_info->shared_vref ? "vref" : ad5064_vref_names[vref]; |
608 | } | 745 | } |
609 | 746 | ||
747 | static int ad5064_set_config(struct ad5064_state *st, unsigned int val) | ||
748 | { | ||
749 | unsigned int cmd; | ||
750 | |||
751 | switch (st->chip_info->regmap_type) { | ||
752 | case AD5064_REGMAP_ADI2: | ||
753 | cmd = AD5064_CMD_CONFIG_V2; | ||
754 | break; | ||
755 | default: | ||
756 | cmd = AD5064_CMD_CONFIG; | ||
757 | break; | ||
758 | } | ||
759 | |||
760 | return ad5064_write(st, cmd, 0, val, 0); | ||
761 | } | ||
762 | |||
610 | static int ad5064_probe(struct device *dev, enum ad5064_type type, | 763 | static int ad5064_probe(struct device *dev, enum ad5064_type type, |
611 | const char *name, ad5064_write_func write) | 764 | const char *name, ad5064_write_func write) |
612 | { | 765 | { |
@@ -636,8 +789,7 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type, | |||
636 | if (!st->chip_info->internal_vref) | 789 | if (!st->chip_info->internal_vref) |
637 | return ret; | 790 | return ret; |
638 | st->use_internal_vref = true; | 791 | st->use_internal_vref = true; |
639 | ret = ad5064_write(st, AD5064_CMD_CONFIG, 0, | 792 | ret = ad5064_set_config(st, AD5064_CONFIG_INT_VREF_ENABLE); |
640 | AD5064_CONFIG_INT_VREF_ENABLE, 0); | ||
641 | if (ret) { | 793 | if (ret) { |
642 | dev_err(dev, "Failed to enable internal vref: %d\n", | 794 | dev_err(dev, "Failed to enable internal vref: %d\n", |
643 | ret); | 795 | ret); |
@@ -766,9 +918,19 @@ static int ad5064_i2c_write(struct ad5064_state *st, unsigned int cmd, | |||
766 | unsigned int addr, unsigned int val) | 918 | unsigned int addr, unsigned int val) |
767 | { | 919 | { |
768 | struct i2c_client *i2c = to_i2c_client(st->dev); | 920 | struct i2c_client *i2c = to_i2c_client(st->dev); |
921 | unsigned int cmd_shift; | ||
769 | int ret; | 922 | int ret; |
770 | 923 | ||
771 | st->data.i2c[0] = (cmd << 4) | addr; | 924 | switch (st->chip_info->regmap_type) { |
925 | case AD5064_REGMAP_ADI2: | ||
926 | cmd_shift = 3; | ||
927 | break; | ||
928 | default: | ||
929 | cmd_shift = 4; | ||
930 | break; | ||
931 | } | ||
932 | |||
933 | st->data.i2c[0] = (cmd << cmd_shift) | addr; | ||
772 | put_unaligned_be16(val, &st->data.i2c[1]); | 934 | put_unaligned_be16(val, &st->data.i2c[1]); |
773 | 935 | ||
774 | ret = i2c_master_send(i2c, st->data.i2c, 3); | 936 | ret = i2c_master_send(i2c, st->data.i2c, 3); |
@@ -791,9 +953,23 @@ static int ad5064_i2c_remove(struct i2c_client *i2c) | |||
791 | } | 953 | } |
792 | 954 | ||
793 | static const struct i2c_device_id ad5064_i2c_ids[] = { | 955 | static const struct i2c_device_id ad5064_i2c_ids[] = { |
956 | {"ad5625", ID_AD5625 }, | ||
957 | {"ad5625r-1v25", ID_AD5625R_1V25 }, | ||
958 | {"ad5625r-2v5", ID_AD5625R_2V5 }, | ||
959 | {"ad5627", ID_AD5627 }, | ||
960 | {"ad5627r-1v25", ID_AD5627R_1V25 }, | ||
961 | {"ad5627r-2v5", ID_AD5627R_2V5 }, | ||
794 | {"ad5629-1", ID_AD5629_1}, | 962 | {"ad5629-1", ID_AD5629_1}, |
795 | {"ad5629-2", ID_AD5629_2}, | 963 | {"ad5629-2", ID_AD5629_2}, |
796 | {"ad5629-3", ID_AD5629_2}, /* similar enough to ad5629-2 */ | 964 | {"ad5629-3", ID_AD5629_2}, /* similar enough to ad5629-2 */ |
965 | {"ad5645r-1v25", ID_AD5645R_1V25 }, | ||
966 | {"ad5645r-2v5", ID_AD5645R_2V5 }, | ||
967 | {"ad5665", ID_AD5665 }, | ||
968 | {"ad5665r-1v25", ID_AD5665R_1V25 }, | ||
969 | {"ad5665r-2v5", ID_AD5665R_2V5 }, | ||
970 | {"ad5667", ID_AD5667 }, | ||
971 | {"ad5667r-1v25", ID_AD5667R_1V25 }, | ||
972 | {"ad5667r-2v5", ID_AD5667R_2V5 }, | ||
797 | {"ad5669-1", ID_AD5669_1}, | 973 | {"ad5669-1", ID_AD5669_1}, |
798 | {"ad5669-2", ID_AD5669_2}, | 974 | {"ad5669-2", ID_AD5669_2}, |
799 | {"ad5669-3", ID_AD5669_2}, /* similar enough to ad5669-2 */ | 975 | {"ad5669-3", ID_AD5669_2}, /* similar enough to ad5669-2 */ |