@@ -85,6 +85,10 @@ static const unsigned int ad7606_oversampling_avail[7] = {
8585 1 , 2 , 4 , 8 , 16 , 32 , 64 ,
8686};
8787
88+ static const unsigned int ad7606b_oversampling_avail [9 ] = {
89+ 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 ,
90+ };
91+
8892static const unsigned int ad7616_oversampling_avail [8 ] = {
8993 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 ,
9094};
@@ -187,6 +191,8 @@ static int ad7608_chan_scale_setup(struct iio_dev *indio_dev,
187191 struct iio_chan_spec * chan , int ch );
188192static int ad7609_chan_scale_setup (struct iio_dev * indio_dev ,
189193 struct iio_chan_spec * chan , int ch );
194+ static int ad7616_sw_mode_setup (struct iio_dev * indio_dev );
195+ static int ad7606b_sw_mode_setup (struct iio_dev * indio_dev );
190196
191197const struct ad7606_chip_info ad7605_4_info = {
192198 .channels = ad7605_channels ,
@@ -239,6 +245,7 @@ const struct ad7606_chip_info ad7606b_info = {
239245 .oversampling_avail = ad7606_oversampling_avail ,
240246 .oversampling_num = ARRAY_SIZE (ad7606_oversampling_avail ),
241247 .scale_setup_cb = ad7606_16bit_chan_scale_setup ,
248+ .sw_setup_cb = ad7606b_sw_mode_setup ,
242249};
243250EXPORT_SYMBOL_NS_GPL (ad7606b_info , "IIO_AD7606" );
244251
@@ -250,6 +257,7 @@ const struct ad7606_chip_info ad7606c_16_info = {
250257 .oversampling_avail = ad7606_oversampling_avail ,
251258 .oversampling_num = ARRAY_SIZE (ad7606_oversampling_avail ),
252259 .scale_setup_cb = ad7606c_16bit_chan_scale_setup ,
260+ .sw_setup_cb = ad7606b_sw_mode_setup ,
253261};
254262EXPORT_SYMBOL_NS_GPL (ad7606c_16_info , "IIO_AD7606" );
255263
@@ -294,6 +302,7 @@ const struct ad7606_chip_info ad7606c_18_info = {
294302 .oversampling_avail = ad7606_oversampling_avail ,
295303 .oversampling_num = ARRAY_SIZE (ad7606_oversampling_avail ),
296304 .scale_setup_cb = ad7606c_18bit_chan_scale_setup ,
305+ .sw_setup_cb = ad7606b_sw_mode_setup ,
297306};
298307EXPORT_SYMBOL_NS_GPL (ad7606c_18_info , "IIO_AD7606" );
299308
@@ -307,6 +316,7 @@ const struct ad7606_chip_info ad7616_info = {
307316 .oversampling_num = ARRAY_SIZE (ad7616_oversampling_avail ),
308317 .os_req_reset = true,
309318 .scale_setup_cb = ad7606_16bit_chan_scale_setup ,
319+ .sw_setup_cb = ad7616_sw_mode_setup ,
310320};
311321EXPORT_SYMBOL_NS_GPL (ad7616_info , "IIO_AD7606" );
312322
@@ -1138,16 +1148,118 @@ static const struct iio_trigger_ops ad7606_trigger_ops = {
11381148 .validate_device = iio_trigger_validate_own_device ,
11391149};
11401150
1141- static int ad7606_sw_mode_setup (struct iio_dev * indio_dev )
1151+ static int ad7606_write_mask (struct ad7606_state * st , unsigned int addr ,
1152+ unsigned long mask , unsigned int val )
1153+ {
1154+ int readval ;
1155+
1156+ readval = st -> bops -> reg_read (st , addr );
1157+ if (readval < 0 )
1158+ return readval ;
1159+
1160+ readval &= ~mask ;
1161+ readval |= val ;
1162+
1163+ return st -> bops -> reg_write (st , addr , readval );
1164+ }
1165+
1166+ static int ad7616_write_scale_sw (struct iio_dev * indio_dev , int ch , int val )
11421167{
11431168 struct ad7606_state * st = iio_priv (indio_dev );
1169+ unsigned int ch_addr , mode , ch_index ;
11441170
1145- st -> sw_mode_en = st -> bops -> sw_mode_config &&
1146- device_property_present (st -> dev , "adi,sw-mode" );
1147- if (!st -> sw_mode_en )
1148- return 0 ;
1171+ /*
1172+ * Ad7616 has 16 channels divided in group A and group B.
1173+ * The range of channels from A are stored in registers with address 4
1174+ * while channels from B are stored in register with address 6.
1175+ * The last bit from channels determines if it is from group A or B
1176+ * because the order of channels in iio is 0A, 0B, 1A, 1B...
1177+ */
1178+ ch_index = ch >> 1 ;
1179+
1180+ ch_addr = AD7616_RANGE_CH_ADDR (ch_index );
1181+
1182+ if ((ch & 0x1 ) == 0 ) /* channel A */
1183+ ch_addr += AD7616_RANGE_CH_A_ADDR_OFF ;
1184+ else /* channel B */
1185+ ch_addr += AD7616_RANGE_CH_B_ADDR_OFF ;
1186+
1187+ /* 0b01 for 2.5v, 0b10 for 5v and 0b11 for 10v */
1188+ mode = AD7616_RANGE_CH_MODE (ch_index , ((val + 1 ) & 0b11 ));
11491189
1150- indio_dev -> info = & ad7606_info_sw_mode ;
1190+ return ad7606_write_mask (st , ch_addr , AD7616_RANGE_CH_MSK (ch_index ),
1191+ mode );
1192+ }
1193+
1194+ static int ad7616_write_os_sw (struct iio_dev * indio_dev , int val )
1195+ {
1196+ struct ad7606_state * st = iio_priv (indio_dev );
1197+
1198+ return ad7606_write_mask (st , AD7616_CONFIGURATION_REGISTER ,
1199+ AD7616_OS_MASK , val << 2 );
1200+ }
1201+
1202+ static int ad7606_write_scale_sw (struct iio_dev * indio_dev , int ch , int val )
1203+ {
1204+ struct ad7606_state * st = iio_priv (indio_dev );
1205+
1206+ return ad7606_write_mask (st , AD7606_RANGE_CH_ADDR (ch ),
1207+ AD7606_RANGE_CH_MSK (ch ),
1208+ AD7606_RANGE_CH_MODE (ch , val ));
1209+ }
1210+
1211+ static int ad7606_write_os_sw (struct iio_dev * indio_dev , int val )
1212+ {
1213+ struct ad7606_state * st = iio_priv (indio_dev );
1214+
1215+ return st -> bops -> reg_write (st , AD7606_OS_MODE , val );
1216+ }
1217+
1218+ static int ad7616_sw_mode_setup (struct iio_dev * indio_dev )
1219+ {
1220+ struct ad7606_state * st = iio_priv (indio_dev );
1221+ int ret ;
1222+
1223+ /*
1224+ * Scale can be configured individually for each channel
1225+ * in software mode.
1226+ */
1227+
1228+ st -> write_scale = ad7616_write_scale_sw ;
1229+ st -> write_os = & ad7616_write_os_sw ;
1230+
1231+ ret = st -> bops -> sw_mode_config (indio_dev );
1232+ if (ret )
1233+ return ret ;
1234+
1235+ /* Activate Burst mode and SEQEN MODE */
1236+ return ad7606_write_mask (st , AD7616_CONFIGURATION_REGISTER ,
1237+ AD7616_BURST_MODE | AD7616_SEQEN_MODE ,
1238+ AD7616_BURST_MODE | AD7616_SEQEN_MODE );
1239+ }
1240+
1241+ static int ad7606b_sw_mode_setup (struct iio_dev * indio_dev )
1242+ {
1243+ struct ad7606_state * st = iio_priv (indio_dev );
1244+ DECLARE_BITMAP (os , 3 );
1245+
1246+ bitmap_fill (os , 3 );
1247+ /*
1248+ * Software mode is enabled when all three oversampling
1249+ * pins are set to high. If oversampling gpios are defined
1250+ * in the device tree, then they need to be set to high,
1251+ * otherwise, they must be hardwired to VDD
1252+ */
1253+ if (st -> gpio_os ) {
1254+ gpiod_set_array_value (st -> gpio_os -> ndescs , st -> gpio_os -> desc ,
1255+ st -> gpio_os -> info , os );
1256+ }
1257+ /* OS of 128 and 256 are available only in software mode */
1258+ st -> oversampling_avail = ad7606b_oversampling_avail ;
1259+ st -> num_os_ratios = ARRAY_SIZE (ad7606b_oversampling_avail );
1260+
1261+ st -> write_scale = ad7606_write_scale_sw ;
1262+ st -> write_os = & ad7606_write_os_sw ;
11511263
11521264 return st -> bops -> sw_mode_config (indio_dev );
11531265}
@@ -1326,9 +1438,12 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
13261438 st -> write_scale = ad7606_write_scale_hw ;
13271439 st -> write_os = ad7606_write_os_hw ;
13281440
1329- ret = ad7606_sw_mode_setup (indio_dev );
1330- if (ret )
1331- return ret ;
1441+ st -> sw_mode_en = st -> chip_info -> sw_setup_cb &&
1442+ device_property_present (st -> dev , "adi,sw-mode" );
1443+ if (st -> sw_mode_en ) {
1444+ indio_dev -> info = & ad7606_info_sw_mode ;
1445+ st -> chip_info -> sw_setup_cb (indio_dev );
1446+ }
13321447
13331448 ret = ad7606_chan_scales_setup (indio_dev );
13341449 if (ret )
0 commit comments