66 */
77
88#include <linux/array_size.h>
9+ #include <linux/bitfield.h>
910#include <linux/bitops.h>
1011#include <linux/errno.h>
1112#include <linux/export.h>
1213#include <linux/kstrtox.h>
1314#include <linux/module.h>
1415#include <linux/regulator/consumer.h>
1516#include <linux/sysfs.h>
17+ #include <linux/wordpart.h>
1618
1719#include <linux/iio/iio.h>
1820
@@ -24,6 +26,24 @@ static const char * const ad5686_powerdown_modes[] = {
2426 "three_state"
2527};
2628
29+ static int ad5310_control_sync (struct ad5686_state * st )
30+ {
31+ unsigned int pd_val = st -> pwr_down_mask & st -> pwr_down_mode ;
32+
33+ return st -> write (st , AD5686_CMD_CONTROL_REG , 0 ,
34+ FIELD_PREP (AD5310_PD_MSK , pd_val & AD5686_PD_MSK ) |
35+ FIELD_PREP (AD5310_REF_BIT_MSK , st -> use_internal_vref ? 0 : 1 ));
36+ }
37+
38+ static int ad5683_control_sync (struct ad5686_state * st )
39+ {
40+ unsigned int pd_val = st -> pwr_down_mask & st -> pwr_down_mode ;
41+
42+ return st -> write (st , AD5686_CMD_CONTROL_REG , 0 ,
43+ FIELD_PREP (AD5683_PD_MSK , pd_val & AD5686_PD_MSK ) |
44+ FIELD_PREP (AD5683_REF_BIT_MSK , st -> use_internal_vref ? 0 : 1 ));
45+ }
46+
2747static inline unsigned int ad5686_pd_mask_shift (const struct iio_chan_spec * chan )
2848{
2949 if (chan -> channel == chan -> address )
@@ -98,8 +118,8 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
98118 bool readin ;
99119 int ret ;
100120 struct ad5686_state * st = iio_priv (indio_dev );
101- unsigned int val , ref_bit_msk ;
102- u8 shift , address = 0 ;
121+ unsigned int val ;
122+ u8 address ;
103123
104124 ret = kstrtobool (buf , & readin );
105125 if (ret )
@@ -114,32 +134,34 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
114134
115135 switch (st -> chip_info -> regmap_type ) {
116136 case AD5310_REGMAP :
117- shift = 9 ;
118- ref_bit_msk = AD5310_REF_BIT_MSK ;
137+ ret = ad5310_control_sync (st );
138+ if (ret )
139+ return ret ;
119140 break ;
120141 case AD5683_REGMAP :
121- shift = 13 ;
122- ref_bit_msk = AD5683_REF_BIT_MSK ;
142+ ret = ad5683_control_sync (st );
143+ if (ret )
144+ return ret ;
123145 break ;
124146 case AD5686_REGMAP :
125- shift = 0 ;
126- ref_bit_msk = 0 ;
127147 /* AD5674R/AD5679R have 16 channels and 2 powerdown registers */
128- if (chan -> channel > 0x7 )
148+ val = st -> pwr_down_mask & st -> pwr_down_mode ;
149+ if (chan -> channel > 0x7 ) {
129150 address = 0x8 ;
151+ val = upper_16_bits (val );
152+ } else {
153+ address = 0x0 ;
154+ val = lower_16_bits (val );
155+ }
156+ ret = st -> write (st , AD5686_CMD_POWERDOWN_DAC , address , val );
157+ if (ret )
158+ return ret ;
130159 break ;
131160 default :
132161 return - EINVAL ;
133162 }
134163
135- val = ((st -> pwr_down_mask & st -> pwr_down_mode ) << shift );
136- if (!st -> use_internal_vref )
137- val |= ref_bit_msk ;
138-
139- ret = st -> write (st , AD5686_CMD_POWERDOWN_DAC ,
140- address , val >> (address * 2 ));
141-
142- return ret ? ret : len ;
164+ return len ;
143165}
144166
145167static int ad5686_read_raw (struct iio_dev * indio_dev ,
@@ -453,9 +475,6 @@ int ad5686_probe(struct device *dev,
453475{
454476 struct ad5686_state * st ;
455477 struct iio_dev * indio_dev ;
456- unsigned int val , ref_bit_msk , shift ;
457- bool has_external_vref ;
458- u8 cmd ;
459478 int ret , i ;
460479
461480 indio_dev = devm_iio_device_alloc (dev , sizeof (* st ));
@@ -473,13 +492,12 @@ int ad5686_probe(struct device *dev,
473492 if (ret < 0 && ret != - ENODEV )
474493 return ret ;
475494
476- has_external_vref = ret ! = - ENODEV ;
477- st -> vref_mv = has_external_vref ? ret / 1000 : st -> chip_info -> int_vref_mv ;
495+ st -> use_internal_vref = ret = = - ENODEV ;
496+ st -> vref_mv = st -> use_internal_vref ? st -> chip_info -> int_vref_mv : ret / 1000 ;
478497
479- /* Initialize masks to all ones provided the max shift (last channel) */
480- shift = ad5686_pd_mask_shift (& st -> chip_info -> channels [st -> chip_info -> num_channels - 1 ]);
481- st -> pwr_down_mask = GENMASK (shift + 1 , 0 );
482- st -> pwr_down_mode = GENMASK (shift + 1 , 0 );
498+ /* Initialize masks to all ones */
499+ st -> pwr_down_mask = ~0 ;
500+ st -> pwr_down_mode = ~0 ;
483501
484502 /* Set all the power down mode for all channels to 1K pulldown */
485503 for (i = 0 ; i < st -> chip_info -> num_channels ; i ++ ) {
@@ -501,29 +519,25 @@ int ad5686_probe(struct device *dev,
501519
502520 switch (st -> chip_info -> regmap_type ) {
503521 case AD5310_REGMAP :
504- cmd = AD5686_CMD_CONTROL_REG ;
505- ref_bit_msk = AD5310_REF_BIT_MSK ;
506- st -> use_internal_vref = ! has_external_vref ;
522+ ret = ad5310_control_sync ( st ) ;
523+ if ( ret )
524+ return ret ;
507525 break ;
508526 case AD5683_REGMAP :
509- cmd = AD5686_CMD_CONTROL_REG ;
510- ref_bit_msk = AD5683_REF_BIT_MSK ;
511- st -> use_internal_vref = ! has_external_vref ;
527+ ret = ad5683_control_sync ( st ) ;
528+ if ( ret )
529+ return ret ;
512530 break ;
513531 case AD5686_REGMAP :
514- cmd = AD5686_CMD_INTERNAL_REFER_SETUP ;
515- ref_bit_msk = AD5686_REF_BIT_MSK ;
532+ ret = st -> write (st , AD5686_CMD_INTERNAL_REFER_SETUP , 0 ,
533+ st -> use_internal_vref ? 0 : AD5686_REF_BIT_MSK );
534+ if (ret )
535+ return ret ;
516536 break ;
517537 default :
518538 return - EINVAL ;
519539 }
520540
521- val = has_external_vref ? ref_bit_msk : 0 ;
522-
523- ret = st -> write (st , cmd , 0 , val );
524- if (ret )
525- return ret ;
526-
527541 return devm_iio_device_register (dev , indio_dev );
528542}
529543EXPORT_SYMBOL_NS_GPL (ad5686_probe , "IIO_AD5686" );
0 commit comments