150150#define AD7173_FILTER_ODR0_MASK GENMASK(5, 0)
151151#define AD7173_MAX_CONFIGS 8
152152
153+ #define AD7173_MODE_CAL_INT_ZERO 0x4 /* Internal Zero-Scale Calibration */
154+ #define AD7173_MODE_CAL_INT_FULL 0x5 /* Internal Full-Scale Calibration */
155+ #define AD7173_MODE_CAL_SYS_ZERO 0x6 /* System Zero-Scale Calibration */
156+ #define AD7173_MODE_CAL_SYS_FULL 0x7 /* System Full-Scale Calibration */
157+
153158struct ad7173_device_info {
154159 const unsigned int * sinc5_data_rates ;
155160 unsigned int num_sinc5_data_rates ;
@@ -175,6 +180,7 @@ struct ad7173_device_info {
175180 bool has_input_buf ;
176181 bool has_int_ref ;
177182 bool has_ref2 ;
183+ bool has_internal_fs_calibration ;
178184 bool higher_gpio_bits ;
179185 u8 num_gpios ;
180186};
@@ -195,6 +201,7 @@ struct ad7173_channel_config {
195201struct ad7173_channel {
196202 unsigned int ain ;
197203 struct ad7173_channel_config cfg ;
204+ u8 syscalib_mode ;
198205};
199206
200207struct ad7173_state {
@@ -271,6 +278,7 @@ static const struct ad7173_device_info ad4111_device_info = {
271278 .has_input_buf = true,
272279 .has_current_inputs = true,
273280 .has_int_ref = true,
281+ .has_internal_fs_calibration = true,
274282 .clock = 2 * HZ_PER_MHZ ,
275283 .sinc5_data_rates = ad7173_sinc5_data_rates ,
276284 .num_sinc5_data_rates = ARRAY_SIZE (ad7173_sinc5_data_rates ),
@@ -290,6 +298,7 @@ static const struct ad7173_device_info ad4112_device_info = {
290298 .has_input_buf = true,
291299 .has_current_inputs = true,
292300 .has_int_ref = true,
301+ .has_internal_fs_calibration = true,
293302 .clock = 2 * HZ_PER_MHZ ,
294303 .sinc5_data_rates = ad7173_sinc5_data_rates ,
295304 .num_sinc5_data_rates = ARRAY_SIZE (ad7173_sinc5_data_rates ),
@@ -325,6 +334,7 @@ static const struct ad7173_device_info ad4114_device_info = {
325334 .has_temp = true,
326335 .has_input_buf = true,
327336 .has_int_ref = true,
337+ .has_internal_fs_calibration = true,
328338 .clock = 2 * HZ_PER_MHZ ,
329339 .sinc5_data_rates = ad7173_sinc5_data_rates ,
330340 .num_sinc5_data_rates = ARRAY_SIZE (ad7173_sinc5_data_rates ),
@@ -342,6 +352,7 @@ static const struct ad7173_device_info ad4115_device_info = {
342352 .has_temp = true,
343353 .has_input_buf = true,
344354 .has_int_ref = true,
355+ .has_internal_fs_calibration = true,
345356 .clock = 8 * HZ_PER_MHZ ,
346357 .sinc5_data_rates = ad4115_sinc5_data_rates ,
347358 .num_sinc5_data_rates = ARRAY_SIZE (ad4115_sinc5_data_rates ),
@@ -359,6 +370,7 @@ static const struct ad7173_device_info ad4116_device_info = {
359370 .has_temp = true,
360371 .has_input_buf = true,
361372 .has_int_ref = true,
373+ .has_internal_fs_calibration = true,
362374 .clock = 4 * HZ_PER_MHZ ,
363375 .sinc5_data_rates = ad4116_sinc5_data_rates ,
364376 .num_sinc5_data_rates = ARRAY_SIZE (ad4116_sinc5_data_rates ),
@@ -504,6 +516,105 @@ static const struct regmap_config ad7173_regmap_config = {
504516 .read_flag_mask = BIT (6 ),
505517};
506518
519+ enum {
520+ AD7173_SYSCALIB_ZERO_SCALE ,
521+ AD7173_SYSCALIB_FULL_SCALE ,
522+ };
523+
524+ static const char * const ad7173_syscalib_modes [] = {
525+ [AD7173_SYSCALIB_ZERO_SCALE ] = "zero_scale" ,
526+ [AD7173_SYSCALIB_FULL_SCALE ] = "full_scale" ,
527+ };
528+
529+ static int ad7173_set_syscalib_mode (struct iio_dev * indio_dev ,
530+ const struct iio_chan_spec * chan ,
531+ unsigned int mode )
532+ {
533+ struct ad7173_state * st = iio_priv (indio_dev );
534+
535+ st -> channels [chan -> channel ].syscalib_mode = mode ;
536+
537+ return 0 ;
538+ }
539+
540+ static int ad7173_get_syscalib_mode (struct iio_dev * indio_dev ,
541+ const struct iio_chan_spec * chan )
542+ {
543+ struct ad7173_state * st = iio_priv (indio_dev );
544+
545+ return st -> channels [chan -> channel ].syscalib_mode ;
546+ }
547+
548+ static ssize_t ad7173_write_syscalib (struct iio_dev * indio_dev ,
549+ uintptr_t private ,
550+ const struct iio_chan_spec * chan ,
551+ const char * buf , size_t len )
552+ {
553+ struct ad7173_state * st = iio_priv (indio_dev );
554+ bool sys_calib ;
555+ int ret , mode ;
556+
557+ ret = kstrtobool (buf , & sys_calib );
558+ if (ret )
559+ return ret ;
560+
561+ mode = st -> channels [chan -> channel ].syscalib_mode ;
562+ if (sys_calib ) {
563+ if (mode == AD7173_SYSCALIB_ZERO_SCALE )
564+ ret = ad_sd_calibrate (& st -> sd , AD7173_MODE_CAL_SYS_ZERO ,
565+ chan -> address );
566+ else
567+ ret = ad_sd_calibrate (& st -> sd , AD7173_MODE_CAL_SYS_FULL ,
568+ chan -> address );
569+ }
570+
571+ return ret ? : len ;
572+ }
573+
574+ static const struct iio_enum ad7173_syscalib_mode_enum = {
575+ .items = ad7173_syscalib_modes ,
576+ .num_items = ARRAY_SIZE (ad7173_syscalib_modes ),
577+ .set = ad7173_set_syscalib_mode ,
578+ .get = ad7173_get_syscalib_mode
579+ };
580+
581+ static const struct iio_chan_spec_ext_info ad7173_calibsys_ext_info [] = {
582+ {
583+ .name = "sys_calibration" ,
584+ .write = ad7173_write_syscalib ,
585+ .shared = IIO_SEPARATE ,
586+ },
587+ IIO_ENUM ("sys_calibration_mode" , IIO_SEPARATE ,
588+ & ad7173_syscalib_mode_enum ),
589+ IIO_ENUM_AVAILABLE ("sys_calibration_mode" , IIO_SHARED_BY_TYPE ,
590+ & ad7173_syscalib_mode_enum ),
591+ { }
592+ };
593+
594+ static int ad7173_calibrate_all (struct ad7173_state * st , struct iio_dev * indio_dev )
595+ {
596+ int ret ;
597+ int i ;
598+
599+ for (i = 0 ; i < st -> num_channels ; i ++ ) {
600+ if (indio_dev -> channels [i ].type != IIO_VOLTAGE )
601+ continue ;
602+
603+ ret = ad_sd_calibrate (& st -> sd , AD7173_MODE_CAL_INT_ZERO , st -> channels [i ].ain );
604+ if (ret < 0 )
605+ return ret ;
606+
607+ if (st -> info -> has_internal_fs_calibration ) {
608+ ret = ad_sd_calibrate (& st -> sd , AD7173_MODE_CAL_INT_FULL ,
609+ st -> channels [i ].ain );
610+ if (ret < 0 )
611+ return ret ;
612+ }
613+ }
614+
615+ return 0 ;
616+ }
617+
507618static int ad7173_mask_xlate (struct gpio_regmap * gpio , unsigned int base ,
508619 unsigned int offset , unsigned int * reg ,
509620 unsigned int * mask )
@@ -801,6 +912,10 @@ static int ad7173_setup(struct iio_dev *indio_dev)
801912 if (!st -> config_cnts )
802913 return - ENOMEM ;
803914
915+ ret = ad7173_calibrate_all (st , indio_dev );
916+ if (ret )
917+ return ret ;
918+
804919 /* All channels are enabled by default after a reset */
805920 return ad7173_disable_all (& st -> sd );
806921}
@@ -1023,6 +1138,7 @@ static const struct iio_chan_spec ad7173_channel_template = {
10231138 .storagebits = 32 ,
10241139 .endianness = IIO_BE ,
10251140 },
1141+ .ext_info = ad7173_calibsys_ext_info ,
10261142};
10271143
10281144static const struct iio_chan_spec ad7173_temp_iio_channel_template = {
0 commit comments