Message ID | 20250318-iio-adc-ad7606-improvements-v2-9-4b605427774c@baylibre.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | iio: adc: ad7606: improvements and ad7606c parallel interface support | expand |
Hi David, kernel test robot noticed the following build warnings: url: https://github.com/intel-lab-lkp/linux/commits/David-Lechner/iio-adc-ad7606-check-for-NULL-before-calling-sw_mode_config/20250319-065737 base: 9f36acefb2621d980734a5bb7d74e0e24e0af166 patch link: https://lore.kernel.org/r/20250318-iio-adc-ad7606-improvements-v2-9-4b605427774c%40baylibre.com patch subject: [PATCH v2 09/10] iio: adc: ad7606: dynamically allocate channel info config: arm64-randconfig-r071-20250322 (https://download.01.org/0day-ci/archive/20250322/202503222246.RafigmhQ-lkp@intel.com/config) compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project c2692afc0a92cd5da140dfcdfff7818a5b8ce997) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Reported-by: Dan Carpenter <dan.carpenter@linaro.org> | Closes: https://lore.kernel.org/r/202503222246.RafigmhQ-lkp@intel.com/ smatch warnings: drivers/iio/adc/ad7606.c:1270 ad7606_probe_channels() warn: potentially one past the end of array 'channels[i]' vim +1270 drivers/iio/adc/ad7606.c 87cf5705725eeb David Lechner 2025-03-18 1196 static int ad7606_probe_channels(struct iio_dev *indio_dev) e571c1902116a3 Alexandru Ardelean 2024-09-19 1197 { e571c1902116a3 Alexandru Ardelean 2024-09-19 1198 struct ad7606_state *st = iio_priv(indio_dev); 87cf5705725eeb David Lechner 2025-03-18 1199 struct device *dev = indio_dev->dev.parent; 87cf5705725eeb David Lechner 2025-03-18 1200 struct iio_chan_spec *channels; 87cf5705725eeb David Lechner 2025-03-18 1201 bool slow_bus; 87cf5705725eeb David Lechner 2025-03-18 1202 int ret, i; 87cf5705725eeb David Lechner 2025-03-18 1203 87cf5705725eeb David Lechner 2025-03-18 1204 slow_bus = !st->bops->iio_backend_config; 87cf5705725eeb David Lechner 2025-03-18 1205 indio_dev->num_channels = st->chip_info->num_adc_channels; 87cf5705725eeb David Lechner 2025-03-18 1206 87cf5705725eeb David Lechner 2025-03-18 1207 /* Slow buses also get 1 more channel for soft timestamp */ 87cf5705725eeb David Lechner 2025-03-18 1208 if (slow_bus) 87cf5705725eeb David Lechner 2025-03-18 1209 indio_dev->num_channels++; 87cf5705725eeb David Lechner 2025-03-18 1210 87cf5705725eeb David Lechner 2025-03-18 1211 channels = devm_kcalloc(dev, indio_dev->num_channels, sizeof(*channels), 87cf5705725eeb David Lechner 2025-03-18 1212 GFP_KERNEL); 87cf5705725eeb David Lechner 2025-03-18 1213 if (!channels) f3838e934dfff2 Alexandru Ardelean 2024-09-19 1214 return -ENOMEM; f3838e934dfff2 Alexandru Ardelean 2024-09-19 1215 87cf5705725eeb David Lechner 2025-03-18 1216 for (i = 0; i < indio_dev->num_channels; i++) { 87cf5705725eeb David Lechner 2025-03-18 1217 struct iio_chan_spec *chan = &channels[i]; 87cf5705725eeb David Lechner 2025-03-18 1218 87cf5705725eeb David Lechner 2025-03-18 1219 chan->type = IIO_VOLTAGE; 87cf5705725eeb David Lechner 2025-03-18 1220 chan->indexed = 1; 87cf5705725eeb David Lechner 2025-03-18 1221 chan->channel = i; 87cf5705725eeb David Lechner 2025-03-18 1222 chan->scan_index = i; 87cf5705725eeb David Lechner 2025-03-18 1223 chan->scan_type.sign = 's'; 87cf5705725eeb David Lechner 2025-03-18 1224 chan->scan_type.realbits = st->chip_info->bits; 87cf5705725eeb David Lechner 2025-03-18 1225 chan->scan_type.storagebits = st->chip_info->bits > 16 ? 32 : 16; 87cf5705725eeb David Lechner 2025-03-18 1226 chan->scan_type.endianness = IIO_CPU; f3838e934dfff2 Alexandru Ardelean 2024-09-19 1227 87cf5705725eeb David Lechner 2025-03-18 1228 if (indio_dev->modes & INDIO_DIRECT_MODE) 87cf5705725eeb David Lechner 2025-03-18 1229 chan->info_mask_separate |= BIT(IIO_CHAN_INFO_RAW); 87cf5705725eeb David Lechner 2025-03-18 1230 87cf5705725eeb David Lechner 2025-03-18 1231 if (st->sw_mode_en) { 87cf5705725eeb David Lechner 2025-03-18 1232 chan->info_mask_separate |= BIT(IIO_CHAN_INFO_SCALE); 87cf5705725eeb David Lechner 2025-03-18 1233 chan->info_mask_separate_available |= 87cf5705725eeb David Lechner 2025-03-18 1234 BIT(IIO_CHAN_INFO_SCALE); 87cf5705725eeb David Lechner 2025-03-18 1235 87cf5705725eeb David Lechner 2025-03-18 1236 /* 87cf5705725eeb David Lechner 2025-03-18 1237 * All chips with software mode support oversampling, 87cf5705725eeb David Lechner 2025-03-18 1238 * so we skip the oversampling_available check. And the 87cf5705725eeb David Lechner 2025-03-18 1239 * shared_by_type instead of shared_by_all on slow 87cf5705725eeb David Lechner 2025-03-18 1240 * buses is for backward compatibility. 87cf5705725eeb David Lechner 2025-03-18 1241 */ 87cf5705725eeb David Lechner 2025-03-18 1242 if (slow_bus) 87cf5705725eeb David Lechner 2025-03-18 1243 chan->info_mask_shared_by_type |= 87cf5705725eeb David Lechner 2025-03-18 1244 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); 87cf5705725eeb David Lechner 2025-03-18 1245 else 87cf5705725eeb David Lechner 2025-03-18 1246 chan->info_mask_shared_by_all |= 87cf5705725eeb David Lechner 2025-03-18 1247 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); 87cf5705725eeb David Lechner 2025-03-18 1248 87cf5705725eeb David Lechner 2025-03-18 1249 chan->info_mask_shared_by_all_available |= 87cf5705725eeb David Lechner 2025-03-18 1250 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); 87cf5705725eeb David Lechner 2025-03-18 1251 } else { 87cf5705725eeb David Lechner 2025-03-18 1252 chan->info_mask_shared_by_type |= 87cf5705725eeb David Lechner 2025-03-18 1253 BIT(IIO_CHAN_INFO_SCALE); 87cf5705725eeb David Lechner 2025-03-18 1254 87cf5705725eeb David Lechner 2025-03-18 1255 if (st->chip_info->oversampling_avail) 87cf5705725eeb David Lechner 2025-03-18 1256 chan->info_mask_shared_by_all |= 87cf5705725eeb David Lechner 2025-03-18 1257 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); 87cf5705725eeb David Lechner 2025-03-18 1258 } 87cf5705725eeb David Lechner 2025-03-18 1259 87cf5705725eeb David Lechner 2025-03-18 1260 if (!slow_bus) 87cf5705725eeb David Lechner 2025-03-18 1261 chan->info_mask_shared_by_all |= 87cf5705725eeb David Lechner 2025-03-18 1262 BIT(IIO_CHAN_INFO_SAMP_FREQ); 87cf5705725eeb David Lechner 2025-03-18 1263 87cf5705725eeb David Lechner 2025-03-18 1264 ret = st->chip_info->scale_setup_cb(indio_dev, chan); e571c1902116a3 Alexandru Ardelean 2024-09-19 1265 if (ret) e571c1902116a3 Alexandru Ardelean 2024-09-19 1266 return ret; e571c1902116a3 Alexandru Ardelean 2024-09-19 1267 } e571c1902116a3 Alexandru Ardelean 2024-09-19 1268 87cf5705725eeb David Lechner 2025-03-18 1269 if (slow_bus) 87cf5705725eeb David Lechner 2025-03-18 @1270 channels[i] = (struct iio_chan_spec)IIO_CHAN_SOFT_TIMESTAMP(i); ^^^^^^^^^^^ i is == indio_dev->num_channels so this is out of bounds by one element. 87cf5705725eeb David Lechner 2025-03-18 1271 87cf5705725eeb David Lechner 2025-03-18 1272 indio_dev->channels = channels; 87cf5705725eeb David Lechner 2025-03-18 1273 e571c1902116a3 Alexandru Ardelean 2024-09-19 1274 return 0; e571c1902116a3 Alexandru Ardelean 2024-09-19 1275 }
On 3/22/25 12:25 PM, Dan Carpenter wrote: > Hi David, > > kernel test robot noticed the following build warnings: > > url: https://github.com/intel-lab-lkp/linux/commits/David-Lechner/iio-adc-ad7606-check-for-NULL-before-calling-sw_mode_config/20250319-065737 > base: 9f36acefb2621d980734a5bb7d74e0e24e0af166 > patch link: https://lore.kernel.org/r/20250318-iio-adc-ad7606-improvements-v2-9-4b605427774c%40baylibre.com > patch subject: [PATCH v2 09/10] iio: adc: ad7606: dynamically allocate channel info > config: arm64-randconfig-r071-20250322 (https://download.01.org/0day-ci/archive/20250322/202503222246.RafigmhQ-lkp@intel.com/config) > compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project c2692afc0a92cd5da140dfcdfff7818a5b8ce997) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Reported-by: Dan Carpenter <dan.carpenter@linaro.org> > | Closes: https://lore.kernel.org/r/202503222246.RafigmhQ-lkp@intel.com/ > > smatch warnings: > drivers/iio/adc/ad7606.c:1270 ad7606_probe_channels() warn: potentially one past the end of array 'channels[i]' > > vim +1270 drivers/iio/adc/ad7606.c > > 87cf5705725eeb David Lechner 2025-03-18 1196 static int ad7606_probe_channels(struct iio_dev *indio_dev) > e571c1902116a3 Alexandru Ardelean 2024-09-19 1197 { > e571c1902116a3 Alexandru Ardelean 2024-09-19 1198 struct ad7606_state *st = iio_priv(indio_dev); > 87cf5705725eeb David Lechner 2025-03-18 1199 struct device *dev = indio_dev->dev.parent; > 87cf5705725eeb David Lechner 2025-03-18 1200 struct iio_chan_spec *channels; > 87cf5705725eeb David Lechner 2025-03-18 1201 bool slow_bus; > 87cf5705725eeb David Lechner 2025-03-18 1202 int ret, i; > 87cf5705725eeb David Lechner 2025-03-18 1203 > 87cf5705725eeb David Lechner 2025-03-18 1204 slow_bus = !st->bops->iio_backend_config; > 87cf5705725eeb David Lechner 2025-03-18 1205 indio_dev->num_channels = st->chip_info->num_adc_channels; > 87cf5705725eeb David Lechner 2025-03-18 1206 > 87cf5705725eeb David Lechner 2025-03-18 1207 /* Slow buses also get 1 more channel for soft timestamp */ > 87cf5705725eeb David Lechner 2025-03-18 1208 if (slow_bus) > 87cf5705725eeb David Lechner 2025-03-18 1209 indio_dev->num_channels++; > 87cf5705725eeb David Lechner 2025-03-18 1210 > 87cf5705725eeb David Lechner 2025-03-18 1211 channels = devm_kcalloc(dev, indio_dev->num_channels, sizeof(*channels), > 87cf5705725eeb David Lechner 2025-03-18 1212 GFP_KERNEL); > 87cf5705725eeb David Lechner 2025-03-18 1213 if (!channels) > f3838e934dfff2 Alexandru Ardelean 2024-09-19 1214 return -ENOMEM; > f3838e934dfff2 Alexandru Ardelean 2024-09-19 1215 > 87cf5705725eeb David Lechner 2025-03-18 1216 for (i = 0; i < indio_dev->num_channels; i++) { The fix is to change this line to: for (i = 0; i < st->chip_info->num_adc_channels; i++) { > 87cf5705725eeb David Lechner 2025-03-18 1217 struct iio_chan_spec *chan = &channels[i]; > 87cf5705725eeb David Lechner 2025-03-18 1218 > 87cf5705725eeb David Lechner 2025-03-18 1219 chan->type = IIO_VOLTAGE; > 87cf5705725eeb David Lechner 2025-03-18 1220 chan->indexed = 1; > 87cf5705725eeb David Lechner 2025-03-18 1221 chan->channel = i; > 87cf5705725eeb David Lechner 2025-03-18 1222 chan->scan_index = i; > 87cf5705725eeb David Lechner 2025-03-18 1223 chan->scan_type.sign = 's'; > 87cf5705725eeb David Lechner 2025-03-18 1224 chan->scan_type.realbits = st->chip_info->bits; > 87cf5705725eeb David Lechner 2025-03-18 1225 chan->scan_type.storagebits = st->chip_info->bits > 16 ? 32 : 16; > 87cf5705725eeb David Lechner 2025-03-18 1226 chan->scan_type.endianness = IIO_CPU; > f3838e934dfff2 Alexandru Ardelean 2024-09-19 1227 > 87cf5705725eeb David Lechner 2025-03-18 1228 if (indio_dev->modes & INDIO_DIRECT_MODE) > 87cf5705725eeb David Lechner 2025-03-18 1229 chan->info_mask_separate |= BIT(IIO_CHAN_INFO_RAW); > 87cf5705725eeb David Lechner 2025-03-18 1230 > 87cf5705725eeb David Lechner 2025-03-18 1231 if (st->sw_mode_en) { > 87cf5705725eeb David Lechner 2025-03-18 1232 chan->info_mask_separate |= BIT(IIO_CHAN_INFO_SCALE); > 87cf5705725eeb David Lechner 2025-03-18 1233 chan->info_mask_separate_available |= > 87cf5705725eeb David Lechner 2025-03-18 1234 BIT(IIO_CHAN_INFO_SCALE); > 87cf5705725eeb David Lechner 2025-03-18 1235 > 87cf5705725eeb David Lechner 2025-03-18 1236 /* > 87cf5705725eeb David Lechner 2025-03-18 1237 * All chips with software mode support oversampling, > 87cf5705725eeb David Lechner 2025-03-18 1238 * so we skip the oversampling_available check. And the > 87cf5705725eeb David Lechner 2025-03-18 1239 * shared_by_type instead of shared_by_all on slow > 87cf5705725eeb David Lechner 2025-03-18 1240 * buses is for backward compatibility. > 87cf5705725eeb David Lechner 2025-03-18 1241 */ > 87cf5705725eeb David Lechner 2025-03-18 1242 if (slow_bus) > 87cf5705725eeb David Lechner 2025-03-18 1243 chan->info_mask_shared_by_type |= > 87cf5705725eeb David Lechner 2025-03-18 1244 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); > 87cf5705725eeb David Lechner 2025-03-18 1245 else > 87cf5705725eeb David Lechner 2025-03-18 1246 chan->info_mask_shared_by_all |= > 87cf5705725eeb David Lechner 2025-03-18 1247 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); > 87cf5705725eeb David Lechner 2025-03-18 1248 > 87cf5705725eeb David Lechner 2025-03-18 1249 chan->info_mask_shared_by_all_available |= > 87cf5705725eeb David Lechner 2025-03-18 1250 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); > 87cf5705725eeb David Lechner 2025-03-18 1251 } else { > 87cf5705725eeb David Lechner 2025-03-18 1252 chan->info_mask_shared_by_type |= > 87cf5705725eeb David Lechner 2025-03-18 1253 BIT(IIO_CHAN_INFO_SCALE); > 87cf5705725eeb David Lechner 2025-03-18 1254 > 87cf5705725eeb David Lechner 2025-03-18 1255 if (st->chip_info->oversampling_avail) > 87cf5705725eeb David Lechner 2025-03-18 1256 chan->info_mask_shared_by_all |= > 87cf5705725eeb David Lechner 2025-03-18 1257 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); > 87cf5705725eeb David Lechner 2025-03-18 1258 } > 87cf5705725eeb David Lechner 2025-03-18 1259 > 87cf5705725eeb David Lechner 2025-03-18 1260 if (!slow_bus) > 87cf5705725eeb David Lechner 2025-03-18 1261 chan->info_mask_shared_by_all |= > 87cf5705725eeb David Lechner 2025-03-18 1262 BIT(IIO_CHAN_INFO_SAMP_FREQ); > 87cf5705725eeb David Lechner 2025-03-18 1263 > 87cf5705725eeb David Lechner 2025-03-18 1264 ret = st->chip_info->scale_setup_cb(indio_dev, chan); > e571c1902116a3 Alexandru Ardelean 2024-09-19 1265 if (ret) > e571c1902116a3 Alexandru Ardelean 2024-09-19 1266 return ret; > e571c1902116a3 Alexandru Ardelean 2024-09-19 1267 } > e571c1902116a3 Alexandru Ardelean 2024-09-19 1268 > 87cf5705725eeb David Lechner 2025-03-18 1269 if (slow_bus) > 87cf5705725eeb David Lechner 2025-03-18 @1270 channels[i] = (struct iio_chan_spec)IIO_CHAN_SOFT_TIMESTAMP(i); > ^^^^^^^^^^^ > i is == indio_dev->num_channels so this is out of bounds by one element. > > 87cf5705725eeb David Lechner 2025-03-18 1271 > 87cf5705725eeb David Lechner 2025-03-18 1272 indio_dev->channels = channels; > 87cf5705725eeb David Lechner 2025-03-18 1273 > e571c1902116a3 Alexandru Ardelean 2024-09-19 1274 return 0; > e571c1902116a3 Alexandru Ardelean 2024-09-19 1275 } >
On Mon, 24 Mar 2025 08:50:15 -0500 David Lechner <dlechner@baylibre.com> wrote: > On 3/22/25 12:25 PM, Dan Carpenter wrote: > > Hi David, > > > > kernel test robot noticed the following build warnings: > > > > url: https://github.com/intel-lab-lkp/linux/commits/David-Lechner/iio-adc-ad7606-check-for-NULL-before-calling-sw_mode_config/20250319-065737 > > base: 9f36acefb2621d980734a5bb7d74e0e24e0af166 > > patch link: https://lore.kernel.org/r/20250318-iio-adc-ad7606-improvements-v2-9-4b605427774c%40baylibre.com > > patch subject: [PATCH v2 09/10] iio: adc: ad7606: dynamically allocate channel info > > config: arm64-randconfig-r071-20250322 (https://download.01.org/0day-ci/archive/20250322/202503222246.RafigmhQ-lkp@intel.com/config) > > compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project c2692afc0a92cd5da140dfcdfff7818a5b8ce997) > > > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > > the same patch/commit), kindly add following tags > > | Reported-by: kernel test robot <lkp@intel.com> > > | Reported-by: Dan Carpenter <dan.carpenter@linaro.org> > > | Closes: https://lore.kernel.org/r/202503222246.RafigmhQ-lkp@intel.com/ > > > > smatch warnings: > > drivers/iio/adc/ad7606.c:1270 ad7606_probe_channels() warn: potentially one past the end of array 'channels[i]' > > > > vim +1270 drivers/iio/adc/ad7606.c > > > > 87cf5705725eeb David Lechner 2025-03-18 1196 static int ad7606_probe_channels(struct iio_dev *indio_dev) > > e571c1902116a3 Alexandru Ardelean 2024-09-19 1197 { > > e571c1902116a3 Alexandru Ardelean 2024-09-19 1198 struct ad7606_state *st = iio_priv(indio_dev); > > 87cf5705725eeb David Lechner 2025-03-18 1199 struct device *dev = indio_dev->dev.parent; > > 87cf5705725eeb David Lechner 2025-03-18 1200 struct iio_chan_spec *channels; > > 87cf5705725eeb David Lechner 2025-03-18 1201 bool slow_bus; > > 87cf5705725eeb David Lechner 2025-03-18 1202 int ret, i; > > 87cf5705725eeb David Lechner 2025-03-18 1203 > > 87cf5705725eeb David Lechner 2025-03-18 1204 slow_bus = !st->bops->iio_backend_config; > > 87cf5705725eeb David Lechner 2025-03-18 1205 indio_dev->num_channels = st->chip_info->num_adc_channels; > > 87cf5705725eeb David Lechner 2025-03-18 1206 > > 87cf5705725eeb David Lechner 2025-03-18 1207 /* Slow buses also get 1 more channel for soft timestamp */ > > 87cf5705725eeb David Lechner 2025-03-18 1208 if (slow_bus) > > 87cf5705725eeb David Lechner 2025-03-18 1209 indio_dev->num_channels++; > > 87cf5705725eeb David Lechner 2025-03-18 1210 > > 87cf5705725eeb David Lechner 2025-03-18 1211 channels = devm_kcalloc(dev, indio_dev->num_channels, sizeof(*channels), > > 87cf5705725eeb David Lechner 2025-03-18 1212 GFP_KERNEL); > > 87cf5705725eeb David Lechner 2025-03-18 1213 if (!channels) > > f3838e934dfff2 Alexandru Ardelean 2024-09-19 1214 return -ENOMEM; > > f3838e934dfff2 Alexandru Ardelean 2024-09-19 1215 > > 87cf5705725eeb David Lechner 2025-03-18 1216 for (i = 0; i < indio_dev->num_channels; i++) { > > The fix is to change this line to: > > for (i = 0; i < st->chip_info->num_adc_channels; i++) { > Tweaked and applied. > > 87cf5705725eeb David Lechner 2025-03-18 1217 struct iio_chan_spec *chan = &channels[i]; > > 87cf5705725eeb David Lechner 2025-03-18 1218 > > 87cf5705725eeb David Lechner 2025-03-18 1219 chan->type = IIO_VOLTAGE; > > 87cf5705725eeb David Lechner 2025-03-18 1220 chan->indexed = 1; > > 87cf5705725eeb David Lechner 2025-03-18 1221 chan->channel = i; > > 87cf5705725eeb David Lechner 2025-03-18 1222 chan->scan_index = i; > > 87cf5705725eeb David Lechner 2025-03-18 1223 chan->scan_type.sign = 's'; > > 87cf5705725eeb David Lechner 2025-03-18 1224 chan->scan_type.realbits = st->chip_info->bits; > > 87cf5705725eeb David Lechner 2025-03-18 1225 chan->scan_type.storagebits = st->chip_info->bits > 16 ? 32 : 16; > > 87cf5705725eeb David Lechner 2025-03-18 1226 chan->scan_type.endianness = IIO_CPU; > > f3838e934dfff2 Alexandru Ardelean 2024-09-19 1227 > > 87cf5705725eeb David Lechner 2025-03-18 1228 if (indio_dev->modes & INDIO_DIRECT_MODE) > > 87cf5705725eeb David Lechner 2025-03-18 1229 chan->info_mask_separate |= BIT(IIO_CHAN_INFO_RAW); > > 87cf5705725eeb David Lechner 2025-03-18 1230 > > 87cf5705725eeb David Lechner 2025-03-18 1231 if (st->sw_mode_en) { > > 87cf5705725eeb David Lechner 2025-03-18 1232 chan->info_mask_separate |= BIT(IIO_CHAN_INFO_SCALE); > > 87cf5705725eeb David Lechner 2025-03-18 1233 chan->info_mask_separate_available |= > > 87cf5705725eeb David Lechner 2025-03-18 1234 BIT(IIO_CHAN_INFO_SCALE); > > 87cf5705725eeb David Lechner 2025-03-18 1235 > > 87cf5705725eeb David Lechner 2025-03-18 1236 /* > > 87cf5705725eeb David Lechner 2025-03-18 1237 * All chips with software mode support oversampling, > > 87cf5705725eeb David Lechner 2025-03-18 1238 * so we skip the oversampling_available check. And the > > 87cf5705725eeb David Lechner 2025-03-18 1239 * shared_by_type instead of shared_by_all on slow > > 87cf5705725eeb David Lechner 2025-03-18 1240 * buses is for backward compatibility. > > 87cf5705725eeb David Lechner 2025-03-18 1241 */ > > 87cf5705725eeb David Lechner 2025-03-18 1242 if (slow_bus) > > 87cf5705725eeb David Lechner 2025-03-18 1243 chan->info_mask_shared_by_type |= > > 87cf5705725eeb David Lechner 2025-03-18 1244 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); > > 87cf5705725eeb David Lechner 2025-03-18 1245 else > > 87cf5705725eeb David Lechner 2025-03-18 1246 chan->info_mask_shared_by_all |= > > 87cf5705725eeb David Lechner 2025-03-18 1247 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); > > 87cf5705725eeb David Lechner 2025-03-18 1248 > > 87cf5705725eeb David Lechner 2025-03-18 1249 chan->info_mask_shared_by_all_available |= > > 87cf5705725eeb David Lechner 2025-03-18 1250 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); > > 87cf5705725eeb David Lechner 2025-03-18 1251 } else { > > 87cf5705725eeb David Lechner 2025-03-18 1252 chan->info_mask_shared_by_type |= > > 87cf5705725eeb David Lechner 2025-03-18 1253 BIT(IIO_CHAN_INFO_SCALE); > > 87cf5705725eeb David Lechner 2025-03-18 1254 > > 87cf5705725eeb David Lechner 2025-03-18 1255 if (st->chip_info->oversampling_avail) > > 87cf5705725eeb David Lechner 2025-03-18 1256 chan->info_mask_shared_by_all |= > > 87cf5705725eeb David Lechner 2025-03-18 1257 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); > > 87cf5705725eeb David Lechner 2025-03-18 1258 } > > 87cf5705725eeb David Lechner 2025-03-18 1259 > > 87cf5705725eeb David Lechner 2025-03-18 1260 if (!slow_bus) > > 87cf5705725eeb David Lechner 2025-03-18 1261 chan->info_mask_shared_by_all |= > > 87cf5705725eeb David Lechner 2025-03-18 1262 BIT(IIO_CHAN_INFO_SAMP_FREQ); > > 87cf5705725eeb David Lechner 2025-03-18 1263 > > 87cf5705725eeb David Lechner 2025-03-18 1264 ret = st->chip_info->scale_setup_cb(indio_dev, chan); > > e571c1902116a3 Alexandru Ardelean 2024-09-19 1265 if (ret) > > e571c1902116a3 Alexandru Ardelean 2024-09-19 1266 return ret; > > e571c1902116a3 Alexandru Ardelean 2024-09-19 1267 } > > e571c1902116a3 Alexandru Ardelean 2024-09-19 1268 > > 87cf5705725eeb David Lechner 2025-03-18 1269 if (slow_bus) > > 87cf5705725eeb David Lechner 2025-03-18 @1270 channels[i] = (struct iio_chan_spec)IIO_CHAN_SOFT_TIMESTAMP(i); > > ^^^^^^^^^^^ > > i is == indio_dev->num_channels so this is out of bounds by one element. > > > > 87cf5705725eeb David Lechner 2025-03-18 1271 > > 87cf5705725eeb David Lechner 2025-03-18 1272 indio_dev->channels = channels; > > 87cf5705725eeb David Lechner 2025-03-18 1273 > > e571c1902116a3 Alexandru Ardelean 2024-09-19 1274 return 0; > > e571c1902116a3 Alexandru Ardelean 2024-09-19 1275 } > > >
diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index 09c35161df365e531b8d254c7333359facf045c7..f3a78b01278527a3a380b80423d39774cee269c4 100644 --- a/drivers/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c @@ -95,92 +95,6 @@ static const unsigned int ad7616_oversampling_avail[8] = { 1, 2, 4, 8, 16, 32, 64, 128, }; -static const struct iio_chan_spec ad7605_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(4), - AD7605_CHANNEL(0), - AD7605_CHANNEL(1), - AD7605_CHANNEL(2), - AD7605_CHANNEL(3), -}; - -static const struct iio_chan_spec ad7606_channels_16bit[] = { - IIO_CHAN_SOFT_TIMESTAMP(8), - AD7606_CHANNEL(0, 16), - AD7606_CHANNEL(1, 16), - AD7606_CHANNEL(2, 16), - AD7606_CHANNEL(3, 16), - AD7606_CHANNEL(4, 16), - AD7606_CHANNEL(5, 16), - AD7606_CHANNEL(6, 16), - AD7606_CHANNEL(7, 16), -}; - -static const struct iio_chan_spec ad7606_channels_18bit[] = { - IIO_CHAN_SOFT_TIMESTAMP(8), - AD7606_CHANNEL(0, 18), - AD7606_CHANNEL(1, 18), - AD7606_CHANNEL(2, 18), - AD7606_CHANNEL(3, 18), - AD7606_CHANNEL(4, 18), - AD7606_CHANNEL(5, 18), - AD7606_CHANNEL(6, 18), - AD7606_CHANNEL(7, 18), -}; - -static const struct iio_chan_spec ad7607_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(8), - AD7606_CHANNEL(0, 14), - AD7606_CHANNEL(1, 14), - AD7606_CHANNEL(2, 14), - AD7606_CHANNEL(3, 14), - AD7606_CHANNEL(4, 14), - AD7606_CHANNEL(5, 14), - AD7606_CHANNEL(6, 14), - AD7606_CHANNEL(7, 14), -}; - -static const struct iio_chan_spec ad7608_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(8), - AD7606_CHANNEL(0, 18), - AD7606_CHANNEL(1, 18), - AD7606_CHANNEL(2, 18), - AD7606_CHANNEL(3, 18), - AD7606_CHANNEL(4, 18), - AD7606_CHANNEL(5, 18), - AD7606_CHANNEL(6, 18), - AD7606_CHANNEL(7, 18), -}; - -/* - * The current assumption that this driver makes for AD7616, is that it's - * working in Hardware Mode with Serial, Burst and Sequencer modes activated. - * To activate them, following pins must be pulled high: - * -SER/PAR - * -SEQEN - * And following pins must be pulled low: - * -WR/BURST - * -DB4/SER1W - */ -static const struct iio_chan_spec ad7616_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(16), - AD7606_CHANNEL(0, 16), - AD7606_CHANNEL(1, 16), - AD7606_CHANNEL(2, 16), - AD7606_CHANNEL(3, 16), - AD7606_CHANNEL(4, 16), - AD7606_CHANNEL(5, 16), - AD7606_CHANNEL(6, 16), - AD7606_CHANNEL(7, 16), - AD7606_CHANNEL(8, 16), - AD7606_CHANNEL(9, 16), - AD7606_CHANNEL(10, 16), - AD7606_CHANNEL(11, 16), - AD7606_CHANNEL(12, 16), - AD7606_CHANNEL(13, 16), - AD7606_CHANNEL(14, 16), - AD7606_CHANNEL(15, 16), -}; - static int ad7606c_18bit_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan); static int ad7606c_16bit_chan_scale_setup(struct iio_dev *indio_dev, @@ -198,20 +112,18 @@ static int ad7606b_sw_mode_setup(struct iio_dev *indio_dev); const struct ad7606_chip_info ad7605_4_info = { .max_samplerate = 300 * KILO, - .channels = ad7605_channels, .name = "ad7605-4", + .bits = 16, .num_adc_channels = 4, - .num_channels = 5, .scale_setup_cb = ad7606_16bit_chan_scale_setup, }; EXPORT_SYMBOL_NS_GPL(ad7605_4_info, "IIO_AD7606"); const struct ad7606_chip_info ad7606_8_info = { .max_samplerate = 200 * KILO, - .channels = ad7606_channels_16bit, .name = "ad7606-8", + .bits = 16, .num_adc_channels = 8, - .num_channels = 9, .oversampling_avail = ad7606_oversampling_avail, .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), .scale_setup_cb = ad7606_16bit_chan_scale_setup, @@ -220,10 +132,9 @@ EXPORT_SYMBOL_NS_GPL(ad7606_8_info, "IIO_AD7606"); const struct ad7606_chip_info ad7606_6_info = { .max_samplerate = 200 * KILO, - .channels = ad7606_channels_16bit, .name = "ad7606-6", + .bits = 16, .num_adc_channels = 6, - .num_channels = 7, .oversampling_avail = ad7606_oversampling_avail, .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), .scale_setup_cb = ad7606_16bit_chan_scale_setup, @@ -232,10 +143,9 @@ EXPORT_SYMBOL_NS_GPL(ad7606_6_info, "IIO_AD7606"); const struct ad7606_chip_info ad7606_4_info = { .max_samplerate = 200 * KILO, - .channels = ad7606_channels_16bit, .name = "ad7606-4", + .bits = 16, .num_adc_channels = 4, - .num_channels = 5, .oversampling_avail = ad7606_oversampling_avail, .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), .scale_setup_cb = ad7606_16bit_chan_scale_setup, @@ -243,11 +153,10 @@ const struct ad7606_chip_info ad7606_4_info = { EXPORT_SYMBOL_NS_GPL(ad7606_4_info, "IIO_AD7606"); const struct ad7606_chip_info ad7606b_info = { - .channels = ad7606_channels_16bit, .max_samplerate = 800 * KILO, .name = "ad7606b", + .bits = 16, .num_adc_channels = 8, - .num_channels = 9, .oversampling_avail = ad7606_oversampling_avail, .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), .scale_setup_cb = ad7606_16bit_chan_scale_setup, @@ -257,10 +166,9 @@ EXPORT_SYMBOL_NS_GPL(ad7606b_info, "IIO_AD7606"); const struct ad7606_chip_info ad7606c_16_info = { .max_samplerate = 1 * MEGA, - .channels = ad7606_channels_16bit, .name = "ad7606c16", + .bits = 16, .num_adc_channels = 8, - .num_channels = 9, .oversampling_avail = ad7606_oversampling_avail, .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), .scale_setup_cb = ad7606c_16bit_chan_scale_setup, @@ -270,10 +178,9 @@ EXPORT_SYMBOL_NS_GPL(ad7606c_16_info, "IIO_AD7606"); const struct ad7606_chip_info ad7607_info = { .max_samplerate = 200 * KILO, - .channels = ad7607_channels, .name = "ad7607", + .bits = 14, .num_adc_channels = 8, - .num_channels = 9, .oversampling_avail = ad7606_oversampling_avail, .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), .scale_setup_cb = ad7607_chan_scale_setup, @@ -282,10 +189,9 @@ EXPORT_SYMBOL_NS_GPL(ad7607_info, "IIO_AD7606"); const struct ad7606_chip_info ad7608_info = { .max_samplerate = 200 * KILO, - .channels = ad7608_channels, .name = "ad7608", + .bits = 18, .num_adc_channels = 8, - .num_channels = 9, .oversampling_avail = ad7606_oversampling_avail, .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), .scale_setup_cb = ad7608_chan_scale_setup, @@ -294,10 +200,9 @@ EXPORT_SYMBOL_NS_GPL(ad7608_info, "IIO_AD7606"); const struct ad7606_chip_info ad7609_info = { .max_samplerate = 200 * KILO, - .channels = ad7608_channels, .name = "ad7609", + .bits = 18, .num_adc_channels = 8, - .num_channels = 9, .oversampling_avail = ad7606_oversampling_avail, .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), .scale_setup_cb = ad7609_chan_scale_setup, @@ -306,10 +211,9 @@ EXPORT_SYMBOL_NS_GPL(ad7609_info, "IIO_AD7606"); const struct ad7606_chip_info ad7606c_18_info = { .max_samplerate = 1 * MEGA, - .channels = ad7606_channels_18bit, .name = "ad7606c18", + .bits = 18, .num_adc_channels = 8, - .num_channels = 9, .oversampling_avail = ad7606_oversampling_avail, .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), .scale_setup_cb = ad7606c_18bit_chan_scale_setup, @@ -319,11 +223,10 @@ EXPORT_SYMBOL_NS_GPL(ad7606c_18_info, "IIO_AD7606"); const struct ad7606_chip_info ad7616_info = { .max_samplerate = 1 * MEGA, - .channels = ad7616_channels, .init_delay_ms = 15, .name = "ad7616", + .bits = 16, .num_adc_channels = 16, - .num_channels = 17, .oversampling_avail = ad7616_oversampling_avail, .oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail), .os_req_reset = true, @@ -373,7 +276,6 @@ static int ad7606_get_chan_config(struct iio_dev *indio_dev, int ch, { struct ad7606_state *st = iio_priv(indio_dev); unsigned int num_channels = st->chip_info->num_adc_channels; - unsigned int offset = indio_dev->num_channels - st->chip_info->num_adc_channels; struct device *dev = st->dev; int ret; @@ -389,7 +291,7 @@ static int ad7606_get_chan_config(struct iio_dev *indio_dev, int ch, continue; /* channel number (here) is from 1 to num_channels */ - if (reg < offset || reg > num_channels) { + if (reg < 1 || reg > num_channels) { dev_warn(dev, "Invalid channel number (ignoring): %d\n", reg); continue; @@ -706,8 +608,8 @@ static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch, int *val) { struct ad7606_state *st = iio_priv(indio_dev); - unsigned int realbits = st->chip_info->channels[1].scan_type.realbits; const struct iio_chan_spec *chan; + unsigned int realbits; int ret; if (st->gpio_convst) { @@ -739,7 +641,9 @@ static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch, if (ret) goto error_ret; - chan = &indio_dev->channels[ch + 1]; + chan = &indio_dev->channels[ch]; + realbits = chan->scan_type.realbits; + if (chan->scan_type.sign == 'u') { if (realbits > 16) *val = st->data.buf32[ch]; @@ -1289,29 +1193,84 @@ static int ad7606b_sw_mode_setup(struct iio_dev *indio_dev) return st->bops->sw_mode_config(indio_dev); } -static int ad7606_chan_scales_setup(struct iio_dev *indio_dev) +static int ad7606_probe_channels(struct iio_dev *indio_dev) { struct ad7606_state *st = iio_priv(indio_dev); - unsigned int offset = indio_dev->num_channels - st->chip_info->num_adc_channels; - struct iio_chan_spec *chans; - size_t size; - int ch, ret; - - /* Clone IIO channels, since some may be differential */ - size = indio_dev->num_channels * sizeof(*indio_dev->channels); - chans = devm_kzalloc(st->dev, size, GFP_KERNEL); - if (!chans) + struct device *dev = indio_dev->dev.parent; + struct iio_chan_spec *channels; + bool slow_bus; + int ret, i; + + slow_bus = !st->bops->iio_backend_config; + indio_dev->num_channels = st->chip_info->num_adc_channels; + + /* Slow buses also get 1 more channel for soft timestamp */ + if (slow_bus) + indio_dev->num_channels++; + + channels = devm_kcalloc(dev, indio_dev->num_channels, sizeof(*channels), + GFP_KERNEL); + if (!channels) return -ENOMEM; - memcpy(chans, indio_dev->channels, size); - indio_dev->channels = chans; + for (i = 0; i < indio_dev->num_channels; i++) { + struct iio_chan_spec *chan = &channels[i]; - for (ch = 0; ch < st->chip_info->num_adc_channels; ch++) { - ret = st->chip_info->scale_setup_cb(indio_dev, &chans[ch + offset]); + chan->type = IIO_VOLTAGE; + chan->indexed = 1; + chan->channel = i; + chan->scan_index = i; + chan->scan_type.sign = 's'; + chan->scan_type.realbits = st->chip_info->bits; + chan->scan_type.storagebits = st->chip_info->bits > 16 ? 32 : 16; + chan->scan_type.endianness = IIO_CPU; + + if (indio_dev->modes & INDIO_DIRECT_MODE) + chan->info_mask_separate |= BIT(IIO_CHAN_INFO_RAW); + + if (st->sw_mode_en) { + chan->info_mask_separate |= BIT(IIO_CHAN_INFO_SCALE); + chan->info_mask_separate_available |= + BIT(IIO_CHAN_INFO_SCALE); + + /* + * All chips with software mode support oversampling, + * so we skip the oversampling_available check. And the + * shared_by_type instead of shared_by_all on slow + * buses is for backward compatibility. + */ + if (slow_bus) + chan->info_mask_shared_by_type |= + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); + else + chan->info_mask_shared_by_all |= + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); + + chan->info_mask_shared_by_all_available |= + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); + } else { + chan->info_mask_shared_by_type |= + BIT(IIO_CHAN_INFO_SCALE); + + if (st->chip_info->oversampling_avail) + chan->info_mask_shared_by_all |= + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); + } + + if (!slow_bus) + chan->info_mask_shared_by_all |= + BIT(IIO_CHAN_INFO_SAMP_FREQ); + + ret = st->chip_info->scale_setup_cb(indio_dev, chan); if (ret) return ret; } + if (slow_bus) + channels[i] = (struct iio_chan_spec)IIO_CHAN_SOFT_TIMESTAMP(i); + + indio_dev->channels = channels; + return 0; } @@ -1343,6 +1302,11 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, st->bops = bops; st->base_address = base_address; st->oversampling = 1; + st->sw_mode_en = device_property_read_bool(dev, "adi,sw-mode"); + + if (st->sw_mode_en && !chip_info->sw_setup_cb) + return dev_err_probe(dev, -EINVAL, + "Software mode is not supported for this chip\n"); ret = devm_regulator_get_enable(dev, "avcc"); if (ret) @@ -1371,10 +1335,14 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, else indio_dev->info = &ad7606_info_no_os_or_range; } - indio_dev->modes = INDIO_DIRECT_MODE; + + /* AXI ADC backend doesn't support single read. */ + indio_dev->modes = st->bops->iio_backend_config ? 0 : INDIO_DIRECT_MODE; indio_dev->name = chip_info->name; - indio_dev->channels = st->chip_info->channels; - indio_dev->num_channels = st->chip_info->num_channels; + + ret = ad7606_probe_channels(indio_dev); + if (ret) + return ret; ret = ad7606_reset(st); if (ret) @@ -1465,17 +1433,11 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, st->write_scale = ad7606_write_scale_hw; st->write_os = ad7606_write_os_hw; - st->sw_mode_en = st->chip_info->sw_setup_cb && - device_property_present(st->dev, "adi,sw-mode"); if (st->sw_mode_en) { indio_dev->info = &ad7606_info_sw_mode; st->chip_info->sw_setup_cb(indio_dev); } - ret = ad7606_chan_scales_setup(indio_dev); - if (ret) - return ret; - return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_NS_GPL(ad7606_probe, "IIO_AD7606"); diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h index c57a193761c92add6f82cf0cc51ccfdb9d8d2ab4..f0b262fb4554f0bf244338c98ca585143321d616 100644 --- a/drivers/iio/adc/ad7606.h +++ b/drivers/iio/adc/ad7606.h @@ -40,76 +40,6 @@ #define AD7606_RANGE_CH_ADDR(ch) (0x03 + ((ch) >> 1)) #define AD7606_OS_MODE 0x08 -#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all, \ - mask_sep_avail, mask_all_avail, bits) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = num, \ - .info_mask_separate = mask_sep, \ - .info_mask_separate_available = \ - mask_sep_avail, \ - .info_mask_shared_by_type = mask_type, \ - .info_mask_shared_by_all = mask_all, \ - .info_mask_shared_by_all_available = \ - mask_all_avail, \ - .scan_index = num, \ - .scan_type = { \ - .sign = 's', \ - .realbits = (bits), \ - .storagebits = (bits) > 16 ? 32 : 16, \ - .endianness = IIO_CPU, \ - }, \ -} - -#define AD7606_SW_CHANNEL(num, bits) \ - AD760X_CHANNEL(num, \ - /* mask separate */ \ - BIT(IIO_CHAN_INFO_RAW) | \ - BIT(IIO_CHAN_INFO_SCALE), \ - /* mask type */ \ - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ - /* mask all */ \ - 0, \ - /* mask separate available */ \ - BIT(IIO_CHAN_INFO_SCALE), \ - /* mask all available */ \ - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ - bits) - -#define AD7605_CHANNEL(num) \ - AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW), \ - BIT(IIO_CHAN_INFO_SCALE), 0, 0, 0, 16) - -#define AD7606_CHANNEL(num, bits) \ - AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW), \ - BIT(IIO_CHAN_INFO_SCALE), \ - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ - 0, 0, bits) - -#define AD7616_CHANNEL(num) AD7606_SW_CHANNEL(num, 16) - -#define AD7606_BI_CHANNEL(num) \ - AD760X_CHANNEL(num, 0, \ - BIT(IIO_CHAN_INFO_SCALE), \ - BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ - 0, 0, 16) - -#define AD7606_BI_SW_CHANNEL(num) \ - AD760X_CHANNEL(num, \ - /* mask separate */ \ - BIT(IIO_CHAN_INFO_SCALE), \ - /* mask type */ \ - 0, \ - /* mask all */ \ - BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ - /* mask separate available */ \ - BIT(IIO_CHAN_INFO_SCALE), \ - /* mask all available */ \ - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ - 16) - struct ad7606_state; typedef int (*ad7606_scale_setup_cb_t)(struct iio_dev *indio_dev, @@ -118,11 +48,10 @@ typedef int (*ad7606_sw_setup_cb_t)(struct iio_dev *indio_dev); /** * struct ad7606_chip_info - chip specific information - * @channels: channel specification * @max_samplerate: maximum supported sample rate * @name: device name + * @bits: data width in bits * @num_adc_channels: the number of physical voltage inputs - * @num_channels: number of IIO channels * @scale_setup_cb: callback to setup the scales for each channel * @sw_setup_cb: callback to setup the software mode if available. * @oversampling_avail: pointer to the array which stores the available @@ -133,11 +62,10 @@ typedef int (*ad7606_sw_setup_cb_t)(struct iio_dev *indio_dev); * after a restart */ struct ad7606_chip_info { - const struct iio_chan_spec *channels; unsigned int max_samplerate; const char *name; + unsigned int bits; unsigned int num_adc_channels; - unsigned int num_channels; ad7606_scale_setup_cb_t scale_setup_cb; ad7606_sw_setup_cb_t sw_setup_cb; const unsigned int *oversampling_avail; diff --git a/drivers/iio/adc/ad7606_par.c b/drivers/iio/adc/ad7606_par.c index 335fb481bfde15b79331eabdcbc970d70880338c..e33b07ab5eace4b78e7cf39ee7e8d9379c9f73e7 100644 --- a/drivers/iio/adc/ad7606_par.c +++ b/drivers/iio/adc/ad7606_par.c @@ -21,28 +21,6 @@ #include "ad7606.h" #include "ad7606_bus_iface.h" -static const struct iio_chan_spec ad7606b_bi_channels[] = { - AD7606_BI_CHANNEL(0), - AD7606_BI_CHANNEL(1), - AD7606_BI_CHANNEL(2), - AD7606_BI_CHANNEL(3), - AD7606_BI_CHANNEL(4), - AD7606_BI_CHANNEL(5), - AD7606_BI_CHANNEL(6), - AD7606_BI_CHANNEL(7), -}; - -static const struct iio_chan_spec ad7606b_bi_sw_channels[] = { - AD7606_BI_SW_CHANNEL(0), - AD7606_BI_SW_CHANNEL(1), - AD7606_BI_SW_CHANNEL(2), - AD7606_BI_SW_CHANNEL(3), - AD7606_BI_SW_CHANNEL(4), - AD7606_BI_SW_CHANNEL(5), - AD7606_BI_SW_CHANNEL(6), - AD7606_BI_SW_CHANNEL(7), -}; - static int ad7606_par_bus_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { @@ -94,9 +72,6 @@ static int ad7606_par_bus_setup_iio_backend(struct device *dev, return ret; } - indio_dev->channels = ad7606b_bi_channels; - indio_dev->num_channels = 8; - return 0; } @@ -120,19 +95,11 @@ static int ad7606_par_bus_reg_write(struct ad7606_state *st, unsigned int addr, return pdata->bus_reg_write(st->back, addr, val); } -static int ad7606_par_bus_sw_mode_config(struct iio_dev *indio_dev) -{ - indio_dev->channels = ad7606b_bi_sw_channels; - - return 0; -} - static const struct ad7606_bus_ops ad7606_bi_bops = { .iio_backend_config = ad7606_par_bus_setup_iio_backend, .update_scan_mode = ad7606_par_bus_update_scan_mode, .reg_read = ad7606_par_bus_reg_read, .reg_write = ad7606_par_bus_reg_write, - .sw_mode_config = ad7606_par_bus_sw_mode_config, }; static int ad7606_par16_read_block(struct device *dev, diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c index 1abaf8626206cb30e532cf9f82e0d050706aa1e0..b2b975fb7fea4d1af6caef59e75ca495501bc140 100644 --- a/drivers/iio/adc/ad7606_spi.c +++ b/drivers/iio/adc/ad7606_spi.c @@ -15,50 +15,6 @@ #define MAX_SPI_FREQ_HZ 23500000 /* VDRIVE above 4.75 V */ -static const struct iio_chan_spec ad7616_sw_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(16), - AD7616_CHANNEL(0), - AD7616_CHANNEL(1), - AD7616_CHANNEL(2), - AD7616_CHANNEL(3), - AD7616_CHANNEL(4), - AD7616_CHANNEL(5), - AD7616_CHANNEL(6), - AD7616_CHANNEL(7), - AD7616_CHANNEL(8), - AD7616_CHANNEL(9), - AD7616_CHANNEL(10), - AD7616_CHANNEL(11), - AD7616_CHANNEL(12), - AD7616_CHANNEL(13), - AD7616_CHANNEL(14), - AD7616_CHANNEL(15), -}; - -static const struct iio_chan_spec ad7606b_sw_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(8), - AD7606_SW_CHANNEL(0, 16), - AD7606_SW_CHANNEL(1, 16), - AD7606_SW_CHANNEL(2, 16), - AD7606_SW_CHANNEL(3, 16), - AD7606_SW_CHANNEL(4, 16), - AD7606_SW_CHANNEL(5, 16), - AD7606_SW_CHANNEL(6, 16), - AD7606_SW_CHANNEL(7, 16), -}; - -static const struct iio_chan_spec ad7606c_18_sw_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(8), - AD7606_SW_CHANNEL(0, 18), - AD7606_SW_CHANNEL(1, 18), - AD7606_SW_CHANNEL(2, 18), - AD7606_SW_CHANNEL(3, 18), - AD7606_SW_CHANNEL(4, 18), - AD7606_SW_CHANNEL(5, 18), - AD7606_SW_CHANNEL(6, 18), - AD7606_SW_CHANNEL(7, 18), -}; - static u16 ad7616_spi_rd_wr_cmd(int addr, char is_write_op) { /* @@ -160,48 +116,13 @@ static int ad7606_spi_reg_write(struct ad7606_state *st, return spi_write(spi, &st->d16[0], sizeof(st->d16[0])); } -static int ad7616_sw_mode_config(struct iio_dev *indio_dev) -{ - /* - * Scale can be configured individually for each channel - * in software mode. - */ - indio_dev->channels = ad7616_sw_channels; - - return 0; -} - static int ad7606b_sw_mode_config(struct iio_dev *indio_dev) { struct ad7606_state *st = iio_priv(indio_dev); - int ret; /* Configure device spi to output on a single channel */ - ret = st->bops->reg_write(st, AD7606_CONFIGURATION_REGISTER, - AD7606_SINGLE_DOUT); - if (ret) - return ret; - - /* - * Scale can be configured individually for each channel - * in software mode. - */ - indio_dev->channels = ad7606b_sw_channels; - - return 0; -} - -static int ad7606c_18_sw_mode_config(struct iio_dev *indio_dev) -{ - int ret; - - ret = ad7606b_sw_mode_config(indio_dev); - if (ret) - return ret; - - indio_dev->channels = ad7606c_18_sw_channels; - - return 0; + return st->bops->reg_write(st, AD7606_CONFIGURATION_REGISTER, + AD7606_SINGLE_DOUT); } static const struct ad7606_bus_ops ad7606_spi_bops = { @@ -221,7 +142,6 @@ static const struct ad7606_bus_ops ad7616_spi_bops = { .reg_read = ad7606_spi_reg_read, .reg_write = ad7606_spi_reg_write, .rd_wr_cmd = ad7616_spi_rd_wr_cmd, - .sw_mode_config = ad7616_sw_mode_config, }; static const struct ad7606_bus_ops ad7606b_spi_bops = { @@ -237,7 +157,7 @@ static const struct ad7606_bus_ops ad7606c_18_spi_bops = { .reg_read = ad7606_spi_reg_read, .reg_write = ad7606_spi_reg_write, .rd_wr_cmd = ad7606b_spi_rd_wr_cmd, - .sw_mode_config = ad7606c_18_sw_mode_config, + .sw_mode_config = ad7606b_sw_mode_config, }; static const struct ad7606_bus_info ad7605_4_bus_info = {