Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: adc: ad7944: Add support for "3-wire mode"

This adds support for AD7944 ADCs wired in "3-wire mode". (NOTE: 3-wire
is the datasheet name for this wiring configuration and has nothing to
do with SPI_3WIRE.)

In the 3-wire mode, the SPI controller CS line can be wired to the CNV
line on the ADC and used to trigger conversions rather that using a
separate GPIO line.

The turbo/chain mode compatibility check at the end of the probe
function is technically can't be triggered right now but adding it now
anyway so that we don't forget to add it later when support for
daisy-chaining is added.

Reviewed-by: Nuno Sa <nuno.sa@analog.com>
Signed-off-by: David Lechner <dlechner@baylibre.com>
Link: https://lore.kernel.org/r/20240314-mainline-ad7944-3-wire-mode-v2-1-d469da0705d2@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

David Lechner and committed by
Jonathan Cameron
346ae0e8 fcdb03e4

+139 -18
+139 -18
drivers/iio/adc/ad7944.c
··· 32 32 unsigned int turbo_conv_ns; 33 33 }; 34 34 35 + enum ad7944_spi_mode { 36 + /* datasheet calls this "4-wire mode" */ 37 + AD7944_SPI_MODE_DEFAULT, 38 + /* datasheet calls this "3-wire mode" (not related to SPI_3WIRE!) */ 39 + AD7944_SPI_MODE_SINGLE, 40 + /* datasheet calls this "chain mode" */ 41 + AD7944_SPI_MODE_CHAIN, 42 + }; 43 + 44 + /* maps adi,spi-mode property value to enum */ 45 + static const char * const ad7944_spi_modes[] = { 46 + [AD7944_SPI_MODE_DEFAULT] = "", 47 + [AD7944_SPI_MODE_SINGLE] = "single", 48 + [AD7944_SPI_MODE_CHAIN] = "chain", 49 + }; 50 + 35 51 struct ad7944_adc { 36 52 struct spi_device *spi; 53 + enum ad7944_spi_mode spi_mode; 37 54 /* Chip-specific timing specifications. */ 38 55 const struct ad7944_timing_spec *timing_spec; 39 56 /* GPIO connected to CNV pin. */ ··· 74 57 u64 timestamp __aligned(8); 75 58 } sample __aligned(IIO_DMA_MINALIGN); 76 59 }; 60 + 61 + /* quite time before CNV rising edge */ 62 + #define T_QUIET_NS 20 77 63 78 64 static const struct ad7944_timing_spec ad7944_timing_spec = { 79 65 .conv_ns = 420, ··· 129 109 AD7944_DEFINE_CHIP_INFO(ad7985, ad7944, 16, 0); 130 110 /* fully differential */ 131 111 AD7944_DEFINE_CHIP_INFO(ad7986, ad7986, 18, 1); 112 + 113 + /* 114 + * ad7944_3wire_cs_mode_conversion - Perform a 3-wire CS mode conversion and 115 + * acquisition 116 + * @adc: The ADC device structure 117 + * @chan: The channel specification 118 + * Return: 0 on success, a negative error code on failure 119 + * 120 + * This performs a conversion and reads data when the chip is wired in 3-wire 121 + * mode with the CNV line on the ADC tied to the CS line on the SPI controller. 122 + * 123 + * Upon successful return adc->sample.raw will contain the conversion result. 124 + */ 125 + static int ad7944_3wire_cs_mode_conversion(struct ad7944_adc *adc, 126 + const struct iio_chan_spec *chan) 127 + { 128 + unsigned int t_conv_ns = adc->always_turbo ? adc->timing_spec->turbo_conv_ns 129 + : adc->timing_spec->conv_ns; 130 + struct spi_transfer xfers[] = { 131 + { 132 + /* 133 + * NB: can get better performance from some SPI 134 + * controllers if we use the same bits_per_word 135 + * in every transfer. 136 + */ 137 + .bits_per_word = chan->scan_type.realbits, 138 + /* 139 + * CS is tied to CNV and we need a low to high 140 + * transition to start the conversion, so place CNV 141 + * low for t_QUIET to prepare for this. 142 + */ 143 + .delay = { 144 + .value = T_QUIET_NS, 145 + .unit = SPI_DELAY_UNIT_NSECS, 146 + }, 147 + 148 + }, 149 + { 150 + .bits_per_word = chan->scan_type.realbits, 151 + /* 152 + * CS has to be high for full conversion time to avoid 153 + * triggering the busy indication. 154 + */ 155 + .cs_off = 1, 156 + .delay = { 157 + .value = t_conv_ns, 158 + .unit = SPI_DELAY_UNIT_NSECS, 159 + }, 160 + }, 161 + { 162 + /* Then we can read the data during the acquisition phase */ 163 + .rx_buf = &adc->sample.raw, 164 + .len = BITS_TO_BYTES(chan->scan_type.storagebits), 165 + .bits_per_word = chan->scan_type.realbits, 166 + }, 167 + }; 168 + 169 + return spi_sync_transfer(adc->spi, xfers, ARRAY_SIZE(xfers)); 170 + } 132 171 133 172 /* 134 173 * ad7944_4wire_mode_conversion - Perform a 4-wire mode conversion and acquisition ··· 246 167 { 247 168 int ret; 248 169 249 - ret = ad7944_4wire_mode_conversion(adc, chan); 250 - if (ret) 251 - return ret; 170 + switch (adc->spi_mode) { 171 + case AD7944_SPI_MODE_DEFAULT: 172 + ret = ad7944_4wire_mode_conversion(adc, chan); 173 + if (ret) 174 + return ret; 175 + 176 + break; 177 + case AD7944_SPI_MODE_SINGLE: 178 + ret = ad7944_3wire_cs_mode_conversion(adc, chan); 179 + if (ret) 180 + return ret; 181 + 182 + break; 183 + default: 184 + return -EOPNOTSUPP; 185 + } 252 186 253 187 if (chan->scan_type.storagebits > 16) 254 188 *val = adc->sample.raw.u32; ··· 322 230 struct ad7944_adc *adc = iio_priv(indio_dev); 323 231 int ret; 324 232 325 - ret = ad7944_4wire_mode_conversion(adc, &indio_dev->channels[0]); 326 - if (ret) 233 + switch (adc->spi_mode) { 234 + case AD7944_SPI_MODE_DEFAULT: 235 + ret = ad7944_4wire_mode_conversion(adc, &indio_dev->channels[0]); 236 + if (ret) 237 + goto out; 238 + 239 + break; 240 + case AD7944_SPI_MODE_SINGLE: 241 + ret = ad7944_3wire_cs_mode_conversion(adc, &indio_dev->channels[0]); 242 + if (ret) 243 + goto out; 244 + 245 + break; 246 + default: 247 + /* not supported */ 327 248 goto out; 249 + } 328 250 329 251 iio_push_to_buffers_with_timestamp(indio_dev, &adc->sample.raw, 330 252 pf->timestamp); ··· 366 260 struct ad7944_adc *adc; 367 261 bool have_refin = false; 368 262 struct regulator *ref; 263 + const char *str_val; 369 264 int ret; 370 - 371 - /* 372 - * driver currently only supports the conventional "4-wire" mode and 373 - * not other special wiring configurations. 374 - */ 375 - if (device_property_present(dev, "adi,spi-mode")) 376 - return dev_err_probe(dev, -EINVAL, 377 - "adi,spi-mode is not currently supported\n"); 378 265 379 266 indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); 380 267 if (!indio_dev) ··· 381 282 return dev_err_probe(dev, -EINVAL, "no chip info\n"); 382 283 383 284 adc->timing_spec = chip_info->timing_spec; 285 + 286 + if (device_property_read_string(dev, "adi,spi-mode", &str_val) == 0) { 287 + ret = sysfs_match_string(ad7944_spi_modes, str_val); 288 + if (ret < 0) 289 + return dev_err_probe(dev, -EINVAL, 290 + "unsupported adi,spi-mode\n"); 291 + 292 + adc->spi_mode = ret; 293 + } else { 294 + /* absence of adi,spi-mode property means default mode */ 295 + adc->spi_mode = AD7944_SPI_MODE_DEFAULT; 296 + } 297 + 298 + if (adc->spi_mode == AD7944_SPI_MODE_CHAIN) 299 + return dev_err_probe(dev, -EINVAL, 300 + "chain mode is not implemented\n"); 384 301 385 302 /* 386 303 * Some chips use unusual word sizes, so check now instead of waiting ··· 464 349 adc->ref_mv = AD7944_INTERNAL_REF_MV; 465 350 } 466 351 467 - /* 468 - * CNV gpio is required in 4-wire mode which is the only currently 469 - * supported mode. 470 - */ 471 - adc->cnv = devm_gpiod_get(dev, "cnv", GPIOD_OUT_LOW); 352 + adc->cnv = devm_gpiod_get_optional(dev, "cnv", GPIOD_OUT_LOW); 472 353 if (IS_ERR(adc->cnv)) 473 354 return dev_err_probe(dev, PTR_ERR(adc->cnv), 474 355 "failed to get CNV GPIO\n"); 356 + 357 + if (!adc->cnv && adc->spi_mode == AD7944_SPI_MODE_DEFAULT) 358 + return dev_err_probe(&spi->dev, -EINVAL, "CNV GPIO is required\n"); 359 + if (adc->cnv && adc->spi_mode != AD7944_SPI_MODE_DEFAULT) 360 + return dev_err_probe(&spi->dev, -EINVAL, 361 + "CNV GPIO in single and chain mode is not currently supported\n"); 475 362 476 363 adc->turbo = devm_gpiod_get_optional(dev, "turbo", GPIOD_OUT_LOW); 477 364 if (IS_ERR(adc->turbo)) ··· 485 368 if (adc->turbo && adc->always_turbo) 486 369 return dev_err_probe(dev, -EINVAL, 487 370 "cannot have both turbo-gpios and adi,always-turbo\n"); 371 + 372 + if (adc->spi_mode == AD7944_SPI_MODE_CHAIN && adc->always_turbo) 373 + return dev_err_probe(dev, -EINVAL, 374 + "cannot have both chain mode and always turbo\n"); 488 375 489 376 indio_dev->name = chip_info->name; 490 377 indio_dev->modes = INDIO_DIRECT_MODE;