diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-05-15 16:03:28 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-05-15 16:03:28 +0200 |
commit | cef077e6aa4c7dbe2f23e1201cf705f9540ec467 (patch) | |
tree | d955418799ae8d491a648e07a44425bb06d957bb /drivers/iio/adc | |
parent | c336c022503d1be719ca06f2526c211709e3d2d3 (diff) | |
parent | 6b46ddb51eab245c64b6b9c55c189e45967d213f (diff) | |
download | linux-cef077e6aa4c7dbe2f23e1201cf705f9540ec467.tar.bz2 |
Merge tag 'iio-for-5.8b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes:
Second set of new device support, cleanups and features for IIO in the 5.8 cycle
Usual mixed back but with a few subsystem wide or device type
wide cleanups.
New device support
* adis16475
- New driver supporting adis16470, adis16475, adis16477, adis16465,
adis16467, adis16500, adis16505 and adis16507.
Includes some rework of the adis library to simplify using it
for this new driver.
* ak8974
- Add support for Alps hscdt008a. ID only. Related patches add support
for scale.
* atlas-sensor
- Add support for RTD-SM OEM temperature sensor.
* cm32181
- Add support for CM3218 including support for SMBUS alert via
ACPI resources.
* ltc2632
- Add support for ltc2634-12/10/8 DACS including handling per
device type numbers of channels.
Major Features
* cm32181
- ACPI bindings including parsing CPM0 and CPM1 custom ACPI tables.
Includes minor tidy ups and fixes.
* vcnl4000
- Add event support
- Add buffered data capture support
- Add control of sampling frequency
Cleanups and minor fixes.
* core
- Trivial rework of iio_device_alloc to use an early return and
improve readability.
- Precursors to addition of multiple buffer support. So far
minor refactoring.
* subsystem wide
- Use get_unaligned_be24 slightly improve readability over open
coding it.
* adis drivers
- Use iio_get_debugfs_dentry access function.
* bh1780, cm32181, cm3232, gp2ap02a00f, opt3001, st_uvis25, vl6180,
dmard06, kxsd9
- Drop use of of_match_ptr to allow ACPI based probing via PRP0001.
Part of clear out of this to avoid cut and paste into new drivers.
* ad5592r, ad5593r
- Fix typos
* ad5933
- Use managed interfaces to automate error handling and remove.
* ak8974
- Fix wrong number of 'real bits' for buffered data.
- Refactor to pull measurement code out as separate function.
bmp280
- Fix lack of clamp on range during data capture.
* at91-sama5d2_adc
- Handle unfinished conversions correctly.
- Allow use of triggers other than it's own.
- Reorganize buffer setup and tear down as part of long running
subsystem wide rework.
* ccs811
- Add DT binding docs and match table.
- Support external reset and wakeup pins.
* hid-sensors
- Reorganize buffer setup and tear down as part of long running
subsystem wide rework.
* ltr501
- Constify some structs.
* vcnl4000
- Fix an endian issue by using explicit byte swapped i2c accessors.
* tag 'iio-for-5.8b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (74 commits)
iio: light: ltr501: Constify structs
staging: iio: ad5933: attach life-cycle of kfifo buffer to parent device and use managed calls throughout
iio: bmp280: fix compensation of humidity
iio: light: cm32181: Fix integartion time typo
iio: light: cm32181: Add support for parsing CPM0 and CPM1 ACPI tables
iio: light: cm32181: Make lux_per_bit and lux_per_bit_base_it runtime settings
iio: light: cm32181: Use units of 1/100000th for calibscale and lux_per_bit
iio: light: cm32181: Change reg_init to use a bitmap of which registers to init
iio: light: cm32181: Handle CM3218 ACPI devices with 2 I2C resources
iio: light: cm32181: Clean up the probe function a bit
iio: light: cm32181: Add support for the CM3218
iio: light: cm32181: Add some extra register defines
iio: light: cm32181: Add support for ACPI enumeration
iio: light: cm32181: Switch to new style i2c-driver probe function
iio: hid-sensors: move triggered buffer setup into hid_sensor_setup_trigger
iio: vcnl4000: Add buffer support for VCNL4010/20.
iio: vcnl4000: Add sampling frequency support for VCNL4010/20.
iio: vcnl4000: Add event support for VCNL4010/20.
iio: vcnl4000: Factorize data reading and writing.
iio: vcnl4000: Fix i2c swapped word reading.
...
Diffstat (limited to 'drivers/iio/adc')
-rw-r--r-- | drivers/iio/adc/ad7476.c | 2 | ||||
-rw-r--r-- | drivers/iio/adc/ad_sigma_delta.c | 8 | ||||
-rw-r--r-- | drivers/iio/adc/at91-sama5d2_adc.c | 233 | ||||
-rw-r--r-- | drivers/iio/adc/mcp3422.c | 5 | ||||
-rw-r--r-- | drivers/iio/adc/ti-ads124s08.c | 7 |
5 files changed, 149 insertions, 106 deletions
diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index e9984a38fc4c..4e816d714ad2 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -309,7 +309,7 @@ static int ad7476_probe(struct spi_device *spi) indio_dev->num_channels = 2; indio_dev->info = &ad7476_info; - if (st->convst_gpio && st->chip_info->convst_channel) + if (st->convst_gpio) indio_dev->channels = st->chip_info->convst_channel; /* Setup default message */ diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index 8115b6de1d6c..dd3d54b3bc8b 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -70,9 +70,7 @@ int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, switch (size) { case 3: - data[1] = val >> 16; - data[2] = val >> 8; - data[3] = val; + put_unaligned_be24(val, &data[1]); break; case 2: put_unaligned_be16(val, &data[1]); @@ -157,9 +155,7 @@ int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, *val = get_unaligned_be32(sigma_delta->data); break; case 3: - *val = (sigma_delta->data[0] << 16) | - (sigma_delta->data[1] << 8) | - sigma_delta->data[2]; + *val = get_unaligned_be24(&sigma_delta->data[0]); break; case 2: *val = get_unaligned_be16(sigma_delta->data); diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 9d96f7d08b95..9abbbdcc7420 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -8,6 +8,7 @@ #include <linux/bitops.h> #include <linux/clk.h> +#include <linux/delay.h> #include <linux/dma-mapping.h> #include <linux/dmaengine.h> #include <linux/interrupt.h> @@ -100,6 +101,8 @@ #define AT91_SAMA5D2_IER_YRDY BIT(21) /* Interrupt Enable Register - TS pressure measurement ready */ #define AT91_SAMA5D2_IER_PRDY BIT(22) +/* Interrupt Enable Register - Data ready */ +#define AT91_SAMA5D2_IER_DRDY BIT(24) /* Interrupt Enable Register - general overrun error */ #define AT91_SAMA5D2_IER_GOVRE BIT(25) /* Interrupt Enable Register - Pen detect */ @@ -486,6 +489,21 @@ static inline int at91_adc_of_xlate(struct iio_dev *indio_dev, return at91_adc_chan_xlate(indio_dev, iiospec->args[0]); } +static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev) +{ + u32 mask = 0; + u8 bit; + + for_each_set_bit(bit, indio_dev->active_scan_mask, + indio_dev->num_channels) { + struct iio_chan_spec const *chan = + at91_adc_chan_get(indio_dev, bit); + mask |= BIT(chan->channel); + } + + return mask & GENMASK(11, 0); +} + static void at91_adc_config_emr(struct at91_adc_state *st) { /* configure the extended mode register */ @@ -710,7 +728,6 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) struct iio_dev *indio = iio_trigger_get_drvdata(trig); struct at91_adc_state *st = iio_priv(indio); u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR); - u8 bit; /* clear TRGMOD */ status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK; @@ -721,50 +738,6 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) /* set/unset hw trigger */ at91_adc_writel(st, AT91_SAMA5D2_TRGR, status); - for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) { - struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit); - u32 cor; - - if (!chan) - continue; - /* these channel types cannot be handled by this trigger */ - if (chan->type == IIO_POSITIONRELATIVE || - chan->type == IIO_PRESSURE) - continue; - - if (state) { - cor = at91_adc_readl(st, AT91_SAMA5D2_COR); - - if (chan->differential) - cor |= (BIT(chan->channel) | - BIT(chan->channel2)) << - AT91_SAMA5D2_COR_DIFF_OFFSET; - else - cor &= ~(BIT(chan->channel) << - AT91_SAMA5D2_COR_DIFF_OFFSET); - - at91_adc_writel(st, AT91_SAMA5D2_COR, cor); - } - - if (state) { - at91_adc_writel(st, AT91_SAMA5D2_CHER, - BIT(chan->channel)); - /* enable irq only if not using DMA */ - if (!st->dma_st.dma_chan) { - at91_adc_writel(st, AT91_SAMA5D2_IER, - BIT(chan->channel)); - } - } else { - /* disable irq only if not using DMA */ - if (!st->dma_st.dma_chan) { - at91_adc_writel(st, AT91_SAMA5D2_IDR, - BIT(chan->channel)); - } - at91_adc_writel(st, AT91_SAMA5D2_CHDR, - BIT(chan->channel)); - } - } - return 0; } @@ -781,6 +754,7 @@ static int at91_adc_reenable_trigger(struct iio_trigger *trig) /* Needed to ACK the DRDY interruption */ at91_adc_readl(st, AT91_SAMA5D2_LCDR); + return 0; } @@ -888,18 +862,37 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev) return 0; } -static int at91_adc_buffer_postenable(struct iio_dev *indio_dev) +static bool at91_adc_buffer_check_use_irq(struct iio_dev *indio, + struct at91_adc_state *st) +{ + /* if using DMA, we do not use our own IRQ (we use DMA-controller) */ + if (st->dma_st.dma_chan) + return false; + /* if the trigger is not ours, then it has its own IRQ */ + if (iio_trigger_validate_own_device(indio->trig, indio)) + return false; + return true; +} + +static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev) +{ + struct at91_adc_state *st = iio_priv(indio_dev); + + return !!bitmap_subset(indio_dev->active_scan_mask, + &st->touch_st.channels_bitmask, + AT91_SAMA5D2_MAX_CHAN_IDX + 1); +} + +static int at91_adc_buffer_preenable(struct iio_dev *indio_dev) { int ret; + u8 bit; struct at91_adc_state *st = iio_priv(indio_dev); /* check if we are enabling triggered buffer or the touchscreen */ - if (bitmap_subset(indio_dev->active_scan_mask, - &st->touch_st.channels_bitmask, - AT91_SAMA5D2_MAX_CHAN_IDX + 1)) { - /* touchscreen enabling */ + if (at91_adc_current_chan_is_touch(indio_dev)) return at91_adc_configure_touch(st, true); - } + /* if we are not in triggered mode, we cannot enable the buffer. */ if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES)) return -EINVAL; @@ -911,41 +904,65 @@ static int at91_adc_buffer_postenable(struct iio_dev *indio_dev) return ret; } + for_each_set_bit(bit, indio_dev->active_scan_mask, + indio_dev->num_channels) { + struct iio_chan_spec const *chan = + at91_adc_chan_get(indio_dev, bit); + u32 cor; + + if (!chan) + continue; + /* these channel types cannot be handled by this trigger */ + if (chan->type == IIO_POSITIONRELATIVE || + chan->type == IIO_PRESSURE) + continue; + + cor = at91_adc_readl(st, AT91_SAMA5D2_COR); + + if (chan->differential) + cor |= (BIT(chan->channel) | BIT(chan->channel2)) << + AT91_SAMA5D2_COR_DIFF_OFFSET; + else + cor &= ~(BIT(chan->channel) << + AT91_SAMA5D2_COR_DIFF_OFFSET); + + at91_adc_writel(st, AT91_SAMA5D2_COR, cor); + + at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel)); + } + + if (at91_adc_buffer_check_use_irq(indio_dev, st)) + at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_DRDY); + + return 0; +} + +static int at91_adc_buffer_postenable(struct iio_dev *indio_dev) +{ + if (at91_adc_current_chan_is_touch(indio_dev)) + return 0; + return iio_triggered_buffer_postenable(indio_dev); } -static int at91_adc_buffer_predisable(struct iio_dev *indio_dev) +static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev) { struct at91_adc_state *st = iio_priv(indio_dev); - int ret; u8 bit; /* check if we are disabling triggered buffer or the touchscreen */ - if (bitmap_subset(indio_dev->active_scan_mask, - &st->touch_st.channels_bitmask, - AT91_SAMA5D2_MAX_CHAN_IDX + 1)) { - /* touchscreen disable */ + if (at91_adc_current_chan_is_touch(indio_dev)) return at91_adc_configure_touch(st, false); - } + /* if we are not in triggered mode, nothing to do here */ if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES)) return -EINVAL; - /* continue with the triggered buffer */ - ret = iio_triggered_buffer_predisable(indio_dev); - if (ret < 0) - dev_err(&indio_dev->dev, "buffer predisable failed\n"); - - if (!st->dma_st.dma_chan) - return ret; - - /* if we are using DMA we must clear registers and end DMA */ - dmaengine_terminate_sync(st->dma_st.dma_chan); - /* - * For each enabled channel we must read the last converted value + * For each enable channel we must disable it in hardware. + * In the case of DMA, we must read the last converted value * to clear EOC status and not get a possible interrupt later. - * This value is being read by DMA from LCDR anyway + * This value is being read by DMA from LCDR anyway, so it's not lost. */ for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->num_channels) { @@ -958,16 +975,37 @@ static int at91_adc_buffer_predisable(struct iio_dev *indio_dev) if (chan->type == IIO_POSITIONRELATIVE || chan->type == IIO_PRESSURE) continue; + + at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel)); + if (st->dma_st.dma_chan) at91_adc_readl(st, chan->address); } + if (at91_adc_buffer_check_use_irq(indio_dev, st)) + at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_DRDY); + /* read overflow register to clear possible overflow status */ at91_adc_readl(st, AT91_SAMA5D2_OVER); - return ret; + + /* if we are using DMA we must clear registers and end DMA */ + if (st->dma_st.dma_chan) + dmaengine_terminate_sync(st->dma_st.dma_chan); + + return 0; +} + +static int at91_adc_buffer_predisable(struct iio_dev *indio_dev) +{ + if (at91_adc_current_chan_is_touch(indio_dev)) + return 0; + + return iio_triggered_buffer_predisable(indio_dev); } static const struct iio_buffer_setup_ops at91_buffer_setup_ops = { + .preenable = &at91_adc_buffer_preenable, + .postdisable = &at91_adc_buffer_postdisable, .postenable = &at91_adc_buffer_postenable, .predisable = &at91_adc_buffer_predisable, }; @@ -1015,6 +1053,22 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev, int i = 0; int val; u8 bit; + u32 mask = at91_adc_active_scan_mask_to_reg(indio_dev); + unsigned int timeout = 50; + + /* + * Check if the conversion is ready. If not, wait a little bit, and + * in case of timeout exit with an error. + */ + while ((at91_adc_readl(st, AT91_SAMA5D2_ISR) & mask) != mask && + timeout) { + usleep_range(50, 100); + timeout--; + } + + /* Cannot read data, not ready. Continue without reporting data */ + if (!timeout) + return; for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->num_channels) { @@ -1102,6 +1156,13 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct at91_adc_state *st = iio_priv(indio_dev); + /* + * If it's not our trigger, start a conversion now, as we are + * actually polling the trigger now. + */ + if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev)) + at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START); + if (st->dma_st.dma_chan) at91_adc_trigger_handler_dma(indio_dev); else @@ -1114,20 +1175,9 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) static int at91_adc_buffer_init(struct iio_dev *indio) { - struct at91_adc_state *st = iio_priv(indio); - - if (st->selected_trig->hw_trig) { - return devm_iio_triggered_buffer_setup(&indio->dev, indio, - &iio_pollfunc_store_time, - &at91_adc_trigger_handler, &at91_buffer_setup_ops); - } - /* - * we need to prepare the buffer ops in case we will get - * another buffer attached (like a callback buffer for the touchscreen) - */ - indio->setup_ops = &at91_buffer_setup_ops; - - return 0; + return devm_iio_triggered_buffer_setup(&indio->dev, indio, + &iio_pollfunc_store_time, + &at91_adc_trigger_handler, &at91_buffer_setup_ops); } static unsigned at91_adc_startup_time(unsigned startup_time_min, @@ -1281,7 +1331,8 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private) status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR); status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR); status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR); - } else if (iio_buffer_enabled(indio) && !st->dma_st.dma_chan) { + } else if (iio_buffer_enabled(indio) && + (status & AT91_SAMA5D2_IER_DRDY)) { /* triggered buffer without DMA */ disable_irq_nosync(irq); iio_trigger_poll(indio->trig); @@ -1901,14 +1952,10 @@ static __maybe_unused int at91_adc_resume(struct device *dev) return 0; /* check if we are enabling triggered buffer or the touchscreen */ - if (bitmap_subset(indio_dev->active_scan_mask, - &st->touch_st.channels_bitmask, - AT91_SAMA5D2_MAX_CHAN_IDX + 1)) { - /* touchscreen enabling */ + if (at91_adc_current_chan_is_touch(indio_dev)) return at91_adc_configure_touch(st, true); - } else { + else return at91_adc_configure_trigger(st->trig, true); - } /* not needed but more explicit */ return 0; diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c index ea24d7c58b12..d86c0b5d80a3 100644 --- a/drivers/iio/adc/mcp3422.c +++ b/drivers/iio/adc/mcp3422.c @@ -19,6 +19,7 @@ #include <linux/delay.h> #include <linux/sysfs.h> #include <linux/of.h> +#include <asm/unaligned.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -117,11 +118,11 @@ static int mcp3422_read(struct mcp3422 *adc, int *value, u8 *config) if (sample_rate == MCP3422_SRATE_3) { ret = i2c_master_recv(adc->i2c, buf, 4); - temp = buf[0] << 16 | buf[1] << 8 | buf[2]; + temp = get_unaligned_be24(&buf[0]); *config = buf[3]; } else { ret = i2c_master_recv(adc->i2c, buf, 3); - temp = buf[0] << 8 | buf[1]; + temp = get_unaligned_be16(&buf[0]); *config = buf[2]; } diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c index 552c2be8d87a..f1ee3b1e2827 100644 --- a/drivers/iio/adc/ti-ads124s08.c +++ b/drivers/iio/adc/ti-ads124s08.c @@ -22,6 +22,8 @@ #include <linux/iio/triggered_buffer.h> #include <linux/iio/sysfs.h> +#include <asm/unaligned.h> + /* Commands */ #define ADS124S08_CMD_NOP 0x00 #define ADS124S08_CMD_WAKEUP 0x02 @@ -188,7 +190,6 @@ static int ads124s_read(struct iio_dev *indio_dev, unsigned int chan) { struct ads124s_private *priv = iio_priv(indio_dev); int ret; - u32 tmp; struct spi_transfer t[] = { { .tx_buf = &priv->data[0], @@ -208,9 +209,7 @@ static int ads124s_read(struct iio_dev *indio_dev, unsigned int chan) if (ret < 0) return ret; - tmp = priv->data[2] << 16 | priv->data[3] << 8 | priv->data[4]; - - return tmp; + return get_unaligned_be24(&priv->data[2]); } static int ads124s_read_raw(struct iio_dev *indio_dev, |