aboutsummaryrefslogtreecommitdiff
path: root/drivers/iio/adc/stm32-adc.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-01-10 10:44:00 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-01-10 10:44:00 +0100
commit821f7ce79fd1ef2bf96a1b93521d8800abd24a1f (patch)
treed17f9fd1ade5c3e0a70a1ab8ae04964b1290dcf5 /drivers/iio/adc/stm32-adc.c
parent0469fc6a1a8715b5c09117a26700da0d67061fb5 (diff)
parentc1d1c4a62db5c4745b9e15cfee0daf0f774f73fc (diff)
downloadlinux-821f7ce79fd1ef2bf96a1b93521d8800abd24a1f.tar.gz
Merge tag 'iio-for-5.6a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes: First set of new device support, features and cleanups for IIO in the 5.6 cycle New device support * ad7091r5 ADC - New driver with follow up patch adding scale and vref support. - DT bindings * ad7923 - Support for ad7908, ad7918 and ad7928 added to driver. * bma180 - Support the BMA254 accelerometer. Required fairly substantial rework to allow for small differences between this an existing parts. * bma400 accelerometer - New driver with follow up patch for regulator support. - DT bindings. * asc dlhl60d - New driver support this range of pressure and temperature sensors. - DT bindings. * ltc2496 ADC - New driver to support this ADC. - Split the existing LTC2497 driver generic component out and reuse. - DT bindings. * parallax ping - New driver supporting ultrasonic and laser tof distance sensors. - Bindings for these sensors. New features * core - New char type for read_raw returns, used for thermocouple types. - Rename read_first_n callback to read. The reasons behind the original naming are lost to the mists of time. * ad799x - Allow pm_ops to disable device completely allowing regulator power down. * bma180 - Enable basic regulator support. * dmaengine buffer - Report platform data alignment requirements via new ABI. * max31856 - Add option to set mains filter rejection frequency and document new in_temp_filter_notch_center_frequency ABI. - Add support for configuring HW averaging (oversampling ratio) - Add runtime configuration of thermocouple type and document new ABI. * maxim-thermocouple - Add read only access to thermocouple type using new ABI, includes adding more specific compatibles to reflect which variant of the chip is being used. * mpu6050 - Provide option to support the PMU9150 in package magnetometer directly rather than via auxiliary bus. * stm32_adc - Add overrun interrupt checks to detect if this happens. * st_lsm6dsx - Enable the sensor-hub support for lsm6dsm. Includes various reworks to allow this. Cleanups and minor fixes * Subsystem wide - Tidy up indentation in Kconfig and fix alphabetical order of AD7091R5. - Drop linux/gpio.h and linux/of_gpio.h from drivers that don't use them. * ad7266 - Convert to GPIO descriptors. * ad7303 - Avoid a dance with checking if the regulator is supplied by just using the optional request interface. * ad7887 - Simplify channel specification assignment to enable adding more devices. * ad7923 - Drop some unused and largely pointless defines of BOB_N==N variety. - Tidy up checkpatch warnings. - Add missing of_device_id table. * adf4350 - Convert to GPIO descriptors. * ak8975 - Convert to GPIO descriptors. * ADIS library and drivers - Expand scope of txrx_lock to cover all state and rename as state_lock - Add unlocked read / write to allow grouping of consecutive calls under single lock / unlock. - Add unlocked check_status, reset to allow grouping under single lock / unlock. - Remove remaining uses of core mlock for local state protection. mlock should never be used directly as it protects tightly defined core IIO device management state. * adis16240 - Enforce only supported SPI mode on driver load + add DT binding doc. * atlas-ph-sensor - Rename to atlas-sensor given it now covers things beyond ph sensors. * bma180 - Use local dev variable to tidy up code. - Use c99 style explicity .member assignment to make driver more readable. * bmp280 - Drop ACPI support. No evidence this was used and appropriate ID is not registered. - Allow ACPI to bind device via PRP0001 * dmaengine buffer - Use dma_request_chan instead of dma_request_slave_channel_reason as that ABI is going away. - Add module info to avoid tainting the kernel. * hts221 - Avoid magic number defines when only used to fill structure elements that are self describing. * lm3533 - Drop a stray semicolon. * max9611 - Cleanup enum handling to be more resilient to future changes. * mpu6050 - Delete MPU9150 from supported SPI devices as doesn't provide SPI. - Select I2C_MUX again after kbuild issue fixed elsewhere. * stm32-timer - Drop an unnecessary register update. * ssp_sensors - Convert to GPIO descriptors. * st_sensors - drop !CONFIG_ACPI defines as ACPI_PTR() will stop them being used anyway. - Make default platform data structures __maybe_unsued. - Fill in some missing kernel-doc function parameters. * st_lsm6dsx - white space fixes. - Mark some constants that aren't always used as __maybe_unused. - Drop of ID table guards as they just pervent use under ACPI. - Switch to device properties to allow ACPI usage. * st_uvis25 - Drop acpi.h include as no ACPI APIs used. * ti-ads1015 - Drop legacy platform data as no one seems to be using it. - Use the device property API instead of OF specific. * ti-ads7950 - typo fix in error message. * tag 'iio-for-5.6a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (99 commits) iio: accel: bma180: BMA254 support iio: pressure: bmp280: Allow device to be enumerated from ACPI iio: pressure: bmp280: Drop ACPI support dt-bindings: iio: adc: convert sd modulator to json-schema iio: buffer: rename 'read_first_n' callback to 'read' iio: buffer-dmaengine: Report buffer length requirements bindings: iio: pressure: Add documentation for dlh driver dt-bindings: Add asc vendor iio: pressure: Add driver for DLH pressure sensors iio: buffer-dmaengine: Add module information iio: accel: bma180: Use explicit member assignment iio: accel: bma180: Basic regulator support iio: accel: bma180: Add dev helper variable iio: imu: st_lsm6dsx: enable sensor-hub support for lsm6dsm iio: imu: st_lsm6dsx: rename st_lsm6dsx_shub_read_reg in st_lsm6dsx_shub_read_output iio: imu: st_lsm6dsx: check if shub_output reg is located in primary page iio: imu: st_lsm6dsx: check if pull_up is located in primary page iio: imu: st_lsm6dsx: check if master_enable is located in primary page iio: imu: st_lsm6dsx: export max num of slave devices in st_lsm6dsx_shub_settings iio: light: remove unneeded semicolon ...
Diffstat (limited to 'drivers/iio/adc/stm32-adc.c')
-rw-r--r--drivers/iio/adc/stm32-adc.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
index 3b291d72701c..5f05bf9f16ea 100644
--- a/drivers/iio/adc/stm32-adc.c
+++ b/drivers/iio/adc/stm32-adc.c
@@ -117,7 +117,9 @@ struct stm32_adc_regs {
* struct stm32_adc_regspec - stm32 registers definition
* @dr: data register offset
* @ier_eoc: interrupt enable register & eocie bitfield
+ * @ier_ovr: interrupt enable register & overrun bitfield
* @isr_eoc: interrupt status register & eoc bitfield
+ * @isr_ovr: interrupt status register & overrun bitfield
* @sqr: reference to sequence registers array
* @exten: trigger control register & bitfield
* @extsel: trigger selection register & bitfield
@@ -128,7 +130,9 @@ struct stm32_adc_regs {
struct stm32_adc_regspec {
const u32 dr;
const struct stm32_adc_regs ier_eoc;
+ const struct stm32_adc_regs ier_ovr;
const struct stm32_adc_regs isr_eoc;
+ const struct stm32_adc_regs isr_ovr;
const struct stm32_adc_regs *sqr;
const struct stm32_adc_regs exten;
const struct stm32_adc_regs extsel;
@@ -337,7 +341,9 @@ static const unsigned int stm32f4_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = {
static const struct stm32_adc_regspec stm32f4_adc_regspec = {
.dr = STM32F4_ADC_DR,
.ier_eoc = { STM32F4_ADC_CR1, STM32F4_EOCIE },
+ .ier_ovr = { STM32F4_ADC_CR1, STM32F4_OVRIE },
.isr_eoc = { STM32F4_ADC_SR, STM32F4_EOC },
+ .isr_ovr = { STM32F4_ADC_SR, STM32F4_OVR },
.sqr = stm32f4_sq,
.exten = { STM32F4_ADC_CR2, STM32F4_EXTEN_MASK, STM32F4_EXTEN_SHIFT },
.extsel = { STM32F4_ADC_CR2, STM32F4_EXTSEL_MASK,
@@ -429,7 +435,9 @@ static const unsigned int stm32h7_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = {
static const struct stm32_adc_regspec stm32h7_adc_regspec = {
.dr = STM32H7_ADC_DR,
.ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE },
+ .ier_ovr = { STM32H7_ADC_IER, STM32H7_OVRIE },
.isr_eoc = { STM32H7_ADC_ISR, STM32H7_EOC },
+ .isr_ovr = { STM32H7_ADC_ISR, STM32H7_OVR },
.sqr = stm32h7_sq,
.exten = { STM32H7_ADC_CFGR, STM32H7_EXTEN_MASK, STM32H7_EXTEN_SHIFT },
.extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK,
@@ -506,6 +514,18 @@ static void stm32_adc_conv_irq_disable(struct stm32_adc *adc)
adc->cfg->regs->ier_eoc.mask);
}
+static void stm32_adc_ovr_irq_enable(struct stm32_adc *adc)
+{
+ stm32_adc_set_bits(adc, adc->cfg->regs->ier_ovr.reg,
+ adc->cfg->regs->ier_ovr.mask);
+}
+
+static void stm32_adc_ovr_irq_disable(struct stm32_adc *adc)
+{
+ stm32_adc_clr_bits(adc, adc->cfg->regs->ier_ovr.reg,
+ adc->cfg->regs->ier_ovr.mask);
+}
+
static void stm32_adc_set_res(struct stm32_adc *adc)
{
const struct stm32_adc_regs *res = &adc->cfg->regs->res;
@@ -1205,6 +1225,19 @@ static int stm32_adc_read_raw(struct iio_dev *indio_dev,
}
}
+static irqreturn_t stm32_adc_threaded_isr(int irq, void *data)
+{
+ struct stm32_adc *adc = data;
+ struct iio_dev *indio_dev = iio_priv_to_dev(adc);
+ const struct stm32_adc_regspec *regs = adc->cfg->regs;
+ u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg);
+
+ if (status & regs->isr_ovr.mask)
+ dev_err(&indio_dev->dev, "Overrun, stopping: restart needed\n");
+
+ return IRQ_HANDLED;
+}
+
static irqreturn_t stm32_adc_isr(int irq, void *data)
{
struct stm32_adc *adc = data;
@@ -1212,6 +1245,19 @@ static irqreturn_t stm32_adc_isr(int irq, void *data)
const struct stm32_adc_regspec *regs = adc->cfg->regs;
u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg);
+ if (status & regs->isr_ovr.mask) {
+ /*
+ * Overrun occurred on regular conversions: data for wrong
+ * channel may be read. Unconditionally disable interrupts
+ * to stop processing data and print error message.
+ * Restarting the capture can be done by disabling, then
+ * re-enabling it (e.g. write 0, then 1 to buffer/enable).
+ */
+ stm32_adc_ovr_irq_disable(adc);
+ stm32_adc_conv_irq_disable(adc);
+ return IRQ_WAKE_THREAD;
+ }
+
if (status & regs->isr_eoc.mask) {
/* Reading DR also clears EOC status flag */
adc->buffer[adc->bufi] = stm32_adc_readw(adc, regs->dr);
@@ -1441,6 +1487,8 @@ static int __stm32_adc_buffer_postenable(struct iio_dev *indio_dev)
/* Reset adc buffer index */
adc->bufi = 0;
+ stm32_adc_ovr_irq_enable(adc);
+
if (!adc->dma_chan)
stm32_adc_conv_irq_enable(adc);
@@ -1481,6 +1529,8 @@ static void __stm32_adc_buffer_predisable(struct iio_dev *indio_dev)
if (!adc->dma_chan)
stm32_adc_conv_irq_disable(adc);
+ stm32_adc_ovr_irq_disable(adc);
+
if (adc->dma_chan)
dmaengine_terminate_sync(adc->dma_chan);
@@ -1818,8 +1868,9 @@ static int stm32_adc_probe(struct platform_device *pdev)
if (adc->irq < 0)
return adc->irq;
- ret = devm_request_irq(&pdev->dev, adc->irq, stm32_adc_isr,
- 0, pdev->name, adc);
+ ret = devm_request_threaded_irq(&pdev->dev, adc->irq, stm32_adc_isr,
+ stm32_adc_threaded_isr,
+ 0, pdev->name, adc);
if (ret) {
dev_err(&pdev->dev, "failed to request IRQ\n");
return ret;