diff options
Diffstat (limited to 'drivers/iio/adc')
81 files changed, 2687 insertions, 430 deletions
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 614fa41559b1..ef86296b8b0d 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -158,6 +158,7 @@ config AT91_SAMA5D2_ADC tristate "Atmel AT91 SAMA5D2 ADC" depends on ARCH_AT91 || COMPILE_TEST depends on HAS_IOMEM + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Atmel SAMA5D2 ADC which is available on SAMA5D2 SoC family. @@ -239,6 +240,17 @@ config DA9150_GPADC To compile this driver as a module, choose M here: the module will be called berlin2-adc. +config DLN2_ADC + tristate "Diolan DLN-2 ADC driver support" + depends on MFD_DLN2 + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Diolan DLN-2 ADC. + + This driver can also be built as a module. If so, the module will be + called adc_dln2. + config ENVELOPE_DETECTOR tristate "Envelope detector using a DAC and a comparator" depends on OF @@ -249,6 +261,17 @@ config ENVELOPE_DETECTOR To compile this driver as a module, choose M here: the module will be called envelope-detector. +config EP93XX_ADC + tristate "Cirrus Logic EP93XX ADC driver" + depends on ARCH_EP93XX + help + Driver for the ADC module on the EP93XX series of SoC from Cirrus Logic. + It's recommended to switch on CONFIG_HIGH_RES_TIMERS option, in this + case driver will reduce its CPU usage by 90% in some use cases. + + To compile this driver as a module, choose M here: the module will be + called ep93xx_adc. + config EXYNOS_ADC tristate "Exynos ADC driver support" depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST) @@ -322,7 +345,7 @@ config INA2XX_ADC This driver is mutually exclusive with the HWMON version. config IMX7D_ADC - tristate "IMX7D ADC driver" + tristate "Freescale IMX7D ADC driver" depends on ARCH_MXC || COMPILE_TEST depends on HAS_IOMEM help @@ -362,6 +385,16 @@ config LPC32XX_ADC activate only one via device tree selection. Provides direct access via sysfs. +config LTC2471 + tristate "Linear Technology LTC2471 and LTC2473 ADC driver" + depends on I2C + help + Say yes here to build support for Linear Technology LTC2471 and + LTC2473 16-bit I2C ADC. + + This driver can also be built as a module. If so, the module will + be called ltc2471. + config LTC2485 tristate "Linear Technology LTC2485 ADC driver" depends on I2C @@ -444,12 +477,13 @@ config MAX9611 called max9611. config MCP320X - tristate "Microchip Technology MCP3x01/02/04/08" + tristate "Microchip Technology MCP3x01/02/04/08 and MCP3550/1/3" depends on SPI help Say yes here to build support for Microchip Technology's MCP3001, MCP3002, MCP3004, MCP3008, MCP3201, MCP3202, MCP3204, - MCP3208 or MCP3301 analog to digital converter. + MCP3208, MCP3301, MCP3550, MCP3551 and MCP3553 analog to digital + converters. This driver can also be built as a module. If so, the module will be called mcp320x. @@ -562,7 +596,7 @@ config QCOM_SPMI_VADC config RCAR_GYRO_ADC tristate "Renesas R-Car GyroADC driver" - depends on ARCH_RCAR_GEN2 || (ARM && COMPILE_TEST) + depends on ARCH_RCAR_GEN2 || COMPILE_TEST help Say yes here to build support for the GyroADC found in Renesas R-Car Gen2 SoCs. This block is a simple SPI offload engine for diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index b546736a5541..9572c1090f35 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for IIO ADC drivers # @@ -24,7 +25,9 @@ obj-$(CONFIG_BERLIN2_ADC) += berlin2-adc.o obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o obj-$(CONFIG_CPCAP_ADC) += cpcap-adc.o obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o +obj-$(CONFIG_DLN2_ADC) += dln2-adc.o obj-$(CONFIG_ENVELOPE_DETECTOR) += envelope-detector.o +obj-$(CONFIG_EP93XX_ADC) += ep93xx_adc.o obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o obj-$(CONFIG_HI8435) += hi8435.o @@ -34,6 +37,7 @@ obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o +obj-$(CONFIG_LTC2471) += ltc2471.o obj-$(CONFIG_LTC2485) += ltc2485.o obj-$(CONFIG_LTC2497) += ltc2497.o obj-$(CONFIG_MAX1027) += max1027.o diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c index b8d5cfd57ec4..605eb5e7e829 100644 --- a/drivers/iio/adc/ad7266.c +++ b/drivers/iio/adc/ad7266.c @@ -280,7 +280,6 @@ static AD7266_DECLARE_DIFF_CHANNELS_FIXED(u, 'u'); static const struct iio_info ad7266_info = { .read_raw = &ad7266_read_raw, .update_scan_mode = &ad7266_update_scan_mode, - .driver_module = THIS_MODULE, }; static const unsigned long ad7266_available_scan_masks[] = { diff --git a/drivers/iio/adc/ad7291.c b/drivers/iio/adc/ad7291.c index 1d90b02732bb..a862b5d8fb4b 100644 --- a/drivers/iio/adc/ad7291.c +++ b/drivers/iio/adc/ad7291.c @@ -461,7 +461,6 @@ static const struct iio_info ad7291_info = { .write_event_config = &ad7291_write_event_config, .read_event_value = &ad7291_read_event_value, .write_event_value = &ad7291_write_event_value, - .driver_module = THIS_MODULE, }; static int ad7291_probe(struct i2c_client *client, diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c index e399bf04c73a..2b20c6c8ec7f 100644 --- a/drivers/iio/adc/ad7298.c +++ b/drivers/iio/adc/ad7298.c @@ -280,7 +280,6 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, static const struct iio_info ad7298_info = { .read_raw = &ad7298_read_raw, .update_scan_mode = ad7298_update_scan_mode, - .driver_module = THIS_MODULE, }; static int ad7298_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index b7ecf9aab90f..b7706bf10ffe 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -195,7 +195,6 @@ static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { }; static const struct iio_info ad7476_info = { - .driver_module = THIS_MODULE, .read_raw = &ad7476_read_raw, }; diff --git a/drivers/iio/adc/ad7766.c b/drivers/iio/adc/ad7766.c index 75cca42b6e70..3ae14fc8c649 100644 --- a/drivers/iio/adc/ad7766.c +++ b/drivers/iio/adc/ad7766.c @@ -103,8 +103,7 @@ static int ad7766_preenable(struct iio_dev *indio_dev) return ret; } - if (ad7766->pd_gpio) - gpiod_set_value(ad7766->pd_gpio, 0); + gpiod_set_value(ad7766->pd_gpio, 0); return 0; } @@ -113,8 +112,7 @@ static int ad7766_postdisable(struct iio_dev *indio_dev) { struct ad7766 *ad7766 = iio_priv(indio_dev); - if (ad7766->pd_gpio) - gpiod_set_value(ad7766->pd_gpio, 1); + gpiod_set_value(ad7766->pd_gpio, 1); /* * The PD pin is synchronous to the clock, so give it some time to @@ -187,7 +185,6 @@ static const struct iio_buffer_setup_ops ad7766_buffer_setup_ops = { }; static const struct iio_info ad7766_info = { - .driver_module = THIS_MODULE, .read_raw = &ad7766_read_raw, }; @@ -210,7 +207,6 @@ static int ad7766_set_trigger_state(struct iio_trigger *trig, bool enable) } static const struct iio_trigger_ops ad7766_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = ad7766_set_trigger_state, .validate_device = iio_trigger_validate_own_device, }; diff --git a/drivers/iio/adc/ad7791.c b/drivers/iio/adc/ad7791.c index 34e353c43ac8..70fbf92f9827 100644 --- a/drivers/iio/adc/ad7791.c +++ b/drivers/iio/adc/ad7791.c @@ -308,13 +308,11 @@ static const struct iio_info ad7791_info = { .read_raw = &ad7791_read_raw, .attrs = &ad7791_attribute_group, .validate_trigger = ad_sd_validate_trigger, - .driver_module = THIS_MODULE, }; static const struct iio_info ad7791_no_filter_info = { .read_raw = &ad7791_read_raw, .validate_trigger = ad_sd_validate_trigger, - .driver_module = THIS_MODULE, }; static int ad7791_setup(struct ad7791_state *st, diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c index e6706a09e100..801afb61310b 100644 --- a/drivers/iio/adc/ad7793.c +++ b/drivers/iio/adc/ad7793.c @@ -257,7 +257,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, unsigned int vref_mv) { struct ad7793_state *st = iio_priv(indio_dev); - int i, ret = -1; + int i, ret; unsigned long long scale_uv; u32 id; @@ -266,7 +266,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, return ret; /* reset the serial interface */ - ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret)); + ret = ad_sd_reset(&st->sd, 32); if (ret < 0) goto out; usleep_range(500, 2000); /* Wait for at least 500us */ @@ -563,7 +563,6 @@ static const struct iio_info ad7793_info = { .write_raw_get_fmt = &ad7793_write_raw_get_fmt, .attrs = &ad7793_attribute_group, .validate_trigger = ad_sd_validate_trigger, - .driver_module = THIS_MODULE, }; static const struct iio_info ad7797_info = { @@ -572,7 +571,6 @@ static const struct iio_info ad7797_info = { .write_raw_get_fmt = &ad7793_write_raw_get_fmt, .attrs = &ad7793_attribute_group, .validate_trigger = ad_sd_validate_trigger, - .driver_module = THIS_MODULE, }; #define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \ diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c index 7a483bfbd70c..205c0f1761aa 100644 --- a/drivers/iio/adc/ad7887.c +++ b/drivers/iio/adc/ad7887.c @@ -229,7 +229,6 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { static const struct iio_info ad7887_info = { .read_raw = &ad7887_read_raw, - .driver_module = THIS_MODULE, }; static int ad7887_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c index 77a675e11ebb..ffb7e089969c 100644 --- a/drivers/iio/adc/ad7923.c +++ b/drivers/iio/adc/ad7923.c @@ -262,7 +262,6 @@ static int ad7923_read_raw(struct iio_dev *indio_dev, static const struct iio_info ad7923_info = { .read_raw = &ad7923_read_raw, .update_scan_mode = ad7923_update_scan_mode, - .driver_module = THIS_MODULE, }; static int ad7923_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index 22426ae4af97..e1da67d5ee22 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c @@ -526,13 +526,11 @@ static const struct attribute_group ad799x_event_attrs_group = { static const struct iio_info ad7991_info = { .read_raw = &ad799x_read_raw, - .driver_module = THIS_MODULE, .update_scan_mode = ad799x_update_scan_mode, }; static const struct iio_info ad7993_4_7_8_noirq_info = { .read_raw = &ad799x_read_raw, - .driver_module = THIS_MODULE, .update_scan_mode = ad799x_update_scan_mode, }; @@ -543,7 +541,6 @@ static const struct iio_info ad7993_4_7_8_irq_info = { .write_event_config = &ad799x_write_event_config, .read_event_value = &ad799x_read_event_value, .write_event_value = &ad799x_write_event_value, - .driver_module = THIS_MODULE, .update_scan_mode = ad799x_update_scan_mode, }; diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index d10bd0c97233..cf1b048b0665 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -177,6 +177,34 @@ out: } EXPORT_SYMBOL_GPL(ad_sd_read_reg); +/** + * ad_sd_reset() - Reset the serial interface + * + * @sigma_delta: The sigma delta device + * @reset_length: Number of SCLKs with DIN = 1 + * + * Returns 0 on success, an error code otherwise. + **/ +int ad_sd_reset(struct ad_sigma_delta *sigma_delta, + unsigned int reset_length) +{ + uint8_t *buf; + unsigned int size; + int ret; + + size = DIV_ROUND_UP(reset_length, 8); + buf = kcalloc(size, sizeof(*buf), GFP_KERNEL); + if (!buf) + return -ENOMEM; + + memset(buf, 0xff, size); + ret = spi_write(sigma_delta->spi, buf, size); + kfree(buf); + + return ret; +} +EXPORT_SYMBOL_GPL(ad_sd_reset); + static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta, unsigned int mode, unsigned int channel) { @@ -435,7 +463,6 @@ int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig) EXPORT_SYMBOL_GPL(ad_sd_validate_trigger); static const struct iio_trigger_ops ad_sd_trigger_ops = { - .owner = THIS_MODULE, }; static int ad_sd_probe_trigger(struct iio_dev *indio_dev) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index e0ea411a0b2d..8a958d5f1905 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -22,6 +22,7 @@ #include <linux/iio/iio.h> #include <linux/iio/driver.h> +#include <linux/iopoll.h> #define ASPEED_RESOLUTION_BITS 10 #define ASPEED_CLOCKS_PER_SAMPLE 12 @@ -38,11 +39,17 @@ #define ASPEED_ENGINE_ENABLE BIT(0) +#define ASPEED_ADC_CTRL_INIT_RDY BIT(8) + +#define ASPEED_ADC_INIT_POLLING_TIME 500 +#define ASPEED_ADC_INIT_TIMEOUT 500000 + struct aspeed_adc_model_data { const char *model_name; unsigned int min_sampling_rate; // Hz unsigned int max_sampling_rate; // Hz unsigned int vref_voltage; // mV + bool wait_init_sequence; }; struct aspeed_adc_data { @@ -158,7 +165,6 @@ static int aspeed_adc_reg_access(struct iio_dev *indio_dev, } static const struct iio_info aspeed_adc_iio_info = { - .driver_module = THIS_MODULE, .read_raw = aspeed_adc_read_raw, .write_raw = aspeed_adc_write_raw, .debugfs_reg_access = aspeed_adc_reg_access, @@ -211,6 +217,24 @@ static int aspeed_adc_probe(struct platform_device *pdev) goto scaler_error; } + model_data = of_device_get_match_data(&pdev->dev); + + if (model_data->wait_init_sequence) { + /* Enable engine in normal mode. */ + writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE, + data->base + ASPEED_REG_ENGINE_CONTROL); + + /* Wait for initial sequence complete. */ + ret = readl_poll_timeout(data->base + ASPEED_REG_ENGINE_CONTROL, + adc_engine_control_reg_val, + adc_engine_control_reg_val & + ASPEED_ADC_CTRL_INIT_RDY, + ASPEED_ADC_INIT_POLLING_TIME, + ASPEED_ADC_INIT_TIMEOUT); + if (ret) + goto scaler_error; + } + /* Start all channels in normal mode. */ ret = clk_prepare_enable(data->clk_scaler->clk); if (ret) @@ -274,6 +298,7 @@ static const struct aspeed_adc_model_data ast2500_model_data = { .vref_voltage = 1800, // mV .min_sampling_rate = 1, .max_sampling_rate = 1000000, + .wait_init_sequence = true, }; static const struct of_device_id aspeed_adc_matches[] = { diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index e10dca3ed74b..755a493c2a2c 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -25,6 +25,11 @@ #include <linux/wait.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> +#include <linux/iio/trigger.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/pinctrl/consumer.h> #include <linux/regulator/consumer.h> /* Control Register */ @@ -132,6 +137,17 @@ #define AT91_SAMA5D2_PRESSR 0xbc /* Trigger Register */ #define AT91_SAMA5D2_TRGR 0xc0 +/* Mask for TRGMOD field of TRGR register */ +#define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0) +/* No trigger, only software trigger can start conversions */ +#define AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER 0 +/* Trigger Mode external trigger rising edge */ +#define AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE 1 +/* Trigger Mode external trigger falling edge */ +#define AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL 2 +/* Trigger Mode external trigger any edge */ +#define AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY 3 + /* Correction Select Register */ #define AT91_SAMA5D2_COSR 0xd0 /* Correction Value Register */ @@ -145,14 +161,29 @@ /* Version Register */ #define AT91_SAMA5D2_VERSION 0xfc +#define AT91_SAMA5D2_HW_TRIG_CNT 3 +#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12 +#define AT91_SAMA5D2_DIFF_CHAN_CNT 6 + +/* + * Maximum number of bytes to hold conversion from all channels + * plus the timestamp + */ +#define AT91_BUFFER_MAX_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \ + AT91_SAMA5D2_DIFF_CHAN_CNT) * 2 + 8) + +#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2) + #define AT91_SAMA5D2_CHAN_SINGLE(num, addr) \ { \ .type = IIO_VOLTAGE, \ .channel = num, \ .address = addr, \ + .scan_index = num, \ .scan_type = { \ .sign = 'u', \ .realbits = 12, \ + .storagebits = 16, \ }, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ @@ -168,9 +199,11 @@ .channel = num, \ .channel2 = num2, \ .address = addr, \ + .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT, \ .scan_type = { \ .sign = 's', \ .realbits = 12, \ + .storagebits = 16, \ }, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ @@ -188,6 +221,13 @@ struct at91_adc_soc_info { unsigned max_sample_rate; }; +struct at91_adc_trigger { + char *name; + unsigned int trgmod_value; + unsigned int edge_type; + bool hw_trig; +}; + struct at91_adc_state { void __iomem *base; int irq; @@ -195,11 +235,14 @@ struct at91_adc_state { struct regulator *reg; struct regulator *vref; int vref_uv; + struct iio_trigger *trig; + const struct at91_adc_trigger *selected_trig; const struct iio_chan_spec *chan; bool conversion_done; u32 conversion_value; struct at91_adc_soc_info soc_info; wait_queue_head_t wq_data_available; + u16 buffer[AT91_BUFFER_MAX_HWORDS]; /* * lock to prevent concurrent 'single conversion' requests through * sysfs. @@ -207,6 +250,33 @@ struct at91_adc_state { struct mutex lock; }; +static const struct at91_adc_trigger at91_adc_trigger_list[] = { + { + .name = "external_rising", + .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE, + .edge_type = IRQ_TYPE_EDGE_RISING, + .hw_trig = true, + }, + { + .name = "external_falling", + .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL, + .edge_type = IRQ_TYPE_EDGE_FALLING, + .hw_trig = true, + }, + { + .name = "external_any", + .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY, + .edge_type = IRQ_TYPE_EDGE_BOTH, + .hw_trig = true, + }, + { + .name = "software", + .trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER, + .edge_type = IRQ_TYPE_NONE, + .hw_trig = false, + }, +}; + static const struct iio_chan_spec at91_adc_channels[] = { AT91_SAMA5D2_CHAN_SINGLE(0, 0x50), AT91_SAMA5D2_CHAN_SINGLE(1, 0x54), @@ -226,12 +296,131 @@ static const struct iio_chan_spec at91_adc_channels[] = { AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68), AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70), AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78), + IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_SINGLE_CHAN_CNT + + AT91_SAMA5D2_DIFF_CHAN_CNT + 1), }; +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; + + if (state) + status |= st->selected_trig->trgmod_value; + + /* 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 = indio->channels + bit; + + if (state) { + at91_adc_writel(st, AT91_SAMA5D2_CHER, + BIT(chan->channel)); + at91_adc_writel(st, AT91_SAMA5D2_IER, + BIT(chan->channel)); + } else { + at91_adc_writel(st, AT91_SAMA5D2_IDR, + BIT(chan->channel)); + at91_adc_writel(st, AT91_SAMA5D2_CHDR, + BIT(chan->channel)); + } + } + + return 0; +} + +static int at91_adc_reenable_trigger(struct iio_trigger *trig) +{ + struct iio_dev *indio = iio_trigger_get_drvdata(trig); + struct at91_adc_state *st = iio_priv(indio); + + enable_irq(st->irq); + + /* Needed to ACK the DRDY interruption */ + at91_adc_readl(st, AT91_SAMA5D2_LCDR); + return 0; +} + +static const struct iio_trigger_ops at91_adc_trigger_ops = { + .set_trigger_state = &at91_adc_configure_trigger, + .try_reenable = &at91_adc_reenable_trigger, +}; + +static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *indio, + char *trigger_name) +{ + struct iio_trigger *trig; + int ret; + + trig = devm_iio_trigger_alloc(&indio->dev, "%s-dev%d-%s", indio->name, + indio->id, trigger_name); + if (!trig) + return NULL; + + trig->dev.parent = indio->dev.parent; + iio_trigger_set_drvdata(trig, indio); + trig->ops = &at91_adc_trigger_ops; + + ret = devm_iio_trigger_register(&indio->dev, trig); + if (ret) + return ERR_PTR(ret); + + return trig; +} + +static int at91_adc_trigger_init(struct iio_dev *indio) +{ + struct at91_adc_state *st = iio_priv(indio); + + st->trig = at91_adc_allocate_trigger(indio, st->selected_trig->name); + if (IS_ERR(st->trig)) { + dev_err(&indio->dev, + "could not allocate trigger\n"); + return PTR_ERR(st->trig); + } + + return 0; +} + +static irqreturn_t at91_adc_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio = pf->indio_dev; + struct at91_adc_state *st = iio_priv(indio); + int i = 0; + u8 bit; + + for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) { + struct iio_chan_spec const *chan = indio->channels + bit; + + st->buffer[i] = at91_adc_readl(st, chan->address); + i++; + } + + iio_push_to_buffers_with_timestamp(indio, st->buffer, pf->timestamp); + + iio_trigger_notify_done(indio->trig); + + return IRQ_HANDLED; +} + +static int at91_adc_buffer_init(struct iio_dev *indio) +{ + return devm_iio_triggered_buffer_setup(&indio->dev, indio, + &iio_pollfunc_store_time, + &at91_adc_trigger_handler, NULL); +} + static unsigned at91_adc_startup_time(unsigned startup_time_min, unsigned adc_clk_khz) { - const unsigned startup_lookup[] = { + static const unsigned int startup_lookup[] = { 0, 8, 16, 24, 64, 80, 96, 112, 512, 576, 640, 704, @@ -293,14 +482,18 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private) u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR); u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR); - if (status & imr) { + if (!(status & imr)) + return IRQ_NONE; + + if (iio_buffer_enabled(indio)) { + disable_irq_nosync(irq); + iio_trigger_poll(indio->trig); + } else { st->conversion_value = at91_adc_readl(st, st->chan->address); st->conversion_done = true; wake_up_interruptible(&st->wq_data_available); - return IRQ_HANDLED; } - - return IRQ_NONE; + return IRQ_HANDLED; } static int at91_adc_read_raw(struct iio_dev *indio_dev, @@ -313,6 +506,11 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: + /* we cannot use software trigger if hw trigger enabled */ + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + mutex_lock(&st->lock); st->chan = chan; @@ -344,6 +542,8 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel)); mutex_unlock(&st->lock); + + iio_device_release_direct_mode(indio_dev); return ret; case IIO_CHAN_INFO_SCALE: @@ -383,15 +583,29 @@ static int at91_adc_write_raw(struct iio_dev *indio_dev, static const struct iio_info at91_adc_info = { .read_raw = &at91_adc_read_raw, .write_raw = &at91_adc_write_raw, - .driver_module = THIS_MODULE, }; +static void at91_adc_hw_init(struct at91_adc_state *st) +{ + at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST); + at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff); + /* + * Transfer field must be set to 2 according to the datasheet and + * allows different analog settings for each channel. + */ + at91_adc_writel(st, AT91_SAMA5D2_MR, + AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH); + + at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate); +} + static int at91_adc_probe(struct platform_device *pdev) { struct iio_dev *indio_dev; struct at91_adc_state *st; struct resource *res; - int ret; + int ret, i; + u32 edge_type = IRQ_TYPE_NONE; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); if (!indio_dev) @@ -432,6 +646,27 @@ static int at91_adc_probe(struct platform_device *pdev) return ret; } + ret = of_property_read_u32(pdev->dev.of_node, + "atmel,trigger-edge-type", &edge_type); + if (ret) { + dev_dbg(&pdev->dev, + "atmel,trigger-edge-type not specified, only software trigger available\n"); + } + + st->selected_trig = NULL; + + /* find the right trigger, or no trigger at all */ + for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++) + if (at91_adc_trigger_list[i].edge_type == edge_type) { + st->selected_trig = &at91_adc_trigger_list[i]; + break; + } + + if (!st->selected_trig) { + dev_err(&pdev->dev, "invalid external trigger edge value\n"); + return -EINVAL; + } + init_waitqueue_head(&st->wq_data_available); mutex_init(&st->lock); @@ -482,16 +717,7 @@ static int at91_adc_probe(struct platform_device *pdev) goto vref_disable; } - at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST); - at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff); - /* - * Transfer field must be set to 2 according to the datasheet and - * allows different analog settings for each channel. - */ - at91_adc_writel(st, AT91_SAMA5D2_MR, - AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH); - - at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate); + at91_adc_hw_init(st); ret = clk_prepare_enable(st->per_clk); if (ret) @@ -499,10 +725,28 @@ static int at91_adc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, indio_dev); + if (st->selected_trig->hw_trig) { + ret = at91_adc_buffer_init(indio_dev); + if (ret < 0) { + dev_err(&pdev->dev, "couldn't initialize the buffer.\n"); + goto per_clk_disable_unprepare; + } + + ret = at91_adc_trigger_init(indio_dev); + if (ret < 0) { + dev_err(&pdev->dev, "couldn't setup the triggers.\n"); + goto per_clk_disable_unprepare; + } + } + ret = iio_device_register(indio_dev); if (ret < 0) goto per_clk_disable_unprepare; + if (st->selected_trig->hw_trig) + dev_info(&pdev->dev, "setting up trigger as %s\n", + st->selected_trig->name); + dev_info(&pdev->dev, "version: %x\n", readl_relaxed(st->base + AT91_SAMA5D2_VERSION)); @@ -532,6 +776,69 @@ static int at91_adc_remove(struct platform_device *pdev) return 0; } +static __maybe_unused int at91_adc_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = + platform_get_drvdata(to_platform_device(dev)); + struct at91_adc_state *st = iio_priv(indio_dev); + + /* + * Do a sofware reset of the ADC before we go to suspend. + * this will ensure that all pins are free from being muxed by the ADC + * and can be used by for other devices. + * Otherwise, ADC will hog them and we can't go to suspend mode. + */ + at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST); + + clk_disable_unprepare(st->per_clk); + regulator_disable(st->vref); + regulator_disable(st->reg); + + return pinctrl_pm_select_sleep_state(dev); +} + +static __maybe_unused int at91_adc_resume(struct device *dev) +{ + struct iio_dev *indio_dev = + platform_get_drvdata(to_platform_device(dev)); + struct at91_adc_state *st = iio_priv(indio_dev); + int ret; + + ret = pinctrl_pm_select_default_state(dev); + if (ret) + goto resume_failed; + + ret = regulator_enable(st->reg); + if (ret) + goto resume_failed; + + ret = regulator_enable(st->vref); + if (ret) + goto reg_disable_resume; + + ret = clk_prepare_enable(st->per_clk); + if (ret) + goto vref_disable_resume; + + at91_adc_hw_init(st); + + /* reconfiguring trigger hardware state */ + if (iio_buffer_enabled(indio_dev)) + at91_adc_configure_trigger(st->trig, true); + + return 0; + +vref_disable_resume: + regulator_disable(st->vref); +reg_disable_resume: + regulator_disable(st->reg); +resume_failed: + dev_err(&indio_dev->dev, "failed to resume\n"); + return ret; +} + +static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume); + static const struct of_device_id at91_adc_dt_match[] = { { .compatible = "atmel,sama5d2-adc", @@ -547,6 +854,7 @@ static struct platform_driver at91_adc_driver = { .driver = { .name = "at91-sama5d2_adc", .of_match_table = at91_adc_dt_match, + .pm = &at91_adc_pm_ops, }, }; module_platform_driver(at91_adc_driver) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 34b928cefeed..3836d4222a3e 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -594,7 +594,6 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) } static const struct iio_trigger_ops at91_adc_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = &at91_adc_configure_trigger, }; @@ -799,7 +798,7 @@ static u32 calc_startup_ticks_9x5(u32 startup_time, u32 adc_clk_khz) * For sama5d3x and at91sam9x5, the formula changes to: * Startup Time = <lookup_table_value> / ADC Clock */ - const int startup_lookup[] = { + static const int startup_lookup[] = { 0, 8, 16, 24, 64, 80, 96, 112, 512, 576, 640, 704, @@ -976,7 +975,6 @@ static int at91_adc_probe_pdata(struct at91_adc_state *st, } static const struct iio_info at91_adc_info = { - .driver_module = THIS_MODULE, .read_raw = &at91_adc_read_raw, }; diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c index 11e177180ea0..a30a97245e91 100644 --- a/drivers/iio/adc/axp20x_adc.c +++ b/drivers/iio/adc/axp20x_adc.c @@ -464,12 +464,10 @@ static int axp20x_write_raw(struct iio_dev *indio_dev, static const struct iio_info axp20x_adc_iio_info = { .read_raw = axp20x_read_raw, .write_raw = axp20x_write_raw, - .driver_module = THIS_MODULE, }; static const struct iio_info axp22x_adc_iio_info = { .read_raw = axp22x_read_raw, - .driver_module = THIS_MODULE, }; static int axp20x_adc_rate(int rate) diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c index 64799ad7ebad..60c9e853dd81 100644 --- a/drivers/iio/adc/axp288_adc.c +++ b/drivers/iio/adc/axp288_adc.c @@ -28,6 +28,8 @@ #include <linux/iio/driver.h> #define AXP288_ADC_EN_MASK 0xF1 +#define AXP288_ADC_TS_PIN_GPADC 0xF2 +#define AXP288_ADC_TS_PIN_ON 0xF3 enum axp288_adc_id { AXP288_ADC_TS, @@ -121,6 +123,26 @@ static int axp288_adc_read_channel(int *val, unsigned long address, return IIO_VAL_INT; } +static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode, + unsigned long address) +{ + int ret; + + /* channels other than GPADC do not need to switch TS pin */ + if (address != AXP288_GP_ADC_H) + return 0; + + ret = regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode); + if (ret) + return ret; + + /* When switching to the GPADC pin give things some time to settle */ + if (mode == AXP288_ADC_TS_PIN_GPADC) + usleep_range(6000, 10000); + + return 0; +} + static int axp288_adc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -131,7 +153,16 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); switch (mask) { case IIO_CHAN_INFO_RAW: + if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC, + chan->address)) { + dev_err(&indio_dev->dev, "GPADC mode\n"); + ret = -EINVAL; + break; + } ret = axp288_adc_read_channel(val, chan->address, info->regmap); + if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON, + chan->address)) + dev_err(&indio_dev->dev, "TS pin restore\n"); break; default: ret = -EINVAL; @@ -141,9 +172,17 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, return ret; } +static int axp288_adc_set_state(struct regmap *regmap) +{ + /* ADC should be always enabled for internal FG to function */ + if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON)) + return -EIO; + + return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK); +} + static const struct iio_info axp288_adc_iio_info = { .read_raw = &axp288_adc_read_raw, - .driver_module = THIS_MODULE, }; static int axp288_adc_probe(struct platform_device *pdev) @@ -169,7 +208,7 @@ static int axp288_adc_probe(struct platform_device *pdev) * Set ADC to enabled state at all time, including system suspend. * otherwise internal fuel gauge functionality may be affected. */ - ret = regmap_write(info->regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK); + ret = axp288_adc_set_state(axp20x->regmap); if (ret) { dev_err(&pdev->dev, "unable to enable ADC device\n"); return ret; diff --git a/drivers/iio/adc/bcm_iproc_adc.c b/drivers/iio/adc/bcm_iproc_adc.c index 7f4f9c4150e3..7af59a4bbd8d 100644 --- a/drivers/iio/adc/bcm_iproc_adc.c +++ b/drivers/iio/adc/bcm_iproc_adc.c @@ -492,7 +492,6 @@ static int iproc_adc_read_raw(struct iio_dev *indio_dev, static const struct iio_info iproc_adc_iio_info = { .read_raw = &iproc_adc_read_raw, - .driver_module = THIS_MODULE, }; #define IPROC_ADC_CHANNEL(_index, _id) { \ diff --git a/drivers/iio/adc/berlin2-adc.c b/drivers/iio/adc/berlin2-adc.c index 71c806ecc722..72d8fa94ab31 100644 --- a/drivers/iio/adc/berlin2-adc.c +++ b/drivers/iio/adc/berlin2-adc.c @@ -277,7 +277,6 @@ static irqreturn_t berlin2_adc_tsen_irq(int irq, void *private) } static const struct iio_info berlin2_adc_info = { - .driver_module = THIS_MODULE, .read_raw = berlin2_adc_read_raw, }; diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c index 91636c0ba5b5..707d8b24b072 100644 --- a/drivers/iio/adc/cc10001_adc.c +++ b/drivers/iio/adc/cc10001_adc.c @@ -262,7 +262,6 @@ static int cc10001_update_scan_mode(struct iio_dev *indio_dev, } static const struct iio_info cc10001_adc_info = { - .driver_module = THIS_MODULE, .read_raw = &cc10001_adc_read_raw, .update_scan_mode = &cc10001_update_scan_mode, }; diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c index 6e419d5a7c14..3576ec73ec23 100644 --- a/drivers/iio/adc/cpcap-adc.c +++ b/drivers/iio/adc/cpcap-adc.c @@ -932,7 +932,6 @@ err_unlock: static const struct iio_info cpcap_adc_info = { .read_raw = &cpcap_adc_read, - .driver_module = THIS_MODULE, }; /* diff --git a/drivers/iio/adc/da9150-gpadc.c b/drivers/iio/adc/da9150-gpadc.c index 3445107e10b7..0a5d9ce79164 100644 --- a/drivers/iio/adc/da9150-gpadc.c +++ b/drivers/iio/adc/da9150-gpadc.c @@ -249,7 +249,6 @@ static int da9150_gpadc_read_raw(struct iio_dev *indio_dev, static const struct iio_info da9150_gpadc_info = { .read_raw = &da9150_gpadc_read_raw, - .driver_module = THIS_MODULE, }; #define DA9150_GPADC_CHANNEL(_id, _hw_id, _type, chan_info, \ diff --git a/drivers/iio/adc/dln2-adc.c b/drivers/iio/adc/dln2-adc.c new file mode 100644 index 000000000000..c64c6675cae6 --- /dev/null +++ b/drivers/iio/adc/dln2-adc.c @@ -0,0 +1,716 @@ +/* + * Driver for the Diolan DLN-2 USB-ADC adapter + * + * Copyright (c) 2017 Jack Andersen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/mfd/dln2.h> + +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/trigger.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/iio/buffer.h> +#include <linux/iio/kfifo_buf.h> + +#define DLN2_ADC_MOD_NAME "dln2-adc" + +#define DLN2_ADC_ID 0x06 + +#define DLN2_ADC_GET_CHANNEL_COUNT DLN2_CMD(0x01, DLN2_ADC_ID) +#define DLN2_ADC_ENABLE DLN2_CMD(0x02, DLN2_ADC_ID) +#define DLN2_ADC_DISABLE DLN2_CMD(0x03, DLN2_ADC_ID) +#define DLN2_ADC_CHANNEL_ENABLE DLN2_CMD(0x05, DLN2_ADC_ID) +#define DLN2_ADC_CHANNEL_DISABLE DLN2_CMD(0x06, DLN2_ADC_ID) +#define DLN2_ADC_SET_RESOLUTION DLN2_CMD(0x08, DLN2_ADC_ID) +#define DLN2_ADC_CHANNEL_GET_VAL DLN2_CMD(0x0A, DLN2_ADC_ID) +#define DLN2_ADC_CHANNEL_GET_ALL_VAL DLN2_CMD(0x0B, DLN2_ADC_ID) +#define DLN2_ADC_CHANNEL_SET_CFG DLN2_CMD(0x0C, DLN2_ADC_ID) +#define DLN2_ADC_CHANNEL_GET_CFG DLN2_CMD(0x0D, DLN2_ADC_ID) +#define DLN2_ADC_CONDITION_MET_EV DLN2_CMD(0x10, DLN2_ADC_ID) + +#define DLN2_ADC_EVENT_NONE 0 +#define DLN2_ADC_EVENT_BELOW 1 +#define DLN2_ADC_EVENT_LEVEL_ABOVE 2 +#define DLN2_ADC_EVENT_OUTSIDE 3 +#define DLN2_ADC_EVENT_INSIDE 4 +#define DLN2_ADC_EVENT_ALWAYS 5 + +#define DLN2_ADC_MAX_CHANNELS 8 +#define DLN2_ADC_DATA_BITS 10 + +/* + * Plays similar role to iio_demux_table in subsystem core; except allocated + * in a fixed 8-element array. + */ +struct dln2_adc_demux_table { + unsigned int from; + unsigned int to; + unsigned int length; +}; + +struct dln2_adc { + struct platform_device *pdev; + struct iio_chan_spec iio_channels[DLN2_ADC_MAX_CHANNELS + 1]; + int port, trigger_chan; + struct iio_trigger *trig; + struct mutex mutex; + /* Cached sample period in milliseconds */ + unsigned int sample_period; + /* Demux table */ + unsigned int demux_count; + struct dln2_adc_demux_table demux[DLN2_ADC_MAX_CHANNELS]; + /* Precomputed timestamp padding offset and length */ + unsigned int ts_pad_offset, ts_pad_length; +}; + +struct dln2_adc_port_chan { + u8 port; + u8 chan; +}; + +struct dln2_adc_get_all_vals { + __le16 channel_mask; + __le16 values[DLN2_ADC_MAX_CHANNELS]; +}; + +static void dln2_adc_add_demux(struct dln2_adc *dln2, + unsigned int in_loc, unsigned int out_loc, + unsigned int length) +{ + struct dln2_adc_demux_table *p = dln2->demux_count ? + &dln2->demux[dln2->demux_count - 1] : NULL; + + if (p && p->from + p->length == in_loc && + p->to + p->length == out_loc) { + p->length += length; + } else if (dln2->demux_count < DLN2_ADC_MAX_CHANNELS) { + p = &dln2->demux[dln2->demux_count++]; + p->from = in_loc; + p->to = out_loc; + p->length = length; + } +} + +static void dln2_adc_update_demux(struct dln2_adc *dln2) +{ + int in_ind = -1, out_ind; + unsigned int in_loc = 0, out_loc = 0; + struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev); + + /* Clear out any old demux */ + dln2->demux_count = 0; + + /* Optimize all 8-channels case */ + if (indio_dev->masklength && + (*indio_dev->active_scan_mask & 0xff) == 0xff) { + dln2_adc_add_demux(dln2, 0, 0, 16); + dln2->ts_pad_offset = 0; + dln2->ts_pad_length = 0; + return; + } + + /* Build demux table from fixed 8-channels to active_scan_mask */ + for_each_set_bit(out_ind, + indio_dev->active_scan_mask, + indio_dev->masklength) { + /* Handle timestamp separately */ + if (out_ind == DLN2_ADC_MAX_CHANNELS) + break; + for (++in_ind; in_ind != out_ind; ++in_ind) + in_loc += 2; + dln2_adc_add_demux(dln2, in_loc, out_loc, 2); + out_loc += 2; + in_loc += 2; + } + + if (indio_dev->scan_timestamp) { + size_t ts_offset = indio_dev->scan_bytes / sizeof(int64_t) - 1; + + dln2->ts_pad_offset = out_loc; + dln2->ts_pad_length = ts_offset * sizeof(int64_t) - out_loc; + } else { + dln2->ts_pad_offset = 0; + dln2->ts_pad_length = 0; + } +} + +static int dln2_adc_get_chan_count(struct dln2_adc *dln2) +{ + int ret; + u8 port = dln2->port; + u8 count; + int olen = sizeof(count); + + ret = dln2_transfer(dln2->pdev, DLN2_ADC_GET_CHANNEL_COUNT, + &port, sizeof(port), &count, &olen); + if (ret < 0) { + dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__); + return ret; + } + if (olen < sizeof(count)) + return -EPROTO; + + return count; +} + +static int dln2_adc_set_port_resolution(struct dln2_adc *dln2) +{ + int ret; + struct dln2_adc_port_chan port_chan = { + .port = dln2->port, + .chan = DLN2_ADC_DATA_BITS, + }; + + ret = dln2_transfer_tx(dln2->pdev, DLN2_ADC_SET_RESOLUTION, + &port_chan, sizeof(port_chan)); + if (ret < 0) + dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__); + + return ret; +} + +static int dln2_adc_set_chan_enabled(struct dln2_adc *dln2, + int channel, bool enable) +{ + int ret; + struct dln2_adc_port_chan port_chan = { + .port = dln2->port, + .chan = channel, + }; + u16 cmd = enable ? DLN2_ADC_CHANNEL_ENABLE : DLN2_ADC_CHANNEL_DISABLE; + + ret = dln2_transfer_tx(dln2->pdev, cmd, &port_chan, sizeof(port_chan)); + if (ret < 0) + dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__); + + return ret; +} + +static int dln2_adc_set_port_enabled(struct dln2_adc *dln2, bool enable, + u16 *conflict_out) +{ + int ret; + u8 port = dln2->port; + __le16 conflict; + int olen = sizeof(conflict); + u16 cmd = enable ? DLN2_ADC_ENABLE : DLN2_ADC_DISABLE; + + if (conflict_out) + *conflict_out = 0; + + ret = dln2_transfer(dln2->pdev, cmd, &port, sizeof(port), + &conflict, &olen); + if (ret < 0) { + dev_dbg(&dln2->pdev->dev, "Problem in %s(%d)\n", + __func__, (int)enable); + if (conflict_out && enable && olen >= sizeof(conflict)) + *conflict_out = le16_to_cpu(conflict); + return ret; + } + if (enable && olen < sizeof(conflict)) + return -EPROTO; + + return ret; +} + +static int dln2_adc_set_chan_period(struct dln2_adc *dln2, + unsigned int channel, unsigned int period) +{ + int ret; + struct { + struct dln2_adc_port_chan port_chan; + __u8 type; + __le16 period; + __le16 low; + __le16 high; + } __packed set_cfg = { + .port_chan.port = dln2->port, + .port_chan.chan = channel, + .type = period ? DLN2_ADC_EVENT_ALWAYS : DLN2_ADC_EVENT_NONE, + .period = cpu_to_le16(period) + }; + + ret = dln2_transfer_tx(dln2->pdev, DLN2_ADC_CHANNEL_SET_CFG, + &set_cfg, sizeof(set_cfg)); + if (ret < 0) + dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__); + + return ret; +} + +static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel) +{ + int ret, i; + struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev); + u16 conflict; + __le16 value; + int olen = sizeof(value); + struct dln2_adc_port_chan port_chan = { + .port = dln2->port, + .chan = channel, + }; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret < 0) + return ret; + + ret = dln2_adc_set_chan_enabled(dln2, channel, true); + if (ret < 0) + goto release_direct; + + ret = dln2_adc_set_port_enabled(dln2, true, &conflict); + if (ret < 0) { + if (conflict) { + dev_err(&dln2->pdev->dev, + "ADC pins conflict with mask %04X\n", + (int)conflict); + ret = -EBUSY; + } + goto disable_chan; + } + + /* + * Call GET_VAL twice due to initial zero-return immediately after + * enabling channel. + */ + for (i = 0; i < 2; ++i) { + ret = dln2_transfer(dln2->pdev, DLN2_ADC_CHANNEL_GET_VAL, + &port_chan, sizeof(port_chan), + &value, &olen); + if (ret < 0) { + dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__); + goto disable_port; + } + if (olen < sizeof(value)) { + ret = -EPROTO; + goto disable_port; + } + } + + ret = le16_to_cpu(value); + +disable_port: + dln2_adc_set_port_enabled(dln2, false, NULL); +disable_chan: + dln2_adc_set_chan_enabled(dln2, channel, false); +release_direct: + iio_device_release_direct_mode(indio_dev); + + return ret; +} + +static int dln2_adc_read_all(struct dln2_adc *dln2, + struct dln2_adc_get_all_vals *get_all_vals) +{ + int ret; + __u8 port = dln2->port; + int olen = sizeof(*get_all_vals); + + ret = dln2_transfer(dln2->pdev, DLN2_ADC_CHANNEL_GET_ALL_VAL, + &port, sizeof(port), get_all_vals, &olen); + if (ret < 0) { + dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__); + return ret; + } + if (olen < sizeof(*get_all_vals)) + return -EPROTO; + + return ret; +} + +static int dln2_adc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + int ret; + unsigned int microhertz; + struct dln2_adc *dln2 = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&dln2->mutex); + ret = dln2_adc_read(dln2, chan->channel); + mutex_unlock(&dln2->mutex); + + if (ret < 0) + return ret; + + *val = ret; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + /* + * Voltage reference is fixed at 3.3v + * 3.3 / (1 << 10) * 1000000000 + */ + *val = 0; + *val2 = 3222656; + return IIO_VAL_INT_PLUS_NANO; + + case IIO_CHAN_INFO_SAMP_FREQ: + if (dln2->sample_period) { + microhertz = 1000000000 / dln2->sample_period; + *val = microhertz / 1000000; + *val2 = microhertz % 1000000; + } else { + *val = 0; + *val2 = 0; + } + + return IIO_VAL_INT_PLUS_MICRO; + + default: + return -EINVAL; + } +} + +static int dln2_adc_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + int ret; + unsigned int microhertz; + struct dln2_adc *dln2 = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + microhertz = 1000000 * val + val2; + + mutex_lock(&dln2->mutex); + + dln2->sample_period = + microhertz ? 1000000000 / microhertz : UINT_MAX; + if (dln2->sample_period > 65535) { + dln2->sample_period = 65535; + dev_warn(&dln2->pdev->dev, + "clamping period to 65535ms\n"); + } + + /* + * The first requested channel is arbitrated as a shared + * trigger source, so only one event is registered with the + * DLN. The event handler will then read all enabled channel + * values using DLN2_ADC_CHANNEL_GET_ALL_VAL to maintain + * synchronization between ADC readings. + */ + if (dln2->trigger_chan != -1) + ret = dln2_adc_set_chan_period(dln2, + dln2->trigger_chan, dln2->sample_period); + else + ret = 0; + + mutex_unlock(&dln2->mutex); + + return ret; + + default: + return -EINVAL; + } +} + +static int dln2_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct dln2_adc *dln2 = iio_priv(indio_dev); + int chan_count = indio_dev->num_channels - 1; + int ret, i, j; + + mutex_lock(&dln2->mutex); + + for (i = 0; i < chan_count; ++i) { + ret = dln2_adc_set_chan_enabled(dln2, i, + test_bit(i, scan_mask)); + if (ret < 0) { + for (j = 0; j < i; ++j) + dln2_adc_set_chan_enabled(dln2, j, false); + mutex_unlock(&dln2->mutex); + dev_err(&dln2->pdev->dev, + "Unable to enable ADC channel %d\n", i); + return -EBUSY; + } + } + + dln2_adc_update_demux(dln2); + + mutex_unlock(&dln2->mutex); + + return 0; +} + +#define DLN2_ADC_CHAN(lval, idx) { \ + lval.type = IIO_VOLTAGE; \ + lval.channel = idx; \ + lval.indexed = 1; \ + lval.info_mask_separate = BIT(IIO_CHAN_INFO_RAW); \ + lval.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ); \ + lval.scan_index = idx; \ + lval.scan_type.sign = 'u'; \ + lval.scan_type.realbits = DLN2_ADC_DATA_BITS; \ + lval.scan_type.storagebits = 16; \ + lval.scan_type.endianness = IIO_LE; \ +} + +/* Assignment version of IIO_CHAN_SOFT_TIMESTAMP */ +#define IIO_CHAN_SOFT_TIMESTAMP_ASSIGN(lval, _si) { \ + lval.type = IIO_TIMESTAMP; \ + lval.channel = -1; \ + lval.scan_index = _si; \ + lval.scan_type.sign = 's'; \ + lval.scan_type.realbits = 64; \ + lval.scan_type.storagebits = 64; \ +} + +static const struct iio_info dln2_adc_info = { + .read_raw = dln2_adc_read_raw, + .write_raw = dln2_adc_write_raw, + .update_scan_mode = dln2_update_scan_mode, +}; + +static irqreturn_t dln2_adc_trigger_h(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct { + __le16 values[DLN2_ADC_MAX_CHANNELS]; + int64_t timestamp_space; + } data; + struct dln2_adc_get_all_vals dev_data; + struct dln2_adc *dln2 = iio_priv(indio_dev); + const struct dln2_adc_demux_table *t; + int ret, i; + + mutex_lock(&dln2->mutex); + ret = dln2_adc_read_all(dln2, &dev_data); + mutex_unlock(&dln2->mutex); + if (ret < 0) + goto done; + + /* Demux operation */ + for (i = 0; i < dln2->demux_count; ++i) { + t = &dln2->demux[i]; + memcpy((void *)data.values + t->to, + (void *)dev_data.values + t->from, t->length); + } + + /* Zero padding space between values and timestamp */ + if (dln2->ts_pad_length) + memset((void *)data.values + dln2->ts_pad_offset, + 0, dln2->ts_pad_length); + + iio_push_to_buffers_with_timestamp(indio_dev, &data, + iio_get_time_ns(indio_dev)); + +done: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + +static int dln2_adc_triggered_buffer_postenable(struct iio_dev *indio_dev) +{ + int ret; + struct dln2_adc *dln2 = iio_priv(indio_dev); + u16 conflict; + unsigned int trigger_chan; + + mutex_lock(&dln2->mutex); + + /* Enable ADC */ + ret = dln2_adc_set_port_enabled(dln2, true, &conflict); + if (ret < 0) { + mutex_unlock(&dln2->mutex); + dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__); + if (conflict) { + dev_err(&dln2->pdev->dev, + "ADC pins conflict with mask %04X\n", + (int)conflict); + ret = -EBUSY; + } + return ret; + } + + /* Assign trigger channel based on first enabled channel */ + trigger_chan = find_first_bit(indio_dev->active_scan_mask, + indio_dev->masklength); + if (trigger_chan < DLN2_ADC_MAX_CHANNELS) { + dln2->trigger_chan = trigger_chan; + ret = dln2_adc_set_chan_period(dln2, dln2->trigger_chan, + dln2->sample_period); + mutex_unlock(&dln2->mutex); + if (ret < 0) { + dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__); + return ret; + } + } else { + dln2->trigger_chan = -1; + mutex_unlock(&dln2->mutex); + } + + return iio_triggered_buffer_postenable(indio_dev); +} + +static int dln2_adc_triggered_buffer_predisable(struct iio_dev *indio_dev) +{ + int ret; + struct dln2_adc *dln2 = iio_priv(indio_dev); + + mutex_lock(&dln2->mutex); + + /* Disable trigger channel */ + if (dln2->trigger_chan != -1) { + dln2_adc_set_chan_period(dln2, dln2->trigger_chan, 0); + dln2->trigger_chan = -1; + } + + /* Disable ADC */ + ret = dln2_adc_set_port_enabled(dln2, false, NULL); + + mutex_unlock(&dln2->mutex); + if (ret < 0) { + dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__); + return ret; + } + + return iio_triggered_buffer_predisable(indio_dev); +} + +static const struct iio_buffer_setup_ops dln2_adc_buffer_setup_ops = { + .postenable = dln2_adc_triggered_buffer_postenable, + .predisable = dln2_adc_triggered_buffer_predisable, +}; + +static void dln2_adc_event(struct platform_device *pdev, u16 echo, + const void *data, int len) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct dln2_adc *dln2 = iio_priv(indio_dev); + + /* Called via URB completion handler */ + iio_trigger_poll(dln2->trig); +} + +static int dln2_adc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct dln2_adc *dln2; + struct dln2_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct iio_dev *indio_dev; + int i, ret, chans; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*dln2)); + if (!indio_dev) { + dev_err(dev, "failed allocating iio device\n"); + return -ENOMEM; + } + + dln2 = iio_priv(indio_dev); + dln2->pdev = pdev; + dln2->port = pdata->port; + dln2->trigger_chan = -1; + mutex_init(&dln2->mutex); + + platform_set_drvdata(pdev, indio_dev); + + ret = dln2_adc_set_port_resolution(dln2); + if (ret < 0) { + dev_err(dev, "failed to set ADC resolution to 10 bits\n"); + return ret; + } + + chans = dln2_adc_get_chan_count(dln2); + if (chans < 0) { + dev_err(dev, "failed to get channel count: %d\n", chans); + return chans; + } + if (chans > DLN2_ADC_MAX_CHANNELS) { + chans = DLN2_ADC_MAX_CHANNELS; + dev_warn(dev, "clamping channels to %d\n", + DLN2_ADC_MAX_CHANNELS); + } + + for (i = 0; i < chans; ++i) + DLN2_ADC_CHAN(dln2->iio_channels[i], i) + IIO_CHAN_SOFT_TIMESTAMP_ASSIGN(dln2->iio_channels[i], i); + + indio_dev->name = DLN2_ADC_MOD_NAME; + indio_dev->dev.parent = dev; + indio_dev->info = &dln2_adc_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = dln2->iio_channels; + indio_dev->num_channels = chans + 1; + indio_dev->setup_ops = &dln2_adc_buffer_setup_ops; + + dln2->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", + indio_dev->name, indio_dev->id); + if (!dln2->trig) { + dev_err(dev, "failed to allocate trigger\n"); + return -ENOMEM; + } + iio_trigger_set_drvdata(dln2->trig, dln2); + devm_iio_trigger_register(dev, dln2->trig); + iio_trigger_set_immutable(indio_dev, dln2->trig); + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + dln2_adc_trigger_h, + &dln2_adc_buffer_setup_ops); + if (ret) { + dev_err(dev, "failed to allocate triggered buffer: %d\n", ret); + return ret; + } + + ret = dln2_register_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV, + dln2_adc_event); + if (ret) { + dev_err(dev, "failed to setup DLN2 periodic event: %d\n", ret); + return ret; + } + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(dev, "failed to register iio device: %d\n", ret); + goto unregister_event; + } + + return ret; + +unregister_event: + dln2_unregister_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV); + + return ret; +} + +static int dln2_adc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + + iio_device_unregister(indio_dev); + dln2_unregister_event_cb(pdev, DLN2_ADC_CONDITION_MET_EV); + return 0; +} + +static struct platform_driver dln2_adc_driver = { + .driver.name = DLN2_ADC_MOD_NAME, + .probe = dln2_adc_probe, + .remove = dln2_adc_remove, +}; + +module_platform_driver(dln2_adc_driver); + +MODULE_AUTHOR("Jack Andersen <jackoalan@gmail.com"); +MODULE_DESCRIPTION("Driver for the Diolan DLN2 ADC interface"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:dln2-adc"); diff --git a/drivers/iio/adc/envelope-detector.c b/drivers/iio/adc/envelope-detector.c index fef15c0d7c9c..4ebda8ab54fe 100644 --- a/drivers/iio/adc/envelope-detector.c +++ b/drivers/iio/adc/envelope-detector.c @@ -322,7 +322,6 @@ static const struct iio_chan_spec envelope_detector_iio_channel = { static const struct iio_info envelope_detector_info = { .read_raw = &envelope_detector_read_raw, - .driver_module = THIS_MODULE, }; static int envelope_detector_probe(struct platform_device *pdev) diff --git a/drivers/iio/adc/ep93xx_adc.c b/drivers/iio/adc/ep93xx_adc.c new file mode 100644 index 000000000000..81c901507ad2 --- /dev/null +++ b/drivers/iio/adc/ep93xx_adc.c @@ -0,0 +1,254 @@ +/* + * Driver for ADC module on the Cirrus Logic EP93xx series of SoCs + * + * Copyright (C) 2015 Alexander Sverdlin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The driver uses polling to get the conversion status. According to EP93xx + * datasheets, reading ADCResult register starts the conversion, but user is also + * responsible for ensuring that delay between adjacent conversion triggers is + * long enough so that maximum allowed conversion rate is not exceeded. This + * basically renders IRQ mode unusable. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/iio/iio.h> +#include <linux/io.h> +#include <linux/irqflags.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/platform_device.h> + +/* + * This code could benefit from real HR Timers, but jiffy granularity would + * lower ADC conversion rate down to CONFIG_HZ, so we fallback to busy wait + * in such case. + * + * HR Timers-based version loads CPU only up to 10% during back to back ADC + * conversion, while busy wait-based version consumes whole CPU power. + */ +#ifdef CONFIG_HIGH_RES_TIMERS +#define ep93xx_adc_delay(usmin, usmax) usleep_range(usmin, usmax) +#else +#define ep93xx_adc_delay(usmin, usmax) udelay(usmin) +#endif + +#define EP93XX_ADC_RESULT 0x08 +#define EP93XX_ADC_SDR BIT(31) +#define EP93XX_ADC_SWITCH 0x18 +#define EP93XX_ADC_SW_LOCK 0x20 + +struct ep93xx_adc_priv { + struct clk *clk; + void __iomem *base; + int lastch; + struct mutex lock; +}; + +#define EP93XX_ADC_CH(index, dname, swcfg) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = index, \ + .address = swcfg, \ + .datasheet_name = dname, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ +} + +/* + * Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets. + * EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is + * not defined. So the last three are numbered randomly, let's say. + */ +static const struct iio_chan_spec ep93xx_adc_channels[8] = { + EP93XX_ADC_CH(0, "YM", 0x608), + EP93XX_ADC_CH(1, "SXP", 0x680), + EP93XX_ADC_CH(2, "SXM", 0x640), + EP93XX_ADC_CH(3, "SYP", 0x620), + EP93XX_ADC_CH(4, "SYM", 0x610), + EP93XX_ADC_CH(5, "XP", 0x601), + EP93XX_ADC_CH(6, "XM", 0x602), + EP93XX_ADC_CH(7, "YP", 0x604), +}; + +static int ep93xx_read_raw(struct iio_dev *iiodev, + struct iio_chan_spec const *channel, int *value, + int *shift, long mask) +{ + struct ep93xx_adc_priv *priv = iio_priv(iiodev); + unsigned long timeout; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&priv->lock); + if (priv->lastch != channel->channel) { + priv->lastch = channel->channel; + /* + * Switch register is software-locked, unlocking must be + * immediately followed by write + */ + local_irq_disable(); + writel_relaxed(0xAA, priv->base + EP93XX_ADC_SW_LOCK); + writel_relaxed(channel->address, + priv->base + EP93XX_ADC_SWITCH); + local_irq_enable(); + /* + * Settling delay depends on module clock and could be + * 2ms or 500us + */ + ep93xx_adc_delay(2000, 2000); + } + /* Start the conversion, eventually discarding old result */ + readl_relaxed(priv->base + EP93XX_ADC_RESULT); + /* Ensure maximum conversion rate is not exceeded */ + ep93xx_adc_delay(DIV_ROUND_UP(1000000, 925), + DIV_ROUND_UP(1000000, 925)); + /* At this point conversion must be completed, but anyway... */ + ret = IIO_VAL_INT; + timeout = jiffies + msecs_to_jiffies(1) + 1; + while (1) { + u32 t; + + t = readl_relaxed(priv->base + EP93XX_ADC_RESULT); + if (t & EP93XX_ADC_SDR) { + *value = sign_extend32(t, 15); + break; + } + + if (time_after(jiffies, timeout)) { + dev_err(&iiodev->dev, "Conversion timeout\n"); + ret = -ETIMEDOUT; + break; + } + + cpu_relax(); + } + mutex_unlock(&priv->lock); + return ret; + + case IIO_CHAN_INFO_OFFSET: + /* According to datasheet, range is -25000..25000 */ + *value = 25000; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + /* Typical supply voltage is 3.3v */ + *value = (1ULL << 32) * 3300 / 50000; + *shift = 32; + return IIO_VAL_FRACTIONAL_LOG2; + } + + return -EINVAL; +} + +static const struct iio_info ep93xx_adc_info = { + .read_raw = ep93xx_read_raw, +}; + +static int ep93xx_adc_probe(struct platform_device *pdev) +{ + int ret; + struct iio_dev *iiodev; + struct ep93xx_adc_priv *priv; + struct clk *pclk; + struct resource *res; + + iiodev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv)); + if (!iiodev) + return -ENOMEM; + priv = iio_priv(iiodev); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Cannot obtain memory resource\n"); + return -ENXIO; + } + priv->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->base)) { + dev_err(&pdev->dev, "Cannot map memory resource\n"); + return PTR_ERR(priv->base); + } + + iiodev->dev.parent = &pdev->dev; + iiodev->name = dev_name(&pdev->dev); + iiodev->modes = INDIO_DIRECT_MODE; + iiodev->info = &ep93xx_adc_info; + iiodev->num_channels = ARRAY_SIZE(ep93xx_adc_channels); + iiodev->channels = ep93xx_adc_channels; + + priv->lastch = -1; + mutex_init(&priv->lock); + + platform_set_drvdata(pdev, iiodev); + + priv->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(priv->clk)) { + dev_err(&pdev->dev, "Cannot obtain clock\n"); + return PTR_ERR(priv->clk); + } + + pclk = clk_get_parent(priv->clk); + if (!pclk) { + dev_warn(&pdev->dev, "Cannot obtain parent clock\n"); + } else { + /* + * This is actually a place for improvement: + * EP93xx ADC supports two clock divisors -- 4 and 16, + * resulting in conversion rates 3750 and 925 samples per second + * with 500us or 2ms settling time respectively. + * One might find this interesting enough to be configurable. + */ + ret = clk_set_rate(priv->clk, clk_get_rate(pclk) / 16); + if (ret) + dev_warn(&pdev->dev, "Cannot set clock rate\n"); + /* + * We can tolerate rate setting failure because the module should + * work in any case. + */ + } + + ret = clk_enable(priv->clk); + if (ret) { + dev_err(&pdev->dev, "Cannot enable clock\n"); + return ret; + } + + ret = iio_device_register(iiodev); + if (ret) + clk_disable(priv->clk); + + return ret; +} + +static int ep93xx_adc_remove(struct platform_device *pdev) +{ + struct iio_dev *iiodev = platform_get_drvdata(pdev); + struct ep93xx_adc_priv *priv = iio_priv(iiodev); + + iio_device_unregister(iiodev); + clk_disable(priv->clk); + + return 0; +} + +static struct platform_driver ep93xx_adc_driver = { + .driver = { + .name = "ep93xx-adc", + }, + .probe = ep93xx_adc_probe, + .remove = ep93xx_adc_remove, +}; +module_platform_driver(ep93xx_adc_driver); + +MODULE_AUTHOR("Alexander Sverdlin <alexander.sverdlin@gmail.com>"); +MODULE_DESCRIPTION("Cirrus Logic EP93XX ADC driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ep93xx-adc"); diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 6c5a7be9f8c1..f10443f92e4c 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -657,7 +657,6 @@ static int exynos_adc_reg_access(struct iio_dev *indio_dev, static const struct iio_info exynos_adc_iio_info = { .read_raw = &exynos_read_raw, .debugfs_reg_access = &exynos_adc_reg_access, - .driver_module = THIS_MODULE, }; #define ADC_CHANNEL(_index, _id) { \ diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c index adf7dc712937..6f6c9a348158 100644 --- a/drivers/iio/adc/hi8435.c +++ b/drivers/iio/adc/hi8435.c @@ -408,7 +408,6 @@ static const struct iio_chan_spec hi8435_channels[] = { }; static const struct iio_info hi8435_info = { - .driver_module = THIS_MODULE, .read_raw = hi8435_read_raw, .read_event_config = hi8435_read_event_config, .write_event_config = hi8435_write_event_config, diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c index 27005d84ed73..d10b9f13d557 100644 --- a/drivers/iio/adc/hx711.c +++ b/drivers/iio/adc/hx711.c @@ -374,7 +374,6 @@ static const struct attribute_group hx711_attribute_group = { }; static const struct iio_info hx711_iio_info = { - .driver_module = THIS_MODULE, .read_raw = hx711_read_raw, .write_raw = hx711_write_raw, .write_raw_get_fmt = hx711_write_raw_get_fmt, diff --git a/drivers/iio/adc/imx7d_adc.c b/drivers/iio/adc/imx7d_adc.c index 254b29a68b9d..cfab31162845 100644 --- a/drivers/iio/adc/imx7d_adc.c +++ b/drivers/iio/adc/imx7d_adc.c @@ -412,7 +412,6 @@ static int imx7d_adc_reg_access(struct iio_dev *indio_dev, } static const struct iio_info imx7d_adc_iio_info = { - .driver_module = THIS_MODULE, .read_raw = &imx7d_adc_read_raw, .debugfs_reg_access = &imx7d_adc_reg_access, }; diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 232c0b80d658..84a43871f7dc 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -44,6 +44,7 @@ #define INA226_MASK_ENABLE 0x06 #define INA226_CVRF BIT(3) +#define INA219_CNVR BIT(1) #define INA2XX_MAX_REGISTERS 8 @@ -122,7 +123,7 @@ struct ina2xx_chip_info { struct task_struct *task; const struct ina2xx_config *config; struct mutex state_lock; - unsigned int shunt_resistor; + unsigned int shunt_resistor_uohm; int avg; int int_time_vbus; /* Bus voltage integration time uS */ int int_time_vshunt; /* Shunt voltage integration time uS */ @@ -435,7 +436,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, /* * Set current LSB to 1mA, shunt is in uOhms * (equation 13 in datasheet). We hardcode a Current_LSB - * of 1.0 x10-6. The only remaining parameter is RShunt. + * of 1.0 x10-3. The only remaining parameter is RShunt. * There is no need to expose the CALIBRATION register * to the user for now. But we need to reset this register * if the user updates RShunt after driver init, e.g upon @@ -444,7 +445,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, static int ina2xx_set_calibration(struct ina2xx_chip_info *chip) { u16 regval = DIV_ROUND_CLOSEST(chip->config->calibration_factor, - chip->shunt_resistor); + chip->shunt_resistor_uohm); return regmap_write(chip->regmap, INA2XX_CALIBRATION, regval); } @@ -454,7 +455,7 @@ static int set_shunt_resistor(struct ina2xx_chip_info *chip, unsigned int val) if (val <= 0 || val > chip->config->calibration_factor) return -EINVAL; - chip->shunt_resistor = val; + chip->shunt_resistor_uohm = val; return 0; } @@ -464,8 +465,9 @@ static ssize_t ina2xx_shunt_resistor_show(struct device *dev, char *buf) { struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); + int vals[2] = { chip->shunt_resistor_uohm, 1000000 }; - return sprintf(buf, "%d\n", chip->shunt_resistor); + return iio_format_value(buf, IIO_VAL_FRACTIONAL, 1, vals); } static ssize_t ina2xx_shunt_resistor_store(struct device *dev, @@ -473,14 +475,13 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev, const char *buf, size_t len) { struct ina2xx_chip_info *chip = iio_priv(dev_to_iio_dev(dev)); - unsigned long val; - int ret; + int val, val_fract, ret; - ret = kstrtoul((const char *) buf, 10, &val); + ret = iio_str_to_fixpoint(buf, 100000, &val, &val_fract); if (ret) return ret; - ret = set_shunt_resistor(chip, val); + ret = set_shunt_resistor(chip, val * 1000000 + val_fract); if (ret) return ret; @@ -592,6 +593,7 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) int bit, ret, i = 0; s64 time_a, time_b; unsigned int alert; + int cnvr_need_clear = 0; time_a = iio_get_time_ns(indio_dev); @@ -603,22 +605,30 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) * we check the ConVersionReadyFlag. * On hardware that supports using the ALERT pin to toggle a * GPIO a triggered buffer could be used instead. - * For now, we pay for that extra read of the ALERT register + * For now, we do an extra read of the MASK_ENABLE register (INA226) + * resp. the BUS_VOLTAGE register (INA219). */ if (!chip->allow_async_readout) do { - ret = regmap_read(chip->regmap, INA226_MASK_ENABLE, - &alert); + if (chip->config->chip_id == ina226) { + ret = regmap_read(chip->regmap, + INA226_MASK_ENABLE, &alert); + alert &= INA226_CVRF; + } else { + ret = regmap_read(chip->regmap, + INA2XX_BUS_VOLTAGE, &alert); + alert &= INA219_CNVR; + cnvr_need_clear = alert; + } + if (ret < 0) return ret; - alert &= INA226_CVRF; } while (!alert); /* - * Single register reads: bulk_read will not work with ina226 - * as there is no auto-increment of the address register for - * data length longer than 16bits. + * Single register reads: bulk_read will not work with ina226/219 + * as there is no auto-increment of the register pointer. */ for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { @@ -630,6 +640,18 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) return ret; data[i++] = val; + + if (INA2XX_SHUNT_VOLTAGE + bit == INA2XX_POWER) + cnvr_need_clear = 0; + } + + /* Dummy read on INA219 power register to clear CNVR flag */ + if (cnvr_need_clear && chip->config->chip_id == ina219) { + unsigned int val; + + ret = regmap_read(chip->regmap, INA2XX_POWER, &val); + if (ret < 0) + return ret; } time_b = iio_get_time_ns(indio_dev); @@ -644,7 +666,7 @@ static int ina2xx_capture_thread(void *data) { struct iio_dev *indio_dev = data; struct ina2xx_chip_info *chip = iio_priv(indio_dev); - unsigned int sampling_us = SAMPLING_PERIOD(chip); + int sampling_us = SAMPLING_PERIOD(chip); int buffer_us; /* @@ -756,7 +778,6 @@ static const struct attribute_group ina226_attribute_group = { }; static const struct iio_info ina219_info = { - .driver_module = THIS_MODULE, .attrs = &ina219_attribute_group, .read_raw = ina2xx_read_raw, .write_raw = ina2xx_write_raw, @@ -764,7 +785,6 @@ static const struct iio_info ina219_info = { }; static const struct iio_info ina226_info = { - .driver_module = THIS_MODULE, .attrs = &ina226_attribute_group, .read_raw = ina2xx_read_raw, .write_raw = ina2xx_write_raw, diff --git a/drivers/iio/adc/lp8788_adc.c b/drivers/iio/adc/lp8788_adc.c index 152cfc8e1c7b..3bc4df916420 100644 --- a/drivers/iio/adc/lp8788_adc.c +++ b/drivers/iio/adc/lp8788_adc.c @@ -125,7 +125,6 @@ static int lp8788_adc_read_raw(struct iio_dev *indio_dev, static const struct iio_info lp8788_adc_info = { .read_raw = &lp8788_adc_read_raw, - .driver_module = THIS_MODULE, }; #define LP8788_CHAN(_id, _type) { \ diff --git a/drivers/iio/adc/lpc18xx_adc.c b/drivers/iio/adc/lpc18xx_adc.c index 3ef18f4b27f0..041dc4a3f66c 100644 --- a/drivers/iio/adc/lpc18xx_adc.c +++ b/drivers/iio/adc/lpc18xx_adc.c @@ -116,7 +116,6 @@ static int lpc18xx_adc_read_raw(struct iio_dev *indio_dev, static const struct iio_info lpc18xx_adc_info = { .read_raw = lpc18xx_adc_read_raw, - .driver_module = THIS_MODULE, }; static int lpc18xx_adc_probe(struct platform_device *pdev) diff --git a/drivers/iio/adc/lpc32xx_adc.c b/drivers/iio/adc/lpc32xx_adc.c index 6a5b9a9bc662..20b36690fa4f 100644 --- a/drivers/iio/adc/lpc32xx_adc.c +++ b/drivers/iio/adc/lpc32xx_adc.c @@ -104,7 +104,6 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev, static const struct iio_info lpc32xx_adc_iio_info = { .read_raw = &lpc32xx_read_raw, - .driver_module = THIS_MODULE, }; #define LPC32XX_ADC_CHANNEL(_index) { \ diff --git a/drivers/iio/adc/ltc2471.c b/drivers/iio/adc/ltc2471.c new file mode 100644 index 000000000000..b88102b751cf --- /dev/null +++ b/drivers/iio/adc/ltc2471.c @@ -0,0 +1,159 @@ +/* + * Driver for Linear Technology LTC2471 and LTC2473 voltage monitors + * The LTC2473 is identical to the 2471, but reports a differential signal. + * + * Copyright (C) 2017 Topic Embedded Products + * Author: Mike Looijmans <mike.looijmans@topic.nl> + * + * License: GPLv2 + */ + +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +enum ltc2471_chips { + ltc2471, + ltc2473, +}; + +struct ltc2471_data { + struct i2c_client *client; +}; + +/* Reference voltage is 1.25V */ +#define LTC2471_VREF 1250 + +/* Read two bytes from the I2C bus to obtain the ADC result */ +static int ltc2471_get_value(struct i2c_client *client) +{ + int ret; + __be16 buf; + + ret = i2c_master_recv(client, (char *)&buf, sizeof(buf)); + if (ret < 0) + return ret; + if (ret != sizeof(buf)) + return -EIO; + + /* MSB first */ + return be16_to_cpu(buf); +} + +static int ltc2471_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + struct ltc2471_data *data = iio_priv(indio_dev); + int ret; + + switch (info) { + case IIO_CHAN_INFO_RAW: + ret = ltc2471_get_value(data->client); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + if (chan->differential) + /* Output ranges from -VREF to +VREF */ + *val = 2 * LTC2471_VREF; + else + /* Output ranges from 0 to VREF */ + *val = LTC2471_VREF; + *val2 = 16; /* 16 data bits */ + return IIO_VAL_FRACTIONAL_LOG2; + + case IIO_CHAN_INFO_OFFSET: + /* Only differential chip has this property */ + *val = -LTC2471_VREF; + return IIO_VAL_INT; + + default: + return -EINVAL; + } +} + +static const struct iio_chan_spec ltc2471_channel[] = { + { + .type = IIO_VOLTAGE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), + }, +}; + +static const struct iio_chan_spec ltc2473_channel[] = { + { + .type = IIO_VOLTAGE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .differential = 1, + }, +}; + +static const struct iio_info ltc2471_info = { + .read_raw = ltc2471_read_raw, +}; + +static int ltc2471_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct ltc2471_data *data; + int ret; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -EOPNOTSUPP; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + data->client = client; + + indio_dev->dev.parent = &client->dev; + indio_dev->name = id->name; + indio_dev->info = <c2471_info; + indio_dev->modes = INDIO_DIRECT_MODE; + if (id->driver_data == ltc2473) + indio_dev->channels = ltc2473_channel; + else + indio_dev->channels = ltc2471_channel; + indio_dev->num_channels = 1; + + /* Trigger once to start conversion and check if chip is there */ + ret = ltc2471_get_value(client); + if (ret < 0) { + dev_err(&client->dev, "Cannot read from device.\n"); + return ret; + } + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct i2c_device_id ltc2471_i2c_id[] = { + { "ltc2471", ltc2471 }, + { "ltc2473", ltc2473 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, ltc2471_i2c_id); + +static struct i2c_driver ltc2471_i2c_driver = { + .driver = { + .name = "ltc2471", + }, + .probe = ltc2471_i2c_probe, + .id_table = ltc2471_i2c_id, +}; + +module_i2c_driver(ltc2471_i2c_driver); + +MODULE_DESCRIPTION("LTC2471/LTC2473 ADC driver"); +MODULE_AUTHOR("Topic Embedded Products"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/ltc2485.c b/drivers/iio/adc/ltc2485.c index eab91f12454a..b24c14037fd4 100644 --- a/drivers/iio/adc/ltc2485.c +++ b/drivers/iio/adc/ltc2485.c @@ -90,7 +90,6 @@ static const struct iio_chan_spec ltc2485_channel[] = { static const struct iio_info ltc2485_info = { .read_raw = ltc2485_read_raw, - .driver_module = THIS_MODULE, }; static int ltc2485_probe(struct i2c_client *client, diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c index 2691b10023f5..f1f7cdf66fbd 100644 --- a/drivers/iio/adc/ltc2497.c +++ b/drivers/iio/adc/ltc2497.c @@ -11,6 +11,7 @@ #include <linux/delay.h> #include <linux/i2c.h> #include <linux/iio/iio.h> +#include <linux/iio/driver.h> #include <linux/iio/sysfs.h> #include <linux/module.h> #include <linux/of.h> @@ -127,13 +128,14 @@ static int ltc2497_read_raw(struct iio_dev *indio_dev, } } -#define LTC2497_CHAN(_chan, _addr) { \ +#define LTC2497_CHAN(_chan, _addr, _ds_name) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = (_chan), \ .address = (_addr | (_chan / 2) | ((_chan & 1) ? LTC2497_SIGN : 0)), \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .datasheet_name = (_ds_name), \ } #define LTC2497_CHAN_DIFF(_chan, _addr) { \ @@ -148,22 +150,22 @@ static int ltc2497_read_raw(struct iio_dev *indio_dev, } static const struct iio_chan_spec ltc2497_channel[] = { - LTC2497_CHAN(0, LTC2497_SGL), - LTC2497_CHAN(1, LTC2497_SGL), - LTC2497_CHAN(2, LTC2497_SGL), - LTC2497_CHAN(3, LTC2497_SGL), - LTC2497_CHAN(4, LTC2497_SGL), - LTC2497_CHAN(5, LTC2497_SGL), - LTC2497_CHAN(6, LTC2497_SGL), - LTC2497_CHAN(7, LTC2497_SGL), - LTC2497_CHAN(8, LTC2497_SGL), - LTC2497_CHAN(9, LTC2497_SGL), - LTC2497_CHAN(10, LTC2497_SGL), - LTC2497_CHAN(11, LTC2497_SGL), - LTC2497_CHAN(12, LTC2497_SGL), - LTC2497_CHAN(13, LTC2497_SGL), - LTC2497_CHAN(14, LTC2497_SGL), - LTC2497_CHAN(15, LTC2497_SGL), + LTC2497_CHAN(0, LTC2497_SGL, "CH0"), + LTC2497_CHAN(1, LTC2497_SGL, "CH1"), + LTC2497_CHAN(2, LTC2497_SGL, "CH2"), + LTC2497_CHAN(3, LTC2497_SGL, "CH3"), + LTC2497_CHAN(4, LTC2497_SGL, "CH4"), + LTC2497_CHAN(5, LTC2497_SGL, "CH5"), + LTC2497_CHAN(6, LTC2497_SGL, "CH6"), + LTC2497_CHAN(7, LTC2497_SGL, "CH7"), + LTC2497_CHAN(8, LTC2497_SGL, "CH8"), + LTC2497_CHAN(9, LTC2497_SGL, "CH9"), + LTC2497_CHAN(10, LTC2497_SGL, "CH10"), + LTC2497_CHAN(11, LTC2497_SGL, "CH11"), + LTC2497_CHAN(12, LTC2497_SGL, "CH12"), + LTC2497_CHAN(13, LTC2497_SGL, "CH13"), + LTC2497_CHAN(14, LTC2497_SGL, "CH14"), + LTC2497_CHAN(15, LTC2497_SGL, "CH15"), LTC2497_CHAN_DIFF(0, LTC2497_DIFF), LTC2497_CHAN_DIFF(1, LTC2497_DIFF), LTC2497_CHAN_DIFF(2, LTC2497_DIFF), @@ -184,7 +186,6 @@ static const struct iio_chan_spec ltc2497_channel[] = { static const struct iio_info ltc2497_info = { .read_raw = ltc2497_read_raw, - .driver_module = THIS_MODULE, }; static int ltc2497_probe(struct i2c_client *client, @@ -192,6 +193,7 @@ static int ltc2497_probe(struct i2c_client *client, { struct iio_dev *indio_dev; struct ltc2497_st *st; + struct iio_map *plat_data; int ret; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | @@ -221,19 +223,31 @@ static int ltc2497_probe(struct i2c_client *client, if (ret < 0) return ret; + if (client->dev.platform_data) { + plat_data = ((struct iio_map *)client->dev.platform_data); + ret = iio_map_array_register(indio_dev, plat_data); + if (ret) { + dev_err(&indio_dev->dev, "iio map err: %d\n", ret); + goto err_regulator_disable; + } + } + ret = i2c_smbus_write_byte(st->client, LTC2497_CONFIG_DEFAULT); if (ret < 0) - goto err_regulator_disable; + goto err_array_unregister; st->addr_prev = LTC2497_CONFIG_DEFAULT; st->time_prev = ktime_get(); ret = iio_device_register(indio_dev); if (ret < 0) - goto err_regulator_disable; + goto err_array_unregister; return 0; +err_array_unregister: + iio_map_array_unregister(indio_dev); + err_regulator_disable: regulator_disable(st->ref); @@ -245,6 +259,7 @@ static int ltc2497_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); struct ltc2497_st *st = iio_priv(indio_dev); + iio_map_array_unregister(indio_dev); iio_device_unregister(indio_dev); regulator_disable(st->ref); diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c index ebc715927e63..375da6491499 100644 --- a/drivers/iio/adc/max1027.c +++ b/drivers/iio/adc/max1027.c @@ -381,13 +381,11 @@ static irqreturn_t max1027_trigger_handler(int irq, void *private) } static const struct iio_trigger_ops max1027_trigger_ops = { - .owner = THIS_MODULE, .validate_device = &iio_trigger_validate_own_device, .set_trigger_state = &max1027_set_trigger_state, }; static const struct iio_info max1027_info = { - .driver_module = THIS_MODULE, .read_raw = &max1027_read_raw, .validate_trigger = &max1027_validate_trigger, .debugfs_reg_access = &max1027_debugfs_reg_access, diff --git a/drivers/iio/adc/max11100.c b/drivers/iio/adc/max11100.c index 1180bcc22ff1..af59ab2e650c 100644 --- a/drivers/iio/adc/max11100.c +++ b/drivers/iio/adc/max11100.c @@ -100,7 +100,6 @@ static int max11100_read_raw(struct iio_dev *indio_dev, } static const struct iio_info max11100_info = { - .driver_module = THIS_MODULE, .read_raw = max11100_read_raw, }; diff --git a/drivers/iio/adc/max1118.c b/drivers/iio/adc/max1118.c index 2e9648a078c4..49db9e9ae625 100644 --- a/drivers/iio/adc/max1118.c +++ b/drivers/iio/adc/max1118.c @@ -155,7 +155,6 @@ static int max1118_read_raw(struct iio_dev *indio_dev, static const struct iio_info max1118_info = { .read_raw = max1118_read_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t max1118_trigger_handler(int irq, void *p) diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 80eada4886b3..7f1848dac9bf 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -1029,7 +1029,6 @@ static int max1363_update_scan_mode(struct iio_dev *indio_dev, static const struct iio_info max1238_info = { .read_raw = &max1363_read_raw, - .driver_module = THIS_MODULE, .update_scan_mode = &max1363_update_scan_mode, }; @@ -1040,7 +1039,6 @@ static const struct iio_info max1363_info = { .write_event_config = &max1363_write_event_config, .read_raw = &max1363_read_raw, .update_scan_mode = &max1363_update_scan_mode, - .driver_module = THIS_MODULE, .event_attrs = &max1363_event_attribute_group, }; diff --git a/drivers/iio/adc/max9611.c b/drivers/iio/adc/max9611.c index b0526e4b9530..0538ff8c4ac1 100644 --- a/drivers/iio/adc/max9611.c +++ b/drivers/iio/adc/max9611.c @@ -460,7 +460,6 @@ static const struct attribute_group max9611_attribute_group = { }; static const struct iio_info indio_info = { - .driver_module = THIS_MODULE, .read_raw = max9611_read_raw, .attrs = &max9611_attribute_group, }; @@ -549,8 +548,8 @@ static int max9611_probe(struct i2c_client *client, ret = of_property_read_u32(of_node, shunt_res_prop, &of_shunt); if (ret) { dev_err(&client->dev, - "Missing %s property for %s node\n", - shunt_res_prop, of_node->full_name); + "Missing %s property for %pOF node\n", + shunt_res_prop, of_node); return ret; } max9611->shunt_resistor_uohm = of_shunt; @@ -573,7 +572,6 @@ static int max9611_probe(struct i2c_client *client, static struct i2c_driver max9611_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, .of_match_table = max9611_of_table, }, .probe = max9611_probe, diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index 634717ae12f3..a04856d8afdb 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -17,6 +17,13 @@ * MCP3204 * MCP3208 * ------------ + * 13 bit converter + * MCP3301 + * ------------ + * 22 bit converter + * MCP3550 + * MCP3551 + * MCP3553 * * Datasheet can be found here: * http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf mcp3001 @@ -26,6 +33,7 @@ * http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf mcp3202 * http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf mcp3204/08 * http://ww1.microchip.com/downloads/en/DeviceDoc/21700E.pdf mcp3301 + * http://ww1.microchip.com/downloads/en/DeviceDoc/21950D.pdf mcp3550/1/3 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -49,25 +57,45 @@ enum { mcp3204, mcp3208, mcp3301, + mcp3550_50, + mcp3550_60, + mcp3551, + mcp3553, }; struct mcp320x_chip_info { const struct iio_chan_spec *channels; unsigned int num_channels; unsigned int resolution; + unsigned int conv_time; /* usec */ }; +/** + * struct mcp320x - Microchip SPI ADC instance + * @spi: SPI slave (parent of the IIO device) + * @msg: SPI message to select a channel and receive a value from the ADC + * @transfer: SPI transfers used by @msg + * @start_conv_msg: SPI message to start a conversion by briefly asserting CS + * @start_conv_transfer: SPI transfer used by @start_conv_msg + * @reg: regulator generating Vref + * @lock: protects read sequences + * @chip_info: ADC properties + * @tx_buf: buffer for @transfer[0] (not used on single-channel converters) + * @rx_buf: buffer for @transfer[1] + */ struct mcp320x { struct spi_device *spi; struct spi_message msg; struct spi_transfer transfer[2]; + struct spi_message start_conv_msg; + struct spi_transfer start_conv_transfer; struct regulator *reg; struct mutex lock; const struct mcp320x_chip_info *chip_info; u8 tx_buf ____cacheline_aligned; - u8 rx_buf[2]; + u8 rx_buf[4]; }; static int mcp320x_channel_to_tx_data(int device_index, @@ -76,10 +104,6 @@ static int mcp320x_channel_to_tx_data(int device_index, int start_bit = 1; switch (device_index) { - case mcp3001: - case mcp3201: - case mcp3301: - return 0; case mcp3002: case mcp3202: return ((start_bit << 4) | (!differential << 3) | @@ -96,40 +120,74 @@ static int mcp320x_channel_to_tx_data(int device_index, } static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, - bool differential, int device_index) + bool differential, int device_index, int *val) { int ret; - adc->rx_buf[0] = 0; - adc->rx_buf[1] = 0; - adc->tx_buf = mcp320x_channel_to_tx_data(device_index, - channel, differential); - - if (device_index != mcp3001 && device_index != mcp3201 && device_index != mcp3301) { - ret = spi_sync(adc->spi, &adc->msg); - if (ret < 0) - return ret; - } else { - ret = spi_read(adc->spi, &adc->rx_buf, sizeof(adc->rx_buf)); + if (adc->chip_info->conv_time) { + ret = spi_sync(adc->spi, &adc->start_conv_msg); if (ret < 0) return ret; + + usleep_range(adc->chip_info->conv_time, + adc->chip_info->conv_time + 100); } + memset(&adc->rx_buf, 0, sizeof(adc->rx_buf)); + if (adc->chip_info->num_channels > 1) + adc->tx_buf = mcp320x_channel_to_tx_data(device_index, channel, + differential); + + ret = spi_sync(adc->spi, &adc->msg); + if (ret < 0) + return ret; + switch (device_index) { case mcp3001: - return (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3); + *val = (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3); + return 0; case mcp3002: case mcp3004: case mcp3008: - return (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6); + *val = (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6); + return 0; case mcp3201: - return (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1); + *val = (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1); + return 0; case mcp3202: case mcp3204: case mcp3208: - return (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4); + *val = (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4); + return 0; case mcp3301: - return sign_extend32((adc->rx_buf[0] & 0x1f) << 8 | adc->rx_buf[1], 12); + *val = sign_extend32((adc->rx_buf[0] & 0x1f) << 8 + | adc->rx_buf[1], 12); + return 0; + case mcp3550_50: + case mcp3550_60: + case mcp3551: + case mcp3553: { + u32 raw = be32_to_cpup((u32 *)adc->rx_buf); + + if (!(adc->spi->mode & SPI_CPOL)) + raw <<= 1; /* strip Data Ready bit in SPI mode 0,0 */ + + /* + * If the input is within -vref and vref, bit 21 is the sign. + * Up to 12% overrange or underrange are allowed, in which case + * bit 23 is the sign and bit 0 to 21 is the value. + */ + raw >>= 8; + if (raw & BIT(22) && raw & BIT(23)) + return -EIO; /* cannot have overrange AND underrange */ + else if (raw & BIT(22)) + raw &= ~BIT(22); /* overrange */ + else if (raw & BIT(23) || raw & BIT(21)) + raw |= GENMASK(31, 22); /* underrange or negative */ + + *val = (s32)raw; + return 0; + } default: return -EINVAL; } @@ -150,12 +208,10 @@ static int mcp320x_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: ret = mcp320x_adc_conversion(adc, channel->address, - channel->differential, device_index); - + channel->differential, device_index, val); if (ret < 0) goto out; - *val = ret; ret = IIO_VAL_INT; break; @@ -242,7 +298,6 @@ static const struct iio_chan_spec mcp3208_channels[] = { static const struct iio_info mcp320x_info = { .read_raw = mcp320x_read_raw, - .driver_module = THIS_MODULE, }; static const struct mcp320x_chip_info mcp320x_chip_infos[] = { @@ -291,6 +346,31 @@ static const struct mcp320x_chip_info mcp320x_chip_infos[] = { .num_channels = ARRAY_SIZE(mcp3201_channels), .resolution = 13 }, + [mcp3550_50] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 21, + /* 2% max deviation + 144 clock periods to exit shutdown */ + .conv_time = 80000 * 1.02 + 144000 / 102.4, + }, + [mcp3550_60] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 21, + .conv_time = 66670 * 1.02 + 144000 / 122.88, + }, + [mcp3551] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 21, + .conv_time = 73100 * 1.02 + 144000 / 112.64, + }, + [mcp3553] = { + .channels = mcp3201_channels, + .num_channels = ARRAY_SIZE(mcp3201_channels), + .resolution = 21, + .conv_time = 16670 * 1.02 + 144000 / 122.88, + }, }; static int mcp320x_probe(struct spi_device *spi) @@ -298,7 +378,7 @@ static int mcp320x_probe(struct spi_device *spi) struct iio_dev *indio_dev; struct mcp320x *adc; const struct mcp320x_chip_info *chip_info; - int ret; + int ret, device_index; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); if (!indio_dev) @@ -312,8 +392,10 @@ static int mcp320x_probe(struct spi_device *spi) indio_dev->name = spi_get_device_id(spi)->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &mcp320x_info; + spi_set_drvdata(spi, indio_dev); - chip_info = &mcp320x_chip_infos[spi_get_device_id(spi)->driver_data]; + device_index = spi_get_device_id(spi)->driver_data; + chip_info = &mcp320x_chip_infos[device_index]; indio_dev->channels = chip_info->channels; indio_dev->num_channels = chip_info->num_channels; @@ -322,10 +404,41 @@ static int mcp320x_probe(struct spi_device *spi) adc->transfer[0].tx_buf = &adc->tx_buf; adc->transfer[0].len = sizeof(adc->tx_buf); adc->transfer[1].rx_buf = adc->rx_buf; - adc->transfer[1].len = sizeof(adc->rx_buf); + adc->transfer[1].len = DIV_ROUND_UP(chip_info->resolution, 8); - spi_message_init_with_transfers(&adc->msg, adc->transfer, - ARRAY_SIZE(adc->transfer)); + if (chip_info->num_channels == 1) + /* single-channel converters are rx only (no MOSI pin) */ + spi_message_init_with_transfers(&adc->msg, + &adc->transfer[1], 1); + else + spi_message_init_with_transfers(&adc->msg, adc->transfer, + ARRAY_SIZE(adc->transfer)); + + switch (device_index) { + case mcp3550_50: + case mcp3550_60: + case mcp3551: + case mcp3553: + /* rx len increases from 24 to 25 bit in SPI mode 0,0 */ + if (!(spi->mode & SPI_CPOL)) + adc->transfer[1].len++; + + /* conversions are started by asserting CS pin for 8 usec */ + adc->start_conv_transfer.delay_usecs = 8; + spi_message_init_with_transfers(&adc->start_conv_msg, + &adc->start_conv_transfer, 1); + + /* + * If CS was previously kept low (continuous conversion mode) + * and then changed to high, the chip is in shutdown. + * Sometimes it fails to wake from shutdown and clocks out + * only 0xffffff. The magic sequence of performing two + * conversions without delay between them resets the chip + * and ensures all subsequent conversions succeed. + */ + mcp320x_adc_conversion(adc, 0, 1, device_index, &ret); + mcp320x_adc_conversion(adc, 0, 1, device_index, &ret); + } adc->reg = devm_regulator_get(&spi->dev, "vref"); if (IS_ERR(adc->reg)) @@ -363,62 +476,29 @@ static int mcp320x_remove(struct spi_device *spi) #if defined(CONFIG_OF) static const struct of_device_id mcp320x_dt_ids[] = { /* NOTE: The use of compatibles with no vendor prefix is deprecated. */ - { - .compatible = "mcp3001", - .data = &mcp320x_chip_infos[mcp3001], - }, { - .compatible = "mcp3002", - .data = &mcp320x_chip_infos[mcp3002], - }, { - .compatible = "mcp3004", - .data = &mcp320x_chip_infos[mcp3004], - }, { - .compatible = "mcp3008", - .data = &mcp320x_chip_infos[mcp3008], - }, { - .compatible = "mcp3201", - .data = &mcp320x_chip_infos[mcp3201], - }, { - .compatible = "mcp3202", - .data = &mcp320x_chip_infos[mcp3202], - }, { - .compatible = "mcp3204", - .data = &mcp320x_chip_infos[mcp3204], - }, { - .compatible = "mcp3208", - .data = &mcp320x_chip_infos[mcp3208], - }, { - .compatible = "mcp3301", - .data = &mcp320x_chip_infos[mcp3301], - }, { - .compatible = "microchip,mcp3001", - .data = &mcp320x_chip_infos[mcp3001], - }, { - .compatible = "microchip,mcp3002", - .data = &mcp320x_chip_infos[mcp3002], - }, { - .compatible = "microchip,mcp3004", - .data = &mcp320x_chip_infos[mcp3004], - }, { - .compatible = "microchip,mcp3008", - .data = &mcp320x_chip_infos[mcp3008], - }, { - .compatible = "microchip,mcp3201", - .data = &mcp320x_chip_infos[mcp3201], - }, { - .compatible = "microchip,mcp3202", - .data = &mcp320x_chip_infos[mcp3202], - }, { - .compatible = "microchip,mcp3204", - .data = &mcp320x_chip_infos[mcp3204], - }, { - .compatible = "microchip,mcp3208", - .data = &mcp320x_chip_infos[mcp3208], - }, { - .compatible = "microchip,mcp3301", - .data = &mcp320x_chip_infos[mcp3301], - }, { - } + { .compatible = "mcp3001" }, + { .compatible = "mcp3002" }, + { .compatible = "mcp3004" }, + { .compatible = "mcp3008" }, + { .compatible = "mcp3201" }, + { .compatible = "mcp3202" }, + { .compatible = "mcp3204" }, + { .compatible = "mcp3208" }, + { .compatible = "mcp3301" }, + { .compatible = "microchip,mcp3001" }, + { .compatible = "microchip,mcp3002" }, + { .compatible = "microchip,mcp3004" }, + { .compatible = "microchip,mcp3008" }, + { .compatible = "microchip,mcp3201" }, + { .compatible = "microchip,mcp3202" }, + { .compatible = "microchip,mcp3204" }, + { .compatible = "microchip,mcp3208" }, + { .compatible = "microchip,mcp3301" }, + { .compatible = "microchip,mcp3550-50" }, + { .compatible = "microchip,mcp3550-60" }, + { .compatible = "microchip,mcp3551" }, + { .compatible = "microchip,mcp3553" }, + { } }; MODULE_DEVICE_TABLE(of, mcp320x_dt_ids); #endif @@ -433,6 +513,10 @@ static const struct spi_device_id mcp320x_id[] = { { "mcp3204", mcp3204 }, { "mcp3208", mcp3208 }, { "mcp3301", mcp3301 }, + { "mcp3550-50", mcp3550_50 }, + { "mcp3550-60", mcp3550_60 }, + { "mcp3551", mcp3551 }, + { "mcp3553", mcp3553 }, { } }; MODULE_DEVICE_TABLE(spi, mcp320x_id); @@ -449,5 +533,5 @@ static struct spi_driver mcp320x_driver = { module_spi_driver(mcp320x_driver); MODULE_AUTHOR("Oskar Andero <oskar.andero@gmail.com>"); -MODULE_DESCRIPTION("Microchip Technology MCP3x01/02/04/08"); +MODULE_DESCRIPTION("Microchip Technology MCP3x01/02/04/08 and MCP3550/1/3"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c index 254135e07792..819f26011500 100644 --- a/drivers/iio/adc/mcp3422.c +++ b/drivers/iio/adc/mcp3422.c @@ -327,7 +327,6 @@ static const struct iio_info mcp3422_info = { .write_raw = mcp3422_write_raw, .write_raw_get_fmt = mcp3422_write_raw_get_fmt, .attrs = &mcp3422_attribute_group, - .driver_module = THIS_MODULE, }; static int mcp3422_probe(struct i2c_client *client, @@ -379,10 +378,12 @@ static int mcp3422_probe(struct i2c_client *client, /* meaningful default configuration */ config = (MCP3422_CONT_SAMPLING - | MCP3422_CHANNEL_VALUE(1) + | MCP3422_CHANNEL_VALUE(0) | MCP3422_PGA_VALUE(MCP3422_PGA_1) | MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240)); - mcp3422_update_config(adc, config); + err = mcp3422_update_config(adc, config); + if (err < 0) + return err; err = devm_iio_device_register(&client->dev, indio_dev); if (err < 0) diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c index 8f3606de4eaf..c80261748d8f 100644 --- a/drivers/iio/adc/men_z188_adc.c +++ b/drivers/iio/adc/men_z188_adc.c @@ -80,7 +80,6 @@ static int z188_iio_read_raw(struct iio_dev *iio_dev, static const struct iio_info z188_adc_info = { .read_raw = &z188_iio_read_raw, - .driver_module = THIS_MODULE, }; static void men_z188_config_channels(void __iomem *addr) diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 83da50ed73ab..9c6932ffc0af 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -572,8 +572,8 @@ static int meson_sar_adc_clk_init(struct iio_dev *indio_dev, struct clk_init_data init; const char *clk_parents[1]; - init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_div", - of_node_full_name(indio_dev->dev.of_node)); + init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%pOF#adc_div", + indio_dev->dev.of_node); init.flags = 0; init.ops = &clk_divider_ops; clk_parents[0] = __clk_get_name(priv->clkin); @@ -591,8 +591,8 @@ static int meson_sar_adc_clk_init(struct iio_dev *indio_dev, if (WARN_ON(IS_ERR(priv->adc_div_clk))) return PTR_ERR(priv->adc_div_clk); - init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_en", - of_node_full_name(indio_dev->dev.of_node)); + init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%pOF#adc_en", + indio_dev->dev.of_node); init.flags = CLK_SET_RATE_PARENT; init.ops = &clk_gate_ops; clk_parents[0] = __clk_get_name(priv->adc_div_clk); @@ -840,7 +840,6 @@ out: static const struct iio_info meson_sar_adc_iio_info = { .read_raw = meson_sar_adc_iio_info_read_raw, - .driver_module = THIS_MODULE, }; static const struct meson_sar_adc_data meson_sar_adc_meson8_data = { @@ -915,6 +914,11 @@ static int meson_sar_adc_probe(struct platform_device *pdev) init_completion(&priv->done); match = of_match_device(meson_sar_adc_of_match, &pdev->dev); + if (!match) { + dev_err(&pdev->dev, "failed to match device\n"); + return -ENODEV; + } + priv->data = match->data; indio_dev->name = priv->data->name; diff --git a/drivers/iio/adc/mt6577_auxadc.c b/drivers/iio/adc/mt6577_auxadc.c index 2d104c828041..95d76abb64ec 100644 --- a/drivers/iio/adc/mt6577_auxadc.c +++ b/drivers/iio/adc/mt6577_auxadc.c @@ -180,10 +180,40 @@ static int mt6577_auxadc_read_raw(struct iio_dev *indio_dev, } static const struct iio_info mt6577_auxadc_info = { - .driver_module = THIS_MODULE, .read_raw = &mt6577_auxadc_read_raw, }; +static int __maybe_unused mt6577_auxadc_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev); + int ret; + + ret = clk_prepare_enable(adc_dev->adc_clk); + if (ret) { + pr_err("failed to enable auxadc clock\n"); + return ret; + } + + mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC, + MT6577_AUXADC_PDN_EN, 0); + mdelay(MT6577_AUXADC_POWER_READY_MS); + + return 0; +} + +static int __maybe_unused mt6577_auxadc_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev); + + mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC, + 0, MT6577_AUXADC_PDN_EN); + clk_disable_unprepare(adc_dev->adc_clk); + + return 0; +} + static int mt6577_auxadc_probe(struct platform_device *pdev) { struct mt6577_auxadc_device *adc_dev; @@ -269,8 +299,14 @@ static int mt6577_auxadc_remove(struct platform_device *pdev) return 0; } +static SIMPLE_DEV_PM_OPS(mt6577_auxadc_pm_ops, + mt6577_auxadc_suspend, + mt6577_auxadc_resume); + static const struct of_device_id mt6577_auxadc_of_match[] = { { .compatible = "mediatek,mt2701-auxadc", }, + { .compatible = "mediatek,mt2712-auxadc", }, + { .compatible = "mediatek,mt7622-auxadc", }, { .compatible = "mediatek,mt8173-auxadc", }, { } }; @@ -280,6 +316,7 @@ static struct platform_driver mt6577_auxadc_driver = { .driver = { .name = "mt6577-auxadc", .of_match_table = mt6577_auxadc_of_match, + .pm = &mt6577_auxadc_pm_ops, }, .probe = mt6577_auxadc_probe, .remove = mt6577_auxadc_remove, diff --git a/drivers/iio/adc/mxs-lradc-adc.c b/drivers/iio/adc/mxs-lradc-adc.c index d32b34638c2f..c627513d9f0f 100644 --- a/drivers/iio/adc/mxs-lradc-adc.c +++ b/drivers/iio/adc/mxs-lradc-adc.c @@ -382,7 +382,6 @@ static const struct attribute_group mxs_lradc_adc_attribute_group = { }; static const struct iio_info mxs_lradc_adc_iio_info = { - .driver_module = THIS_MODULE, .read_raw = mxs_lradc_adc_read_raw, .write_raw = mxs_lradc_adc_write_raw, .write_raw_get_fmt = mxs_lradc_adc_write_raw_get_fmt, @@ -455,7 +454,6 @@ static int mxs_lradc_adc_configure_trigger(struct iio_trigger *trig, bool state) } static const struct iio_trigger_ops mxs_lradc_adc_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = &mxs_lradc_adc_configure_trigger, }; diff --git a/drivers/iio/adc/nau7802.c b/drivers/iio/adc/nau7802.c index 08f446695f97..8997e74a8847 100644 --- a/drivers/iio/adc/nau7802.c +++ b/drivers/iio/adc/nau7802.c @@ -402,7 +402,6 @@ static int nau7802_write_raw_get_fmt(struct iio_dev *indio_dev, } static const struct iio_info nau7802_info = { - .driver_module = THIS_MODULE, .read_raw = &nau7802_read_raw, .write_raw = &nau7802_write_raw, .write_raw_get_fmt = nau7802_write_raw_get_fmt, diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c index 7d61b566e148..69b9affeef1e 100644 --- a/drivers/iio/adc/palmas_gpadc.c +++ b/drivers/iio/adc/palmas_gpadc.c @@ -430,7 +430,6 @@ out: static const struct iio_info palmas_gpadc_iio_info = { .read_raw = palmas_gpadc_read_raw, - .driver_module = THIS_MODULE, }; #define PALMAS_ADC_CHAN_IIO(chan, _type, chan_info) \ diff --git a/drivers/iio/adc/qcom-pm8xxx-xoadc.c b/drivers/iio/adc/qcom-pm8xxx-xoadc.c index cea8f1fb444a..b093ecddf1a8 100644 --- a/drivers/iio/adc/qcom-pm8xxx-xoadc.c +++ b/drivers/iio/adc/qcom-pm8xxx-xoadc.c @@ -728,7 +728,6 @@ static int pm8xxx_of_xlate(struct iio_dev *indio_dev, } static const struct iio_info pm8xxx_xoadc_info = { - .driver_module = THIS_MODULE, .of_xlate = pm8xxx_of_xlate, .read_raw = pm8xxx_read_raw, }; diff --git a/drivers/iio/adc/qcom-spmi-iadc.c b/drivers/iio/adc/qcom-spmi-iadc.c index fabd24edc2a1..3f062cd61aba 100644 --- a/drivers/iio/adc/qcom-spmi-iadc.c +++ b/drivers/iio/adc/qcom-spmi-iadc.c @@ -356,7 +356,6 @@ static int iadc_read_raw(struct iio_dev *indio_dev, static const struct iio_info iadc_info = { .read_raw = iadc_read_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t iadc_isr(int irq, void *dev_id) diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c index 9e600bfd1765..3680e0d47412 100644 --- a/drivers/iio/adc/qcom-spmi-vadc.c +++ b/drivers/iio/adc/qcom-spmi-vadc.c @@ -506,7 +506,6 @@ static int vadc_of_xlate(struct iio_dev *indio_dev, static const struct iio_info vadc_info = { .read_raw = vadc_read_raw, .of_xlate = vadc_of_xlate, - .driver_module = THIS_MODULE, }; struct vadc_channels { diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c index 102fc51b10aa..47d24ae5462f 100644 --- a/drivers/iio/adc/qcom-vadc-common.c +++ b/drivers/iio/adc/qcom-vadc-common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/bug.h> #include <linux/kernel.h> #include <linux/bitops.h> diff --git a/drivers/iio/adc/qcom-vadc-common.h b/drivers/iio/adc/qcom-vadc-common.h index 63c872a70adc..1d5354ff5c72 100644 --- a/drivers/iio/adc/qcom-vadc-common.h +++ b/drivers/iio/adc/qcom-vadc-common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Code shared between the different Qualcomm PMIC voltage ADCs */ diff --git a/drivers/iio/adc/rcar-gyroadc.c b/drivers/iio/adc/rcar-gyroadc.c index 27a318164619..dcb50172186f 100644 --- a/drivers/iio/adc/rcar-gyroadc.c +++ b/drivers/iio/adc/rcar-gyroadc.c @@ -277,7 +277,6 @@ static int rcar_gyroadc_reg_access(struct iio_dev *indio_dev, } static const struct iio_info rcar_gyroadc_iio_info = { - .driver_module = THIS_MODULE, .read_raw = rcar_gyroadc_read_raw, .debugfs_reg_access = rcar_gyroadc_reg_access, }; @@ -349,7 +348,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) continue; } - childmode = (unsigned int)of_id->data; + childmode = (uintptr_t)of_id->data; switch (childmode) { case RCAR_GYROADC_MODE_SELECT_1_MB88101A: sample_width = 12; @@ -488,8 +487,6 @@ err: static int rcar_gyroadc_probe(struct platform_device *pdev) { - const struct of_device_id *of_id = - of_match_device(rcar_gyroadc_match, &pdev->dev); struct device *dev = &pdev->dev; struct rcar_gyroadc *priv; struct iio_dev *indio_dev; @@ -526,7 +523,8 @@ static int rcar_gyroadc_probe(struct platform_device *pdev) if (ret) return ret; - priv->model = (enum rcar_gyroadc_model)of_id->data; + priv->model = (enum rcar_gyroadc_model) + of_device_get_match_data(&pdev->dev); platform_set_drvdata(pdev, indio_dev); diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index ae6d3324f518..1f98566d5b3c 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c @@ -125,7 +125,6 @@ static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id) static const struct iio_info rockchip_saradc_iio_info = { .read_raw = rockchip_saradc_read_raw, - .driver_module = THIS_MODULE, }; #define ADC_CHANNEL(_index, _id) { \ @@ -224,6 +223,11 @@ static int rockchip_saradc_probe(struct platform_device *pdev) info = iio_priv(indio_dev); match = of_match_device(rockchip_saradc_match, &pdev->dev); + if (!match) { + dev_err(&pdev->dev, "failed to match device\n"); + return -ENODEV; + } + info->data = match->data; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -235,7 +239,8 @@ static int rockchip_saradc_probe(struct platform_device *pdev) * The reset should be an optional property, as it should work * with old devicetrees as well */ - info->reset = devm_reset_control_get(&pdev->dev, "saradc-apb"); + info->reset = devm_reset_control_get_exclusive(&pdev->dev, + "saradc-apb"); if (IS_ERR(info->reset)) { ret = PTR_ERR(info->reset); if (ret != -ENOENT) diff --git a/drivers/iio/adc/spear_adc.c b/drivers/iio/adc/spear_adc.c index 5dd61f6a57b9..b1da2c46107c 100644 --- a/drivers/iio/adc/spear_adc.c +++ b/drivers/iio/adc/spear_adc.c @@ -254,7 +254,6 @@ static int spear_adc_configure(struct spear_adc_state *st) static const struct iio_info spear_adc_info = { .read_raw = &spear_adc_read_raw, .write_raw = &spear_adc_write_raw, - .driver_module = THIS_MODULE, }; static int spear_adc_probe(struct platform_device *pdev) diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index e09233b03c05..6aefef99f935 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -64,7 +64,7 @@ #define STM32H7_CKMODE_MASK GENMASK(17, 16) /* STM32 H7 maximum analog clock rate (from datasheet) */ -#define STM32H7_ADC_MAX_CLK_RATE 72000000 +#define STM32H7_ADC_MAX_CLK_RATE 36000000 /** * stm32_adc_common_regs - stm32 common registers, compatible dependent data @@ -139,6 +139,11 @@ static int stm32f4_adc_clk_sel(struct platform_device *pdev, } rate = clk_get_rate(priv->aclk); + if (!rate) { + dev_err(&pdev->dev, "Invalid clock rate: 0\n"); + return -EINVAL; + } + for (i = 0; i < ARRAY_SIZE(stm32f4_pclk_div); i++) { if ((rate / stm32f4_pclk_div[i]) <= STM32F4_ADC_MAX_CLK_RATE) break; @@ -148,14 +153,14 @@ static int stm32f4_adc_clk_sel(struct platform_device *pdev, return -EINVAL; } - priv->common.rate = rate; + priv->common.rate = rate / stm32f4_pclk_div[i]; val = readl_relaxed(priv->common.base + STM32F4_ADC_CCR); val &= ~STM32F4_ADC_ADCPRE_MASK; val |= i << STM32F4_ADC_ADCPRE_SHIFT; writel_relaxed(val, priv->common.base + STM32F4_ADC_CCR); dev_dbg(&pdev->dev, "Using analog clock source at %ld kHz\n", - rate / (stm32f4_pclk_div[i] * 1000)); + priv->common.rate / 1000); return 0; } @@ -172,7 +177,7 @@ struct stm32h7_adc_ck_spec { int div; }; -const struct stm32h7_adc_ck_spec stm32h7_adc_ckmodes_spec[] = { +static const struct stm32h7_adc_ck_spec stm32h7_adc_ckmodes_spec[] = { /* 00: CK_ADC[1..3]: Asynchronous clock modes */ { 0, 0, 1 }, { 0, 1, 2 }, @@ -216,6 +221,10 @@ static int stm32h7_adc_clk_sel(struct platform_device *pdev, * From spec: PLL output musn't exceed max rate */ rate = clk_get_rate(priv->aclk); + if (!rate) { + dev_err(&pdev->dev, "Invalid adc clock rate: 0\n"); + return -EINVAL; + } for (i = 0; i < ARRAY_SIZE(stm32h7_adc_ckmodes_spec); i++) { ckmode = stm32h7_adc_ckmodes_spec[i].ckmode; @@ -232,6 +241,10 @@ static int stm32h7_adc_clk_sel(struct platform_device *pdev, /* Synchronous clock modes (e.g. ckmode is 1, 2 or 3) */ rate = clk_get_rate(priv->bclk); + if (!rate) { + dev_err(&pdev->dev, "Invalid bus clock rate: 0\n"); + return -EINVAL; + } for (i = 0; i < ARRAY_SIZE(stm32h7_adc_ckmodes_spec); i++) { ckmode = stm32h7_adc_ckmodes_spec[i].ckmode; @@ -250,7 +263,7 @@ static int stm32h7_adc_clk_sel(struct platform_device *pdev, out: /* rate used later by each ADC instance to control BOOST mode */ - priv->common.rate = rate; + priv->common.rate = rate / div; /* Set common clock mode and prescaler */ val = readl_relaxed(priv->common.base + STM32H7_ADC_CCR); @@ -260,7 +273,7 @@ out: writel_relaxed(val, priv->common.base + STM32H7_ADC_CCR); dev_dbg(&pdev->dev, "Using %s clock/%d source at %ld kHz\n", - ckmode ? "bus" : "adc", div, rate / (div * 1000)); + ckmode ? "bus" : "adc", div, priv->common.rate / 1000); return 0; } diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 5bfcc1f13105..c9d96f935dba 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -25,6 +25,7 @@ #include <linux/dmaengine.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> +#include <linux/iio/timer/stm32-lptim-trigger.h> #include <linux/iio/timer/stm32-timer-trigger.h> #include <linux/iio/trigger.h> #include <linux/iio/trigger_consumer.h> @@ -83,6 +84,8 @@ #define STM32H7_ADC_IER 0x04 #define STM32H7_ADC_CR 0x08 #define STM32H7_ADC_CFGR 0x0C +#define STM32H7_ADC_SMPR1 0x14 +#define STM32H7_ADC_SMPR2 0x18 #define STM32H7_ADC_PCSEL 0x1C #define STM32H7_ADC_SQR1 0x30 #define STM32H7_ADC_SQR2 0x34 @@ -151,6 +154,7 @@ enum stm32h7_adc_dmngt { #define STM32H7_BOOST_CLKRATE 20000000UL #define STM32_ADC_MAX_SQ 16 /* SQ1..SQ16 */ +#define STM32_ADC_MAX_SMP 7 /* SMPx range is [0..7] */ #define STM32_ADC_TIMEOUT_US 100000 #define STM32_ADC_TIMEOUT (msecs_to_jiffies(STM32_ADC_TIMEOUT_US / 1000)) @@ -182,6 +186,11 @@ enum stm32_adc_extsel { STM32_EXT13, STM32_EXT14, STM32_EXT15, + STM32_EXT16, + STM32_EXT17, + STM32_EXT18, + STM32_EXT19, + STM32_EXT20, }; /** @@ -227,6 +236,8 @@ struct stm32_adc_regs { * @exten: trigger control register & bitfield * @extsel: trigger selection register & bitfield * @res: resolution selection register & bitfield + * @smpr: smpr1 & smpr2 registers offset array + * @smp_bits: smpr1 & smpr2 index and bitfields */ struct stm32_adc_regspec { const u32 dr; @@ -236,6 +247,8 @@ struct stm32_adc_regspec { const struct stm32_adc_regs exten; const struct stm32_adc_regs extsel; const struct stm32_adc_regs res; + const u32 smpr[2]; + const struct stm32_adc_regs *smp_bits; }; struct stm32_adc; @@ -251,6 +264,7 @@ struct stm32_adc; * @start_conv: routine to start conversions * @stop_conv: routine to stop conversions * @unprepare: optional unprepare routine (disable, power-down) + * @smp_cycles: programmable sampling time (ADC clock cycles) */ struct stm32_adc_cfg { const struct stm32_adc_regspec *regs; @@ -262,6 +276,7 @@ struct stm32_adc_cfg { void (*start_conv)(struct stm32_adc *, bool dma); void (*stop_conv)(struct stm32_adc *); void (*unprepare)(struct stm32_adc *); + const unsigned int *smp_cycles; }; /** @@ -283,6 +298,7 @@ struct stm32_adc_cfg { * @rx_dma_buf: dma rx buffer bus address * @rx_buf_sz: dma rx buffer size * @pcsel bitmask to preselect channels on some devices + * @smpr_val: sampling time settings (e.g. smpr1 / smpr2) * @cal: optional calibration data on some devices */ struct stm32_adc { @@ -303,6 +319,7 @@ struct stm32_adc { dma_addr_t rx_dma_buf; unsigned int rx_buf_sz; u32 pcsel; + u32 smpr_val[2]; struct stm32_adc_calib cal; }; @@ -431,6 +448,39 @@ static struct stm32_adc_trig_info stm32f4_adc_trigs[] = { {}, /* sentinel */ }; +/** + * stm32f4_smp_bits[] - describe sampling time register index & bit fields + * Sorted so it can be indexed by channel number. + */ +static const struct stm32_adc_regs stm32f4_smp_bits[] = { + /* STM32F4_ADC_SMPR2: smpr[] index, mask, shift for SMP0 to SMP9 */ + { 1, GENMASK(2, 0), 0 }, + { 1, GENMASK(5, 3), 3 }, + { 1, GENMASK(8, 6), 6 }, + { 1, GENMASK(11, 9), 9 }, + { 1, GENMASK(14, 12), 12 }, + { 1, GENMASK(17, 15), 15 }, + { 1, GENMASK(20, 18), 18 }, + { 1, GENMASK(23, 21), 21 }, + { 1, GENMASK(26, 24), 24 }, + { 1, GENMASK(29, 27), 27 }, + /* STM32F4_ADC_SMPR1, smpr[] index, mask, shift for SMP10 to SMP18 */ + { 0, GENMASK(2, 0), 0 }, + { 0, GENMASK(5, 3), 3 }, + { 0, GENMASK(8, 6), 6 }, + { 0, GENMASK(11, 9), 9 }, + { 0, GENMASK(14, 12), 12 }, + { 0, GENMASK(17, 15), 15 }, + { 0, GENMASK(20, 18), 18 }, + { 0, GENMASK(23, 21), 21 }, + { 0, GENMASK(26, 24), 24 }, +}; + +/* STM32F4 programmable sampling time (ADC clock cycles) */ +static const unsigned int stm32f4_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = { + 3, 15, 28, 56, 84, 112, 144, 480, +}; + static const struct stm32_adc_regspec stm32f4_adc_regspec = { .dr = STM32F4_ADC_DR, .ier_eoc = { STM32F4_ADC_CR1, STM32F4_EOCIE }, @@ -440,6 +490,8 @@ static const struct stm32_adc_regspec stm32f4_adc_regspec = { .extsel = { STM32F4_ADC_CR2, STM32F4_EXTSEL_MASK, STM32F4_EXTSEL_SHIFT }, .res = { STM32F4_ADC_CR1, STM32F4_RES_MASK, STM32F4_RES_SHIFT }, + .smpr = { STM32F4_ADC_SMPR1, STM32F4_ADC_SMPR2 }, + .smp_bits = stm32f4_smp_bits, }; static const struct stm32_adc_regs stm32h7_sq[STM32_ADC_MAX_SQ + 1] = { @@ -479,10 +531,48 @@ static struct stm32_adc_trig_info stm32h7_adc_trigs[] = { { TIM2_TRGO, STM32_EXT11 }, { TIM4_TRGO, STM32_EXT12 }, { TIM6_TRGO, STM32_EXT13 }, + { TIM15_TRGO, STM32_EXT14 }, { TIM3_CH4, STM32_EXT15 }, + { LPTIM1_OUT, STM32_EXT18 }, + { LPTIM2_OUT, STM32_EXT19 }, + { LPTIM3_OUT, STM32_EXT20 }, {}, }; +/** + * stm32h7_smp_bits - describe sampling time register index & bit fields + * Sorted so it can be indexed by channel number. + */ +static const struct stm32_adc_regs stm32h7_smp_bits[] = { + /* STM32H7_ADC_SMPR1, smpr[] index, mask, shift for SMP0 to SMP9 */ + { 0, GENMASK(2, 0), 0 }, + { 0, GENMASK(5, 3), 3 }, + { 0, GENMASK(8, 6), 6 }, + { 0, GENMASK(11, 9), 9 }, + { 0, GENMASK(14, 12), 12 }, + { 0, GENMASK(17, 15), 15 }, + { 0, GENMASK(20, 18), 18 }, + { 0, GENMASK(23, 21), 21 }, + { 0, GENMASK(26, 24), 24 }, + { 0, GENMASK(29, 27), 27 }, + /* STM32H7_ADC_SMPR2, smpr[] index, mask, shift for SMP10 to SMP19 */ + { 1, GENMASK(2, 0), 0 }, + { 1, GENMASK(5, 3), 3 }, + { 1, GENMASK(8, 6), 6 }, + { 1, GENMASK(11, 9), 9 }, + { 1, GENMASK(14, 12), 12 }, + { 1, GENMASK(17, 15), 15 }, + { 1, GENMASK(20, 18), 18 }, + { 1, GENMASK(23, 21), 21 }, + { 1, GENMASK(26, 24), 24 }, + { 1, GENMASK(29, 27), 27 }, +}; + +/* STM32H7 programmable sampling time (ADC clock cycles, rounded down) */ +static const unsigned int stm32h7_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = { + 1, 2, 8, 16, 32, 64, 387, 810, +}; + static const struct stm32_adc_regspec stm32h7_adc_regspec = { .dr = STM32H7_ADC_DR, .ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE }, @@ -492,6 +582,8 @@ static const struct stm32_adc_regspec stm32h7_adc_regspec = { .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK, STM32H7_EXTSEL_SHIFT }, .res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT }, + .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, + .smp_bits = stm32h7_smp_bits, }; /** @@ -933,6 +1025,7 @@ static void stm32h7_adc_unprepare(struct stm32_adc *adc) * @scan_mask: channels to be converted * * Conversion sequence : + * Apply sampling time settings for all channels. * Configure ADC scan sequence based on selected channels in scan_mask. * Add channels to SQR registers, from scan_mask LSB to MSB, then * program sequence len. @@ -946,6 +1039,10 @@ static int stm32_adc_conf_scan_seq(struct iio_dev *indio_dev, u32 val, bit; int i = 0; + /* Apply sampling time settings */ + stm32_adc_writel(adc, adc->cfg->regs->smpr[0], adc->smpr_val[0]); + stm32_adc_writel(adc, adc->cfg->regs->smpr[1], adc->smpr_val[1]); + for_each_set_bit(bit, scan_mask, indio_dev->masklength) { chan = indio_dev->channels + bit; /* @@ -995,7 +1092,8 @@ static int stm32_adc_get_trig_extsel(struct iio_dev *indio_dev, * Checking both stm32 timer trigger type and trig name * should be safe against arbitrary trigger names. */ - if (is_stm32_timer_trigger(trig) && + if ((is_stm32_timer_trigger(trig) || + is_stm32_lptim_trigger(trig)) && !strcmp(adc->cfg->trigs[i].name, trig->name)) { return adc->cfg->trigs[i].extsel; } @@ -1079,6 +1177,7 @@ static const struct iio_enum stm32_adc_trig_pol = { * @res: conversion result * * The function performs a single conversion on a given channel: + * - Apply sampling time settings * - Program sequencer with one channel (e.g. in SQ1 with len = 1) * - Use SW trigger * - Start conversion, then wait for interrupt completion. @@ -1103,6 +1202,10 @@ static int stm32_adc_single_conv(struct iio_dev *indio_dev, return ret; } + /* Apply sampling time settings */ + stm32_adc_writel(adc, regs->smpr[0], adc->smpr_val[0]); + stm32_adc_writel(adc, regs->smpr[1], adc->smpr_val[1]); + /* Program chan number in regular sequence (SQ1) */ val = stm32_adc_readl(adc, regs->sqr[1].reg); val &= ~regs->sqr[1].mask; @@ -1283,7 +1386,6 @@ static const struct iio_info stm32_adc_iio_info = { .update_scan_mode = stm32_adc_update_scan_mode, .debugfs_reg_access = stm32_adc_debugfs_reg_access, .of_xlate = stm32_adc_of_xlate, - .driver_module = THIS_MODULE, }; static unsigned int stm32_adc_dma_residue(struct stm32_adc *adc) @@ -1507,10 +1609,28 @@ static int stm32_adc_of_get_resolution(struct iio_dev *indio_dev) return 0; } +static void stm32_adc_smpr_init(struct stm32_adc *adc, int channel, u32 smp_ns) +{ + const struct stm32_adc_regs *smpr = &adc->cfg->regs->smp_bits[channel]; + u32 period_ns, shift = smpr->shift, mask = smpr->mask; + unsigned int smp, r = smpr->reg; + + /* Determine sampling time (ADC clock cycles) */ + period_ns = NSEC_PER_SEC / adc->common->rate; + for (smp = 0; smp <= STM32_ADC_MAX_SMP; smp++) + if ((period_ns * adc->cfg->smp_cycles[smp]) >= smp_ns) + break; + if (smp > STM32_ADC_MAX_SMP) + smp = STM32_ADC_MAX_SMP; + + /* pre-build sampling time registers (e.g. smpr1, smpr2) */ + adc->smpr_val[r] = (adc->smpr_val[r] & ~mask) | (smp << shift); +} + static void stm32_adc_chan_init_one(struct iio_dev *indio_dev, struct iio_chan_spec *chan, const struct stm32_adc_chan_spec *channel, - int scan_index) + int scan_index, u32 smp) { struct stm32_adc *adc = iio_priv(indio_dev); @@ -1526,6 +1646,9 @@ static void stm32_adc_chan_init_one(struct iio_dev *indio_dev, chan->scan_type.storagebits = 16; chan->ext_info = stm32_adc_ext_info; + /* Prepare sampling time settings */ + stm32_adc_smpr_init(adc, chan->channel, smp); + /* pre-build selected channels mask */ adc->pcsel |= BIT(chan->channel); } @@ -1538,16 +1661,23 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev) struct property *prop; const __be32 *cur; struct iio_chan_spec *channels; - int scan_index = 0, num_channels; - u32 val; + int scan_index = 0, num_channels, ret; + u32 val, smp = 0; num_channels = of_property_count_u32_elems(node, "st,adc-channels"); if (num_channels < 0 || - num_channels >= adc_info->max_channels) { + num_channels > adc_info->max_channels) { dev_err(&indio_dev->dev, "Bad st,adc-channels?\n"); return num_channels < 0 ? num_channels : -EINVAL; } + /* Optional sample time is provided either for each, or all channels */ + ret = of_property_count_u32_elems(node, "st,min-sample-time-nsecs"); + if (ret > 1 && ret != num_channels) { + dev_err(&indio_dev->dev, "Invalid st,min-sample-time-nsecs\n"); + return -EINVAL; + } + channels = devm_kcalloc(&indio_dev->dev, num_channels, sizeof(struct iio_chan_spec), GFP_KERNEL); if (!channels) @@ -1558,9 +1688,19 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev) dev_err(&indio_dev->dev, "Invalid channel %d\n", val); return -EINVAL; } + + /* + * Using of_property_read_u32_index(), smp value will only be + * modified if valid u32 value can be decoded. This allows to + * get either no value, 1 shared value for all indexes, or one + * value per channel. + */ + of_property_read_u32_index(node, "st,min-sample-time-nsecs", + scan_index, &smp); + stm32_adc_chan_init_one(indio_dev, &channels[scan_index], &adc_info->channels[val], - scan_index); + scan_index, smp); scan_index++; } @@ -1634,7 +1774,7 @@ static int stm32_adc_probe(struct platform_device *pdev) indio_dev->dev.parent = &pdev->dev; indio_dev->dev.of_node = pdev->dev.of_node; indio_dev->info = &stm32_adc_iio_info; - indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->modes = INDIO_DIRECT_MODE | INDIO_HARDWARE_TRIGGERED; platform_set_drvdata(pdev, adc); @@ -1755,6 +1895,7 @@ static const struct stm32_adc_cfg stm32f4_adc_cfg = { .clk_required = true, .start_conv = stm32f4_adc_start_conv, .stop_conv = stm32f4_adc_stop_conv, + .smp_cycles = stm32f4_adc_smp_cycles, }; static const struct stm32_adc_cfg stm32h7_adc_cfg = { @@ -1766,6 +1907,7 @@ static const struct stm32_adc_cfg stm32h7_adc_cfg = { .stop_conv = stm32h7_adc_stop_conv, .prepare = stm32h7_adc_prepare, .unprepare = stm32h7_adc_unprepare, + .smp_cycles = stm32h7_adc_smp_cycles, }; static const struct of_device_id stm32_adc_of_match[] = { diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c index 2da741d27540..17b021f33180 100644 --- a/drivers/iio/adc/stx104.c +++ b/drivers/iio/adc/stx104.c @@ -172,7 +172,6 @@ static int stx104_write_raw(struct iio_dev *indio_dev, } static const struct iio_info stx104_info = { - .driver_module = THIS_MODULE, .read_raw = stx104_read_raw, .write_raw = stx104_write_raw }; diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c index 81d4c39e414a..04d7147e0110 100644 --- a/drivers/iio/adc/sun4i-gpadc-iio.c +++ b/drivers/iio/adc/sun4i-gpadc-iio.c @@ -256,6 +256,7 @@ static int sun4i_gpadc_read(struct iio_dev *indio_dev, int channel, int *val, err: pm_runtime_put_autosuspend(indio_dev->dev.parent); + disable_irq(irq); mutex_unlock(&info->mutex); return ret; @@ -351,7 +352,6 @@ static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev, static const struct iio_info sun4i_gpadc_iio_info = { .read_raw = sun4i_gpadc_read_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t sun4i_gpadc_temp_data_irq_handler(int irq, void *dev_id) @@ -365,7 +365,6 @@ static irqreturn_t sun4i_gpadc_temp_data_irq_handler(int irq, void *dev_id) complete(&info->completion); out: - disable_irq_nosync(info->temp_data_irq); return IRQ_HANDLED; } @@ -380,7 +379,6 @@ static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id) complete(&info->completion); out: - disable_irq_nosync(info->fifo_data_irq); return IRQ_HANDLED; } @@ -503,17 +501,15 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, struct iio_dev *indio_dev) { struct sun4i_gpadc_iio *info = iio_priv(indio_dev); - const struct of_device_id *of_dev; struct resource *mem; void __iomem *base; int ret; - of_dev = of_match_device(sun4i_gpadc_of_id, &pdev->dev); - if (!of_dev) + info->data = of_device_get_match_data(&pdev->dev); + if (!info->data) return -ENODEV; info->no_irq = true; - info->data = (struct gpadc_data *)of_dev->data; indio_dev->num_channels = ARRAY_SIZE(sun8i_a33_gpadc_channels); indio_dev->channels = sun8i_a33_gpadc_channels; @@ -530,17 +526,10 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, return ret; } - if (!IS_ENABLED(CONFIG_THERMAL_OF)) - return 0; + if (IS_ENABLED(CONFIG_THERMAL_OF)) + info->sensor_device = &pdev->dev; - info->sensor_device = &pdev->dev; - info->tzd = thermal_zone_of_sensor_register(info->sensor_device, 0, - info, &sun4i_ts_tz_ops); - if (IS_ERR(info->tzd)) - dev_err(&pdev->dev, "could not register thermal sensor: %ld\n", - PTR_ERR(info->tzd)); - - return PTR_ERR_OR_ZERO(info->tzd); + return 0; } static int sun4i_gpadc_probe_mfd(struct platform_device *pdev, @@ -587,15 +576,6 @@ static int sun4i_gpadc_probe_mfd(struct platform_device *pdev, * return the temperature. */ info->sensor_device = pdev->dev.parent; - info->tzd = thermal_zone_of_sensor_register(info->sensor_device, - 0, info, - &sun4i_ts_tz_ops); - if (IS_ERR(info->tzd)) { - dev_err(&pdev->dev, - "could not register thermal sensor: %ld\n", - PTR_ERR(info->tzd)); - return PTR_ERR(info->tzd); - } } else { indio_dev->num_channels = ARRAY_SIZE(sun4i_gpadc_channels_no_temp); @@ -665,6 +645,22 @@ static int sun4i_gpadc_probe(struct platform_device *pdev) pm_runtime_set_suspended(&pdev->dev); pm_runtime_enable(&pdev->dev); + if (IS_ENABLED(CONFIG_THERMAL_OF)) { + info->tzd = thermal_zone_of_sensor_register(info->sensor_device, + 0, info, + &sun4i_ts_tz_ops); + /* + * Do not fail driver probing when failing to register in + * thermal because no thermal DT node is found. + */ + if (IS_ERR(info->tzd) && PTR_ERR(info->tzd) != -ENODEV) { + dev_err(&pdev->dev, + "could not register thermal sensor: %ld\n", + PTR_ERR(info->tzd)); + return PTR_ERR(info->tzd); + } + } + ret = devm_iio_device_register(&pdev->dev, indio_dev); if (ret < 0) { dev_err(&pdev->dev, "could not register the device\n"); diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c index 319172cf7da8..405e3779c0c5 100644 --- a/drivers/iio/adc/ti-adc081c.c +++ b/drivers/iio/adc/ti-adc081c.c @@ -124,7 +124,6 @@ static struct adcxx1c_model adcxx1c_models[] = { static const struct iio_info adc081c_info = { .read_raw = adc081c_read_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t adc081c_trigger_handler(int irq, void *p) diff --git a/drivers/iio/adc/ti-adc0832.c b/drivers/iio/adc/ti-adc0832.c index e952e94a14af..188dae705bf7 100644 --- a/drivers/iio/adc/ti-adc0832.c +++ b/drivers/iio/adc/ti-adc0832.c @@ -195,7 +195,6 @@ static int adc0832_read_raw(struct iio_dev *iio, static const struct iio_info adc0832_info = { .read_raw = adc0832_read_raw, - .driver_module = THIS_MODULE, }; static irqreturn_t adc0832_trigger_handler(int irq, void *p) diff --git a/drivers/iio/adc/ti-adc084s021.c b/drivers/iio/adc/ti-adc084s021.c index a355121c11a4..25504640e126 100644 --- a/drivers/iio/adc/ti-adc084s021.c +++ b/drivers/iio/adc/ti-adc084s021.c @@ -186,7 +186,6 @@ static int adc084s021_buffer_postdisable(struct iio_dev *indio_dev) static const struct iio_info adc084s021_info = { .read_raw = adc084s021_read_raw, - .driver_module = THIS_MODULE, }; static const struct iio_buffer_setup_ops adc084s021_buffer_setup_ops = { diff --git a/drivers/iio/adc/ti-adc108s102.c b/drivers/iio/adc/ti-adc108s102.c index de4e5ac98c6e..841203edaac5 100644 --- a/drivers/iio/adc/ti-adc108s102.c +++ b/drivers/iio/adc/ti-adc108s102.c @@ -220,7 +220,6 @@ static int adc108s102_read_raw(struct iio_dev *indio_dev, static const struct iio_info adc108s102_info = { .read_raw = &adc108s102_read_raw, .update_scan_mode = &adc108s102_update_scan_mode, - .driver_module = THIS_MODULE, }; static int adc108s102_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ti-adc12138.c b/drivers/iio/adc/ti-adc12138.c index 072f03bfe6a0..703d68ae96b7 100644 --- a/drivers/iio/adc/ti-adc12138.c +++ b/drivers/iio/adc/ti-adc12138.c @@ -164,7 +164,7 @@ static int __adc12138_start_conv(struct adc12138 *adc, void *data, int len) { - const u8 ch_to_mux[] = { 0, 4, 1, 5, 2, 6, 3, 7 }; + static const u8 ch_to_mux[] = { 0, 4, 1, 5, 2, 6, 3, 7 }; u8 mode = (ch_to_mux[channel->channel] << 4) | (channel->differential ? 0 : 0x80); @@ -277,7 +277,6 @@ static int adc12138_read_raw(struct iio_dev *iio, static const struct iio_info adc12138_info = { .read_raw = adc12138_read_raw, - .driver_module = THIS_MODULE, }; static int adc12138_init(struct adc12138 *adc) diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c index 89dfbd31be5c..7cf39b3e2416 100644 --- a/drivers/iio/adc/ti-adc128s052.c +++ b/drivers/iio/adc/ti-adc128s052.c @@ -130,7 +130,6 @@ static const struct adc128_configuration adc128_config[] = { static const struct iio_info adc128_info = { .read_raw = adc128_read_raw, - .driver_module = THIS_MODULE, }; static int adc128_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ti-adc161s626.c b/drivers/iio/adc/ti-adc161s626.c index 4836a0d7aef5..10fa7677ac4b 100644 --- a/drivers/iio/adc/ti-adc161s626.c +++ b/drivers/iio/adc/ti-adc161s626.c @@ -173,7 +173,6 @@ static int ti_adc_read_raw(struct iio_dev *indio_dev, } static const struct iio_info ti_adc_info = { - .driver_module = THIS_MODULE, .read_raw = ti_adc_read_raw, }; diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 884b8e461b17..6a114dcb4a3a 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -17,6 +17,7 @@ #include <linux/module.h> #include <linux/of_device.h> #include <linux/init.h> +#include <linux/irq.h> #include <linux/i2c.h> #include <linux/regmap.h> #include <linux/pm_runtime.h> @@ -28,6 +29,7 @@ #include <linux/iio/iio.h> #include <linux/iio/types.h> #include <linux/iio/sysfs.h> +#include <linux/iio/events.h> #include <linux/iio/buffer.h> #include <linux/iio/triggered_buffer.h> #include <linux/iio/trigger_consumer.h> @@ -36,17 +38,38 @@ #define ADS1015_CONV_REG 0x00 #define ADS1015_CFG_REG 0x01 +#define ADS1015_LO_THRESH_REG 0x02 +#define ADS1015_HI_THRESH_REG 0x03 +#define ADS1015_CFG_COMP_QUE_SHIFT 0 +#define ADS1015_CFG_COMP_LAT_SHIFT 2 +#define ADS1015_CFG_COMP_POL_SHIFT 3 +#define ADS1015_CFG_COMP_MODE_SHIFT 4 #define ADS1015_CFG_DR_SHIFT 5 #define ADS1015_CFG_MOD_SHIFT 8 #define ADS1015_CFG_PGA_SHIFT 9 #define ADS1015_CFG_MUX_SHIFT 12 +#define ADS1015_CFG_COMP_QUE_MASK GENMASK(1, 0) +#define ADS1015_CFG_COMP_LAT_MASK BIT(2) +#define ADS1015_CFG_COMP_POL_MASK BIT(3) +#define ADS1015_CFG_COMP_MODE_MASK BIT(4) #define ADS1015_CFG_DR_MASK GENMASK(7, 5) #define ADS1015_CFG_MOD_MASK BIT(8) #define ADS1015_CFG_PGA_MASK GENMASK(11, 9) #define ADS1015_CFG_MUX_MASK GENMASK(14, 12) +/* Comparator queue and disable field */ +#define ADS1015_CFG_COMP_DISABLE 3 + +/* Comparator polarity field */ +#define ADS1015_CFG_COMP_POL_LOW 0 +#define ADS1015_CFG_COMP_POL_HIGH 1 + +/* Comparator mode field */ +#define ADS1015_CFG_COMP_MODE_TRAD 0 +#define ADS1015_CFG_COMP_MODE_WINDOW 1 + /* device operating modes */ #define ADS1015_CONTINUOUS 0 #define ADS1015_SINGLESHOT 1 @@ -81,18 +104,36 @@ static const unsigned int ads1115_data_rate[] = { 8, 16, 32, 64, 128, 250, 475, 860 }; -static const struct { - int scale; - int uscale; -} ads1015_scale[] = { - {3, 0}, - {2, 0}, - {1, 0}, - {0, 500000}, - {0, 250000}, - {0, 125000}, - {0, 125000}, - {0, 125000}, +/* + * Translation from PGA bits to full-scale positive and negative input voltage + * range in mV + */ +static int ads1015_fullscale_range[] = { + 6144, 4096, 2048, 1024, 512, 256, 256, 256 +}; + +/* + * Translation from COMP_QUE field value to the number of successive readings + * exceed the threshold values before an interrupt is generated + */ +static const int ads1015_comp_queue[] = { 1, 2, 4 }; + +static const struct iio_event_spec ads1015_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE), + }, { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_PERIOD), + }, }; #define ADS1015_V_CHAN(_chan, _addr) { \ @@ -111,6 +152,8 @@ static const struct { .shift = 4, \ .endianness = IIO_CPU, \ }, \ + .event_spec = ads1015_events, \ + .num_event_specs = ARRAY_SIZE(ads1015_events), \ .datasheet_name = "AIN"#_chan, \ } @@ -132,6 +175,8 @@ static const struct { .shift = 4, \ .endianness = IIO_CPU, \ }, \ + .event_spec = ads1015_events, \ + .num_event_specs = ARRAY_SIZE(ads1015_events), \ .datasheet_name = "AIN"#_chan"-AIN"#_chan2, \ } @@ -150,6 +195,8 @@ static const struct { .storagebits = 16, \ .endianness = IIO_CPU, \ }, \ + .event_spec = ads1015_events, \ + .num_event_specs = ARRAY_SIZE(ads1015_events), \ .datasheet_name = "AIN"#_chan, \ } @@ -170,9 +217,17 @@ static const struct { .storagebits = 16, \ .endianness = IIO_CPU, \ }, \ + .event_spec = ads1015_events, \ + .num_event_specs = ARRAY_SIZE(ads1015_events), \ .datasheet_name = "AIN"#_chan"-AIN"#_chan2, \ } +struct ads1015_thresh_data { + unsigned int comp_queue; + int high_thresh; + int low_thresh; +}; + struct ads1015_data { struct regmap *regmap; /* @@ -182,18 +237,54 @@ struct ads1015_data { struct mutex lock; struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; + unsigned int event_channel; + unsigned int comp_mode; + struct ads1015_thresh_data thresh_data[ADS1015_CHANNELS]; + unsigned int *data_rate; + /* + * Set to true when the ADC is switched to the continuous-conversion + * mode and exits from a power-down state. This flag is used to avoid + * getting the stale result from the conversion register. + */ + bool conv_invalid; }; +static bool ads1015_event_channel_enabled(struct ads1015_data *data) +{ + return (data->event_channel != ADS1015_CHANNELS); +} + +static void ads1015_event_channel_enable(struct ads1015_data *data, int chan, + int comp_mode) +{ + WARN_ON(ads1015_event_channel_enabled(data)); + + data->event_channel = chan; + data->comp_mode = comp_mode; +} + +static void ads1015_event_channel_disable(struct ads1015_data *data, int chan) +{ + data->event_channel = ADS1015_CHANNELS; +} + static bool ads1015_is_writeable_reg(struct device *dev, unsigned int reg) { - return (reg == ADS1015_CFG_REG); + switch (reg) { + case ADS1015_CFG_REG: + case ADS1015_LO_THRESH_REG: + case ADS1015_HI_THRESH_REG: + return true; + default: + return false; + } } static const struct regmap_config ads1015_regmap_config = { .reg_bits = 8, .val_bits = 16, - .max_register = ADS1015_CFG_REG, + .max_register = ADS1015_HI_THRESH_REG, .writeable_reg = ads1015_is_writeable_reg, }; @@ -235,33 +326,51 @@ static int ads1015_set_power_state(struct ads1015_data *data, bool on) ret = pm_runtime_put_autosuspend(dev); } - return ret; + return ret < 0 ? ret : 0; } static int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val) { - int ret, pga, dr, conv_time; - bool change; + int ret, pga, dr, dr_old, conv_time; + unsigned int old, mask, cfg; if (chan < 0 || chan >= ADS1015_CHANNELS) return -EINVAL; + ret = regmap_read(data->regmap, ADS1015_CFG_REG, &old); + if (ret) + return ret; + pga = data->channel_data[chan].pga; dr = data->channel_data[chan].data_rate; + mask = ADS1015_CFG_MUX_MASK | ADS1015_CFG_PGA_MASK | + ADS1015_CFG_DR_MASK; + cfg = chan << ADS1015_CFG_MUX_SHIFT | pga << ADS1015_CFG_PGA_SHIFT | + dr << ADS1015_CFG_DR_SHIFT; + + if (ads1015_event_channel_enabled(data)) { + mask |= ADS1015_CFG_COMP_QUE_MASK | ADS1015_CFG_COMP_MODE_MASK; + cfg |= data->thresh_data[chan].comp_queue << + ADS1015_CFG_COMP_QUE_SHIFT | + data->comp_mode << + ADS1015_CFG_COMP_MODE_SHIFT; + } - ret = regmap_update_bits_check(data->regmap, ADS1015_CFG_REG, - ADS1015_CFG_MUX_MASK | - ADS1015_CFG_PGA_MASK, - chan << ADS1015_CFG_MUX_SHIFT | - pga << ADS1015_CFG_PGA_SHIFT, - &change); - if (ret < 0) - return ret; - - if (change) { - conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]); + cfg = (old & ~mask) | (cfg & mask); + if (old != cfg) { + ret = regmap_write(data->regmap, ADS1015_CFG_REG, cfg); + if (ret) + return ret; + data->conv_invalid = true; + } + if (data->conv_invalid) { + dr_old = (old & ADS1015_CFG_DR_MASK) >> ADS1015_CFG_DR_SHIFT; + conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr_old]); + conv_time += DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]); + conv_time += conv_time / 10; /* 10% internal clock inaccuracy */ usleep_range(conv_time, conv_time + 1); + data->conv_invalid = false; } return regmap_read(data->regmap, ADS1015_CONV_REG, val); @@ -298,52 +407,36 @@ err: return IRQ_HANDLED; } -static int ads1015_set_scale(struct ads1015_data *data, int chan, +static int ads1015_set_scale(struct ads1015_data *data, + struct iio_chan_spec const *chan, int scale, int uscale) { - int i, ret, rindex = -1; - - for (i = 0; i < ARRAY_SIZE(ads1015_scale); i++) - if (ads1015_scale[i].scale == scale && - ads1015_scale[i].uscale == uscale) { - rindex = i; - break; + int i; + int fullscale = div_s64((scale * 1000000LL + uscale) << + (chan->scan_type.realbits - 1), 1000000); + + for (i = 0; i < ARRAY_SIZE(ads1015_fullscale_range); i++) { + if (ads1015_fullscale_range[i] == fullscale) { + data->channel_data[chan->address].pga = i; + return 0; } - if (rindex < 0) - return -EINVAL; - - ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG, - ADS1015_CFG_PGA_MASK, - rindex << ADS1015_CFG_PGA_SHIFT); - if (ret < 0) - return ret; - - data->channel_data[chan].pga = rindex; + } - return 0; + return -EINVAL; } static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate) { - int i, ret, rindex = -1; + int i; - for (i = 0; i < ARRAY_SIZE(ads1015_data_rate); i++) + for (i = 0; i < ARRAY_SIZE(ads1015_data_rate); i++) { if (data->data_rate[i] == rate) { - rindex = i; - break; + data->channel_data[chan].data_rate = i; + return 0; } - if (rindex < 0) - return -EINVAL; - - ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG, - ADS1015_CFG_DR_MASK, - rindex << ADS1015_CFG_DR_SHIFT); - if (ret < 0) - return ret; - - data->channel_data[chan].data_rate = rindex; + } - return 0; + return -EINVAL; } static int ads1015_read_raw(struct iio_dev *indio_dev, @@ -353,41 +446,47 @@ static int ads1015_read_raw(struct iio_dev *indio_dev, int ret, idx; struct ads1015_data *data = iio_priv(indio_dev); - mutex_lock(&indio_dev->mlock); mutex_lock(&data->lock); switch (mask) { case IIO_CHAN_INFO_RAW: { int shift = chan->scan_type.shift; - if (iio_buffer_enabled(indio_dev)) { - ret = -EBUSY; + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) break; + + if (ads1015_event_channel_enabled(data) && + data->event_channel != chan->address) { + ret = -EBUSY; + goto release_direct; } ret = ads1015_set_power_state(data, true); if (ret < 0) - break; + goto release_direct; ret = ads1015_get_adc_result(data, chan->address, val); if (ret < 0) { ads1015_set_power_state(data, false); - break; + goto release_direct; } *val = sign_extend32(*val >> shift, 15 - shift); ret = ads1015_set_power_state(data, false); if (ret < 0) - break; + goto release_direct; ret = IIO_VAL_INT; +release_direct: + iio_device_release_direct_mode(indio_dev); break; } case IIO_CHAN_INFO_SCALE: idx = data->channel_data[chan->address].pga; - *val = ads1015_scale[idx].scale; - *val2 = ads1015_scale[idx].uscale; - ret = IIO_VAL_INT_PLUS_MICRO; + *val = ads1015_fullscale_range[idx]; + *val2 = chan->scan_type.realbits - 1; + ret = IIO_VAL_FRACTIONAL_LOG2; break; case IIO_CHAN_INFO_SAMP_FREQ: idx = data->channel_data[chan->address].data_rate; @@ -399,7 +498,6 @@ static int ads1015_read_raw(struct iio_dev *indio_dev, break; } mutex_unlock(&data->lock); - mutex_unlock(&indio_dev->mlock); return ret; } @@ -414,7 +512,7 @@ static int ads1015_write_raw(struct iio_dev *indio_dev, mutex_lock(&data->lock); switch (mask) { case IIO_CHAN_INFO_SCALE: - ret = ads1015_set_scale(data, chan->address, val, val2); + ret = ads1015_set_scale(data, chan, val, val2); break; case IIO_CHAN_INFO_SAMP_FREQ: ret = ads1015_set_data_rate(data, chan->address, val); @@ -428,8 +526,254 @@ static int ads1015_write_raw(struct iio_dev *indio_dev, return ret; } +static int ads1015_read_event(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, enum iio_event_type type, + enum iio_event_direction dir, enum iio_event_info info, int *val, + int *val2) +{ + struct ads1015_data *data = iio_priv(indio_dev); + int ret; + unsigned int comp_queue; + int period; + int dr; + + mutex_lock(&data->lock); + + switch (info) { + case IIO_EV_INFO_VALUE: + *val = (dir == IIO_EV_DIR_RISING) ? + data->thresh_data[chan->address].high_thresh : + data->thresh_data[chan->address].low_thresh; + ret = IIO_VAL_INT; + break; + case IIO_EV_INFO_PERIOD: + dr = data->channel_data[chan->address].data_rate; + comp_queue = data->thresh_data[chan->address].comp_queue; + period = ads1015_comp_queue[comp_queue] * + USEC_PER_SEC / data->data_rate[dr]; + + *val = period / USEC_PER_SEC; + *val2 = period % USEC_PER_SEC; + ret = IIO_VAL_INT_PLUS_MICRO; + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&data->lock); + + return ret; +} + +static int ads1015_write_event(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, enum iio_event_type type, + enum iio_event_direction dir, enum iio_event_info info, int val, + int val2) +{ + struct ads1015_data *data = iio_priv(indio_dev); + int realbits = chan->scan_type.realbits; + int ret = 0; + long long period; + int i; + int dr; + + mutex_lock(&data->lock); + + switch (info) { + case IIO_EV_INFO_VALUE: + if (val >= 1 << (realbits - 1) || val < -1 << (realbits - 1)) { + ret = -EINVAL; + break; + } + if (dir == IIO_EV_DIR_RISING) + data->thresh_data[chan->address].high_thresh = val; + else + data->thresh_data[chan->address].low_thresh = val; + break; + case IIO_EV_INFO_PERIOD: + dr = data->channel_data[chan->address].data_rate; + period = val * USEC_PER_SEC + val2; + + for (i = 0; i < ARRAY_SIZE(ads1015_comp_queue) - 1; i++) { + if (period <= ads1015_comp_queue[i] * + USEC_PER_SEC / data->data_rate[dr]) + break; + } + data->thresh_data[chan->address].comp_queue = i; + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&data->lock); + + return ret; +} + +static int ads1015_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, enum iio_event_type type, + enum iio_event_direction dir) +{ + struct ads1015_data *data = iio_priv(indio_dev); + int ret = 0; + + mutex_lock(&data->lock); + if (data->event_channel == chan->address) { + switch (dir) { + case IIO_EV_DIR_RISING: + ret = 1; + break; + case IIO_EV_DIR_EITHER: + ret = (data->comp_mode == ADS1015_CFG_COMP_MODE_WINDOW); + break; + default: + ret = -EINVAL; + break; + } + } + mutex_unlock(&data->lock); + + return ret; +} + +static int ads1015_enable_event_config(struct ads1015_data *data, + const struct iio_chan_spec *chan, int comp_mode) +{ + int low_thresh = data->thresh_data[chan->address].low_thresh; + int high_thresh = data->thresh_data[chan->address].high_thresh; + int ret; + unsigned int val; + + if (ads1015_event_channel_enabled(data)) { + if (data->event_channel != chan->address || + (data->comp_mode == ADS1015_CFG_COMP_MODE_TRAD && + comp_mode == ADS1015_CFG_COMP_MODE_WINDOW)) + return -EBUSY; + + return 0; + } + + if (comp_mode == ADS1015_CFG_COMP_MODE_TRAD) { + low_thresh = max(-1 << (chan->scan_type.realbits - 1), + high_thresh - 1); + } + ret = regmap_write(data->regmap, ADS1015_LO_THRESH_REG, + low_thresh << chan->scan_type.shift); + if (ret) + return ret; + + ret = regmap_write(data->regmap, ADS1015_HI_THRESH_REG, + high_thresh << chan->scan_type.shift); + if (ret) + return ret; + + ret = ads1015_set_power_state(data, true); + if (ret < 0) + return ret; + + ads1015_event_channel_enable(data, chan->address, comp_mode); + + ret = ads1015_get_adc_result(data, chan->address, &val); + if (ret) { + ads1015_event_channel_disable(data, chan->address); + ads1015_set_power_state(data, false); + } + + return ret; +} + +static int ads1015_disable_event_config(struct ads1015_data *data, + const struct iio_chan_spec *chan, int comp_mode) +{ + int ret; + + if (!ads1015_event_channel_enabled(data)) + return 0; + + if (data->event_channel != chan->address) + return 0; + + if (data->comp_mode == ADS1015_CFG_COMP_MODE_TRAD && + comp_mode == ADS1015_CFG_COMP_MODE_WINDOW) + return 0; + + ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG, + ADS1015_CFG_COMP_QUE_MASK, + ADS1015_CFG_COMP_DISABLE << + ADS1015_CFG_COMP_QUE_SHIFT); + if (ret) + return ret; + + ads1015_event_channel_disable(data, chan->address); + + return ads1015_set_power_state(data, false); +} + +static int ads1015_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, enum iio_event_type type, + enum iio_event_direction dir, int state) +{ + struct ads1015_data *data = iio_priv(indio_dev); + int ret; + int comp_mode = (dir == IIO_EV_DIR_EITHER) ? + ADS1015_CFG_COMP_MODE_WINDOW : ADS1015_CFG_COMP_MODE_TRAD; + + mutex_lock(&data->lock); + + /* Prevent from enabling both buffer and event at a time */ + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) { + mutex_unlock(&data->lock); + return ret; + } + + if (state) + ret = ads1015_enable_event_config(data, chan, comp_mode); + else + ret = ads1015_disable_event_config(data, chan, comp_mode); + + iio_device_release_direct_mode(indio_dev); + mutex_unlock(&data->lock); + + return ret; +} + +static irqreturn_t ads1015_event_handler(int irq, void *priv) +{ + struct iio_dev *indio_dev = priv; + struct ads1015_data *data = iio_priv(indio_dev); + int val; + int ret; + + /* Clear the latched ALERT/RDY pin */ + ret = regmap_read(data->regmap, ADS1015_CONV_REG, &val); + if (ret) + return IRQ_HANDLED; + + if (ads1015_event_channel_enabled(data)) { + enum iio_event_direction dir; + u64 code; + + dir = data->comp_mode == ADS1015_CFG_COMP_MODE_TRAD ? + IIO_EV_DIR_RISING : IIO_EV_DIR_EITHER; + code = IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, data->event_channel, + IIO_EV_TYPE_THRESH, dir); + iio_push_event(indio_dev, code, iio_get_time_ns(indio_dev)); + } + + return IRQ_HANDLED; +} + static int ads1015_buffer_preenable(struct iio_dev *indio_dev) { + struct ads1015_data *data = iio_priv(indio_dev); + + /* Prevent from enabling both buffer and event at a time */ + if (ads1015_event_channel_enabled(data)) + return -EBUSY; + return ads1015_set_power_state(iio_priv(indio_dev), true); } @@ -446,7 +790,10 @@ static const struct iio_buffer_setup_ops ads1015_buffer_setup_ops = { .validate_scan_mask = &iio_validate_scan_mask_onehot, }; -static IIO_CONST_ATTR(scale_available, "3 2 1 0.5 0.25 0.125"); +static IIO_CONST_ATTR_NAMED(ads1015_scale_available, scale_available, + "3 2 1 0.5 0.25 0.125"); +static IIO_CONST_ATTR_NAMED(ads1115_scale_available, scale_available, + "0.1875 0.125 0.0625 0.03125 0.015625 0.007813"); static IIO_CONST_ATTR_NAMED(ads1015_sampling_frequency_available, sampling_frequency_available, "128 250 490 920 1600 2400 3300"); @@ -454,7 +801,7 @@ static IIO_CONST_ATTR_NAMED(ads1115_sampling_frequency_available, sampling_frequency_available, "8 16 32 64 128 250 475 860"); static struct attribute *ads1015_attributes[] = { - &iio_const_attr_scale_available.dev_attr.attr, + &iio_const_attr_ads1015_scale_available.dev_attr.attr, &iio_const_attr_ads1015_sampling_frequency_available.dev_attr.attr, NULL, }; @@ -464,7 +811,7 @@ static const struct attribute_group ads1015_attribute_group = { }; static struct attribute *ads1115_attributes[] = { - &iio_const_attr_scale_available.dev_attr.attr, + &iio_const_attr_ads1115_scale_available.dev_attr.attr, &iio_const_attr_ads1115_sampling_frequency_available.dev_attr.attr, NULL, }; @@ -474,16 +821,22 @@ static const struct attribute_group ads1115_attribute_group = { }; static const struct iio_info ads1015_info = { - .driver_module = THIS_MODULE, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, + .read_event_value = ads1015_read_event, + .write_event_value = ads1015_write_event, + .read_event_config = ads1015_read_event_config, + .write_event_config = ads1015_write_event_config, .attrs = &ads1015_attribute_group, }; static const struct iio_info ads1115_info = { - .driver_module = THIS_MODULE, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, + .read_event_value = ads1015_read_event, + .write_event_value = ads1015_write_event, + .read_event_config = ads1015_read_event_config, + .write_event_config = ads1015_write_event_config, .attrs = &ads1115_attribute_group, }; @@ -505,24 +858,24 @@ static int ads1015_get_channels_config_of(struct i2c_client *client) unsigned int data_rate = ADS1015_DEFAULT_DATA_RATE; if (of_property_read_u32(node, "reg", &pval)) { - dev_err(&client->dev, "invalid reg on %s\n", - node->full_name); + dev_err(&client->dev, "invalid reg on %pOF\n", + node); continue; } channel = pval; if (channel >= ADS1015_CHANNELS) { dev_err(&client->dev, - "invalid channel index %d on %s\n", - channel, node->full_name); + "invalid channel index %d on %pOF\n", + channel, node); continue; } if (!of_property_read_u32(node, "ti,gain", &pval)) { pga = pval; if (pga > 6) { - dev_err(&client->dev, "invalid gain on %s\n", - node->full_name); + dev_err(&client->dev, "invalid gain on %pOF\n", + node); of_node_put(node); return -EINVAL; } @@ -532,8 +885,8 @@ static int ads1015_get_channels_config_of(struct i2c_client *client) data_rate = pval; if (data_rate > 7) { dev_err(&client->dev, - "invalid data_rate on %s\n", - node->full_name); + "invalid data_rate on %pOF\n", + node); of_node_put(node); return -EINVAL; } @@ -573,6 +926,13 @@ static void ads1015_get_channels_config(struct i2c_client *client) } } +static int ads1015_set_conv_mode(struct ads1015_data *data, int mode) +{ + return regmap_update_bits(data->regmap, ADS1015_CFG_REG, + ADS1015_CFG_MOD_MASK, + mode << ADS1015_CFG_MOD_SHIFT); +} + static int ads1015_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -580,6 +940,7 @@ static int ads1015_probe(struct i2c_client *client, struct ads1015_data *data; int ret; enum chip_ids chip; + int i; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) @@ -614,6 +975,18 @@ static int ads1015_probe(struct i2c_client *client, break; } + data->event_channel = ADS1015_CHANNELS; + /* + * Set default lower and upper threshold to min and max value + * respectively. + */ + for (i = 0; i < ADS1015_CHANNELS; i++) { + int realbits = indio_dev->channels[i].scan_type.realbits; + + data->thresh_data[i].low_thresh = -1 << (realbits - 1); + data->thresh_data[i].high_thresh = (1 << (realbits - 1)) - 1; + } + /* we need to keep this ABI the same as used by hwmon ADS1015 driver */ ads1015_get_channels_config(client); @@ -623,16 +996,58 @@ static int ads1015_probe(struct i2c_client *client, return PTR_ERR(data->regmap); } - ret = iio_triggered_buffer_setup(indio_dev, NULL, - ads1015_trigger_handler, - &ads1015_buffer_setup_ops); + ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL, + ads1015_trigger_handler, + &ads1015_buffer_setup_ops); if (ret < 0) { dev_err(&client->dev, "iio triggered buffer setup failed\n"); return ret; } + + if (client->irq) { + unsigned long irq_trig = + irqd_get_trigger_type(irq_get_irq_data(client->irq)); + unsigned int cfg_comp_mask = ADS1015_CFG_COMP_QUE_MASK | + ADS1015_CFG_COMP_LAT_MASK | ADS1015_CFG_COMP_POL_MASK; + unsigned int cfg_comp = + ADS1015_CFG_COMP_DISABLE << ADS1015_CFG_COMP_QUE_SHIFT | + 1 << ADS1015_CFG_COMP_LAT_SHIFT; + + switch (irq_trig) { + case IRQF_TRIGGER_LOW: + cfg_comp |= ADS1015_CFG_COMP_POL_LOW << + ADS1015_CFG_COMP_POL_SHIFT; + break; + case IRQF_TRIGGER_HIGH: + cfg_comp |= ADS1015_CFG_COMP_POL_HIGH << + ADS1015_CFG_COMP_POL_SHIFT; + break; + default: + return -EINVAL; + } + + ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG, + cfg_comp_mask, cfg_comp); + if (ret) + return ret; + + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, ads1015_event_handler, + irq_trig | IRQF_ONESHOT, + client->name, indio_dev); + if (ret) + return ret; + } + + ret = ads1015_set_conv_mode(data, ADS1015_CONTINUOUS); + if (ret) + return ret; + + data->conv_invalid = true; + ret = pm_runtime_set_active(&client->dev); if (ret) - goto err_buffer_cleanup; + return ret; pm_runtime_set_autosuspend_delay(&client->dev, ADS1015_SLEEP_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); pm_runtime_enable(&client->dev); @@ -640,15 +1055,10 @@ static int ads1015_probe(struct i2c_client *client, ret = iio_device_register(indio_dev); if (ret < 0) { dev_err(&client->dev, "Failed to register IIO device\n"); - goto err_buffer_cleanup; + return ret; } return 0; - -err_buffer_cleanup: - iio_triggered_buffer_cleanup(indio_dev); - - return ret; } static int ads1015_remove(struct i2c_client *client) @@ -662,12 +1072,8 @@ static int ads1015_remove(struct i2c_client *client) pm_runtime_set_suspended(&client->dev); pm_runtime_put_noidle(&client->dev); - iio_triggered_buffer_cleanup(indio_dev); - /* power down single shot mode */ - return regmap_update_bits(data->regmap, ADS1015_CFG_REG, - ADS1015_CFG_MOD_MASK, - ADS1015_SINGLESHOT << ADS1015_CFG_MOD_SHIFT); + return ads1015_set_conv_mode(data, ADS1015_SINGLESHOT); } #ifdef CONFIG_PM @@ -676,19 +1082,20 @@ static int ads1015_runtime_suspend(struct device *dev) struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); struct ads1015_data *data = iio_priv(indio_dev); - return regmap_update_bits(data->regmap, ADS1015_CFG_REG, - ADS1015_CFG_MOD_MASK, - ADS1015_SINGLESHOT << ADS1015_CFG_MOD_SHIFT); + return ads1015_set_conv_mode(data, ADS1015_SINGLESHOT); } static int ads1015_runtime_resume(struct device *dev) { struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); struct ads1015_data *data = iio_priv(indio_dev); + int ret; - return regmap_update_bits(data->regmap, ADS1015_CFG_REG, - ADS1015_CFG_MOD_MASK, - ADS1015_CONTINUOUS << ADS1015_CFG_MOD_SHIFT); + ret = ads1015_set_conv_mode(data, ADS1015_CONTINUOUS); + if (!ret) + data->conv_invalid = true; + + return ret; } #endif diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c index 16a06633332c..0225c1b333ab 100644 --- a/drivers/iio/adc/ti-ads7950.c +++ b/drivers/iio/adc/ti-ads7950.c @@ -21,6 +21,7 @@ * GNU General Public License for more details. */ +#include <linux/acpi.h> #include <linux/bitops.h> #include <linux/device.h> #include <linux/err.h> @@ -37,6 +38,12 @@ #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> +/* + * In case of ACPI, we use the 5000 mV as default for the reference pin. + * Device tree users encode that via the vref-supply regulator. + */ +#define TI_ADS7950_VA_MV_ACPI_DEFAULT 5000 + #define TI_ADS7950_CR_MANUAL BIT(12) #define TI_ADS7950_CR_WRITE BIT(11) #define TI_ADS7950_CR_CHAN(ch) ((ch) << 7) @@ -58,6 +65,7 @@ struct ti_ads7950_state { struct spi_message scan_single_msg; struct regulator *reg; + unsigned int vref_mv; unsigned int settings; @@ -305,11 +313,15 @@ static int ti_ads7950_get_range(struct ti_ads7950_state *st) { int vref; - vref = regulator_get_voltage(st->reg); - if (vref < 0) - return vref; + if (st->vref_mv) { + vref = st->vref_mv; + } else { + vref = regulator_get_voltage(st->reg); + if (vref < 0) + return vref; - vref /= 1000; + vref /= 1000; + } if (st->settings & TI_ADS7950_CR_RANGE_5V) vref *= 2; @@ -360,7 +372,6 @@ static int ti_ads7950_read_raw(struct iio_dev *indio_dev, static const struct iio_info ti_ads7950_info = { .read_raw = &ti_ads7950_read_raw, .update_scan_mode = ti_ads7950_update_scan_mode, - .driver_module = THIS_MODULE, }; static int ti_ads7950_probe(struct spi_device *spi) @@ -411,6 +422,10 @@ static int ti_ads7950_probe(struct spi_device *spi) spi_message_init_with_transfers(&st->scan_single_msg, st->scan_single_xfer, 3); + /* Use hard coded value for reference voltage in ACPI case */ + if (ACPI_COMPANION(&spi->dev)) + st->vref_mv = TI_ADS7950_VA_MV_ACPI_DEFAULT; + st->reg = devm_regulator_get(&spi->dev, "vref"); if (IS_ERR(st->reg)) { dev_err(&spi->dev, "Failed get get regulator \"vref\"\n"); @@ -475,9 +490,27 @@ static const struct spi_device_id ti_ads7950_id[] = { }; MODULE_DEVICE_TABLE(spi, ti_ads7950_id); +static const struct of_device_id ads7950_of_table[] = { + { .compatible = "ti,ads7950", .data = &ti_ads7950_chip_info[TI_ADS7950] }, + { .compatible = "ti,ads7951", .data = &ti_ads7950_chip_info[TI_ADS7951] }, + { .compatible = "ti,ads7952", .data = &ti_ads7950_chip_info[TI_ADS7952] }, + { .compatible = "ti,ads7953", .data = &ti_ads7950_chip_info[TI_ADS7953] }, + { .compatible = "ti,ads7954", .data = &ti_ads7950_chip_info[TI_ADS7954] }, + { .compatible = "ti,ads7955", .data = &ti_ads7950_chip_info[TI_ADS7955] }, + { .compatible = "ti,ads7956", .data = &ti_ads7950_chip_info[TI_ADS7956] }, + { .compatible = "ti,ads7957", .data = &ti_ads7950_chip_info[TI_ADS7957] }, + { .compatible = "ti,ads7958", .data = &ti_ads7950_chip_info[TI_ADS7958] }, + { .compatible = "ti,ads7959", .data = &ti_ads7950_chip_info[TI_ADS7959] }, + { .compatible = "ti,ads7960", .data = &ti_ads7950_chip_info[TI_ADS7960] }, + { .compatible = "ti,ads7961", .data = &ti_ads7950_chip_info[TI_ADS7961] }, + { }, +}; +MODULE_DEVICE_TABLE(of, ads7950_of_table); + static struct spi_driver ti_ads7950_driver = { .driver = { .name = "ads7950", + .of_match_table = ads7950_of_table, }, .probe = ti_ads7950_probe, .remove = ti_ads7950_remove, diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c index 4a163496d9e4..079f133144b0 100644 --- a/drivers/iio/adc/ti-ads8688.c +++ b/drivers/iio/adc/ti-ads8688.c @@ -369,7 +369,6 @@ static const struct iio_info ads8688_info = { .write_raw = &ads8688_write_raw, .write_raw_get_fmt = &ads8688_write_raw_get_fmt, .attrs = &ads8688_attribute_group, - .driver_module = THIS_MODULE, }; static const struct ads8688_chip_info ads8688_chip_info_tbl[] = { @@ -474,7 +473,6 @@ MODULE_DEVICE_TABLE(of, ads8688_of_match); static struct spi_driver ads8688_driver = { .driver = { .name = "ads8688", - .owner = THIS_MODULE, }, .probe = ads8688_probe, .remove = ads8688_remove, diff --git a/drivers/iio/adc/ti-tlc4541.c b/drivers/iio/adc/ti-tlc4541.c index 78d91a069ea4..2290024c89fc 100644 --- a/drivers/iio/adc/ti-tlc4541.c +++ b/drivers/iio/adc/ti-tlc4541.c @@ -157,7 +157,6 @@ static int tlc4541_read_raw(struct iio_dev *indio_dev, static const struct iio_info tlc4541_info = { .read_raw = &tlc4541_read_raw, - .driver_module = THIS_MODULE, }; static int tlc4541_probe(struct spi_device *spi) diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 6cbed7eb118a..b3e573cc6f5f 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -533,7 +533,6 @@ err_unlock: static const struct iio_info tiadc_info = { .read_raw = &tiadc_read_raw, - .driver_module = THIS_MODULE, }; static int tiadc_request_dma(struct platform_device *pdev, diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c index bd3d37fc2144..8c019bb6625f 100644 --- a/drivers/iio/adc/twl4030-madc.c +++ b/drivers/iio/adc/twl4030-madc.c @@ -35,7 +35,7 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/slab.h> -#include <linux/i2c/twl.h> +#include <linux/mfd/twl.h> #include <linux/module.h> #include <linux/stddef.h> #include <linux/mutex.h> @@ -212,7 +212,6 @@ static int twl4030_madc_read(struct iio_dev *iio_dev, static const struct iio_info twl4030_madc_iio_info = { .read_raw = &twl4030_madc_read, - .driver_module = THIS_MODULE, }; #define TWL4030_ADC_CHANNEL(_channel, _type, _name) { \ @@ -887,21 +886,27 @@ static int twl4030_madc_probe(struct platform_device *pdev) /* Enable 3v1 bias regulator for MADC[3:6] */ madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1"); - if (IS_ERR(madc->usb3v1)) - return -ENODEV; + if (IS_ERR(madc->usb3v1)) { + ret = -ENODEV; + goto err_i2c; + } ret = regulator_enable(madc->usb3v1); - if (ret) + if (ret) { dev_err(madc->dev, "could not enable 3v1 bias regulator\n"); + goto err_i2c; + } ret = iio_device_register(iio_dev); if (ret) { dev_err(&pdev->dev, "could not register iio device\n"); - goto err_i2c; + goto err_usb3v1; } return 0; +err_usb3v1: + regulator_disable(madc->usb3v1); err_i2c: twl4030_madc_set_current_generator(madc, 0, 0); err_current_generator: diff --git a/drivers/iio/adc/twl6030-gpadc.c b/drivers/iio/adc/twl6030-gpadc.c index becbb0aef232..dc83f8f6c3d3 100644 --- a/drivers/iio/adc/twl6030-gpadc.c +++ b/drivers/iio/adc/twl6030-gpadc.c @@ -33,7 +33,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/of_platform.h> -#include <linux/i2c/twl.h> +#include <linux/mfd/twl.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -843,7 +843,6 @@ static const struct iio_chan_spec twl6032_gpadc_iio_channels[] = { static const struct iio_info twl6030_gpadc_iio_info = { .read_raw = &twl6030_gpadc_read_raw, - .driver_module = THIS_MODULE, }; static const struct twl6030_gpadc_platform_data twl6030_pdata = { diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index 01fc76f7d660..bbcb7a4d7edf 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -77,7 +77,7 @@ #define VF610_ADC_ADSTS_MASK 0x300 #define VF610_ADC_ADLPC_EN 0x80 #define VF610_ADC_ADHSC_EN 0x400 -#define VF610_ADC_REFSEL_VALT 0x100 +#define VF610_ADC_REFSEL_VALT 0x800 #define VF610_ADC_REFSEL_VBG 0x1000 #define VF610_ADC_ADTRG_HARD 0x2000 #define VF610_ADC_AVGS_8 0x4000 @@ -799,7 +799,6 @@ static int vf610_adc_reg_access(struct iio_dev *indio_dev, } static const struct iio_info vf610_adc_iio_info = { - .driver_module = THIS_MODULE, .read_raw = &vf610_read_raw, .write_raw = &vf610_write_raw, .debugfs_reg_access = &vf610_adc_reg_access, diff --git a/drivers/iio/adc/viperboard_adc.c b/drivers/iio/adc/viperboard_adc.c index 3be2e35721cc..53eb5a4136fe 100644 --- a/drivers/iio/adc/viperboard_adc.c +++ b/drivers/iio/adc/viperboard_adc.c @@ -107,7 +107,6 @@ error: static const struct iio_info vprbrd_adc_iio_info = { .read_raw = &vprbrd_iio_read_raw, - .driver_module = THIS_MODULE, }; static int vprbrd_adc_probe(struct platform_device *pdev) diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index 4a60497a1f19..d4f21d1be6c8 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -675,7 +675,6 @@ err_out: } static const struct iio_trigger_ops xadc_trigger_ops = { - .owner = THIS_MODULE, .set_trigger_state = &xadc_trigger_set_state, }; @@ -1028,7 +1027,6 @@ static const struct iio_info xadc_info = { .read_event_value = &xadc_read_event_value, .write_event_value = &xadc_write_event_value, .update_scan_mode = &xadc_update_scan_mode, - .driver_module = THIS_MODULE, }; static const struct of_device_id xadc_of_match_table[] = { diff --git a/drivers/iio/adc/xilinx-xadc-events.c b/drivers/iio/adc/xilinx-xadc-events.c index 6d5c2a6f4e6e..dc0670308253 100644 --- a/drivers/iio/adc/xilinx-xadc-events.c +++ b/drivers/iio/adc/xilinx-xadc-events.c @@ -68,7 +68,7 @@ void xadc_handle_events(struct iio_dev *indio_dev, unsigned long events) xadc_handle_event(indio_dev, i); } -static unsigned xadc_get_threshold_offset(const struct iio_chan_spec *chan, +static unsigned int xadc_get_threshold_offset(const struct iio_chan_spec *chan, enum iio_event_direction dir) { unsigned int offset; @@ -90,26 +90,24 @@ static unsigned xadc_get_threshold_offset(const struct iio_chan_spec *chan, static unsigned int xadc_get_alarm_mask(const struct iio_chan_spec *chan) { - if (chan->type == IIO_TEMP) { + if (chan->type == IIO_TEMP) return XADC_ALARM_OT_MASK; - } else { - switch (chan->channel) { - case 0: - return XADC_ALARM_VCCINT_MASK; - case 1: - return XADC_ALARM_VCCAUX_MASK; - case 2: - return XADC_ALARM_VCCBRAM_MASK; - case 3: - return XADC_ALARM_VCCPINT_MASK; - case 4: - return XADC_ALARM_VCCPAUX_MASK; - case 5: - return XADC_ALARM_VCCODDR_MASK; - default: - /* We will never get here */ - return 0; - } + switch (chan->channel) { + case 0: + return XADC_ALARM_VCCINT_MASK; + case 1: + return XADC_ALARM_VCCAUX_MASK; + case 2: + return XADC_ALARM_VCCBRAM_MASK; + case 3: + return XADC_ALARM_VCCPINT_MASK; + case 4: + return XADC_ALARM_VCCPAUX_MASK; + case 5: + return XADC_ALARM_VCCODDR_MASK; + default: + /* We will never get here */ + return 0; } } diff --git a/drivers/iio/adc/xilinx-xadc.h b/drivers/iio/adc/xilinx-xadc.h index f6f081965647..62edbdae1244 100644 --- a/drivers/iio/adc/xilinx-xadc.h +++ b/drivers/iio/adc/xilinx-xadc.h @@ -71,13 +71,13 @@ struct xadc { }; struct xadc_ops { - int (*read)(struct xadc *, unsigned int, uint16_t *); - int (*write)(struct xadc *, unsigned int, uint16_t); + int (*read)(struct xadc *xadc, unsigned int reg, uint16_t *val); + int (*write)(struct xadc *xadc, unsigned int reg, uint16_t val); int (*setup)(struct platform_device *pdev, struct iio_dev *indio_dev, int irq); - void (*update_alarm)(struct xadc *, unsigned int); - unsigned long (*get_dclk_rate)(struct xadc *); - irqreturn_t (*interrupt_handler)(int, void *); + void (*update_alarm)(struct xadc *xadc, unsigned int alarm); + unsigned long (*get_dclk_rate)(struct xadc *xadc); + irqreturn_t (*interrupt_handler)(int irq, void *devid); unsigned int flags; }; |