aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Titinger <mtitinger@baylibre.com>2015-12-07 04:09:35 -0500
committerJonathan Cameron <jic23@kernel.org>2015-12-12 11:07:41 -0500
commitf9993c0771ce24063fe62bf73ac57bcfc9ad81de (patch)
tree8d2de8e4b48df74802ad3588e83d19b3432d595a
parentc43a102e67db99c8bfe6e8a9280cec13ff53b789 (diff)
iio: ina2xx: provide a sysfs parameter to allow async readout of the ADCs
This can lead to repeated or skipped samples depending on the clock beat between the capture thread and the chip sampling clock, but will also spare reading/waiting for the Capture Ready Flag and improve the available i2c bandwidth for reading measurements. Output of iio_info: ...snip... 4 device-specific attributes found: attr 0: in_oversampling_ratio value: 4 attr 1: in_allow_async_readout value: 0 attr 2: integration_time_available value: 140 204 332 588 1100 2116... attr 3: in_sampling_frequency value: 114 Signed-off-by: Marc Titinger <mtitinger@baylibre.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/iio/adc/ina2xx-adc.c54
1 files changed, 45 insertions, 9 deletions
diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c
index 707bd69a7353..ff31f5b49a41 100644
--- a/drivers/iio/adc/ina2xx-adc.c
+++ b/drivers/iio/adc/ina2xx-adc.c
@@ -116,6 +116,7 @@ struct ina2xx_chip_info {
116 s64 prev_ns; /* track buffer capture time, check for underruns*/ 116 s64 prev_ns; /* track buffer capture time, check for underruns*/
117 int int_time_vbus; /* Bus voltage integration time uS */ 117 int int_time_vbus; /* Bus voltage integration time uS */
118 int int_time_vshunt; /* Shunt voltage integration time uS */ 118 int int_time_vshunt; /* Shunt voltage integration time uS */
119 bool allow_async_readout;
119}; 120};
120 121
121static const struct ina2xx_config ina2xx_config[] = { 122static const struct ina2xx_config ina2xx_config[] = {
@@ -322,6 +323,33 @@ _err:
322} 323}
323 324
324 325
326static ssize_t ina2xx_allow_async_readout_show(struct device *dev,
327 struct device_attribute *attr,
328 char *buf)
329{
330 struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev));
331
332 return sprintf(buf, "%d\n", chip->allow_async_readout);
333}
334
335static ssize_t ina2xx_allow_async_readout_store(struct device *dev,
336 struct device_attribute *attr,
337 const char *buf, size_t len)
338{
339 struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev));
340 bool val;
341 int ret;
342
343 ret = strtobool((const char *) buf, &val);
344 if (ret)
345 return ret;
346
347 chip->allow_async_readout = val;
348
349 return len;
350}
351
352
325#define INA2XX_CHAN(_type, _index, _address) { \ 353#define INA2XX_CHAN(_type, _index, _address) { \
326 .type = (_type), \ 354 .type = (_type), \
327 .address = (_address), \ 355 .address = (_address), \
@@ -390,16 +418,17 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)
390 * GPIO a triggered buffer could be used instead. 418 * GPIO a triggered buffer could be used instead.
391 * For now, we pay for that extra read of the ALERT register 419 * For now, we pay for that extra read of the ALERT register
392 */ 420 */
393 do { 421 if (!chip->allow_async_readout)
394 ret = regmap_read(chip->regmap, INA226_ALERT_MASK, 422 do {
395 &alert); 423 ret = regmap_read(chip->regmap, INA226_ALERT_MASK,
396 if (ret < 0) 424 &alert);
397 return ret; 425 if (ret < 0)
426 return ret;
398 427
399 alert &= INA266_CVRF; 428 alert &= INA266_CVRF;
400 trace_printk("Conversion ready: %d\n", !!alert); 429 trace_printk("Conversion ready: %d\n", !!alert);
401 430
402 } while (!alert); 431 } while (!alert);
403 432
404 /* 433 /*
405 * Single register reads: bulk_read will not work with ina226 434 * Single register reads: bulk_read will not work with ina226
@@ -444,7 +473,8 @@ static int ina2xx_capture_thread(void *data)
444 * Poll a bit faster than the chip internal Fs, in case 473 * Poll a bit faster than the chip internal Fs, in case
445 * we wish to sync with the conversion ready flag. 474 * we wish to sync with the conversion ready flag.
446 */ 475 */
447 sampling_us -= 200; 476 if (!chip->allow_async_readout)
477 sampling_us -= 200;
448 478
449 do { 479 do {
450 buffer_us = ina2xx_work_buffer(indio_dev); 480 buffer_us = ina2xx_work_buffer(indio_dev);
@@ -469,6 +499,7 @@ static int ina2xx_buffer_enable(struct iio_dev *indio_dev)
469 1000000/sampling_us, chip->avg); 499 1000000/sampling_us, chip->avg);
470 500
471 trace_printk("Expected work period: %u us\n", sampling_us); 501 trace_printk("Expected work period: %u us\n", sampling_us);
502 trace_printk("Async readout mode: %d\n", chip->allow_async_readout);
472 503
473 chip->prev_ns = iio_get_time_ns(); 504 chip->prev_ns = iio_get_time_ns();
474 505
@@ -510,7 +541,12 @@ static int ina2xx_debug_reg(struct iio_dev *indio_dev,
510static IIO_CONST_ATTR_INT_TIME_AVAIL \ 541static IIO_CONST_ATTR_INT_TIME_AVAIL \
511 ("0.000140 0.000204 0.000332 0.000588 0.001100 0.002116 0.004156 0.008244"); 542 ("0.000140 0.000204 0.000332 0.000588 0.001100 0.002116 0.004156 0.008244");
512 543
544static IIO_DEVICE_ATTR(in_allow_async_readout, S_IRUGO | S_IWUSR,
545 ina2xx_allow_async_readout_show,
546 ina2xx_allow_async_readout_store, 0);
547
513static struct attribute *ina2xx_attributes[] = { 548static struct attribute *ina2xx_attributes[] = {
549 &iio_dev_attr_in_allow_async_readout.dev_attr.attr,
514 &iio_const_attr_integration_time_available.dev_attr.attr, 550 &iio_const_attr_integration_time_available.dev_attr.attr,
515 NULL, 551 NULL,
516}; 552};