diff options
47 files changed, 1429 insertions, 266 deletions
diff --git a/Documentation/devicetree/bindings/iio/dac/ltc2632.txt b/Documentation/devicetree/bindings/iio/dac/ltc2632.txt new file mode 100644 index 000000000000..eb911e5a8ab4 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/ltc2632.txt @@ -0,0 +1,23 @@ +Linear Technology LTC2632 DAC device driver + +Required properties: + - compatible: Has to contain one of the following: + lltc,ltc2632-l12 + lltc,ltc2632-l10 + lltc,ltc2632-l8 + lltc,ltc2632-h12 + lltc,ltc2632-h10 + lltc,ltc2632-h8 + +Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt +apply. In particular, "reg" and "spi-max-frequency" properties must be given. + +Example: + + spi_master { + dac: ltc2632@0 { + compatible = "lltc,ltc2632-l12"; + reg = <0>; /* CS0 */ + spi-max-frequency = <1000000>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index c406cd852d22..a7d6f9a4c951 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3024,7 +3024,6 @@ CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVER M: Kevin Tsai <ktsai@capellamicro.com> S: Maintained F: drivers/iio/light/cm* -F: Documentation/devicetree/bindings/i2c/trivial-admin-guide/devices.rst CAVIUM THUNDERX2 ARM64 SOC M: Jayachandran C <jnair@caviumnetworks.com> diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 0890934ef66f..efc67739c28f 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -18,6 +18,7 @@ #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/delay.h> +#include <linux/of_device.h> #include <linux/of.h> #include <linux/bitops.h> #include <linux/slab.h> @@ -32,7 +33,7 @@ #define BMA180_DRV_NAME "bma180" #define BMA180_IRQ_NAME "bma180_event" -enum { +enum chip_ids { BMA180, BMA250, }; @@ -41,11 +42,11 @@ struct bma180_data; struct bma180_part_info { const struct iio_chan_spec *channels; - unsigned num_channels; + unsigned int num_channels; const int *scale_table; - unsigned num_scales; + unsigned int num_scales; const int *bw_table; - unsigned num_bw; + unsigned int num_bw; u8 int_reset_reg, int_reset_mask; u8 sleep_reg, sleep_mask; @@ -408,7 +409,7 @@ err: dev_err(&data->client->dev, "failed to disable the chip\n"); } -static ssize_t bma180_show_avail(char *buf, const int *vals, unsigned n, +static ssize_t bma180_show_avail(char *buf, const int *vals, unsigned int n, bool micros) { size_t len = 0; @@ -707,6 +708,7 @@ static int bma180_probe(struct i2c_client *client, { struct bma180_data *data; struct iio_dev *indio_dev; + enum chip_ids chip; int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); @@ -716,7 +718,11 @@ static int bma180_probe(struct i2c_client *client, data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; - data->part_info = &bma180_part_info[id->driver_data]; + if (client->dev.of_node) + chip = (enum chip_ids)of_device_get_match_data(&client->dev); + else + chip = id->driver_data; + data->part_info = &bma180_part_info[chip]; ret = data->part_info->chip_config(data); if (ret < 0) @@ -844,10 +850,24 @@ static struct i2c_device_id bma180_ids[] = { MODULE_DEVICE_TABLE(i2c, bma180_ids); +static const struct of_device_id bma180_of_match[] = { + { + .compatible = "bosch,bma180", + .data = (void *)BMA180 + }, + { + .compatible = "bosch,bma250", + .data = (void *)BMA250 + }, + { } +}; +MODULE_DEVICE_TABLE(of, bma180_of_match); + static struct i2c_driver bma180_driver = { .driver = { .name = "bma180", .pm = BMA180_PM_OPS, + .of_match_table = bma180_of_match, }, .probe = bma180_probe, .remove = bma180_remove, diff --git a/drivers/iio/accel/mma7455_i2c.c b/drivers/iio/accel/mma7455_i2c.c index 3cab5fb4a3c4..73bf81a8ab14 100644 --- a/drivers/iio/accel/mma7455_i2c.c +++ b/drivers/iio/accel/mma7455_i2c.c @@ -41,12 +41,20 @@ static const struct i2c_device_id mma7455_i2c_ids[] = { }; MODULE_DEVICE_TABLE(i2c, mma7455_i2c_ids); +static const struct of_device_id mma7455_of_match[] = { + { .compatible = "fsl,mma7455" }, + { .compatible = "fsl,mma7456" }, + { } +}; +MODULE_DEVICE_TABLE(of, mma7455_of_match); + static struct i2c_driver mma7455_i2c_driver = { .probe = mma7455_i2c_probe, .remove = mma7455_i2c_remove, .id_table = mma7455_i2c_ids, .driver = { .name = "mma7455-i2c", + .of_match_table = mma7455_of_match, }, }; module_i2c_driver(mma7455_i2c_driver); diff --git a/drivers/iio/accel/mma7660.c b/drivers/iio/accel/mma7660.c index 3a40774cca74..42fa57e41bdd 100644 --- a/drivers/iio/accel/mma7660.c +++ b/drivers/iio/accel/mma7660.c @@ -253,6 +253,12 @@ static const struct i2c_device_id mma7660_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, mma7660_i2c_id); +static const struct of_device_id mma7660_of_match[] = { + { .compatible = "fsl,mma7660" }, + { } +}; +MODULE_DEVICE_TABLE(of, mma7660_of_match); + static const struct acpi_device_id mma7660_acpi_id[] = { {"MMA7660", 0}, {} @@ -264,6 +270,7 @@ static struct i2c_driver mma7660_driver = { .driver = { .name = "mma7660", .pm = MMA7660_PM_OPS, + .of_match_table = mma7660_of_match, .acpi_match_table = ACPI_PTR(mma7660_acpi_id), }, .probe = mma7660_probe, diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index d777a972586d..2268a6fb9865 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -546,7 +546,7 @@ config STM32_ADC config STX104 tristate "Apex Embedded Systems STX104 driver" - depends on X86 && ISA_BUS_API + depends on PC104 && X86 && ISA_BUS_API select GPIOLIB help Say yes here to build support for the Apex Embedded Systems STX104 @@ -559,6 +559,23 @@ config STX104 The base port addresses for the devices may be configured via the base array module parameter. +config SUN4I_GPADC + tristate "Support for the Allwinner SoCs GPADC" + depends on IIO + depends on MFD_SUN4I_GPADC + help + Say yes here to build support for Allwinner (A10, A13 and A31) SoCs + GPADC. This ADC provides 4 channels which can be used as an ADC or as + a touchscreen input and one channel for thermal sensor. + + The thermal sensor slows down ADC readings and can be disabled by + disabling CONFIG_THERMAL_OF. However, the thermal sensor should be + enabled by default since the SoC temperature is usually more critical + than ADC readings. + + To compile this driver as a module, choose M here: the module will be + called sun4i-gpadc-iio. + config TI_ADC081C tristate "Texas Instruments ADC081C/ADC101C/ADC121C family" depends on I2C diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index b11bb5767543..73dbe399f894 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -49,6 +49,7 @@ obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o obj-$(CONFIG_SPEAR_ADC) += spear_adc.o obj-$(CONFIG_STX104) += stx104.o +obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o obj-$(CONFIG_STM32_ADC) += stm32-adc.o obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 3263231276ca..db9838230257 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -28,6 +28,7 @@ #include <linux/iio/sysfs.h> #include <linux/kthread.h> #include <linux/module.h> +#include <linux/of_device.h> #include <linux/regmap.h> #include <linux/util_macros.h> @@ -635,6 +636,7 @@ static int ina2xx_probe(struct i2c_client *client, struct iio_dev *indio_dev; struct iio_buffer *buffer; unsigned int val; + enum ina2xx_ids type; int ret; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); @@ -652,7 +654,11 @@ static int ina2xx_probe(struct i2c_client *client, return PTR_ERR(chip->regmap); } - chip->config = &ina2xx_config[id->driver_data]; + if (client->dev.of_node) + type = (enum ina2xx_ids)of_device_get_match_data(&client->dev); + else + type = id->driver_data; + chip->config = &ina2xx_config[type]; mutex_init(&chip->state_lock); @@ -726,9 +732,35 @@ static const struct i2c_device_id ina2xx_id[] = { }; MODULE_DEVICE_TABLE(i2c, ina2xx_id); +static const struct of_device_id ina2xx_of_match[] = { + { + .compatible = "ti,ina219", + .data = (void *)ina219 + }, + { + .compatible = "ti,ina220", + .data = (void *)ina219 + }, + { + .compatible = "ti,ina226", + .data = (void *)ina226 + }, + { + .compatible = "ti,ina230", + .data = (void *)ina226 + }, + { + .compatible = "ti,ina231", + .data = (void *)ina226 + }, + {}, +}; +MODULE_DEVICE_TABLE(of, ina2xx_of_match); + static struct i2c_driver ina2xx_driver = { .driver = { .name = KBUILD_MODNAME, + .of_match_table = ina2xx_of_match, }, .probe = ina2xx_probe, .remove = ina2xx_remove, diff --git a/drivers/iio/adc/max11100.c b/drivers/iio/adc/max11100.c index a088cf99bfe1..23c060e1b663 100644 --- a/drivers/iio/adc/max11100.c +++ b/drivers/iio/adc/max11100.c @@ -167,7 +167,6 @@ MODULE_DEVICE_TABLE(of, max11100_ids); static struct spi_driver max11100_driver = { .driver = { .name = "max11100", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(max11100_ids), }, .probe = max11100_probe, diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c new file mode 100644 index 000000000000..a8e134fa190d --- /dev/null +++ b/drivers/iio/adc/sun4i-gpadc-iio.c @@ -0,0 +1,613 @@ +/* ADC driver for sunxi platforms' (A10, A13 and A31) GPADC + * + * Copyright (c) 2016 Quentin Schulz <quentin.schulz@free-electrons.com> + * + * 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 Allwinner SoCs all have an ADC that can also act as a touchscreen + * controller and a thermal sensor. + * The thermal sensor works only when the ADC acts as a touchscreen controller + * and is configured to throw an interrupt every fixed periods of time (let say + * every X seconds). + * One would be tempted to disable the IP on the hardware side rather than + * disabling interrupts to save some power but that resets the internal clock of + * the IP, resulting in having to wait X seconds every time we want to read the + * value of the thermal sensor. + * This is also the reason of using autosuspend in pm_runtime. If there was no + * autosuspend, the thermal sensor would need X seconds after every + * pm_runtime_get_sync to get a value from the ADC. The autosuspend allows the + * thermal sensor to be requested again in a certain time span before it gets + * shutdown for not being used. + */ + +#include <linux/completion.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> +#include <linux/thermal.h> +#include <linux/delay.h> + +#include <linux/iio/iio.h> +#include <linux/iio/driver.h> +#include <linux/iio/machine.h> +#include <linux/mfd/sun4i-gpadc.h> + +static unsigned int sun4i_gpadc_chan_select(unsigned int chan) +{ + return SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(chan); +} + +static unsigned int sun6i_gpadc_chan_select(unsigned int chan) +{ + return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan); +} + +struct gpadc_data { + int temp_offset; + int temp_scale; + unsigned int tp_mode_en; + unsigned int tp_adc_select; + unsigned int (*adc_chan_select)(unsigned int chan); + unsigned int adc_chan_mask; +}; + +static const struct gpadc_data sun4i_gpadc_data = { + .temp_offset = -1932, + .temp_scale = 133, + .tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN, + .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT, + .adc_chan_select = &sun4i_gpadc_chan_select, + .adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK, +}; + +static const struct gpadc_data sun5i_gpadc_data = { + .temp_offset = -1447, + .temp_scale = 100, + .tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN, + .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT, + .adc_chan_select = &sun4i_gpadc_chan_select, + .adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK, +}; + +static const struct gpadc_data sun6i_gpadc_data = { + .temp_offset = -1623, + .temp_scale = 167, + .tp_mode_en = SUN6I_GPADC_CTRL1_TP_MODE_EN, + .tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT, + .adc_chan_select = &sun6i_gpadc_chan_select, + .adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK, +}; + +struct sun4i_gpadc_iio { + struct iio_dev *indio_dev; + struct completion completion; + int temp_data; + u32 adc_data; + struct regmap *regmap; + unsigned int fifo_data_irq; + atomic_t ignore_fifo_data_irq; + unsigned int temp_data_irq; + atomic_t ignore_temp_data_irq; + const struct gpadc_data *data; + /* prevents concurrent reads of temperature and ADC */ + struct mutex mutex; +}; + +#define SUN4I_GPADC_ADC_CHANNEL(_channel, _name) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _channel, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .datasheet_name = _name, \ +} + +static struct iio_map sun4i_gpadc_hwmon_maps[] = { + { + .adc_channel_label = "temp_adc", + .consumer_dev_name = "iio_hwmon.0", + }, + { /* sentinel */ }, +}; + +static const struct iio_chan_spec sun4i_gpadc_channels[] = { + SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"), + SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"), + SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"), + SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"), + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .datasheet_name = "temp_adc", + }, +}; + +static const struct iio_chan_spec sun4i_gpadc_channels_no_temp[] = { + SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"), + SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"), + SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"), + SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"), +}; + +static int sun4i_prepare_for_irq(struct iio_dev *indio_dev, int channel, + unsigned int irq) +{ + struct sun4i_gpadc_iio *info = iio_priv(indio_dev); + int ret; + u32 reg; + + pm_runtime_get_sync(indio_dev->dev.parent); + + reinit_completion(&info->completion); + + ret = regmap_write(info->regmap, SUN4I_GPADC_INT_FIFOC, + SUN4I_GPADC_INT_FIFOC_TP_FIFO_TRIG_LEVEL(1) | + SUN4I_GPADC_INT_FIFOC_TP_FIFO_FLUSH); + if (ret) + return ret; + + ret = regmap_read(info->regmap, SUN4I_GPADC_CTRL1, ®); + if (ret) + return ret; + + if (irq == info->fifo_data_irq) { + ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1, + info->data->tp_mode_en | + info->data->tp_adc_select | + info->data->adc_chan_select(channel)); + /* + * When the IP changes channel, it needs a bit of time to get + * correct values. + */ + if ((reg & info->data->adc_chan_mask) != + info->data->adc_chan_select(channel)) + mdelay(10); + + } else { + /* + * The temperature sensor returns valid data only when the ADC + * operates in touchscreen mode. + */ + ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1, + info->data->tp_mode_en); + } + + if (ret) + return ret; + + /* + * When the IP changes mode between ADC or touchscreen, it + * needs a bit of time to get correct values. + */ + if ((reg & info->data->tp_adc_select) != info->data->tp_adc_select) + mdelay(100); + + return 0; +} + +static int sun4i_gpadc_read(struct iio_dev *indio_dev, int channel, int *val, + unsigned int irq) +{ + struct sun4i_gpadc_iio *info = iio_priv(indio_dev); + int ret; + + mutex_lock(&info->mutex); + + ret = sun4i_prepare_for_irq(indio_dev, channel, irq); + if (ret) + goto err; + + enable_irq(irq); + + /* + * The temperature sensor throws an interruption periodically (currently + * set at periods of ~0.6s in sun4i_gpadc_runtime_resume). A 1s delay + * makes sure an interruption occurs in normal conditions. If it doesn't + * occur, then there is a timeout. + */ + if (!wait_for_completion_timeout(&info->completion, + msecs_to_jiffies(1000))) { + ret = -ETIMEDOUT; + goto err; + } + + if (irq == info->fifo_data_irq) + *val = info->adc_data; + else + *val = info->temp_data; + + ret = 0; + pm_runtime_mark_last_busy(indio_dev->dev.parent); + +err: + pm_runtime_put_autosuspend(indio_dev->dev.parent); + mutex_unlock(&info->mutex); + + return ret; +} + +static int sun4i_gpadc_adc_read(struct iio_dev *indio_dev, int channel, + int *val) +{ + struct sun4i_gpadc_iio *info = iio_priv(indio_dev); + + return sun4i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq); +} + +static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val) +{ + struct sun4i_gpadc_iio *info = iio_priv(indio_dev); + + return sun4i_gpadc_read(indio_dev, 0, val, info->temp_data_irq); +} + +static int sun4i_gpadc_temp_offset(struct iio_dev *indio_dev, int *val) +{ + struct sun4i_gpadc_iio *info = iio_priv(indio_dev); + + *val = info->data->temp_offset; + + return 0; +} + +static int sun4i_gpadc_temp_scale(struct iio_dev *indio_dev, int *val) +{ + struct sun4i_gpadc_iio *info = iio_priv(indio_dev); + + *val = info->data->temp_scale; + + return 0; +} + +static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + int ret; + + switch (mask) { + case IIO_CHAN_INFO_OFFSET: + ret = sun4i_gpadc_temp_offset(indio_dev, val); + if (ret) + return ret; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_RAW: + if (chan->type == IIO_VOLTAGE) + ret = sun4i_gpadc_adc_read(indio_dev, chan->channel, + val); + else + ret = sun4i_gpadc_temp_read(indio_dev, val); + + if (ret) + return ret; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if (chan->type == IIO_VOLTAGE) { + /* 3000mV / 4096 * raw */ + *val = 0; + *val2 = 732421875; + return IIO_VAL_INT_PLUS_NANO; + } + + ret = sun4i_gpadc_temp_scale(indio_dev, val); + if (ret) + return ret; + + return IIO_VAL_INT; + default: + return -EINVAL; + } + + return -EINVAL; +} + +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) +{ + struct sun4i_gpadc_iio *info = dev_id; + + if (atomic_read(&info->ignore_temp_data_irq)) + goto out; + + if (!regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, &info->temp_data)) + complete(&info->completion); + +out: + disable_irq_nosync(info->temp_data_irq); + return IRQ_HANDLED; +} + +static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id) +{ + struct sun4i_gpadc_iio *info = dev_id; + + if (atomic_read(&info->ignore_fifo_data_irq)) + goto out; + + if (!regmap_read(info->regmap, SUN4I_GPADC_DATA, &info->adc_data)) + complete(&info->completion); + +out: + disable_irq_nosync(info->fifo_data_irq); + return IRQ_HANDLED; +} + +static int sun4i_gpadc_runtime_suspend(struct device *dev) +{ + struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev)); + + /* Disable the ADC on IP */ + regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0); + /* Disable temperature sensor on IP */ + regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); + + return 0; +} + +static int sun4i_gpadc_runtime_resume(struct device *dev) +{ + struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev)); + + /* clkin = 6MHz */ + regmap_write(info->regmap, SUN4I_GPADC_CTRL0, + SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) | + SUN4I_GPADC_CTRL0_FS_DIV(7) | + SUN4I_GPADC_CTRL0_T_ACQ(63)); + regmap_write(info->regmap, SUN4I_GPADC_CTRL1, info->data->tp_mode_en); + regmap_write(info->regmap, SUN4I_GPADC_CTRL3, + SUN4I_GPADC_CTRL3_FILTER_EN | + SUN4I_GPADC_CTRL3_FILTER_TYPE(1)); + /* period = SUN4I_GPADC_TPR_TEMP_PERIOD * 256 * 16 / clkin; ~0.6s */ + regmap_write(info->regmap, SUN4I_GPADC_TPR, + SUN4I_GPADC_TPR_TEMP_ENABLE | + SUN4I_GPADC_TPR_TEMP_PERIOD(800)); + + return 0; +} + +static int sun4i_gpadc_get_temp(void *data, int *temp) +{ + struct sun4i_gpadc_iio *info = (struct sun4i_gpadc_iio *)data; + int val, scale, offset; + + if (sun4i_gpadc_temp_read(info->indio_dev, &val)) + return -ETIMEDOUT; + + sun4i_gpadc_temp_scale(info->indio_dev, &scale); + sun4i_gpadc_temp_offset(info->indio_dev, &offset); + + *temp = (val + offset) * scale; + + return 0; +} + +static const struct thermal_zone_of_device_ops sun4i_ts_tz_ops = { + .get_temp = &sun4i_gpadc_get_temp, +}; + +static const struct dev_pm_ops sun4i_gpadc_pm_ops = { + .runtime_suspend = &sun4i_gpadc_runtime_suspend, + .runtime_resume = &sun4i_gpadc_runtime_resume, +}; + +static int sun4i_irq_init(struct platform_device *pdev, const char *name, + irq_handler_t handler, const char *devname, + unsigned int *irq, atomic_t *atomic) +{ + int ret; + struct sun4i_gpadc_dev *mfd_dev = dev_get_drvdata(pdev->dev.parent); + struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(&pdev->dev)); + + /* + * Once the interrupt is activated, the IP continuously performs + * conversions thus throws interrupts. The interrupt is activated right + * after being requested but we want to control when these interrupts + * occur thus we disable it right after being requested. However, an + * interrupt might occur between these two instructions and we have to + * make sure that does not happen, by using atomic flags. We set the + * flag before requesting the interrupt and unset it right after + * disabling the interrupt. When an interrupt occurs between these two + * instructions, reading the atomic flag will tell us to ignore the + * interrupt. + */ + atomic_set(atomic, 1); + + ret = platform_get_irq_byname(pdev, name); + if (ret < 0) { + dev_err(&pdev->dev, "no %s interrupt registered\n", name); + return ret; + } + + ret = regmap_irq_get_virq(mfd_dev->regmap_irqc, ret); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get virq for irq %s\n", name); + return ret; + } + + *irq = ret; + ret = devm_request_any_context_irq(&pdev->dev, *irq, handler, 0, + devname, info); + if (ret < 0) { + dev_err(&pdev->dev, "could not request %s interrupt: %d\n", + name, ret); + return ret; + } + + disable_irq(*irq); + atomic_set(atomic, 0); + + return 0; +} + +static int sun4i_gpadc_probe(struct platform_device *pdev) +{ + struct sun4i_gpadc_iio *info; + struct iio_dev *indio_dev; + int ret; + struct sun4i_gpadc_dev *sun4i_gpadc_dev; + + sun4i_gpadc_dev = dev_get_drvdata(pdev->dev.parent); + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); + if (!indio_dev) + return -ENOMEM; + + info = iio_priv(indio_dev); + platform_set_drvdata(pdev, indio_dev); + + mutex_init(&info->mutex); + info->regmap = sun4i_gpadc_dev->regmap; + info->indio_dev = indio_dev; + init_completion(&info->completion); + indio_dev->name = dev_name(&pdev->dev); + indio_dev->dev.parent = &pdev->dev; + indio_dev->dev.of_node = pdev->dev.of_node; + indio_dev->info = &sun4i_gpadc_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->num_channels = ARRAY_SIZE(sun4i_gpadc_channels); + indio_dev->channels = sun4i_gpadc_channels; + + info->data = (struct gpadc_data *)platform_get_device_id(pdev)->driver_data; + + /* + * Since the controller needs to be in touchscreen mode for its thermal + * sensor to operate properly, and that switching between the two modes + * needs a delay, always registering in the thermal framework will + * significantly slow down the conversion rate of the ADCs. + * + * Therefore, instead of depending on THERMAL_OF in Kconfig, we only + * register the sensor if that option is enabled, eventually leaving + * that choice to the user. + */ + + if (IS_ENABLED(CONFIG_THERMAL_OF)) { + /* + * This driver is a child of an MFD which has a node in the DT + * but not its children, because of DT backward compatibility + * for A10, A13 and A31 SoCs. Therefore, the resulting devices + * of this driver do not have an of_node variable. + * However, its parent (the MFD driver) has an of_node variable + * and since devm_thermal_zone_of_sensor_register uses its first + * argument to match the phandle defined in the node of the + * thermal driver with the of_node of the device passed as first + * argument and the third argument to call ops from + * thermal_zone_of_device_ops, the solution is to use the parent + * device as first argument to match the phandle with its + * of_node, and the device from this driver as third argument to + * return the temperature. + */ + struct thermal_zone_device *tzd; + tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0, + info, + &sun4i_ts_tz_ops); + if (IS_ERR(tzd)) { + dev_err(&pdev->dev, + "could not register thermal sensor: %ld\n", + PTR_ERR(tzd)); + ret = PTR_ERR(tzd); + goto err; + } + } else { + indio_dev->num_channels = + ARRAY_SIZE(sun4i_gpadc_channels_no_temp); + indio_dev->channels = sun4i_gpadc_channels_no_temp; + } + + pm_runtime_set_autosuspend_delay(&pdev->dev, + SUN4I_GPADC_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + if (IS_ENABLED(CONFIG_THERMAL_OF)) { + ret = sun4i_irq_init(pdev, "TEMP_DATA_PENDING", + sun4i_gpadc_temp_data_irq_handler, + "temp_data", &info->temp_data_irq, + &info->ignore_temp_data_irq); + if (ret < 0) + goto err; + } + + ret = sun4i_irq_init(pdev, "FIFO_DATA_PENDING", + sun4i_gpadc_fifo_data_irq_handler, "fifo_data", + &info->fifo_data_irq, &info->ignore_fifo_data_irq); + if (ret < 0) + goto err; + + if (IS_ENABLED(CONFIG_THERMAL_OF)) { + ret = iio_map_array_register(indio_dev, sun4i_gpadc_hwmon_maps); + if (ret < 0) { + dev_err(&pdev->dev, + "failed to register iio map array\n"); + goto err; + } + } + + ret = devm_iio_device_register(&pdev->dev, indio_dev); + if (ret < 0) { + dev_err(&pdev->dev, "could not register the device\n"); + goto err_map; + } + + return 0; + +err_map: + if (IS_ENABLED(CONFIG_THERMAL_OF)) + iio_map_array_unregister(indio_dev); + +err: + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static int sun4i_gpadc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); + if (IS_ENABLED(CONFIG_THERMAL_OF)) + iio_map_array_unregister(indio_dev); + + return 0; +} + +static const struct platform_device_id sun4i_gpadc_id[] = { + { "sun4i-a10-gpadc-iio", (kernel_ulong_t)&sun4i_gpadc_data }, + { "sun5i-a13-gpadc-iio", (kernel_ulong_t)&sun5i_gpadc_data }, + { "sun6i-a31-gpadc-iio", (kernel_ulong_t)&sun6i_gpadc_data }, + { /* sentinel */ }, +}; + +static struct platform_driver sun4i_gpadc_driver = { + .driver = { + .name = "sun4i-gpadc-iio", + .pm = &sun4i_gpadc_pm_ops, + }, + .id_table = sun4i_gpadc_id, + .probe = sun4i_gpadc_probe, + .remove = sun4i_gpadc_remove, +}; + +module_platform_driver(sun4i_gpadc_driver); + +MODULE_DESCRIPTION("ADC driver for sunxi platforms"); +MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 422b314f5a3f..f76d979fb7e8 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -15,6 +15,7 @@ */ #include <linux/module.h> +#include <linux/of_device.h> #include <linux/init.h> #include <linux/i2c.h> #include <linux/regmap.h> @@ -55,7 +56,7 @@ #define ADS1015_DEFAULT_DATA_RATE 4 #define ADS1015_DEFAULT_CHAN 0 -enum { +enum chip_ids { ADS1015, ADS1115, }; @@ -578,6 +579,7 @@ static int ads1015_probe(struct i2c_client *client, struct iio_dev *indio_dev; struct ads1015_data *data; int ret; + enum chip_ids chip; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) @@ -593,7 +595,11 @@ static int ads1015_probe(struct i2c_client *client, indio_dev->name = ADS1015_DRV_NAME; indio_dev->modes = INDIO_DIRECT_MODE; - switch (id->driver_data) { + if (client->dev.of_node) + chip = (enum chip_ids)of_device_get_match_data(&client->dev); + else + chip = id->driver_data; + switch (chip) { case ADS1015: indio_dev->channels = ads1015_channels; indio_dev->num_channels = ARRAY_SIZE(ads1015_channels); @@ -698,9 +704,23 @@ static const struct i2c_device_id ads1015_id[] = { }; MODULE_DEVICE_TABLE(i2c, ads1015_id); +static const struct of_device_id ads1015_of_match[] = { + { + .compatible = "ti,ads1015", + .data = (void *)ADS1015 + }, + { + .compatible = "ti,ads1115", + .data = (void *)ADS1115 + }, + {} +}; +MODULE_DEVICE_TABLE(of, ads1015_of_match); + static struct i2c_driver ads1015_driver = { .driver = { .name = ADS1015_DRV_NAME, + .of_match_table = ads1015_of_match, .pm = &ads1015_pm_ops, }, .probe = ads1015_probe, diff --git a/drivers/iio/counter/Kconfig b/drivers/iio/counter/Kconfig index 44627f6e4861..b37e5fc03149 100644 --- a/drivers/iio/counter/Kconfig +++ b/drivers/iio/counter/Kconfig @@ -7,7 +7,7 @@ menu "Counters" config 104_QUAD_8 tristate "ACCES 104-QUAD-8 driver" - depends on X86 && ISA_BUS_API + depends on PC104 && X86 && ISA_BUS_API help Say yes here to build support for the ACCES 104-QUAD-8 quadrature encoder counter/interface device family (104-QUAD-8, 104-QUAD-4). diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index d3084028905b..08f2f9037409 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -118,6 +118,16 @@ config AD5624R_SPI Say yes here to build support for Analog Devices AD5624R, AD5644R and AD5664R converters (DAC). This driver uses the common SPI interface. +config LTC2632 + tristate "Linear Technology LTC2632-12/10/8 DAC spi driver" + depends on SPI + help + Say yes here to build support for Linear Technology + LTC2632-12, LTC2632-10, LTC2632-8 converters (DAC). + + To compile this driver as a module, choose M here: the + module will be called ltc2632. + config AD5686 tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver" depends on SPI diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index f01bf4a99867..6e4d99557309 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_AD8801) += ad8801.o obj-$(CONFIG_CIO_DAC) += cio-dac.o obj-$(CONFIG_DPOT_DAC) += dpot-dac.o obj-$(CONFIG_LPC18XX_DAC) += lpc18xx_dac.o +obj-$(CONFIG_LTC2632) += ltc2632.o obj-$(CONFIG_M62332) += m62332.o obj-$(CONFIG_MAX517) += max517.o obj-$(CONFIG_MAX5821) += max5821.o diff --git a/drivers/iio/dac/ltc2632.c b/drivers/iio/dac/ltc2632.c new file mode 100644 index 000000000000..ac5e05f6eb8b --- /dev/null +++ b/drivers/iio/dac/ltc2632.c @@ -0,0 +1,314 @@ +/* + * LTC2632 Digital to analog convertors spi driver + * + * Copyright 2017 Maxime Roussin-Bélanger + * + * Licensed under the GPL-2. + */ + +#include <linux/device.h> +#include <linux/spi/spi.h> +#include <linux/module.h> +#include <linux/iio/iio.h> + +#define LTC2632_DAC_CHANNELS 2 + +#define LTC2632_ADDR_DAC0 0x0 +#define LTC2632_ADDR_DAC1 0x1 + +#define LTC2632_CMD_WRITE_INPUT_N 0x0 +#define LTC2632_CMD_UPDATE_DAC_N 0x1 +#define LTC2632_CMD_WRITE_INPUT_N_UPDATE_ALL 0x2 +#define LTC2632_CMD_WRITE_INPUT_N_UPDATE_N 0x3 +#define LTC2632_CMD_POWERDOWN_DAC_N 0x4 +#define LTC2632_CMD_POWERDOWN_CHIP 0x5 +#define LTC2632_CMD_INTERNAL_REFER 0x6 +#define LTC2632_CMD_EXTERNAL_REFER 0x7 + +/** + * struct ltc2632_chip_info - chip specific information + * @channels: channel spec for the DAC + * @vref_mv: reference voltage + */ +struct ltc2632_chip_info { + const struct iio_chan_spec *channels; + const int vref_mv; +}; + +/** + * struct ltc2632_state - driver instance specific data + * @spi_dev: pointer to the spi_device struct + * @powerdown_cache_mask used to show current channel powerdown state + */ +struct ltc2632_state { + struct spi_device *spi_dev; + unsigned int powerdown_cache_mask; +}; + +enum ltc2632_supported_device_ids { + ID_LTC2632L12, + ID_LTC2632L10, + ID_LTC2632L8, + ID_LTC2632H12, + ID_LTC2632H10, + ID_LTC2632H8, +}; + +static int ltc2632_spi_write(struct spi_device *spi, + u8 cmd, u8 addr, u16 val, u8 shift) +{ + u32 data; + u8 msg[3]; + + /* + * The input shift register is 24 bits wide. + * The next four are the command bits, C3 to C0, + * followed by the 4-bit DAC address, A3 to A0, and then the + * 12-, 10-, 8-bit data-word. The data-word comprises the 12-, + * 10-, 8-bit input code followed by 4, 6, or 8 don't care bits. + */ + data = (cmd << 20) | (addr << 16) | (val << shift); + msg[0] = data >> 16; + msg[1] = data >> 8; + msg[2] = data; + + return spi_write(spi, msg, sizeof(msg)); +} + +static int ltc2632_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ltc2632_chip_info *chip_info; + + const struct ltc2632_state *st = iio_priv(indio_dev); + const struct spi_device_id *spi_dev_id = spi_get_device_id(st->spi_dev); + + chip_info = (struct ltc2632_chip_info *)spi_dev_id->driver_data; + + switch (m) { + case IIO_CHAN_INFO_SCALE: + *val = chip_info->vref_mv; + *val2 = chan->scan_type.realbits; + return IIO_VAL_FRACTIONAL_LOG2; + } + return -EINVAL; +} + +static int ltc2632_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct ltc2632_state *st = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (val >= (1 << chan->scan_type.realbits) || val < 0) + return -EINVAL; + + return ltc2632_spi_write(st->spi_dev, + LTC2632_CMD_WRITE_INPUT_N_UPDATE_N, + chan->address, val, + chan->scan_type.shift); + default: + return -EINVAL; + } +} + +static ssize_t ltc2632_read_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) +{ + struct ltc2632_state *st = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", + !!(st->powerdown_cache_mask & (1 << chan->channel))); +} + +static ssize_t ltc2632_write_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, + size_t len) +{ + bool pwr_down; + int ret; + struct ltc2632_state *st = iio_priv(indio_dev); + + ret = strtobool(buf, &pwr_down); + if (ret) + return ret; + + if (pwr_down) + st->powerdown_cache_mask |= (1 << chan->channel); + else + st->powerdown_cache_mask &= ~(1 << chan->channel); + + ret = ltc2632_spi_write(st->spi_dev, + LTC2632_CMD_POWERDOWN_DAC_N, + chan->channel, 0, 0); + + return ret ? ret : len; +} + +static const struct iio_info ltc2632_info = { + .write_raw = ltc2632_write_raw, + .read_raw = ltc2632_read_raw, + .driver_module = THIS_MODULE, +}; + +static const struct iio_chan_spec_ext_info ltc2632_ext_info[] = { + { + .name = "powerdown", + .read = ltc2632_read_dac_powerdown, + .write = ltc2632_write_dac_powerdown, + .shared = IIO_SEPARATE, + }, + { }, +}; + +#define LTC2632_CHANNEL(_chan, _bits) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .channel = (_chan), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .address = (_chan), \ + .scan_type = { \ + .realbits = (_bits), \ + .shift = 16 - (_bits), \ + }, \ + .ext_info = ltc2632_ext_info, \ +} + +#define DECLARE_LTC2632_CHANNELS(_name, _bits) \ + const struct iio_chan_spec _name ## _channels[] = { \ + LTC2632_CHANNEL(0, _bits), \ + LTC2632_CHANNEL(1, _bits), \ + } + +static DECLARE_LTC2632_CHANNELS(ltc2632l12, 12); +static DECLARE_LTC2632_CHANNELS(ltc2632l10, 10); +static DECLARE_LTC2632_CHANNELS(ltc2632l8, 8); + +static DECLARE_LTC2632_CHANNELS(ltc2632h12, 12); +static DECLARE_LTC2632_CHANNELS(ltc2632h10, 10); +static DECLARE_LTC2632_CHANNELS(ltc2632h8, 8); + +static const struct ltc2632_chip_info ltc2632_chip_info_tbl[] = { + [ID_LTC2632L12] = { + .channels = ltc2632l12_channels, + .vref_mv = 2500, + }, + [ID_LTC2632L10] = { + .channels = ltc2632l10_channels, + .vref_mv = 2500, + }, + [ID_LTC2632L8] = { + .channels = ltc2632l8_channels, + .vref_mv = 2500, + }, + [ID_LTC2632H12] = { + .channels = ltc2632h12_channels, + .vref_mv = 4096, + }, + [ID_LTC2632H10] = { + .channels = ltc2632h10_channels, + .vref_mv = 4096, + }, + [ID_LTC2632H8] = { + .channels = ltc2632h8_channels, + .vref_mv = 4096, + }, +}; + +static int ltc2632_probe(struct spi_device *spi) +{ + struct ltc2632_state *st; + struct iio_dev *indio_dev; + struct ltc2632_chip_info *chip_info; + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + + spi_set_drvdata(spi, indio_dev); + st->spi_dev = spi; + + chip_info = (struct ltc2632_chip_info *) + spi_get_device_id(spi)->driver_data; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = dev_of_node(&spi->dev) ? dev_of_node(&spi->dev)->name + : spi_get_device_id(spi)->name; + indio_dev->info = <c2632_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = chip_info->channels; + indio_dev->num_channels = LTC2632_DAC_CHANNELS; + + ret = ltc2632_spi_write(spi, LTC2632_CMD_INTERNAL_REFER, 0, 0, 0); + if (ret) { + dev_err(&spi->dev, + "Set internal reference command failed, %d\n", ret); + return ret; + } + + return devm_iio_device_register(&spi->dev, indio_dev); +} + +static const struct spi_device_id ltc2632_id[] = { + { "ltc2632-l12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632L12] }, + { "ltc2632-l10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632L10] }, + { "ltc2632-l8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632L8] }, + { "ltc2632-h12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H12] }, + { "ltc2632-h10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H10] }, + { "ltc2632-h8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H8] }, + {} +}; +MODULE_DEVICE_TABLE(spi, ltc2632_id); + +static struct spi_driver ltc2632_driver = { + .driver = { + .name = "ltc2632", + }, + .probe = ltc2632_probe, + .id_table = ltc2632_id, +}; +module_spi_driver(ltc2632_driver); + +static const struct of_device_id ltc2632_of_match[] = { + { + .compatible = "lltc,ltc2632-l12", + .data = <c2632_chip_info_tbl[ID_LTC2632L12] + }, { + .compatible = "lltc,ltc2632-l10", + .data = <c2632_chip_info_tbl[ID_LTC2632L10] + }, { + .compatible = "lltc,ltc2632-l8", + .data = <c2632_chip_info_tbl[ID_LTC2632L8] + }, { + .compatible = "lltc,ltc2632-h12", + .data = <c2632_chip_info_tbl[ID_LTC2632H12] + }, { + .compatible = "lltc,ltc2632-h10", + .data = <c2632_chip_info_tbl[ID_LTC2632H10] + }, { + .compatible = "lltc,ltc2632-h8", + .data = <c2632_chip_info_tbl[ID_LTC2632H8] + }, + {} +}; +MODULE_DEVICE_TABLE(of, ltc2632_of_match); + +MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>"); +MODULE_DESCRIPTION("LTC2632 DAC SPI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/dac/max5821.c b/drivers/iio/dac/max5821.c index 86e9e112f554..193fac3059a3 100644 --- a/drivers/iio/dac/max5821.c +++ b/drivers/iio/dac/max5821.c @@ -392,6 +392,7 @@ MODULE_DEVICE_TABLE(of, max5821_of_match); static struct i2c_driver max5821_driver = { .driver = { .name = "max5821", + .of_match_table = max5821_of_match, .pm = MAX5821_PM_OPS, }, .probe = max5821_probe, diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index db109f0cdd8c..6ab1f23e5a79 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -19,6 +19,7 @@ #include <linux/err.h> #include <linux/delay.h> #include <linux/regulator/consumer.h> +#include <linux/of_device.h> #include <linux/of.h> #include <linux/iio/iio.h> @@ -199,7 +200,7 @@ static ssize_t mcp4725_write_powerdown(struct iio_dev *indio_dev, return len; } -enum { +enum chip_id { MCP4725, MCP4726, }; @@ -406,7 +407,10 @@ static int mcp4725_probe(struct i2c_client *client, data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; - data->id = id->driver_data; + if (client->dev.of_node) + data->id = (enum chip_id)of_device_get_match_data(&client->dev); + else + data->id = id->driver_data; pdata = dev_get_platdata(&client->dev); if (!pdata) { @@ -525,9 +529,25 @@ static const struct i2c_device_id mcp4725_id[] = { }; MODULE_DEVICE_TABLE(i2c, mcp4725_id); +#ifdef CONFIG_OF +static const struct of_device_id mcp4725_of_match[] = { + { + .compatible = "microchip,mcp4725", + .data = (void *)MCP4725 + }, + { + .compatible = "microchip,mcp4726", + .data = (void *)MCP4726 + }, + { } +}; +MODULE_DEVICE_TABLE(of, mcp4725_of_match); +#endif + static struct i2c_driver mcp4725_driver = { .driver = { .name = MCP4725_DRV_NAME, + .of_match_table = of_match_ptr(mcp4725_of_match), .pm = MCP4725_PM_OPS, }, .probe = mcp4725_probe, diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index c102a6325bb0..cfa2db04a8ab 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -377,9 +377,16 @@ static const struct i2c_device_id itg3200_id[] = { }; MODULE_DEVICE_TABLE(i2c, itg3200_id); +static const struct of_device_id itg3200_of_match[] = { + { .compatible = "invensense,itg3200" }, + { } +}; +MODULE_DEVICE_TABLE(of, itg3200_of_match); + static struct i2c_driver itg3200_driver = { .driver = { .name = "itg3200", + .of_match_table = itg3200_of_match, .pm = &itg3200_pm_ops, }, .id_table = itg3200_id, diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index 2c3f8964a3ea..a8e6330cb906 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -17,6 +17,7 @@ #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/module.h> +#include <linux/of_device.h> #include "inv_mpu_iio.h" static const struct regmap_config inv_mpu_regmap_config = { @@ -69,7 +70,8 @@ static int inv_mpu6050_deselect_bypass(struct i2c_mux_core *muxc, u32 chan_id) return 0; } -static const char *inv_mpu_match_acpi_device(struct device *dev, int *chip_id) +static const char *inv_mpu_match_acpi_device(struct device *dev, + enum inv_devices *chip_id) { const struct acpi_device_id *id; @@ -93,7 +95,8 @@ static int inv_mpu_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct inv_mpu6050_state *st; - int result, chip_type; + int result; + enum inv_devices chip_type; struct regmap *regmap; const char *name; @@ -101,8 +104,13 @@ static int inv_mpu_probe(struct i2c_client *client, I2C_FUNC_SMBUS_I2C_BLOCK)) return -EOPNOTSUPP; - if (id) { - chip_type = (int)id->driver_data; + if (client->dev.of_node) { + chip_type = (enum inv_devices) + of_device_get_match_data(&client->dev); + name = client->name; + } else if (id) { + chip_type = (enum inv_devices) + id->driver_data; name = id->name; } else if (ACPI_HANDLE(&client->dev)) { name = inv_mpu_match_acpi_device(&client->dev, &chip_type); @@ -176,6 +184,27 @@ static const struct i2c_device_id inv_mpu_id[] = { MODULE_DEVICE_TABLE(i2c, inv_mpu_id); +static const struct of_device_id inv_of_match[] = { + { + .compatible = "invensense,mpu6050", + .data = (void *)INV_MPU6050 + }, + { + .compatible = "invensense,mpu6500", + .data = (void *)INV_MPU6500 + }, + { + .compatible = "invensense,mpu9150", + .data = (void *)INV_MPU9150 + }, + { + .compatible = "invensense,icm20608", + .data = (void *)INV_ICM20608 + }, + { } +}; +MODULE_DEVICE_TABLE(of, inv_of_match); + static const struct acpi_device_id inv_acpi_match[] = { {"INVN6500", INV_MPU6500}, { }, @@ -188,6 +217,7 @@ static struct i2c_driver inv_mpu_driver = { .remove = inv_mpu_remove, .id_table = inv_mpu_id, .driver = { + .of_match_table = inv_of_match, .acpi_match_table = ACPI_PTR(inv_acpi_match), .name = "inv-mpu6050-i2c", .pm = &inv_mpu_pmops, diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c index a4304edc3e0f..90bc98df362b 100644 --- a/drivers/iio/light/apds9960.c +++ b/drivers/iio/light/apds9960.c @@ -1122,9 +1122,16 @@ static const struct i2c_device_id apds9960_id[] = { }; MODULE_DEVICE_TABLE(i2c, apds9960_id); +static const struct of_device_id apds9960_of_match[] = { + { .compatible = "avago,apds9960" }, + { } +}; +MODULE_DEVICE_TABLE(of, apds9960_of_match); + static struct i2c_driver apds9960_driver = { .driver = { .name = APDS9960_DRV_NAME, + .of_match_table = apds9960_of_match, .pm = &apds9960_pm_ops, }, .probe = apds9960_probe, diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 04598ae993d4..e7d4ea75e007 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -884,9 +884,19 @@ static const struct i2c_device_id tsl2563_id[] = { }; MODULE_DEVICE_TABLE(i2c, tsl2563_id); +static const struct of_device_id tsl2563_of_match[] = { + { .compatible = "amstaos,tsl2560" }, + { .compatible = "amstaos,tsl2561" }, + { .compatible = "amstaos,tsl2562" }, + { .compatible = "amstaos,tsl2563" }, + {} +}; +MODULE_DEVICE_TABLE(of, tsl2563_of_match); + static struct i2c_driver tsl2563_i2c_driver = { .driver = { .name = "tsl2563", + .of_match_table = tsl2563_of_match, .pm = TSL2563_PM_OPS, }, .probe = tsl2563_probe, diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c index 18cf2e29e4d5..d571ad7291ed 100644 --- a/drivers/iio/light/us5182d.c +++ b/drivers/iio/light/us5182d.c @@ -972,10 +972,17 @@ static const struct i2c_device_id us5182d_id[] = { MODULE_DEVICE_TABLE(i2c, us5182d_id); +static const struct of_device_id us5182d_of_match[] = { + { .compatible = "upisemi,usd5182" }, + {} +}; +MODULE_DEVICE_TABLE(of, us5182d_of_match); + static struct i2c_driver us5182d_driver = { .driver = { .name = US5182D_DRV_NAME, .pm = &us5182d_pm_ops, + .of_match_table = us5182d_of_match, .acpi_match_table = ACPI_PTR(us5182d_acpi_match), }, .probe = us5182d_probe, diff --git a/drivers/iio/magnetometer/bmc150_magn_i2c.c b/drivers/iio/magnetometer/bmc150_magn_i2c.c index ee05722587aa..57e40dd1222e 100644 --- a/drivers/iio/magnetometer/bmc150_magn_i2c.c +++ b/drivers/iio/magnetometer/bmc150_magn_i2c.c @@ -63,9 +63,18 @@ static const struct i2c_device_id bmc150_magn_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, bmc150_magn_i2c_id); +static const struct of_device_id bmc150_magn_of_match[] = { + { .compatible = "bosch,bmc150_magn" }, + { .compatible = "bosch,bmc156_magn" }, + { .compatible = "bosch,bmm150_magn" }, + { } +}; +MODULE_DEVICE_TABLE(of, bmc150_magn_of_match); + static struct i2c_driver bmc150_magn_driver = { .driver = { .name = "bmc150_magn_i2c", + .of_match_table = bmc150_magn_of_match, .acpi_match_table = ACPI_PTR(bmc150_magn_acpi_match), .pm = &bmc150_magn_pm_ops, }, diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index b4f643fb3b1e..dad8d57f7402 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -441,9 +441,16 @@ static const struct i2c_device_id mag3110_id[] = { }; MODULE_DEVICE_TABLE(i2c, mag3110_id); +static const struct of_device_id mag3110_of_match[] = { + { .compatible = "fsl,mag3110" }, + { } +}; +MODULE_DEVICE_TABLE(of, mag3110_of_match); + static struct i2c_driver mag3110_driver = { .driver = { .name = "mag3110", + .of_match_table = mag3110_of_match, .pm = MAG3110_PM_OPS, }, .probe = mag3110_probe, diff --git a/drivers/iio/pressure/hp03.c b/drivers/iio/pressure/hp03.c index ac76515d5d49..8c7b3ec3d84a 100644 --- a/drivers/iio/pressure/hp03.c +++ b/drivers/iio/pressure/hp03.c @@ -297,9 +297,16 @@ static const struct i2c_device_id hp03_id[] = { }; MODULE_DEVICE_TABLE(i2c, hp03_id); +static const struct of_device_id hp03_of_match[] = { + { .compatible = "hoperf,hp03" }, + { }, +}; +MODULE_DEVICE_TABLE(of, hp03_of_match); + static struct i2c_driver hp03_driver = { .driver = { .name = "hp03", + .of_match_table = hp03_of_match, }, .probe = hp03_probe, .remove = hp03_remove, diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c index 525644a7442d..619b963714c7 100644 --- a/drivers/iio/pressure/mpl3115.c +++ b/drivers/iio/pressure/mpl3115.c @@ -321,9 +321,16 @@ static const struct i2c_device_id mpl3115_id[] = { }; MODULE_DEVICE_TABLE(i2c, mpl3115_id); +static const struct of_device_id mpl3115_of_match[] = { + { .compatible = "fsl,mpl3115" }, + { } +}; +MODULE_DEVICE_TABLE(of, mpl3115_of_match); + static struct i2c_driver mpl3115_driver = { .driver = { .name = "mpl3115", + .of_match_table = mpl3115_of_match, .pm = MPL3115_PM_OPS, }, .probe = mpl3115_probe, diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c index 4b645fc672aa..2077eef4095c 100644 --- a/drivers/iio/temperature/mlx90614.c +++ b/drivers/iio/temperature/mlx90614.c @@ -585,6 +585,12 @@ static const struct i2c_device_id mlx90614_id[] = { }; MODULE_DEVICE_TABLE(i2c, mlx90614_id); +static const struct of_device_id mlx90614_of_match[] = { + { .compatible = "melexis,mlx90614" }, + { } +}; +MODULE_DEVICE_TABLE(of, mlx90614_of_match); + #ifdef CONFIG_PM_SLEEP static int mlx90614_pm_suspend(struct device *dev) { @@ -644,6 +650,7 @@ static const struct dev_pm_ops mlx90614_pm_ops = { static struct i2c_driver mlx90614_driver = { .driver = { .name = "mlx90614", + .of_match_table = mlx90614_of_match, .pm = &mlx90614_pm_ops, }, .probe = mlx90614_probe, diff --git a/drivers/staging/iio/accel/adis16201.c b/drivers/staging/iio/accel/adis16201.c index d6c8658c88b9..fbc240663621 100644 --- a/drivers/staging/iio/accel/adis16201.c +++ b/drivers/staging/iio/accel/adis16201.c @@ -223,17 +223,13 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, default: return -EINVAL; } - mutex_lock(&indio_dev->mlock); addr = adis16201_addresses[chan->scan_index]; ret = adis_read_reg_16(st, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); + if (ret) return ret; - } val16 &= (1 << bits) - 1; val16 = (s16)(val16 << (16 - bits)) >> (16 - bits); *val = val16; - mutex_unlock(&indio_dev->mlock); return IIO_VAL_INT; } return -EINVAL; @@ -285,8 +281,8 @@ static const struct iio_chan_spec adis16201_channels[] = { }; static const struct iio_info adis16201_info = { - .read_raw = &adis16201_read_raw, - .write_raw = &adis16201_write_raw, + .read_raw = adis16201_read_raw, + .write_raw = adis16201_write_raw, .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/accel/adis16203.c b/drivers/staging/iio/accel/adis16203.c index 68189aded729..b59755aedd8b 100644 --- a/drivers/staging/iio/accel/adis16203.c +++ b/drivers/staging/iio/accel/adis16203.c @@ -233,8 +233,8 @@ static const struct iio_chan_spec adis16203_channels[] = { }; static const struct iio_info adis16203_info = { - .read_raw = &adis16203_read_raw, - .write_raw = &adis16203_write_raw, + .read_raw = adis16203_read_raw, + .write_raw = adis16203_write_raw, .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/accel/adis16209.c b/drivers/staging/iio/accel/adis16209.c index 8ff537f89d45..52fa2e0511be 100644 --- a/drivers/staging/iio/accel/adis16209.c +++ b/drivers/staging/iio/accel/adis16209.c @@ -7,7 +7,6 @@ */ #include <linux/delay.h> -#include <linux/mutex.h> #include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> @@ -152,14 +151,16 @@ #define ADIS16209_ERROR_ACTIVE BIT(14) -#define ADIS16209_SCAN_SUPPLY 0 -#define ADIS16209_SCAN_ACC_X 1 -#define ADIS16209_SCAN_ACC_Y 2 -#define ADIS16209_SCAN_AUX_ADC 3 -#define ADIS16209_SCAN_TEMP 4 -#define ADIS16209_SCAN_INCLI_X 5 -#define ADIS16209_SCAN_INCLI_Y 6 -#define ADIS16209_SCAN_ROT 7 +enum adis16209_scan { + ADIS16209_SCAN_SUPPLY, + ADIS16209_SCAN_ACC_X, + ADIS16209_SCAN_ACC_Y, + ADIS16209_SCAN_AUX_ADC, + ADIS16209_SCAN_TEMP, + ADIS16209_SCAN_INCLI_X, + ADIS16209_SCAN_INCLI_Y, + ADIS16209_SCAN_ROT, +}; static const u8 adis16209_addresses[8][1] = { [ADIS16209_SCAN_SUPPLY] = { }, @@ -252,17 +253,14 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, default: return -EINVAL; } - mutex_lock(&indio_dev->mlock); addr = adis16209_addresses[chan->scan_index][0]; ret = adis_read_reg_16(st, addr, &val16); if (ret) { - mutex_unlock(&indio_dev->mlock); return ret; } val16 &= (1 << bits) - 1; val16 = (s16)(val16 << (16 - bits)) >> (16 - bits); *val = val16; - mutex_unlock(&indio_dev->mlock); return IIO_VAL_INT; } return -EINVAL; @@ -285,8 +283,8 @@ static const struct iio_chan_spec adis16209_channels[] = { }; static const struct iio_info adis16209_info = { - .read_raw = &adis16209_read_raw, - .write_raw = &adis16209_write_raw, + .read_raw = adis16209_read_raw, + .write_raw = adis16209_write_raw, .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/accel/adis16240.c b/drivers/staging/iio/accel/adis16240.c index 27d7f6ad8c4c..6e3c95c9c3f6 100644 --- a/drivers/staging/iio/accel/adis16240.c +++ b/drivers/staging/iio/accel/adis16240.c @@ -10,7 +10,6 @@ #include <linux/irq.h> #include <linux/gpio.h> #include <linux/delay.h> -#include <linux/mutex.h> #include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> @@ -192,12 +191,14 @@ * filling. This may change! */ -#define ADIS16240_SCAN_ACC_X 0 -#define ADIS16240_SCAN_ACC_Y 1 -#define ADIS16240_SCAN_ACC_Z 2 -#define ADIS16240_SCAN_SUPPLY 3 -#define ADIS16240_SCAN_AUX_ADC 4 -#define ADIS16240_SCAN_TEMP 5 +enum adis16240_scan { + ADIS16240_SCAN_ACC_X, + ADIS16240_SCAN_ACC_Y, + ADIS16240_SCAN_ACC_Z, + ADIS16240_SCAN_SUPPLY, + ADIS16240_SCAN_AUX_ADC, + ADIS16240_SCAN_TEMP, +}; static ssize_t adis16240_spi_read_signed(struct device *dev, struct device_attribute *attr, @@ -227,15 +228,7 @@ static ssize_t adis16240_read_12bit_signed(struct device *dev, struct device_attribute *attr, char *buf) { - ssize_t ret; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - - /* Take the iio_dev status lock */ - mutex_lock(&indio_dev->mlock); - ret = adis16240_spi_read_signed(dev, attr, buf, 12); - mutex_unlock(&indio_dev->mlock); - - return ret; + return adis16240_spi_read_signed(dev, attr, buf, 12); } static IIO_DEVICE_ATTR(in_accel_xyz_squared_peak_raw, 0444, @@ -295,31 +288,25 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_CALIBBIAS: bits = 10; - mutex_lock(&indio_dev->mlock); addr = adis16240_addresses[chan->scan_index][0]; ret = adis_read_reg_16(st, addr, &val16); if (ret) { - mutex_unlock(&indio_dev->mlock); return ret; } val16 &= (1 << bits) - 1; val16 = (s16)(val16 << (16 - bits)) >> (16 - bits); *val = val16; - mutex_unlock(&indio_dev->mlock); return IIO_VAL_INT; case IIO_CHAN_INFO_PEAK: bits = 10; - mutex_lock(&indio_dev->mlock); addr = adis16240_addresses[chan->scan_index][1]; ret = adis_read_reg_16(st, addr, &val16); if (ret) { - mutex_unlock(&indio_dev->mlock); return ret; } val16 &= (1 << bits) - 1; val16 = (s16)(val16 << (16 - bits)) >> (16 - bits); *val = val16; - mutex_unlock(&indio_dev->mlock); return IIO_VAL_INT; } return -EINVAL; @@ -373,8 +360,8 @@ static const struct attribute_group adis16240_attribute_group = { static const struct iio_info adis16240_info = { .attrs = &adis16240_attribute_group, - .read_raw = &adis16240_read_raw, - .write_raw = &adis16240_write_raw, + .read_raw = adis16240_read_raw, + .write_raw = adis16240_write_raw, .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 4fc8588f0392..d11c6de9c777 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -564,18 +564,18 @@ static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev, } static const struct iio_info ad7192_info = { - .read_raw = &ad7192_read_raw, - .write_raw = &ad7192_write_raw, - .write_raw_get_fmt = &ad7192_write_raw_get_fmt, + .read_raw = ad7192_read_raw, + .write_raw = ad7192_write_raw, + .write_raw_get_fmt = ad7192_write_raw_get_fmt, .attrs = &ad7192_attribute_group, .validate_trigger = ad_sd_validate_trigger, .driver_module = THIS_MODULE, }; static const struct iio_info ad7195_info = { - .read_raw = &ad7192_read_raw, - .write_raw = &ad7192_write_raw, - .write_raw_get_fmt = &ad7192_write_raw_get_fmt, + .read_raw = ad7192_read_raw, + .write_raw = ad7192_write_raw, + .write_raw_get_fmt = ad7192_write_raw_get_fmt, .attrs = &ad7195_attribute_group, .validate_trigger = ad_sd_validate_trigger, .driver_module = THIS_MODULE, diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index ee679ac0368f..6a85e284c8a4 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -134,6 +134,7 @@ struct ad7280_state { unsigned char aux_threshhigh; unsigned char aux_threshlow; unsigned char cb_mask[AD7280A_MAX_CHAIN]; + struct mutex lock; /* protect sensor state */ __be32 buf[2] ____cacheline_aligned; }; @@ -410,7 +411,7 @@ static ssize_t ad7280_store_balance_sw(struct device *dev, devaddr = this_attr->address >> 8; ch = this_attr->address & 0xFF; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); if (readin) st->cb_mask[devaddr] |= 1 << (ch + 2); else @@ -418,7 +419,7 @@ static ssize_t ad7280_store_balance_sw(struct device *dev, ret = ad7280_write(st, devaddr, AD7280A_CELL_BALANCE, 0, st->cb_mask[devaddr]); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret ? ret : len; } @@ -433,10 +434,10 @@ static ssize_t ad7280_show_balance_timer(struct device *dev, int ret; unsigned int msecs; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); ret = ad7280_read(st, this_attr->address >> 8, this_attr->address & 0xFF); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); if (ret < 0) return ret; @@ -466,11 +467,11 @@ static ssize_t ad7280_store_balance_timer(struct device *dev, if (val > 31) return -EINVAL; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); ret = ad7280_write(st, this_attr->address >> 8, this_attr->address & 0xFF, 0, (val & 0x1F) << 3); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret ? ret : len; } @@ -655,7 +656,7 @@ static ssize_t ad7280_write_channel_config(struct device *dev, val = clamp(val, 0L, 0xFFL); - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); switch ((u32)this_attr->address) { case AD7280A_CELL_OVERVOLTAGE: st->cell_threshhigh = val; @@ -674,7 +675,7 @@ static ssize_t ad7280_write_channel_config(struct device *dev, ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, this_attr->address, 1, val); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret ? ret : len; } @@ -792,13 +793,13 @@ static int ad7280_read_raw(struct iio_dev *indio_dev, switch (m) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); if (chan->address == AD7280A_ALL_CELLS) ret = ad7280_read_all_channels(st, st->scan_cnt, NULL); else ret = ad7280_read_channel(st, chan->address >> 8, chan->address & 0xFF); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); if (ret < 0) return ret; @@ -847,6 +848,7 @@ static int ad7280_probe(struct spi_device *spi) st = iio_priv(indio_dev); spi_set_drvdata(spi, indio_dev); st->spi = spi; + mutex_init(&st->lock); if (!pdata) pdata = &ad7793_default_pdata; diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index e14960038d3e..dec3ba6eba8a 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -154,7 +154,7 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { }; static const struct iio_info ad7780_info = { - .read_raw = &ad7780_read_raw, + .read_raw = ad7780_read_raw, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c index e8609b866fec..ce0dce85929b 100644 --- a/drivers/staging/iio/cdc/ad7152.c +++ b/drivers/staging/iio/cdc/ad7152.c @@ -155,13 +155,13 @@ static ssize_t ad7152_start_gain_calib(struct device *dev, } static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration, - S_IWUSR, NULL, ad7152_start_offset_calib, 0); + 0200, NULL, ad7152_start_offset_calib, 0); static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration, - S_IWUSR, NULL, ad7152_start_offset_calib, 1); + 0200, NULL, ad7152_start_offset_calib, 1); static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration, - S_IWUSR, NULL, ad7152_start_gain_calib, 0); + 0200, NULL, ad7152_start_gain_calib, 0); static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration, - S_IWUSR, NULL, ad7152_start_gain_calib, 1); + 0200, NULL, ad7152_start_gain_calib, 1); /* Values are Update Rate (Hz), Conversion Time (ms) + 1*/ static const unsigned char ad7152_filter_rate_table[][2] = { @@ -441,9 +441,9 @@ static int ad7152_write_raw_get_fmt(struct iio_dev *indio_dev, static const struct iio_info ad7152_info = { .attrs = &ad7152_attribute_group, - .read_raw = &ad7152_read_raw, - .write_raw = &ad7152_write_raw, - .write_raw_get_fmt = &ad7152_write_raw_get_fmt, + .read_raw = ad7152_read_raw, + .write_raw = ad7152_write_raw, + .write_raw_get_fmt = ad7152_write_raw_get_fmt, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 81f8b9ee1120..c2c8aa5585e4 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -91,6 +91,7 @@ struct ad7746_chip_info { struct i2c_client *client; + struct mutex lock; /* protect sensor state */ /* * Capacitive channel digital filter setup; * conversion time/update rate setup per channel @@ -298,11 +299,11 @@ static inline ssize_t ad7746_start_calib(struct device *dev, if (!doit) return 0; - mutex_lock(&indio_dev->mlock); + mutex_lock(&chip->lock); regval |= chip->config; ret = i2c_smbus_write_byte_data(chip->client, AD7746_REG_CFG, regval); if (ret < 0) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&chip->lock); return ret; } @@ -310,12 +311,12 @@ static inline ssize_t ad7746_start_calib(struct device *dev, msleep(20); ret = i2c_smbus_read_byte_data(chip->client, AD7746_REG_CFG); if (ret < 0) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&chip->lock); return ret; } } while ((ret == regval) && timeout--); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&chip->lock); return len; } @@ -351,15 +352,15 @@ static ssize_t ad7746_start_gain_calib(struct device *dev, } static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration, - S_IWUSR, NULL, ad7746_start_offset_calib, CIN1); + 0200, NULL, ad7746_start_offset_calib, CIN1); static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration, - S_IWUSR, NULL, ad7746_start_offset_calib, CIN2); + 0200, NULL, ad7746_start_offset_calib, CIN2); static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration, - S_IWUSR, NULL, ad7746_start_gain_calib, CIN1); + 0200, NULL, ad7746_start_gain_calib, CIN1); static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration, - S_IWUSR, NULL, ad7746_start_gain_calib, CIN2); + 0200, NULL, ad7746_start_gain_calib, CIN2); static IIO_DEVICE_ATTR(in_voltage0_calibscale_calibration, - S_IWUSR, NULL, ad7746_start_gain_calib, VIN); + 0200, NULL, ad7746_start_gain_calib, VIN); static int ad7746_store_cap_filter_rate_setup(struct ad7746_chip_info *chip, int val) @@ -426,7 +427,7 @@ static int ad7746_write_raw(struct iio_dev *indio_dev, struct ad7746_chip_info *chip = iio_priv(indio_dev); int ret, reg; - mutex_lock(&indio_dev->mlock); + mutex_lock(&chip->lock); switch (mask) { case IIO_CHAN_INFO_CALIBSCALE: @@ -521,7 +522,7 @@ static int ad7746_write_raw(struct iio_dev *indio_dev, } out: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&chip->lock); return ret; } @@ -534,7 +535,7 @@ static int ad7746_read_raw(struct iio_dev *indio_dev, int ret, delay, idx; u8 regval, reg; - mutex_lock(&indio_dev->mlock); + mutex_lock(&chip->lock); switch (mask) { case IIO_CHAN_INFO_RAW: @@ -658,14 +659,14 @@ static int ad7746_read_raw(struct iio_dev *indio_dev, ret = -EINVAL; } out: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&chip->lock); return ret; } static const struct iio_info ad7746_info = { .attrs = &ad7746_attribute_group, - .read_raw = &ad7746_read_raw, - .write_raw = &ad7746_write_raw, + .read_raw = ad7746_read_raw, + .write_raw = ad7746_write_raw, .driver_module = THIS_MODULE, }; @@ -686,6 +687,7 @@ static int ad7746_probe(struct i2c_client *client, if (!indio_dev) return -ENOMEM; chip = iio_priv(indio_dev); + mutex_init(&chip->lock); /* this is only used for device removal purposes */ i2c_set_clientdata(client, indio_dev); diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c index 8d40c8e37173..425b8ab06fec 100644 --- a/drivers/staging/iio/frequency/ad9832.c +++ b/drivers/staging/iio/frequency/ad9832.c @@ -84,6 +84,7 @@ * @freq_msg: tuning word spi message * @phase_xfer: tuning word spi transfer * @phase_msg: tuning word spi message + * @lock protect sensor state * @data: spi transmit buffer * @phase_data: tuning word spi transmit buffer * @freq_data: tuning word spi transmit buffer @@ -103,6 +104,7 @@ struct ad9832_state { struct spi_message freq_msg; struct spi_transfer phase_xfer[2]; struct spi_message phase_msg; + struct mutex lock; /* protect sensor state */ /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. @@ -177,7 +179,7 @@ static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, if (ret) goto error_ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); switch ((u32)this_attr->address) { case AD9832_FREQ0HM: case AD9832_FREQ1HM: @@ -238,7 +240,7 @@ static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, default: ret = -ENODEV; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); error_ret: return ret ? ret : len; @@ -334,6 +336,7 @@ static int ad9832_probe(struct spi_device *spi) st->mclk = pdata->mclk; st->spi = spi; + mutex_init(&st->lock); indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index f92ff7fef6f3..af108e96b3ec 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -63,6 +63,7 @@ * @msg: default spi message * @freq_xfer: tuning word spi transfer * @freq_msg: tuning word spi message + * @lock: protect sensor state * @data: spi transmit buffer * @freq_data: tuning word spi transmit buffer */ @@ -77,6 +78,7 @@ struct ad9834_state { struct spi_message msg; struct spi_transfer freq_xfer[2]; struct spi_message freq_msg; + struct mutex lock; /* protect sensor state */ /* * DMA (thus cache coherency maintenance) requires the @@ -147,9 +149,9 @@ static ssize_t ad9834_write(struct device *dev, ret = kstrtoul(buf, 10, &val); if (ret) - goto error_ret; + return ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); switch ((u32)this_attr->address) { case AD9834_REG_FREQ0: case AD9834_REG_FREQ1: @@ -207,9 +209,8 @@ static ssize_t ad9834_write(struct device *dev, default: ret = -ENODEV; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); -error_ret: return ret ? ret : len; } @@ -224,7 +225,7 @@ static ssize_t ad9834_store_wavetype(struct device *dev, int ret = 0; bool is_ad9833_7 = (st->devid == ID_AD9833) || (st->devid == ID_AD9837); - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); switch ((u32)this_attr->address) { case 0: @@ -267,7 +268,7 @@ static ssize_t ad9834_store_wavetype(struct device *dev, st->data = cpu_to_be16(AD9834_REG_CMD | st->control); ret = spi_sync(st->spi, &st->msg); } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret ? ret : len; } @@ -418,6 +419,7 @@ static int ad9834_probe(struct spi_device *spi) } spi_set_drvdata(spi, indio_dev); st = iio_priv(indio_dev); + mutex_init(&st->lock); st->mclk = pdata->mclk; st->spi = spi; st->devid = spi_get_device_id(spi)->driver_data; diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index ab816a215eb8..c9d46e796f79 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -117,7 +117,7 @@ out_unlock: } static const struct iio_info adis16060_info = { - .read_raw = &adis16060_read_raw, + .read_raw = adis16060_read_raw, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 024463a11c47..c8d2d4c24e9d 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -21,7 +21,92 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include "meter.h" -#include "ade7754.h" + +#define ADE7754_AENERGY 0x01 +#define ADE7754_RAENERGY 0x02 +#define ADE7754_LAENERGY 0x03 +#define ADE7754_VAENERGY 0x04 +#define ADE7754_RVAENERGY 0x05 +#define ADE7754_LVAENERGY 0x06 +#define ADE7754_PERIOD 0x07 +#define ADE7754_TEMP 0x08 +#define ADE7754_WFORM 0x09 +#define ADE7754_OPMODE 0x0A +#define ADE7754_MMODE 0x0B +#define ADE7754_WAVMODE 0x0C +#define ADE7754_WATMODE 0x0D +#define ADE7754_VAMODE 0x0E +#define ADE7754_IRQEN 0x0F +#define ADE7754_STATUS 0x10 +#define ADE7754_RSTATUS 0x11 +#define ADE7754_ZXTOUT 0x12 +#define ADE7754_LINCYC 0x13 +#define ADE7754_SAGCYC 0x14 +#define ADE7754_SAGLVL 0x15 +#define ADE7754_VPEAK 0x16 +#define ADE7754_IPEAK 0x17 +#define ADE7754_GAIN 0x18 +#define ADE7754_AWG 0x19 +#define ADE7754_BWG 0x1A +#define ADE7754_CWG 0x1B +#define ADE7754_AVAG 0x1C +#define ADE7754_BVAG 0x1D +#define ADE7754_CVAG 0x1E +#define ADE7754_APHCAL 0x1F +#define ADE7754_BPHCAL 0x20 +#define ADE7754_CPHCAL 0x21 +#define ADE7754_AAPOS 0x22 +#define ADE7754_BAPOS 0x23 +#define ADE7754_CAPOS 0x24 +#define ADE7754_CFNUM 0x25 +#define ADE7754_CFDEN 0x26 +#define ADE7754_WDIV 0x27 +#define ADE7754_VADIV 0x28 +#define ADE7754_AIRMS 0x29 +#define ADE7754_BIRMS 0x2A +#define ADE7754_CIRMS 0x2B +#define ADE7754_AVRMS 0x2C +#define ADE7754_BVRMS 0x2D +#define ADE7754_CVRMS 0x2E +#define ADE7754_AIRMSOS 0x2F +#define ADE7754_BIRMSOS 0x30 +#define ADE7754_CIRMSOS 0x31 +#define ADE7754_AVRMSOS 0x32 +#define ADE7754_BVRMSOS 0x33 +#define ADE7754_CVRMSOS 0x34 +#define ADE7754_AAPGAIN 0x35 +#define ADE7754_BAPGAIN 0x36 +#define ADE7754_CAPGAIN 0x37 +#define ADE7754_AVGAIN 0x38 +#define ADE7754_BVGAIN 0x39 +#define ADE7754_CVGAIN 0x3A +#define ADE7754_CHKSUM 0x3E +#define ADE7754_VERSION 0x3F + +#define ADE7754_READ_REG(a) a +#define ADE7754_WRITE_REG(a) ((a) | 0x80) + +#define ADE7754_MAX_TX 4 +#define ADE7754_MAX_RX 4 +#define ADE7754_STARTUP_DELAY 1000 + +#define ADE7754_SPI_SLOW (u32)(300 * 1000) +#define ADE7754_SPI_BURST (u32)(1000 * 1000) +#define ADE7754_SPI_FAST (u32)(2000 * 1000) + +/** + * struct ade7754_state - device instance specific data + * @us: actual spi_device + * @buf_lock: mutex to protect tx and rx + * @tx: transmit buffer + * @rx: receive buffer + **/ +struct ade7754_state { + struct spi_device *us; + struct mutex buf_lock; + u8 tx[ADE7754_MAX_TX] ____cacheline_aligned; + u8 rx[ADE7754_MAX_RX]; +}; static int ade7754_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) { @@ -349,9 +434,7 @@ static int ade7754_set_irq(struct device *dev, bool enable) else irqen &= ~BIT(14); - ret = ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen); - - return ret; + return ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen); } /* Power down the device */ diff --git a/drivers/staging/iio/meter/ade7754.h b/drivers/staging/iio/meter/ade7754.h deleted file mode 100644 index 28f71c2cde0c..000000000000 --- a/drivers/staging/iio/meter/ade7754.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef _ADE7754_H -#define _ADE7754_H - -#define ADE7754_AENERGY 0x01 -#define ADE7754_RAENERGY 0x02 -#define ADE7754_LAENERGY 0x03 -#define ADE7754_VAENERGY 0x04 -#define ADE7754_RVAENERGY 0x05 -#define ADE7754_LVAENERGY 0x06 -#define ADE7754_PERIOD 0x07 -#define ADE7754_TEMP 0x08 -#define ADE7754_WFORM 0x09 -#define ADE7754_OPMODE 0x0A -#define ADE7754_MMODE 0x0B -#define ADE7754_WAVMODE 0x0C -#define ADE7754_WATMODE 0x0D -#define ADE7754_VAMODE 0x0E -#define ADE7754_IRQEN 0x0F -#define ADE7754_STATUS 0x10 -#define ADE7754_RSTATUS 0x11 -#define ADE7754_ZXTOUT 0x12 -#define ADE7754_LINCYC 0x13 -#define ADE7754_SAGCYC 0x14 -#define ADE7754_SAGLVL 0x15 -#define ADE7754_VPEAK 0x16 -#define ADE7754_IPEAK 0x17 -#define ADE7754_GAIN 0x18 -#define ADE7754_AWG 0x19 -#define ADE7754_BWG 0x1A -#define ADE7754_CWG 0x1B -#define ADE7754_AVAG 0x1C -#define ADE7754_BVAG 0x1D -#define ADE7754_CVAG 0x1E -#define ADE7754_APHCAL 0x1F -#define ADE7754_BPHCAL 0x20 -#define ADE7754_CPHCAL 0x21 -#define ADE7754_AAPOS 0x22 -#define ADE7754_BAPOS 0x23 -#define ADE7754_CAPOS 0x24 -#define ADE7754_CFNUM 0x25 -#define ADE7754_CFDEN 0x26 -#define ADE7754_WDIV 0x27 -#define ADE7754_VADIV 0x28 -#define ADE7754_AIRMS 0x29 -#define ADE7754_BIRMS 0x2A -#define ADE7754_CIRMS 0x2B -#define ADE7754_AVRMS 0x2C -#define ADE7754_BVRMS 0x2D -#define ADE7754_CVRMS 0x2E -#define ADE7754_AIRMSOS 0x2F -#define ADE7754_BIRMSOS 0x30 -#define ADE7754_CIRMSOS 0x31 -#define ADE7754_AVRMSOS 0x32 -#define ADE7754_BVRMSOS 0x33 -#define ADE7754_CVRMSOS 0x34 -#define ADE7754_AAPGAIN 0x35 -#define ADE7754_BAPGAIN 0x36 -#define ADE7754_CAPGAIN 0x37 -#define ADE7754_AVGAIN 0x38 -#define ADE7754_BVGAIN 0x39 -#define ADE7754_CVGAIN 0x3A -#define ADE7754_CHKSUM 0x3E -#define ADE7754_VERSION 0x3F - -#define ADE7754_READ_REG(a) a -#define ADE7754_WRITE_REG(a) ((a) | 0x80) - -#define ADE7754_MAX_TX 4 -#define ADE7754_MAX_RX 4 -#define ADE7754_STARTUP_DELAY 1000 - -#define ADE7754_SPI_SLOW (u32)(300 * 1000) -#define ADE7754_SPI_BURST (u32)(1000 * 1000) -#define ADE7754_SPI_FAST (u32)(2000 * 1000) - -/** - * struct ade7754_state - device instance specific data - * @us: actual spi_device - * @buf_lock: mutex to protect tx and rx - * @tx: transmit buffer - * @rx: receive buffer - **/ -struct ade7754_state { - struct spi_device *us; - struct mutex buf_lock; - u8 tx[ADE7754_MAX_TX] ____cacheline_aligned; - u8 rx[ADE7754_MAX_RX]; -}; - -#endif diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index 944ee3401029..0b65f1847510 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -21,7 +21,55 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include "meter.h" -#include "ade7759.h" + +#define ADE7759_WAVEFORM 0x01 +#define ADE7759_AENERGY 0x02 +#define ADE7759_RSTENERGY 0x03 +#define ADE7759_STATUS 0x04 +#define ADE7759_RSTSTATUS 0x05 +#define ADE7759_MODE 0x06 +#define ADE7759_CFDEN 0x07 +#define ADE7759_CH1OS 0x08 +#define ADE7759_CH2OS 0x09 +#define ADE7759_GAIN 0x0A +#define ADE7759_APGAIN 0x0B +#define ADE7759_PHCAL 0x0C +#define ADE7759_APOS 0x0D +#define ADE7759_ZXTOUT 0x0E +#define ADE7759_SAGCYC 0x0F +#define ADE7759_IRQEN 0x10 +#define ADE7759_SAGLVL 0x11 +#define ADE7759_TEMP 0x12 +#define ADE7759_LINECYC 0x13 +#define ADE7759_LENERGY 0x14 +#define ADE7759_CFNUM 0x15 +#define ADE7759_CHKSUM 0x1E +#define ADE7759_DIEREV 0x1F + +#define ADE7759_READ_REG(a) a +#define ADE7759_WRITE_REG(a) ((a) | 0x80) + +#define ADE7759_MAX_TX 6 +#define ADE7759_MAX_RX 6 +#define ADE7759_STARTUP_DELAY 1000 + +#define ADE7759_SPI_SLOW (u32)(300 * 1000) +#define ADE7759_SPI_BURST (u32)(1000 * 1000) +#define ADE7759_SPI_FAST (u32)(2000 * 1000) + +/** + * struct ade7759_state - device instance specific data + * @us: actual spi_device + * @buf_lock: mutex to protect tx and rx + * @tx: transmit buffer + * @rx: receive buffer + **/ +struct ade7759_state { + struct spi_device *us; + struct mutex buf_lock; + u8 tx[ADE7759_MAX_TX] ____cacheline_aligned; + u8 rx[ADE7759_MAX_RX]; +}; static int ade7759_spi_write_reg_8(struct device *dev, u8 reg_address, diff --git a/drivers/staging/iio/meter/ade7759.h b/drivers/staging/iio/meter/ade7759.h deleted file mode 100644 index f0716d2fdf8e..000000000000 --- a/drivers/staging/iio/meter/ade7759.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _ADE7759_H -#define _ADE7759_H - -#define ADE7759_WAVEFORM 0x01 -#define ADE7759_AENERGY 0x02 -#define ADE7759_RSTENERGY 0x03 -#define ADE7759_STATUS 0x04 -#define ADE7759_RSTSTATUS 0x05 -#define ADE7759_MODE 0x06 -#define ADE7759_CFDEN 0x07 -#define ADE7759_CH1OS 0x08 -#define ADE7759_CH2OS 0x09 -#define ADE7759_GAIN 0x0A -#define ADE7759_APGAIN 0x0B -#define ADE7759_PHCAL 0x0C -#define ADE7759_APOS 0x0D -#define ADE7759_ZXTOUT 0x0E -#define ADE7759_SAGCYC 0x0F -#define ADE7759_IRQEN 0x10 -#define ADE7759_SAGLVL 0x11 -#define ADE7759_TEMP 0x12 -#define ADE7759_LINECYC 0x13 -#define ADE7759_LENERGY 0x14 -#define ADE7759_CFNUM 0x15 -#define ADE7759_CHKSUM 0x1E -#define ADE7759_DIEREV 0x1F - -#define ADE7759_READ_REG(a) a -#define ADE7759_WRITE_REG(a) ((a) | 0x80) - -#define ADE7759_MAX_TX 6 -#define ADE7759_MAX_RX 6 -#define ADE7759_STARTUP_DELAY 1000 - -#define ADE7759_SPI_SLOW (u32)(300 * 1000) -#define ADE7759_SPI_BURST (u32)(1000 * 1000) -#define ADE7759_SPI_FAST (u32)(2000 * 1000) - -/** - * struct ade7759_state - device instance specific data - * @us: actual spi_device - * @buf_lock: mutex to protect tx and rx - * @tx: transmit buffer - * @rx: receive buffer - **/ -struct ade7759_state { - struct spi_device *us; - struct mutex buf_lock; - u8 tx[ADE7759_MAX_TX] ____cacheline_aligned; - u8 rx[ADE7759_MAX_RX]; -}; - -#endif diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 82b2d88ca942..a37e199225f4 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -97,7 +97,7 @@ static const struct iio_chan_spec ad2s1200_channels[] = { }; static const struct iio_info ad2s1200_info = { - .read_raw = &ad2s1200_read_raw, + .read_raw = ad2s1200_read_raw, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index 90b57c03609c..a6a8393d6664 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -490,8 +490,8 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev, ad2s1210_set_mode(MOD_VEL, st); break; default: - ret = -EINVAL; - break; + ret = -EINVAL; + break; } if (ret < 0) goto error_ret; diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c index 5b1c0db33e7f..b2270908f26f 100644 --- a/drivers/staging/iio/resolver/ad2s90.c +++ b/drivers/staging/iio/resolver/ad2s90.c @@ -47,7 +47,7 @@ error_ret: } static const struct iio_info ad2s90_info = { - .read_raw = &ad2s90_read_raw, + .read_raw = ad2s90_read_raw, .driver_module = THIS_MODULE, }; diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h index d7a29f246d64..509e736d27fb 100644 --- a/include/linux/mfd/sun4i-gpadc.h +++ b/include/linux/mfd/sun4i-gpadc.h @@ -28,6 +28,7 @@ #define SUN4I_GPADC_CTRL1_TP_MODE_EN BIT(4) #define SUN4I_GPADC_CTRL1_TP_ADC_SELECT BIT(3) #define SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(x) (GENMASK(2, 0) & (x)) +#define SUN4I_GPADC_CTRL1_ADC_CHAN_MASK GENMASK(2, 0) /* TP_CTRL1 bits for sun6i SOCs */ #define SUN6I_GPADC_CTRL1_TOUCH_PAN_CALI_EN BIT(7) @@ -35,6 +36,7 @@ #define SUN6I_GPADC_CTRL1_TP_MODE_EN BIT(5) #define SUN6I_GPADC_CTRL1_TP_ADC_SELECT BIT(4) #define SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(x) (GENMASK(3, 0) & BIT(x)) +#define SUN6I_GPADC_CTRL1_ADC_CHAN_MASK GENMASK(3, 0) #define SUN4I_GPADC_CTRL2 0x08 |