@@ -181,6 +181,7 @@ struct ad7124_channel {
181181 struct ad7124_channel_config cfg ;
182182 unsigned int ain ;
183183 unsigned int slot ;
184+ u8 syscalib_mode ;
184185};
185186
186187struct ad7124_state {
@@ -202,23 +203,6 @@ struct ad7124_state {
202203 DECLARE_KFIFO (live_cfgs_fifo , struct ad7124_channel_config * , AD7124_MAX_CONFIGS );
203204};
204205
205- static const struct iio_chan_spec ad7124_channel_template = {
206- .type = IIO_VOLTAGE ,
207- .indexed = 1 ,
208- .differential = 1 ,
209- .info_mask_separate = BIT (IIO_CHAN_INFO_RAW ) |
210- BIT (IIO_CHAN_INFO_SCALE ) |
211- BIT (IIO_CHAN_INFO_OFFSET ) |
212- BIT (IIO_CHAN_INFO_SAMP_FREQ ) |
213- BIT (IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY ),
214- .scan_type = {
215- .sign = 'u' ,
216- .realbits = 24 ,
217- .storagebits = 32 ,
218- .endianness = IIO_BE ,
219- },
220- };
221-
222206static struct ad7124_chip_info ad7124_chip_info_tbl [] = {
223207 [ID_AD7124_4 ] = {
224208 .name = "ad7124-4" ,
@@ -903,6 +887,140 @@ static int ad7124_check_chip_id(struct ad7124_state *st)
903887 return 0 ;
904888}
905889
890+ enum {
891+ AD7124_SYSCALIB_ZERO_SCALE ,
892+ AD7124_SYSCALIB_FULL_SCALE ,
893+ };
894+
895+ static int ad7124_syscalib_locked (struct ad7124_state * st , const struct iio_chan_spec * chan )
896+ {
897+ struct device * dev = & st -> sd .spi -> dev ;
898+ struct ad7124_channel * ch = & st -> channels [chan -> channel ];
899+ int ret ;
900+
901+ if (ch -> syscalib_mode == AD7124_SYSCALIB_ZERO_SCALE ) {
902+ ch -> cfg .calibration_offset = 0x800000 ;
903+
904+ ret = ad_sd_calibrate (& st -> sd , AD7124_MODE_CAL_SYS_ZERO ,
905+ chan -> address );
906+ if (ret < 0 )
907+ return ret ;
908+
909+ ret = ad_sd_read_reg (& st -> sd , AD7124_OFFSET (ch -> cfg .cfg_slot ), 3 ,
910+ & ch -> cfg .calibration_offset );
911+ if (ret < 0 )
912+ return ret ;
913+
914+ dev_dbg (dev , "offset for channel %d after zero-scale calibration: 0x%x\n" ,
915+ chan -> channel , ch -> cfg .calibration_offset );
916+ } else {
917+ ch -> cfg .calibration_gain = st -> gain_default ;
918+
919+ ret = ad_sd_calibrate (& st -> sd , AD7124_MODE_CAL_SYS_FULL ,
920+ chan -> address );
921+ if (ret < 0 )
922+ return ret ;
923+
924+ ret = ad_sd_read_reg (& st -> sd , AD7124_GAIN (ch -> cfg .cfg_slot ), 3 ,
925+ & ch -> cfg .calibration_gain );
926+ if (ret < 0 )
927+ return ret ;
928+
929+ dev_dbg (dev , "gain for channel %d after full-scale calibration: 0x%x\n" ,
930+ chan -> channel , ch -> cfg .calibration_gain );
931+ }
932+
933+ return 0 ;
934+ }
935+
936+ static ssize_t ad7124_write_syscalib (struct iio_dev * indio_dev ,
937+ uintptr_t private ,
938+ const struct iio_chan_spec * chan ,
939+ const char * buf , size_t len )
940+ {
941+ struct ad7124_state * st = iio_priv (indio_dev );
942+ bool sys_calib ;
943+ int ret ;
944+
945+ ret = kstrtobool (buf , & sys_calib );
946+ if (ret )
947+ return ret ;
948+
949+ if (!sys_calib )
950+ return len ;
951+
952+ if (!iio_device_claim_direct (indio_dev ))
953+ return - EBUSY ;
954+
955+ ret = ad7124_syscalib_locked (st , chan );
956+
957+ iio_device_release_direct (indio_dev );
958+
959+ return ret ?: len ;
960+ }
961+
962+ static const char * const ad7124_syscalib_modes [] = {
963+ [AD7124_SYSCALIB_ZERO_SCALE ] = "zero_scale" ,
964+ [AD7124_SYSCALIB_FULL_SCALE ] = "full_scale" ,
965+ };
966+
967+ static int ad7124_set_syscalib_mode (struct iio_dev * indio_dev ,
968+ const struct iio_chan_spec * chan ,
969+ unsigned int mode )
970+ {
971+ struct ad7124_state * st = iio_priv (indio_dev );
972+
973+ st -> channels [chan -> channel ].syscalib_mode = mode ;
974+
975+ return 0 ;
976+ }
977+
978+ static int ad7124_get_syscalib_mode (struct iio_dev * indio_dev ,
979+ const struct iio_chan_spec * chan )
980+ {
981+ struct ad7124_state * st = iio_priv (indio_dev );
982+
983+ return st -> channels [chan -> channel ].syscalib_mode ;
984+ }
985+
986+ static const struct iio_enum ad7124_syscalib_mode_enum = {
987+ .items = ad7124_syscalib_modes ,
988+ .num_items = ARRAY_SIZE (ad7124_syscalib_modes ),
989+ .set = ad7124_set_syscalib_mode ,
990+ .get = ad7124_get_syscalib_mode
991+ };
992+
993+ static const struct iio_chan_spec_ext_info ad7124_calibsys_ext_info [] = {
994+ {
995+ .name = "sys_calibration" ,
996+ .write = ad7124_write_syscalib ,
997+ .shared = IIO_SEPARATE ,
998+ },
999+ IIO_ENUM ("sys_calibration_mode" , IIO_SEPARATE ,
1000+ & ad7124_syscalib_mode_enum ),
1001+ IIO_ENUM_AVAILABLE ("sys_calibration_mode" , IIO_SHARED_BY_TYPE ,
1002+ & ad7124_syscalib_mode_enum ),
1003+ { }
1004+ };
1005+
1006+ static const struct iio_chan_spec ad7124_channel_template = {
1007+ .type = IIO_VOLTAGE ,
1008+ .indexed = 1 ,
1009+ .differential = 1 ,
1010+ .info_mask_separate = BIT (IIO_CHAN_INFO_RAW ) |
1011+ BIT (IIO_CHAN_INFO_SCALE ) |
1012+ BIT (IIO_CHAN_INFO_OFFSET ) |
1013+ BIT (IIO_CHAN_INFO_SAMP_FREQ ) |
1014+ BIT (IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY ),
1015+ .scan_type = {
1016+ .sign = 'u' ,
1017+ .realbits = 24 ,
1018+ .storagebits = 32 ,
1019+ .endianness = IIO_BE ,
1020+ },
1021+ .ext_info = ad7124_calibsys_ext_info ,
1022+ };
1023+
9061024/*
9071025 * Input specifiers 8 - 15 are explicitly reserved for ad7124-4
9081026 * while they are fine for ad7124-8. Values above 31 don't fit
0 commit comments