diff options
122 files changed, 1718 insertions, 835 deletions
diff --git a/Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml b/Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml index c80201d6a716..d66c24cae1e1 100644 --- a/Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml @@ -19,7 +19,8 @@ properties: compatible: items: - enum: - - renesas,r9a07g044-adc # RZ/G2{L,LC} + - renesas,r9a07g044-adc # RZ/G2L + - renesas,r9a07g054-adc # RZ/V2L - const: renesas,rzg2l-adc reg: diff --git a/Documentation/devicetree/bindings/iio/adc/sprd,sc2720-adc.yaml b/Documentation/devicetree/bindings/iio/adc/sprd,sc2720-adc.yaml index caa3ee0b4b8c..44aa28b59197 100644 --- a/Documentation/devicetree/bindings/iio/adc/sprd,sc2720-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/sprd,sc2720-adc.yaml @@ -20,6 +20,7 @@ properties: - sprd,sc2723-adc - sprd,sc2730-adc - sprd,sc2731-adc + - sprd,ump9620-adc reg: maxItems: 1 @@ -33,13 +34,39 @@ properties: hwlocks: maxItems: 1 - nvmem-cells: - maxItems: 2 + nvmem-cells: true - nvmem-cell-names: - items: - - const: big_scale_calib - - const: small_scale_calib + nvmem-cell-names: true + +allOf: + - if: + not: + properties: + compatible: + contains: + enum: + - sprd,ump9620-adc + then: + properties: + nvmem-cells: + maxItems: 2 + nvmem-cell-names: + items: + - const: big_scale_calib + - const: small_scale_calib + + else: + properties: + nvmem-cells: + maxItems: 6 + nvmem-cell-names: + items: + - const: big_scale_calib1 + - const: big_scale_calib2 + - const: small_scale_calib1 + - const: small_scale_calib2 + - const: vbat_det_cal1 + - const: vbat_det_cal2 required: - compatible @@ -69,4 +96,25 @@ examples: nvmem-cell-names = "big_scale_calib", "small_scale_calib"; }; }; + + - | + #include <dt-bindings/interrupt-controller/irq.h> + pmic { + #address-cells = <1>; + #size-cells = <0>; + adc@504 { + compatible = "sprd,ump9620-adc"; + reg = <0x504>; + interrupt-parent = <&ump9620_pmic>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + #io-channel-cells = <1>; + hwlocks = <&hwlock 4>; + nvmem-cells = <&adc_bcal1>, <&adc_bcal2>, + <&adc_scal1>, <&adc_scal2>, + <&vbat_det_cal1>, <&vbat_det_cal2>; + nvmem-cell-names = "big_scale_calib1", "big_scale_calib2", + "small_scale_calib1", "small_scale_calib2", + "vbat_det_cal1", "vbat_det_cal2"; + }; + }; ... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml index 2c2d01bbc296..a3b79438a13a 100644 --- a/Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml +++ b/Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/iio/adc/ti,ads1015.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: TI ADS1015 4 channel I2C analog to digital converter +title: TI ADS1015/ADS1115 4 channel I2C analog to digital converter maintainers: - Daniel Baluta <daniel.baluta@nxp.com> @@ -15,7 +15,10 @@ description: | properties: compatible: - const: ti,ads1015 + enum: + - ti,ads1015 + - ti,ads1115 + - ti,tla2024 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml index 501a463e5d88..9c48c76993fe 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml @@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Analog Devices AD2552R DAC device driver maintainers: - - Mihail Chindris <mihail.chindris@analog.com> + - Nuno Sá <nuno.sa@analog.com> description: | Bindings for the Analog Devices AD3552R DAC device and similar. diff --git a/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml b/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml index edf804d0aca2..b1eb77335d05 100644 --- a/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml +++ b/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml @@ -68,7 +68,7 @@ examples: #size-cells = <0>; dac@0 { - compatible = "lltc,ltc2632"; + compatible = "lltc,ltc2632-l12"; reg = <0>; /* CS0 */ spi-max-frequency = <1000000>; vref-supply = <&vref>; diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml index d69595a524c1..3ebc6526d82d 100644 --- a/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml +++ b/Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml @@ -14,21 +14,25 @@ description: | properties: compatible: - enum: - - invensense,iam20680 - - invensense,icm20608 - - invensense,icm20609 - - invensense,icm20689 - - invensense,icm20602 - - invensense,icm20690 - - invensense,mpu6000 - - invensense,mpu6050 - - invensense,mpu6500 - - invensense,mpu6515 - - invensense,mpu6880 - - invensense,mpu9150 - - invensense,mpu9250 - - invensense,mpu9255 + oneOf: + - enum: + - invensense,iam20680 + - invensense,icm20608 + - invensense,icm20609 + - invensense,icm20689 + - invensense,icm20602 + - invensense,icm20690 + - invensense,mpu6000 + - invensense,mpu6050 + - invensense,mpu6500 + - invensense,mpu6515 + - invensense,mpu6880 + - invensense,mpu9150 + - invensense,mpu9250 + - invensense,mpu9255 + - items: + - const: invensense,icm20608d + - const: invensense,icm20608 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml index 0750f700a143..5d4839f00898 100644 --- a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml +++ b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml @@ -14,23 +14,27 @@ description: properties: compatible: - enum: - - st,lsm6ds3 - - st,lsm6ds3h - - st,lsm6dsl - - st,lsm6dsm - - st,ism330dlc - - st,lsm6dso - - st,asm330lhh - - st,lsm6dsox - - st,lsm6dsr - - st,lsm6ds3tr-c - - st,ism330dhcx - - st,lsm9ds1-imu - - st,lsm6ds0 - - st,lsm6dsrx - - st,lsm6dst - - st,lsm6dsop + oneOf: + - enum: + - st,lsm6ds3 + - st,lsm6ds3h + - st,lsm6dsl + - st,lsm6dsm + - st,ism330dlc + - st,lsm6dso + - st,asm330lhh + - st,lsm6dsox + - st,lsm6dsr + - st,lsm6ds3tr-c + - st,ism330dhcx + - st,lsm9ds1-imu + - st,lsm6ds0 + - st,lsm6dsrx + - st,lsm6dst + - st,lsm6dsop + - items: + - const: st,asm330lhhx + - const: st,lsm6dsr reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/light/stk33xx.yaml b/Documentation/devicetree/bindings/iio/light/stk33xx.yaml index f92bf7b2b7f0..f6e22dc9814a 100644 --- a/Documentation/devicetree/bindings/iio/light/stk33xx.yaml +++ b/Documentation/devicetree/bindings/iio/light/stk33xx.yaml @@ -13,6 +13,9 @@ maintainers: description: | Ambient light and proximity sensor over an i2c interface. +allOf: + - $ref: ../common.yaml# + properties: compatible: enum: @@ -26,6 +29,8 @@ properties: interrupts: maxItems: 1 + proximity-near-level: true + required: - compatible - reg @@ -44,6 +49,7 @@ examples: stk3310@48 { compatible = "sensortek,stk3310"; reg = <0x48>; + proximity-near-level = <25>; interrupt-parent = <&gpio1>; interrupts = <5 IRQ_TYPE_LEVEL_LOW>; }; diff --git a/Documentation/devicetree/bindings/iio/potentiometer/microchip,mcp4131.yaml b/Documentation/devicetree/bindings/iio/potentiometer/microchip,mcp4131.yaml index 945a2d644ddc..32e92bced81f 100644 --- a/Documentation/devicetree/bindings/iio/potentiometer/microchip,mcp4131.yaml +++ b/Documentation/devicetree/bindings/iio/potentiometer/microchip,mcp4131.yaml @@ -95,7 +95,7 @@ examples: #size-cells = <0>; potentiometer@0 { - compatible = "mcp4131-502"; + compatible = "microchip,mcp4131-502"; reg = <0>; spi-max-frequency = <500000>; }; diff --git a/Documentation/devicetree/bindings/iio/st,st-sensors.yaml b/Documentation/devicetree/bindings/iio/st,st-sensors.yaml index 9735a2048255..fcb2902683c7 100644 --- a/Documentation/devicetree/bindings/iio/st,st-sensors.yaml +++ b/Documentation/devicetree/bindings/iio/st,st-sensors.yaml @@ -29,6 +29,7 @@ properties: - st,lis2dw12 - st,lis2hh12 - st,lis2dh12-accel + - st,lis302dl - st,lis331dl-accel - st,lis331dlh-accel - st,lis3de diff --git a/MAINTAINERS b/MAINTAINERS index 1bcc970f9771..c9730bd132ae 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1091,6 +1091,14 @@ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml F: drivers/iio/adc/ad7292.c +ANALOG DEVICES INC AD3552R DRIVER +M: Nuno Sá <nuno.sa@analog.com> +L: linux-iio@vger.kernel.org +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml +F: drivers/iio/dac/ad3552r.c + ANALOG DEVICES INC AD7293 DRIVER M: Antoniu Miclaus <antoniu.miclaus@analog.com> L: linux-iio@vger.kernel.org @@ -9006,7 +9014,7 @@ S: Maintained F: drivers/input/touchscreen/htcpen.c HTS221 TEMPERATURE-HUMIDITY IIO DRIVER -M: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> +M: Lorenzo Bianconi <lorenzo@kernel.org> L: linux-iio@vger.kernel.org S: Maintained W: http://www.st.com/ @@ -18637,7 +18645,7 @@ S: Maintained F: arch/alpha/kernel/srm_env.c ST LSM6DSx IMU IIO DRIVER -M: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> +M: Lorenzo Bianconi <lorenzo@kernel.org> L: linux-iio@vger.kernel.org S: Maintained W: http://www.st.com/ diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index eac3f02662ae..b53f010f3e40 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -290,7 +290,6 @@ config DA311 config DMARD06 tristate "Domintech DMARD06 Digital Accelerometer Driver" - depends on OF || COMPILE_TEST depends on I2C help Say yes here to build support for the Domintech low-g tri-axial diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c index e9c10c8c32f0..7561399daef3 100644 --- a/drivers/iio/accel/adxl355_core.c +++ b/drivers/iio/accel/adxl355_core.c @@ -18,7 +18,7 @@ #include <linux/math64.h> #include <linux/module.h> #include <linux/mod_devicetable.h> -#include <linux/of_irq.h> +#include <linux/property.h> #include <linux/regmap.h> #include <linux/units.h> @@ -745,10 +745,7 @@ int adxl355_core_probe(struct device *dev, struct regmap *regmap, return ret; } - /* - * TODO: Would be good to move it to the generic version. - */ - irq = of_irq_get_byname(dev->of_node, "DRDY"); + irq = fwnode_irq_get_byname(dev_fwnode(dev), "DRDY"); if (irq > 0) { ret = adxl355_probe_trigger(indio_dev, irq); if (ret) diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c index 62960134ea19..0289ed8cf2c6 100644 --- a/drivers/iio/accel/adxl367.c +++ b/drivers/iio/accel/adxl367.c @@ -1567,7 +1567,6 @@ int adxl367_probe(struct device *dev, const struct adxl367_ops *ops, return ret; ret = devm_iio_kfifo_buffer_setup_ext(st->dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &adxl367_buffer_ops, adxl367_fifo_attributes); if (ret) diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 7516d7dde1af..57e8a8350cd1 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -1525,7 +1525,7 @@ static int bmc150_accel_buffer_postenable(struct iio_dev *indio_dev) struct bmc150_accel_data *data = iio_priv(indio_dev); int ret = 0; - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) + if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED) return 0; mutex_lock(&data->mutex); @@ -1557,7 +1557,7 @@ static int bmc150_accel_buffer_predisable(struct iio_dev *indio_dev) { struct bmc150_accel_data *data = iio_priv(indio_dev); - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) + if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED) return 0; mutex_lock(&data->mutex); diff --git a/drivers/iio/accel/dmard09.c b/drivers/iio/accel/dmard09.c index 53ab6078cb7f..cb0246ca72f3 100644 --- a/drivers/iio/accel/dmard09.c +++ b/drivers/iio/accel/dmard09.c @@ -24,7 +24,7 @@ #define DMARD09_AXIS_Y 1 #define DMARD09_AXIS_Z 2 #define DMARD09_AXIS_X_OFFSET ((DMARD09_AXIS_X + 1) * 2) -#define DMARD09_AXIS_Y_OFFSET ((DMARD09_AXIS_Y + 1 )* 2) +#define DMARD09_AXIS_Y_OFFSET ((DMARD09_AXIS_Y + 1) * 2) #define DMARD09_AXIS_Z_OFFSET ((DMARD09_AXIS_Z + 1) * 2) struct dmard09_data { diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c index a9d2f10d5d45..8874d6d61725 100644 --- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -1217,7 +1217,6 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq) return ret; ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &fxls8962af_buffer_ops); if (ret) return ret; diff --git a/drivers/iio/accel/kxsd9-spi.c b/drivers/iio/accel/kxsd9-spi.c index ec17e35e573e..b7b5af45429e 100644 --- a/drivers/iio/accel/kxsd9-spi.c +++ b/drivers/iio/accel/kxsd9-spi.c @@ -44,8 +44,8 @@ static const struct spi_device_id kxsd9_spi_id[] = { MODULE_DEVICE_TABLE(spi, kxsd9_spi_id); static const struct of_device_id kxsd9_of_match[] = { - { .compatible = "kionix,kxsd9" }, - { }, + { .compatible = "kionix,kxsd9" }, + { } }; MODULE_DEVICE_TABLE(of, kxsd9_of_match); diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c index 9c02c681c84c..912a447e6310 100644 --- a/drivers/iio/accel/mma8452.c +++ b/drivers/iio/accel/mma8452.c @@ -166,6 +166,7 @@ static const struct mma8452_event_regs trans_ev_regs = { /** * struct mma_chip_info - chip specific data + * @name: part number of device reported via 'name' attr * @chip_id: WHO_AM_I register's value * @channels: struct iio_chan_spec matching the device's * capabilities diff --git a/drivers/iio/accel/sca3000.c b/drivers/iio/accel/sca3000.c index 83c81072511e..29a68a7d34cd 100644 --- a/drivers/iio/accel/sca3000.c +++ b/drivers/iio/accel/sca3000.c @@ -1474,7 +1474,6 @@ static int sca3000_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; ret = devm_iio_kfifo_buffer_setup(&spi->dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &sca3000_ring_setup_ops); if (ret) return ret; diff --git a/drivers/iio/accel/ssp_accel_sensor.c b/drivers/iio/accel/ssp_accel_sensor.c index a1164b439f41..7ca9d0d543e0 100644 --- a/drivers/iio/accel/ssp_accel_sensor.c +++ b/drivers/iio/accel/ssp_accel_sensor.c @@ -113,7 +113,6 @@ static int ssp_accel_probe(struct platform_device *pdev) indio_dev->available_scan_masks = ssp_accel_scan_mask; ret = devm_iio_kfifo_buffer_setup(&pdev->dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &ssp_accel_buffer_ops); if (ret) return ret; diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h index 00e056c21bfc..5b0f54e33d9e 100644 --- a/drivers/iio/accel/st_accel.h +++ b/drivers/iio/accel/st_accel.h @@ -14,32 +14,6 @@ #include <linux/types.h> #include <linux/iio/common/st_sensors.h> -enum st_accel_type { - LSM303DLH, - LSM303DLHC, - LIS3DH, - LSM330D, - LSM330DL, - LSM330DLC, - LIS331DLH, - LSM303DL, - LSM303DLM, - LSM330, - LSM303AGR, - LIS2DH12, - LIS3L02DQ, - LNG2DM, - H3LIS331DL, - LIS331DL, - LIS3LV02DL, - LIS2DW12, - LIS3DHH, - LIS2DE12, - LIS2HH12, - SC7A20, - ST_ACCEL_MAX, -}; - #define H3LIS331DL_ACCEL_DEV_NAME "h3lis331dl_accel" #define LIS3LV02DL_ACCEL_DEV_NAME "lis3lv02dl_accel" #define LSM303DLHC_ACCEL_DEV_NAME "lsm303dlhc_accel" @@ -62,8 +36,10 @@ enum st_accel_type { #define LIS3DE_ACCEL_DEV_NAME "lis3de" #define LIS2DE12_ACCEL_DEV_NAME "lis2de12" #define LIS2HH12_ACCEL_DEV_NAME "lis2hh12" +#define LIS302DL_ACCEL_DEV_NAME "lis302dl" #define SC7A20_ACCEL_DEV_NAME "sc7a20" + #ifdef CONFIG_IIO_BUFFER int st_accel_allocate_ring(struct iio_dev *indio_dev); int st_accel_trig_set_state(struct iio_trigger *trig, bool state); diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 5c5da6fdb490..c8c8eb15c34e 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -444,6 +444,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, .sensors_supported = { [0] = LIS331DL_ACCEL_DEV_NAME, + [1] = LIS302DL_ACCEL_DEV_NAME, }, .ch = (struct iio_chan_spec *)st_accel_8bit_channels, .odr = { @@ -1209,28 +1210,21 @@ read_error: static int st_accel_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { - int err; - switch (mask) { case IIO_CHAN_INFO_SCALE: { int gain; gain = val * 1000000 + val2; - err = st_sensors_set_fullscale_by_gain(indio_dev, gain); - break; + return st_sensors_set_fullscale_by_gain(indio_dev, gain); } case IIO_CHAN_INFO_SAMP_FREQ: if (val2) return -EINVAL; - mutex_lock(&indio_dev->mlock); - err = st_sensors_set_odr(indio_dev, val); - mutex_unlock(&indio_dev->mlock); - return err; + + return st_sensors_set_odr(indio_dev, val); default: return -EINVAL; } - - return err; } static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL(); diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c index 96adc4344f4a..45ee0ddc133c 100644 --- a/drivers/iio/accel/st_accel_i2c.c +++ b/drivers/iio/accel/st_accel_i2c.c @@ -108,6 +108,10 @@ static const struct of_device_id st_accel_of_match[] = { .data = LIS2HH12_ACCEL_DEV_NAME, }, { + .compatible = "st,lis302dl", + .data = LIS302DL_ACCEL_DEV_NAME, + }, + { .compatible = "silan,sc7a20", .data = SC7A20_ACCEL_DEV_NAME, }, @@ -146,6 +150,7 @@ static const struct i2c_device_id st_accel_id_table[] = { { LIS3DE_ACCEL_DEV_NAME }, { LIS2DE12_ACCEL_DEV_NAME }, { LIS2HH12_ACCEL_DEV_NAME }, + { LIS302DL_ACCEL_DEV_NAME }, { SC7A20_ACCEL_DEV_NAME }, {}, }; diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c index 108b63d0146c..6c0917750288 100644 --- a/drivers/iio/accel/st_accel_spi.c +++ b/drivers/iio/accel/st_accel_spi.c @@ -92,6 +92,10 @@ static const struct of_device_id st_accel_of_match[] = { .compatible = "st,lis3de", .data = LIS3DE_ACCEL_DEV_NAME, }, + { + .compatible = "st,lis302dl", + .data = LIS302DL_ACCEL_DEV_NAME, + }, {} }; MODULE_DEVICE_TABLE(of, st_accel_of_match); @@ -147,6 +151,7 @@ static const struct spi_device_id st_accel_id_table[] = { { LIS2DW12_ACCEL_DEV_NAME }, { LIS3DHH_ACCEL_DEV_NAME }, { LIS3DE_ACCEL_DEV_NAME }, + { LIS302DL_ACCEL_DEV_NAME }, {}, }; MODULE_DEVICE_TABLE(spi, st_accel_id_table); diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 71ab0a06aa82..48ace7412874 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -910,7 +910,7 @@ config ROCKCHIP_SARADC config RZG2L_ADC tristate "Renesas RZ/G2L ADC driver" - depends on ARCH_R9A07G044 || COMPILE_TEST + depends on ARCH_RZG2L || COMPILE_TEST help Say yes here to build support for the ADC found in Renesas RZ/G2L family. diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c index c47ead15f6e5..c5b785d8b241 100644 --- a/drivers/iio/adc/ad7124.c +++ b/drivers/iio/adc/ad7124.c @@ -43,6 +43,8 @@ #define AD7124_STATUS_POR_FLAG_MSK BIT(4) /* AD7124_ADC_CONTROL */ +#define AD7124_ADC_STATUS_EN_MSK BIT(10) +#define AD7124_ADC_STATUS_EN(x) FIELD_PREP(AD7124_ADC_STATUS_EN_MSK, x) #define AD7124_ADC_CTRL_REF_EN_MSK BIT(8) #define AD7124_ADC_CTRL_REF_EN(x) FIELD_PREP(AD7124_ADC_CTRL_REF_EN_MSK, x) #define AD7124_ADC_CTRL_PWR_MSK GENMASK(7, 6) @@ -188,7 +190,6 @@ static const struct iio_chan_spec ad7124_channel_template = { .sign = 'u', .realbits = 24, .storagebits = 32, - .shift = 8, .endianness = IIO_BE, }, }; @@ -501,26 +502,70 @@ static int ad7124_prepare_read(struct ad7124_state *st, int address) return ad7124_enable_channel(st, &st->channels[address]); } +static int __ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int channel) +{ + struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); + + return ad7124_prepare_read(st, channel); +} + static int ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int channel) { struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); int ret; mutex_lock(&st->cfgs_lock); - ret = ad7124_prepare_read(st, channel); + ret = __ad7124_set_channel(sd, channel); mutex_unlock(&st->cfgs_lock); return ret; } +static int ad7124_append_status(struct ad_sigma_delta *sd, bool append) +{ + struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); + unsigned int adc_control = st->adc_control; + int ret; + + adc_control &= ~AD7124_ADC_STATUS_EN_MSK; + adc_control |= AD7124_ADC_STATUS_EN(append); + + ret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, adc_control); + if (ret < 0) + return ret; + + st->adc_control = adc_control; + + return 0; +} + +static int ad7124_disable_all(struct ad_sigma_delta *sd) +{ + struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); + int ret; + int i; + + for (i = 0; i < st->num_channels; i++) { + ret = ad7124_spi_write_mask(st, AD7124_CHANNEL(i), AD7124_CHANNEL_EN_MSK, 0, 2); + if (ret < 0) + return ret; + } + + return 0; +} + static const struct ad_sigma_delta_info ad7124_sigma_delta_info = { .set_channel = ad7124_set_channel, + .append_status = ad7124_append_status, + .disable_all = ad7124_disable_all, .set_mode = ad7124_set_mode, .has_registers = true, .addr_shift = 0, .read_mask = BIT(6), + .status_ch_mask = GENMASK(3, 0), .data_reg = AD7124_DATA, - .irq_flags = IRQF_TRIGGER_FALLING + .num_slots = 8, + .irq_flags = IRQF_TRIGGER_FALLING, }; static int ad7124_read_raw(struct iio_dev *indio_dev, @@ -670,11 +715,40 @@ static const struct attribute_group ad7124_attrs_group = { .attrs = ad7124_attributes, }; +static int ad7124_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct ad7124_state *st = iio_priv(indio_dev); + bool bit_set; + int ret; + int i; + + mutex_lock(&st->cfgs_lock); + for (i = 0; i < st->num_channels; i++) { + bit_set = test_bit(i, scan_mask); + if (bit_set) + ret = __ad7124_set_channel(&st->sd, i); + else + ret = ad7124_spi_write_mask(st, AD7124_CHANNEL(i), AD7124_CHANNEL_EN_MSK, + 0, 2); + if (ret < 0) { + mutex_unlock(&st->cfgs_lock); + + return ret; + } + } + + mutex_unlock(&st->cfgs_lock); + + return 0; +} + static const struct iio_info ad7124_info = { .read_raw = ad7124_read_raw, .write_raw = ad7124_write_raw, .debugfs_reg_access = &ad7124_reg_access, .validate_trigger = ad_sd_validate_trigger, + .update_scan_mode = ad7124_update_scan_mode, .attrs = &ad7124_attrs_group, }; @@ -886,12 +960,14 @@ static int ad7124_probe(struct spi_device *spi) st->chip_info = info; - ad_sd_init(&st->sd, indio_dev, spi, &ad7124_sigma_delta_info); - indio_dev->name = st->chip_info->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &ad7124_info; + ret = ad_sd_init(&st->sd, indio_dev, spi, &ad7124_sigma_delta_info); + if (ret < 0) + return ret; + ret = ad7124_of_parse_channel_config(indio_dev, spi->dev.of_node); if (ret < 0) return ret; diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c index 770b4e59238f..d71977be7d22 100644 --- a/drivers/iio/adc/ad7192.c +++ b/drivers/iio/adc/ad7192.c @@ -58,7 +58,8 @@ /* Mode Register Bit Designations (AD7192_REG_MODE) */ #define AD7192_MODE_SEL(x) (((x) & 0x7) << 21) /* Operation Mode Select */ #define AD7192_MODE_SEL_MASK (0x7 << 21) /* Operation Mode Select Mask */ -#define AD7192_MODE_DAT_STA BIT(20) /* Status Register transmission */ +#define AD7192_MODE_STA(x) (((x) & 0x1) << 20) /* Status Register transmission */ +#define AD7192_MODE_STA_MASK BIT(20) /* Status Register transmission Mask */ #define AD7192_MODE_CLKSRC(x) (((x) & 0x3) << 18) /* Clock Source Select */ #define AD7192_MODE_SINC3 BIT(15) /* SINC3 Filter Select */ #define AD7192_MODE_ACX BIT(14) /* AC excitation enable(AD7195 only)*/ @@ -225,7 +226,7 @@ static ssize_t ad7192_write_syscalib(struct iio_dev *indio_dev, bool sys_calib; int ret, temp; - ret = strtobool(buf, &sys_calib); + ret = kstrtobool(buf, &sys_calib); if (ret) return ret; @@ -288,12 +289,51 @@ static int ad7192_set_mode(struct ad_sigma_delta *sd, return ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); } +static int ad7192_append_status(struct ad_sigma_delta *sd, bool append) +{ + struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd); + unsigned int mode = st->mode; + int ret; + + mode &= ~AD7192_MODE_STA_MASK; + mode |= AD7192_MODE_STA(append); + + ret = ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, mode); + if (ret < 0) + return ret; + + st->mode = mode; + + return 0; +} + +static int ad7192_disable_all(struct ad_sigma_delta *sd) +{ + struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd); + u32 conf = st->conf; + int ret; + + conf &= ~AD7192_CONF_CHAN_MASK; + + ret = ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, conf); + if (ret < 0) + return ret; + + st->conf = conf; + + return 0; +} + static const struct ad_sigma_delta_info ad7192_sigma_delta_info = { .set_channel = ad7192_set_channel, + .append_status = ad7192_append_status, + .disable_all = ad7192_disable_all, .set_mode = ad7192_set_mode, .has_registers = true, .addr_shift = 3, .read_mask = BIT(6), + .status_ch_mask = GENMASK(3, 0), + .num_slots = 4, .irq_flags = IRQF_TRIGGER_FALLING, }; @@ -457,7 +497,7 @@ static ssize_t ad7192_set(struct device *dev, int ret; bool val; - ret = strtobool(buf, &val); + ret = kstrtobool(buf, &val); if (ret < 0) return ret; @@ -783,6 +823,26 @@ static int ad7192_read_avail(struct iio_dev *indio_dev, return -EINVAL; } +static int ad7192_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) +{ + struct ad7192_state *st = iio_priv(indio_dev); + u32 conf = st->conf; + int ret; + int i; + + conf &= ~AD7192_CONF_CHAN_MASK; + for_each_set_bit(i, scan_mask, 8) + conf |= AD7192_CONF_CHAN(i); + + ret = ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, conf); + if (ret < 0) + return ret; + + st->conf = conf; + + return 0; +} + static const struct iio_info ad7192_info = { .read_raw = ad7192_read_raw, .write_raw = ad7192_write_raw, @@ -790,6 +850,7 @@ static const struct iio_info ad7192_info = { .read_avail = ad7192_read_avail, .attrs = &ad7192_attribute_group, .validate_trigger = ad_sd_validate_trigger, + .update_scan_mode = ad7192_update_scan_mode, }; static const struct iio_info ad7195_info = { @@ -799,6 +860,7 @@ static const struct iio_info ad7195_info = { .read_avail = ad7192_read_avail, .attrs = &ad7195_attribute_group, .validate_trigger = ad_sd_validate_trigger, + .update_scan_mode = ad7192_update_scan_mode, }; #define __AD719x_CHANNEL(_si, _channel1, _channel2, _address, _extend_name, \ diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c index c17d9b5fbaf6..f20d39f0bc01 100644 --- a/drivers/iio/adc/ad7266.c +++ b/drivers/iio/adc/ad7266.c @@ -378,6 +378,11 @@ static const char * const ad7266_gpio_labels[] = { "ad0", "ad1", "ad2", }; +static void ad7266_reg_disable(void *reg) +{ + regulator_disable(reg); +} + static int ad7266_probe(struct spi_device *spi) { struct ad7266_platform_data *pdata = spi->dev.platform_data; @@ -398,9 +403,13 @@ static int ad7266_probe(struct spi_device *spi) if (ret) return ret; + ret = devm_add_action_or_reset(&spi->dev, ad7266_reg_disable, st->reg); + if (ret) + return ret; + ret = regulator_get_voltage(st->reg); if (ret < 0) - goto error_disable_reg; + return ret; st->vref_mv = ret / 1000; } else { @@ -423,7 +432,7 @@ static int ad7266_probe(struct spi_device *spi) GPIOD_OUT_LOW); if (IS_ERR(st->gpios[i])) { ret = PTR_ERR(st->gpios[i]); - goto error_disable_reg; + return ret; } } } @@ -433,7 +442,6 @@ static int ad7266_probe(struct spi_device *spi) st->mode = AD7266_MODE_DIFF; } - spi_set_drvdata(spi, indio_dev); st->spi = spi; indio_dev->name = spi_get_device_id(spi)->name; @@ -459,35 +467,12 @@ static int ad7266_probe(struct spi_device *spi) spi_message_add_tail(&st->single_xfer[1], &st->single_msg); spi_message_add_tail(&st->single_xfer[2], &st->single_msg); - ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, &iio_pollfunc_store_time, &ad7266_trigger_handler, &iio_triggered_buffer_setup_ops); if (ret) - goto error_disable_reg; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_buffer_cleanup; - - return 0; - -error_buffer_cleanup: - iio_triggered_buffer_cleanup(indio_dev); -error_disable_reg: - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); - - return ret; -} - -static void ad7266_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad7266_state *st = iio_priv(indio_dev); + return ret; - iio_device_unregister(indio_dev); - iio_triggered_buffer_cleanup(indio_dev); - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + return devm_iio_device_register(&spi->dev, indio_dev); } static const struct spi_device_id ad7266_id[] = { @@ -502,7 +487,6 @@ static struct spi_driver ad7266_driver = { .name = "ad7266", }, .probe = ad7266_probe, - .remove = ad7266_remove, .id_table = ad7266_id, }; module_spi_driver(ad7266_driver); diff --git a/drivers/iio/adc/ad7280a.c b/drivers/iio/adc/ad7280a.c index ec9acbf12b9a..3bdf3d9422f2 100644 --- a/drivers/iio/adc/ad7280a.c +++ b/drivers/iio/adc/ad7280a.c @@ -488,7 +488,7 @@ static ssize_t ad7280_store_balance_sw(struct iio_dev *indio_dev, bool readin; int ret; - ret = strtobool(buf, &readin); + ret = kstrtobool(buf, &readin); if (ret) return ret; diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index ebcd52526cac..261a9a6b45e1 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -6,6 +6,7 @@ * Author: Lars-Peter Clausen <lars@metafoo.de> */ +#include <linux/align.h> #include <linux/interrupt.h> #include <linux/device.h> #include <linux/kernel.h> @@ -342,15 +343,49 @@ EXPORT_SYMBOL_NS_GPL(ad_sigma_delta_single_conversion, IIO_AD_SIGMA_DELTA); static int ad_sd_buffer_postenable(struct iio_dev *indio_dev) { struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + unsigned int i, slot, samples_buf_size; unsigned int channel; + uint8_t *samples_buf; int ret; - channel = find_first_bit(indio_dev->active_scan_mask, - indio_dev->masklength); - ret = ad_sigma_delta_set_channel(sigma_delta, - indio_dev->channels[channel].address); - if (ret) - return ret; + if (sigma_delta->num_slots == 1) { + channel = find_first_bit(indio_dev->active_scan_mask, + indio_dev->masklength); + ret = ad_sigma_delta_set_channel(sigma_delta, + indio_dev->channels[channel].address); + if (ret) + return ret; + slot = 1; + } else { + /* + * At this point update_scan_mode already enabled the required channels. + * For sigma-delta sequencer drivers with multiple slots, an update_scan_mode + * implementation is mandatory. + */ + slot = 0; + for_each_set_bit(i, indio_dev->active_scan_mask, indio_dev->masklength) { + sigma_delta->slots[slot] = indio_dev->channels[i].address; + slot++; + } + } + + sigma_delta->active_slots = slot; + sigma_delta->current_slot = 0; + + if (sigma_delta->active_slots > 1) { + ret = ad_sigma_delta_append_status(sigma_delta, true); + if (ret) + return ret; + } + + samples_buf_size = ALIGN(slot * indio_dev->channels[0].scan_type.storagebits, 8); + samples_buf_size += sizeof(int64_t); + samples_buf = devm_krealloc(&sigma_delta->spi->dev, sigma_delta->samples_buf, + samples_buf_size, GFP_KERNEL); + if (!samples_buf) + return -ENOMEM; + + sigma_delta->samples_buf = samples_buf; spi_bus_lock(sigma_delta->spi->master); sigma_delta->bus_locked = true; @@ -386,6 +421,10 @@ static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev) sigma_delta->keep_cs_asserted = false; ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); + if (sigma_delta->status_appended) + ad_sigma_delta_append_status(sigma_delta, false); + + ad_sigma_delta_disable_all(sigma_delta); sigma_delta->bus_locked = false; return spi_bus_unlock(sigma_delta->spi->master); } @@ -396,6 +435,10 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); uint8_t *data = sigma_delta->rx_buf; + unsigned int transfer_size; + unsigned int sample_size; + unsigned int sample_pos; + unsigned int status_pos; unsigned int reg_size; unsigned int data_reg; @@ -408,21 +451,69 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p) else data_reg = AD_SD_REG_DATA; + /* Status word will be appended to the sample during transfer */ + if (sigma_delta->status_appended) + transfer_size = reg_size + 1; + else + transfer_size = reg_size; + switch (reg_size) { case 4: case 2: case 1: - ad_sd_read_reg_raw(sigma_delta, data_reg, reg_size, &data[0]); + status_pos = reg_size; + ad_sd_read_reg_raw(sigma_delta, data_reg, transfer_size, &data[0]); break; case 3: + /* + * Data array after transfer will look like (if status is appended): + * data[] = { [0][sample][sample][sample][status] } + * Keeping the first byte 0 shifts the status postion by 1 byte to the right. + */ + status_pos = reg_size + 1; + /* We store 24 bit samples in a 32 bit word. Keep the upper * byte set to zero. */ - ad_sd_read_reg_raw(sigma_delta, data_reg, reg_size, &data[1]); + ad_sd_read_reg_raw(sigma_delta, data_reg, transfer_size, &data[1]); break; } - iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp); + /* + * For devices sampling only one channel at + * once, there is no need for sample number tracking. + */ + if (sigma_delta->active_slots == 1) { + iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp); + goto irq_handled; + } + + if (sigma_delta->status_appended) { + u8 converted_channel; + + converted_channel = data[status_pos] & sigma_delta->info->status_ch_mask; + if (converted_channel != sigma_delta->slots[sigma_delta->current_slot]) { + /* + * Desync occurred during continuous sampling of multiple channels. + * Drop this incomplete sample and start from first channel again. + */ + + sigma_delta->current_slot = 0; + goto irq_handled; + } + } + + sample_size = indio_dev->channels[0].scan_type.storagebits / 8; + sample_pos = sample_size * sigma_delta->current_slot; + memcpy(&sigma_delta->samples_buf[sample_pos], data, sample_size); + sigma_delta->current_slot++; + if (sigma_delta->current_slot == sigma_delta->active_slots) { + sigma_delta->current_slot = 0; + iio_push_to_buffers_with_timestamp(indio_dev, sigma_delta->samples_buf, + pf->timestamp); + } + +irq_handled: iio_trigger_notify_done(indio_dev->trig); sigma_delta->irq_dis = false; enable_irq(sigma_delta->spi->irq); @@ -430,10 +521,17 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p) return IRQ_HANDLED; } +static bool ad_sd_validate_scan_mask(struct iio_dev *indio_dev, const unsigned long *mask) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + + return bitmap_weight(mask, indio_dev->masklength) <= sigma_delta->num_slots; +} + static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = { .postenable = &ad_sd_buffer_postenable, .postdisable = &ad_sd_buffer_postdisable, - .validate_scan_mask = &iio_validate_scan_mask_onehot, + .validate_scan_mask = &ad_sd_validate_scan_mask, }; static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private) @@ -513,8 +611,14 @@ static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_de */ int devm_ad_sd_setup_buffer_and_trigger(struct device *dev, struct iio_dev *indio_dev) { + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); int ret; + sigma_delta->slots = devm_kcalloc(dev, sigma_delta->num_slots, + sizeof(*sigma_delta->slots), GFP_KERNEL); + if (!sigma_delta->slots) + return -ENOMEM; + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, &iio_pollfunc_store_time, &ad_sd_trigger_handler, @@ -541,6 +645,25 @@ int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev, { sigma_delta->spi = spi; sigma_delta->info = info; + + /* If the field is unset in ad_sigma_delta_info, asume there can only be 1 slot. */ + if (!info->num_slots) + sigma_delta->num_slots = 1; + else + sigma_delta->num_slots = info->num_slots; + + if (sigma_delta->num_slots > 1) { + if (!indio_dev->info->update_scan_mode) { + dev_err(&spi->dev, "iio_dev lacks update_scan_mode().\n"); + return -EINVAL; + } + + if (!info->disable_all) { + dev_err(&spi->dev, "ad_sigma_delta_info lacks disable_all().\n"); + return -EINVAL; + } + } + iio_device_set_drvdata(indio_dev, sigma_delta); return 0; diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 854b1f81d807..b764823ce57e 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -1117,7 +1117,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev) return at91_adc_configure_touch(st, true); /* if we are not in triggered mode, we cannot enable the buffer. */ - if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES)) + if (!(iio_device_get_current_mode(indio_dev) & INDIO_ALL_TRIGGERED_MODES)) return -EINVAL; /* we continue with the triggered buffer */ @@ -1159,7 +1159,7 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev) return at91_adc_configure_touch(st, false); /* if we are not in triggered mode, nothing to do here */ - if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES)) + if (!(iio_device_get_current_mode(indio_dev) & INDIO_ALL_TRIGGERED_MODES)) return -EINVAL; /* diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 8d902a32a0fd..abad16803849 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -550,7 +550,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev, bool val; int ret; - ret = strtobool(buf, &val); + ret = kstrtobool(buf, &val); if (ret) return ret; @@ -1027,7 +1027,6 @@ static int ina2xx_probe(struct i2c_client *client, indio_dev->name = id->name; ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &ina2xx_setup_ops); if (ret) return ret; diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c index 61e80bf3d05e..fd000345ec5c 100644 --- a/drivers/iio/adc/palmas_gpadc.c +++ b/drivers/iio/adc/palmas_gpadc.c @@ -376,7 +376,8 @@ static int palmas_gpadc_get_calibrated_code(struct palmas_gpadc *adc, adc->adc_info[adc_chan].gain_error; if (val < 0) { - dev_err(adc->dev, "Mismatch with calibration\n"); + if (val < -10) + dev_err(adc->dev, "Mismatch with calibration var = %d\n", val); return 0; } diff --git a/drivers/iio/adc/sc27xx_adc.c b/drivers/iio/adc/sc27xx_adc.c index 00098caf6d9e..e9ff2d6a8a57 100644 --- a/drivers/iio/adc/sc27xx_adc.c +++ b/drivers/iio/adc/sc27xx_adc.c @@ -9,12 +9,16 @@ #include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #include <linux/slab.h> /* PMIC global registers definition */ -#define SC27XX_MODULE_EN 0xc08 +#define SC2730_MODULE_EN 0x1808 +#define SC2731_MODULE_EN 0xc08 #define SC27XX_MODULE_ADC_EN BIT(5) -#define SC27XX_ARM_CLK_EN 0xc10 +#define SC2721_ARM_CLK_EN 0xc0c +#define SC2730_ARM_CLK_EN 0x180c +#define SC2731_ARM_CLK_EN 0xc10 #define SC27XX_CLK_ADC_EN BIT(5) #define SC27XX_CLK_ADC_CLK_EN BIT(6) @@ -36,8 +40,10 @@ /* Bits and mask definition for SC27XX_ADC_CH_CFG register */ #define SC27XX_ADC_CHN_ID_MASK GENMASK(4, 0) -#define SC27XX_ADC_SCALE_MASK GENMASK(10, 8) -#define SC27XX_ADC_SCALE_SHIFT 8 +#define SC27XX_ADC_SCALE_MASK GENMASK(10, 9) +#define SC2721_ADC_SCALE_MASK BIT(5) +#define SC27XX_ADC_SCALE_SHIFT 9 +#define SC2721_ADC_SCALE_SHIFT 5 /* Bits definitions for SC27XX_ADC_INT_EN registers */ #define SC27XX_ADC_IRQ_EN BIT(0) @@ -67,8 +73,15 @@ #define SC27XX_RATIO_NUMERATOR_OFFSET 16 #define SC27XX_RATIO_DENOMINATOR_MASK GENMASK(15, 0) +/* ADC specific channel reference voltage 3.5V */ +#define SC27XX_ADC_REFVOL_VDD35 3500000 + +/* ADC default channel reference voltage is 2.8V */ +#define SC27XX_ADC_REFVOL_VDD28 2800000 + struct sc27xx_adc_data { struct device *dev; + struct regulator *volref; struct regmap *regmap; /* * One hardware spinlock to synchronize between the multiple @@ -78,6 +91,24 @@ struct sc27xx_adc_data { int channel_scale[SC27XX_ADC_CHANNEL_MAX]; u32 base; int irq; + const struct sc27xx_adc_variant_data *var_data; +}; + +/* + * Since different PMICs of SC27xx series can have different + * address and ratio, we should save ratio config and base + * in the device data structure. + */ +struct sc27xx_adc_variant_data { + u32 module_en; + u32 clk_en; + u32 scale_shift; + u32 scale_mask; + const struct sc27xx_adc_linear_graph *bscale_cal; + const struct sc27xx_adc_linear_graph *sscale_cal; + void (*init_scale)(struct sc27xx_adc_data *data); + int (*get_ratio)(int channel, int scale); + bool set_volref; }; struct sc27xx_adc_linear_graph { @@ -103,6 +134,16 @@ static struct sc27xx_adc_linear_graph small_scale_graph = { 100, 341, }; +static const struct sc27xx_adc_linear_graph sc2731_big_scale_graph_calib = { + 4200, 850, + 3600, 728, +}; + +static const struct sc27xx_adc_linear_graph sc2731_small_scale_graph_calib = { + 1000, 838, + 100, 84, +}; + static const struct sc27xx_adc_linear_graph big_scale_graph_calib = { 4200, 856, 3600, 733, @@ -118,49 +159,225 @@ static int sc27xx_adc_get_calib_data(u32 calib_data, int calib_adc) return ((calib_data & 0xff) + calib_adc - 128) * 4; } +/* get the adc nvmem cell calibration data */ +static int adc_nvmem_cell_calib_data(struct sc27xx_adc_data *data, const char *cell_name) +{ + struct nvmem_cell *cell; + void *buf; + u32 origin_calib_data = 0; + size_t len; + + if (!data) + return -EINVAL; + + cell = nvmem_cell_get(data->dev, cell_name); + if (IS_ERR(cell)) + return PTR_ERR(cell); + + buf = nvmem_cell_read(cell, &len); + if (IS_ERR(buf)) { + nvmem_cell_put(cell); + return PTR_ERR(buf); + } + + memcpy(&origin_calib_data, buf, min(len, sizeof(u32))); + + kfree(buf); + nvmem_cell_put(cell); + return origin_calib_data; +} + static int sc27xx_adc_scale_calibration(struct sc27xx_adc_data *data, bool big_scale) { const struct sc27xx_adc_linear_graph *calib_graph; struct sc27xx_adc_linear_graph *graph; - struct nvmem_cell *cell; const char *cell_name; u32 calib_data = 0; - void *buf; - size_t len; if (big_scale) { - calib_graph = &big_scale_graph_calib; + calib_graph = data->var_data->bscale_cal; graph = &big_scale_graph; cell_name = "big_scale_calib"; } else { - calib_graph = &small_scale_graph_calib; + calib_graph = data->var_data->sscale_cal; graph = &small_scale_graph; cell_name = "small_scale_calib"; } - cell = nvmem_cell_get(data->dev, cell_name); - if (IS_ERR(cell)) - return PTR_ERR(cell); - - buf = nvmem_cell_read(cell, &len); - nvmem_cell_put(cell); - - if (IS_ERR(buf)) - return PTR_ERR(buf); - - memcpy(&calib_data, buf, min(len, sizeof(u32))); + calib_data = adc_nvmem_cell_calib_data(data, cell_name); /* Only need to calibrate the adc values in the linear graph. */ graph->adc0 = sc27xx_adc_get_calib_data(calib_data, calib_graph->adc0); graph->adc1 = sc27xx_adc_get_calib_data(calib_data >> 8, calib_graph->adc1); - kfree(buf); return 0; } -static int sc27xx_adc_get_ratio(int channel, int scale) +static int sc2720_adc_get_ratio(int channel, int scale) +{ + switch (channel) { + case 14: + switch (scale) { + case 0: + return SC27XX_VOLT_RATIO(68, 900); + case 1: + return SC27XX_VOLT_RATIO(68, 1760); + case 2: + return SC27XX_VOLT_RATIO(68, 2327); + case 3: + return SC27XX_VOLT_RATIO(68, 3654); + default: + return SC27XX_VOLT_RATIO(1, 1); + } + case 16: + switch (scale) { + case 0: + return SC27XX_VOLT_RATIO(48, 100); + case 1: + return SC27XX_VOLT_RATIO(480, 1955); + case 2: + return SC27XX_VOLT_RATIO(480, 2586); + case 3: + return SC27XX_VOLT_RATIO(48, 406); + default: + return SC27XX_VOLT_RATIO(1, 1); + } + case 21: + case 22: + case 23: + switch (scale) { + case 0: + return SC27XX_VOLT_RATIO(3, 8); + case 1: + return SC27XX_VOLT_RATIO(375, 1955); + case 2: + return SC27XX_VOLT_RATIO(375, 2586); + case 3: + return SC27XX_VOLT_RATIO(300, 3248); + default: + return SC27XX_VOLT_RATIO(1, 1); + } + default: + switch (scale) { + case 0: + return SC27XX_VOLT_RATIO(1, 1); + case 1: + return SC27XX_VOLT_RATIO(1000, 1955); + case 2: + return SC27XX_VOLT_RATIO(1000, 2586); + case 3: + return SC27XX_VOLT_RATIO(100, 406); + default: + return SC27XX_VOLT_RATIO(1, 1); + } + } + return SC27XX_VOLT_RATIO(1, 1); +} + +static int sc2721_adc_get_ratio(int channel, int scale) +{ + switch (channel) { + case 1: + case 2: + case 3: + case 4: + return scale ? SC27XX_VOLT_RATIO(400, 1025) : + SC27XX_VOLT_RATIO(1, 1); + case 5: + return SC27XX_VOLT_RATIO(7, 29); + case 7: + case 9: + return scale ? SC27XX_VOLT_RATIO(100, 125) : + SC27XX_VOLT_RATIO(1, 1); + case 14: + return SC27XX_VOLT_RATIO(68, 900); + case 16: + return SC27XX_VOLT_RATIO(48, 100); + case 19: + return SC27XX_VOLT_RATIO(1, 3); + default: + return SC27XX_VOLT_RATIO(1, 1); + } + return SC27XX_VOLT_RATIO(1, 1); +} + +static int sc2730_adc_get_ratio(int channel, int scale) +{ + switch (channel) { + case 14: + switch (scale) { + case 0: + return SC27XX_VOLT_RATIO(68, 900); + case 1: + return SC27XX_VOLT_RATIO(68, 1760); + case 2: + return SC27XX_VOLT_RATIO(68, 2327); + case 3: + return SC27XX_VOLT_RATIO(68, 3654); + default: + return SC27XX_VOLT_RATIO(1, 1); + } + case 15: + switch (scale) { + case 0: + return SC27XX_VOLT_RATIO(1, 3); + case 1: + return SC27XX_VOLT_RATIO(1000, 5865); + case 2: + return SC27XX_VOLT_RATIO(500, 3879); + case 3: + return SC27XX_VOLT_RATIO(500, 6090); + default: + return SC27XX_VOLT_RATIO(1, 1); + } + case 16: + switch (scale) { + case 0: + return SC27XX_VOLT_RATIO(48, 100); + case 1: + return SC27XX_VOLT_RATIO(480, 1955); + case 2: + return SC27XX_VOLT_RATIO(480, 2586); + case 3: + return SC27XX_VOLT_RATIO(48, 406); + default: + return SC27XX_VOLT_RATIO(1, 1); + } + case 21: + case 22: + case 23: + switch (scale) { + case 0: + return SC27XX_VOLT_RATIO(3, 8); + case 1: + return SC27XX_VOLT_RATIO(375, 1955); + case 2: + return SC27XX_VOLT_RATIO(375, 2586); + case 3: + return SC27XX_VOLT_RATIO(300, 3248); + default: + return SC27XX_VOLT_RATIO(1, 1); + } + default: + switch (scale) { + case 0: + return SC27XX_VOLT_RATIO(1, 1); + case 1: + return SC27XX_VOLT_RATIO(1000, 1955); + case 2: + return SC27XX_VOLT_RATIO(1000, 2586); + case 3: + return SC27XX_VOLT_RATIO(1000, 4060); + default: + return SC27XX_VOLT_RATIO(1, 1); + } + } + return SC27XX_VOLT_RATIO(1, 1); +} + +static int sc2731_adc_get_ratio(int channel, int scale) { switch (channel) { case 1: @@ -185,10 +402,87 @@ static int sc27xx_adc_get_ratio(int channel, int scale) return SC27XX_VOLT_RATIO(1, 1); } +/* + * According to the datasheet set specific value on some channel. + */ +static void sc2720_adc_scale_init(struct sc27xx_adc_data *data) +{ + int i; + + for (i = 0; i < SC27XX_ADC_CHANNEL_MAX; i++) { + switch (i) { + case 5: + data->channel_scale[i] = 3; + break; + case 7: + case 9: + data->channel_scale[i] = 2; + break; + case 13: + data->channel_scale[i] = 1; + break; + case 19: + case 30: + case 31: + data->channel_scale[i] = 3; + break; + default: + data->channel_scale[i] = 0; + break; + } + } +} + +static void sc2730_adc_scale_init(struct sc27xx_adc_data *data) +{ + int i; + + for (i = 0; i < SC27XX_ADC_CHANNEL_MAX; i++) { + switch (i) { + case 5: + case 10: + case 19: + case 30: + case 31: + data->channel_scale[i] = 3; + break; + case 7: + case 9: + data->channel_scale[i] = 2; + break; + case 13: + data->channel_scale[i] = 1; + break; + default: + data->channel_scale[i] = 0; + break; + } + } +} + +static void sc2731_adc_scale_init(struct sc27xx_adc_data *data) +{ + int i; + /* + * In the current software design, SC2731 support 2 scales, + * channels 5 uses big scale, others use smale. + */ + for (i = 0; i < SC27XX_ADC_CHANNEL_MAX; i++) { + switch (i) { + case 5: + data->channel_scale[i] = 1; + break; + default: + data->channel_scale[i] = 0; + break; + } + } +} + static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, int scale, int *val) { - int ret; + int ret, ret_volref; u32 tmp, value, status; ret = hwspin_lock_timeout_raw(data->hwlock, SC27XX_ADC_HWLOCK_TIMEOUT); @@ -197,10 +491,25 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, return ret; } + /* + * According to the sc2721 chip data sheet, the reference voltage of + * specific channel 30 and channel 31 in ADC module needs to be set from + * the default 2.8v to 3.5v. + */ + if ((data->var_data->set_volref) && (channel == 30 || channel == 31)) { + ret = regulator_set_voltage(data->volref, + SC27XX_ADC_REFVOL_VDD35, + SC27XX_ADC_REFVOL_VDD35); + if (ret) { + dev_err(data->dev, "failed to set the volref 3.5v\n"); + goto unlock_adc; + } + } + ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL, SC27XX_ADC_EN, SC27XX_ADC_EN); if (ret) - goto unlock_adc; + goto regulator_restore; ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_CLR, SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR); @@ -208,10 +517,11 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, goto disable_adc; /* Configure the channel id and scale */ - tmp = (scale << SC27XX_ADC_SCALE_SHIFT) & SC27XX_ADC_SCALE_MASK; + tmp = (scale << data->var_data->scale_shift) & data->var_data->scale_mask; tmp |= channel & SC27XX_ADC_CHN_ID_MASK; ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CH_CFG, - SC27XX_ADC_CHN_ID_MASK | SC27XX_ADC_SCALE_MASK, + SC27XX_ADC_CHN_ID_MASK | + data->var_data->scale_mask, tmp); if (ret) goto disable_adc; @@ -249,6 +559,17 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, disable_adc: regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL, SC27XX_ADC_EN, 0); +regulator_restore: + if ((data->var_data->set_volref) && (channel == 30 || channel == 31)) { + ret_volref = regulator_set_voltage(data->volref, + SC27XX_ADC_REFVOL_VDD28, + SC27XX_ADC_REFVOL_VDD28); + if (ret_volref) { + dev_err(data->dev, "failed to set the volref 2.8v,ret_volref = 0x%x\n", + ret_volref); + ret = ret || ret_volref; + } + } unlock_adc: hwspin_unlock_raw(data->hwlock); @@ -262,13 +583,14 @@ static void sc27xx_adc_volt_ratio(struct sc27xx_adc_data *data, int channel, int scale, u32 *div_numerator, u32 *div_denominator) { - u32 ratio = sc27xx_adc_get_ratio(channel, scale); + u32 ratio; + ratio = data->var_data->get_ratio(channel, scale); *div_numerator = ratio >> SC27XX_RATIO_NUMERATOR_OFFSET; *div_denominator = ratio & SC27XX_RATIO_DENOMINATOR_MASK; } -static int sc27xx_adc_to_volt(struct sc27xx_adc_linear_graph *graph, +static int adc_to_volt(struct sc27xx_adc_linear_graph *graph, int raw_adc) { int tmp; @@ -277,6 +599,16 @@ static int sc27xx_adc_to_volt(struct sc27xx_adc_linear_graph *graph, tmp /= (graph->adc0 - graph->adc1); tmp += graph->volt1; + return tmp; +} + +static int sc27xx_adc_to_volt(struct sc27xx_adc_linear_graph *graph, + int raw_adc) +{ + int tmp; + + tmp = adc_to_volt(graph, raw_adc); + return tmp < 0 ? 0 : tmp; } @@ -432,13 +764,13 @@ static int sc27xx_adc_enable(struct sc27xx_adc_data *data) { int ret; - ret = regmap_update_bits(data->regmap, SC27XX_MODULE_EN, + ret = regmap_update_bits(data->regmap, data->var_data->module_en, SC27XX_MODULE_ADC_EN, SC27XX_MODULE_ADC_EN); if (ret) return ret; /* Enable ADC work clock and controller clock */ - ret = regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN, + ret = regmap_update_bits(data->regmap, data->var_data->clk_en, SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN); if (ret) @@ -456,10 +788,10 @@ static int sc27xx_adc_enable(struct sc27xx_adc_data *data) return 0; disable_clk: - regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN, + regmap_update_bits(data->regmap, data->var_data->clk_en, SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, 0); disable_adc: - regmap_update_bits(data->regmap, SC27XX_MODULE_EN, + regmap_update_bits(data->regmap, data->var_data->module_en, SC27XX_MODULE_ADC_EN, 0); return ret; @@ -470,21 +802,76 @@ static void sc27xx_adc_disable(void *_data) struct sc27xx_adc_data *data = _data; /* Disable ADC work clock and controller clock */ - regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN, + regmap_update_bits(data->regmap, data->var_data->clk_en, SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, 0); - regmap_update_bits(data->regmap, SC27XX_MODULE_EN, + regmap_update_bits(data->regmap, data->var_data->module_en, SC27XX_MODULE_ADC_EN, 0); } +static const struct sc27xx_adc_variant_data sc2731_data = { + .module_en = SC2731_MODULE_EN, + .clk_en = SC2731_ARM_CLK_EN, + .scale_shift = SC27XX_ADC_SCALE_SHIFT, + .scale_mask = SC27XX_ADC_SCALE_MASK, + .bscale_cal = &sc2731_big_scale_graph_calib, + .sscale_cal = &sc2731_small_scale_graph_calib, + .init_scale = sc2731_adc_scale_init, + .get_ratio = sc2731_adc_get_ratio, + .set_volref = false, +}; + +static const struct sc27xx_adc_variant_data sc2730_data = { + .module_en = SC2730_MODULE_EN, + .clk_en = SC2730_ARM_CLK_EN, + .scale_shift = SC27XX_ADC_SCALE_SHIFT, + .scale_mask = SC27XX_ADC_SCALE_MASK, + .bscale_cal = &big_scale_graph_calib, + .sscale_cal = &small_scale_graph_calib, + .init_scale = sc2730_adc_scale_init, + .get_ratio = sc2730_adc_get_ratio, + .set_volref = false, +}; + +static const struct sc27xx_adc_variant_data sc2721_data = { + .module_en = SC2731_MODULE_EN, + .clk_en = SC2721_ARM_CLK_EN, + .scale_shift = SC2721_ADC_SCALE_SHIFT, + .scale_mask = SC2721_ADC_SCALE_MASK, + .bscale_cal = &sc2731_big_scale_graph_calib, + .sscale_cal = &sc2731_small_scale_graph_calib, + .init_scale = sc2731_adc_scale_init, + .get_ratio = sc2721_adc_get_ratio, + .set_volref = true, +}; + +static const struct sc27xx_adc_variant_data sc2720_data = { + .module_en = SC2731_MODULE_EN, + .clk_en = SC2721_ARM_CLK_EN, + .scale_shift = SC27XX_ADC_SCALE_SHIFT, + .scale_mask = SC27XX_ADC_SCALE_MASK, + .bscale_cal = &big_scale_graph_calib, + .sscale_cal = &small_scale_graph_calib, + .init_scale = sc2720_adc_scale_init, + .get_ratio = sc2720_adc_get_ratio, + .set_volref = false, +}; + static int sc27xx_adc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct sc27xx_adc_data *sc27xx_data; + const struct sc27xx_adc_variant_data *pdata; struct iio_dev *indio_dev; int ret; + pdata = of_device_get_match_data(dev); + if (!pdata) { + dev_err(dev, "No matching driver data found\n"); + return -EINVAL; + } + indio_dev = devm_iio_device_alloc(dev, sizeof(*sc27xx_data)); if (!indio_dev) return -ENOMEM; @@ -520,6 +907,16 @@ static int sc27xx_adc_probe(struct platform_device *pdev) } sc27xx_data->dev = dev; + if (pdata->set_volref) { + sc27xx_data->volref = devm_regulator_get(dev, "vref"); + if (IS_ERR(sc27xx_data->volref)) { + ret = PTR_ERR(sc27xx_data->volref); + return dev_err_probe(dev, ret, "failed to get ADC volref\n"); + } + } + + sc27xx_data->var_data = pdata; + sc27xx_data->var_data->init_scale(sc27xx_data); ret = sc27xx_adc_enable(sc27xx_data); if (ret) { @@ -546,7 +943,10 @@ static int sc27xx_adc_probe(struct platform_device *pdev) } static const struct of_device_id sc27xx_adc_of_match[] = { - { .compatible = "sprd,sc2731-adc", }, + { .compatible = "sprd,sc2731-adc", .data = &sc2731_data}, + { .compatible = "sprd,sc2730-adc", .data = &sc2730_data}, + { .compatible = "sprd,sc2721-adc", .data = &sc2721_data}, + { .compatible = "sprd,sc2720-adc", .data = &sc2720_data}, { } }; MODULE_DEVICE_TABLE(of, sc27xx_adc_of_match); diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index 9704cf0b9753..6d21ea84fa82 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c @@ -466,8 +466,7 @@ static int stm32_dfsdm_channels_configure(struct iio_dev *indio_dev, * In continuous mode, use fast mode configuration, * if it provides a better resolution. */ - if (adc->nconv == 1 && !trig && - (indio_dev->currentmode & INDIO_BUFFER_SOFTWARE)) { + if (adc->nconv == 1 && !trig && iio_buffer_enabled(indio_dev)) { if (fl->flo[1].res >= fl->flo[0].res) { fl->fast = 1; flo = &fl->flo[1]; @@ -562,7 +561,7 @@ static int stm32_dfsdm_filter_configure(struct iio_dev *indio_dev, cr1 = DFSDM_CR1_RCH(chan->channel); /* Continuous conversions triggered by SPI clk in buffer mode */ - if (indio_dev->currentmode & INDIO_BUFFER_SOFTWARE) + if (iio_buffer_enabled(indio_dev)) cr1 |= DFSDM_CR1_RCONT(1); cr1 |= DFSDM_CR1_RSYNC(fl->sync_mode); diff --git a/drivers/iio/adc/stmpe-adc.c b/drivers/iio/adc/stmpe-adc.c index d2d405388499..000e5cfecb43 100644 --- a/drivers/iio/adc/stmpe-adc.c +++ b/drivers/iio/adc/stmpe-adc.c @@ -61,7 +61,7 @@ struct stmpe_adc { static int stmpe_read_voltage(struct stmpe_adc *info, struct iio_chan_spec const *chan, int *val) { - long ret; + unsigned long ret; mutex_lock(&info->lock); @@ -79,7 +79,7 @@ static int stmpe_read_voltage(struct stmpe_adc *info, ret = wait_for_completion_timeout(&info->completion, STMPE_ADC_TIMEOUT); - if (ret <= 0) { + if (ret == 0) { stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_STA, STMPE_ADC_CH(info->channel)); mutex_unlock(&info->lock); @@ -96,7 +96,7 @@ static int stmpe_read_voltage(struct stmpe_adc *info, static int stmpe_read_temp(struct stmpe_adc *info, struct iio_chan_spec const *chan, int *val) { - long ret; + unsigned long ret; mutex_lock(&info->lock); @@ -114,7 +114,7 @@ static int stmpe_read_temp(struct stmpe_adc *info, ret = wait_for_completion_timeout(&info->completion, STMPE_ADC_TIMEOUT); - if (ret <= 0) { + if (ret == 0) { mutex_unlock(&info->lock); return -ETIMEDOUT; } @@ -345,21 +345,22 @@ static int __maybe_unused stmpe_adc_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(stmpe_adc_pm_ops, NULL, stmpe_adc_resume); +static const struct of_device_id stmpe_adc_ids[] = { + { .compatible = "st,stmpe-adc", }, + { }, +}; +MODULE_DEVICE_TABLE(of, stmpe_adc_ids); + static struct platform_driver stmpe_adc_driver = { .probe = stmpe_adc_probe, .driver = { .name = "stmpe-adc", .pm = &stmpe_adc_pm_ops, + .of_match_table = stmpe_adc_ids, }, }; module_platform_driver(stmpe_adc_driver); -static const struct of_device_id stmpe_adc_ids[] = { - { .compatible = "st,stmpe-adc", }, - { }, -}; -MODULE_DEVICE_TABLE(of, stmpe_adc_ids); - MODULE_AUTHOR("Stefan Agner <stefan.agner@toradex.com>"); MODULE_DESCRIPTION("STMPEXXX ADC driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 068efbce1710..5544da80b636 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -76,10 +76,15 @@ #define ADS1015_DEFAULT_DATA_RATE 4 #define ADS1015_DEFAULT_CHAN 0 -enum chip_ids { - ADSXXXX = 0, - ADS1015, - ADS1115, +struct ads1015_chip_data { + struct iio_chan_spec const *channels; + int num_channels; + const struct iio_info *info; + const int *data_rate; + const int data_rate_len; + const int *scale; + const int scale_len; + bool has_comparator; }; enum ads1015_channels { @@ -94,11 +99,11 @@ enum ads1015_channels { ADS1015_TIMESTAMP, }; -static const unsigned int ads1015_data_rate[] = { +static const int ads1015_data_rate[] = { 128, 250, 490, 920, 1600, 2400, 3300, 3300 }; -static const unsigned int ads1115_data_rate[] = { +static const int ads1115_data_rate[] = { 8, 16, 32, 64, 128, 250, 475, 860 }; @@ -106,10 +111,28 @@ static const unsigned int ads1115_data_rate[] = { * Translation from PGA bits to full-scale positive and negative input voltage * range in mV */ -static int ads1015_fullscale_range[] = { +static const int ads1015_fullscale_range[] = { 6144, 4096, 2048, 1024, 512, 256, 256, 256 }; +static const int ads1015_scale[] = { /* 12bit ADC */ + 256, 11, + 512, 11, + 1024, 11, + 2048, 11, + 4096, 11, + 6144, 11 +}; + +static const int ads1115_scale[] = { /* 16bit ADC */ + 256, 15, + 512, 15, + 1024, 15, + 2048, 15, + 4096, 15, + 6144, 15 +}; + /* * Translation from COMP_QUE field value to the number of successive readings * exceed the threshold values before an interrupt is generated @@ -134,71 +157,53 @@ static const struct iio_event_spec ads1015_events[] = { }, }; -#define ADS1015_V_CHAN(_chan, _addr) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .address = _addr, \ - .channel = _chan, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ - BIT(IIO_CHAN_INFO_SCALE) | \ - BIT(IIO_CHAN_INFO_SAMP_FREQ), \ - .scan_index = _addr, \ - .scan_type = { \ - .sign = 's', \ - .realbits = 12, \ - .storagebits = 16, \ - .shift = 4, \ - .endianness = IIO_CPU, \ - }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ - .datasheet_name = "AIN"#_chan, \ -} - -#define ADS1015_V_DIFF_CHAN(_chan, _chan2, _addr) { \ +/* + * Compile-time check whether _fitbits can accommodate up to _testbits + * bits. Returns _fitbits on success, fails to compile otherwise. + * + * The test works such that it multiplies constant _fitbits by constant + * double-negation of size of a non-empty structure, i.e. it multiplies + * constant _fitbits by constant 1 in each successful compilation case. + * The non-empty structure may contain C11 _Static_assert(), make use of + * this and place the kernel variant of static assert in there, so that + * it performs the compile-time check for _testbits <= _fitbits. Note + * that it is not possible to directly use static_assert in compound + * statements, hence this convoluted construct. + */ +#define FIT_CHECK(_testbits, _fitbits) \ + ( \ + (_fitbits) * \ + !!sizeof(struct { \ + static_assert((_testbits) <= (_fitbits)); \ + int pad; \ + }) \ + ) + +#define ADS1015_V_CHAN(_chan, _addr, _realbits, _shift, _event_spec, _num_event_specs) { \ .type = IIO_VOLTAGE, \ - .differential = 1, \ .indexed = 1, \ .address = _addr, \ .channel = _chan, \ - .channel2 = _chan2, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ - .scan_index = _addr, \ - .scan_type = { \ - .sign = 's', \ - .realbits = 12, \ - .storagebits = 16, \ - .shift = 4, \ - .endianness = IIO_CPU, \ - }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ - .datasheet_name = "AIN"#_chan"-AIN"#_chan2, \ -} - -#define ADS1115_V_CHAN(_chan, _addr) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .address = _addr, \ - .channel = _chan, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + .info_mask_shared_by_all_available = \ BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = _addr, \ .scan_type = { \ .sign = 's', \ - .realbits = 16, \ - .storagebits = 16, \ + .realbits = (_realbits), \ + .storagebits = FIT_CHECK((_realbits) + (_shift), 16), \ + .shift = (_shift), \ .endianness = IIO_CPU, \ }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ + .event_spec = (_event_spec), \ + .num_event_specs = (_num_event_specs), \ .datasheet_name = "AIN"#_chan, \ } -#define ADS1115_V_DIFF_CHAN(_chan, _chan2, _addr) { \ +#define ADS1015_V_DIFF_CHAN(_chan, _chan2, _addr, _realbits, _shift, _event_spec, _num_event_specs) { \ .type = IIO_VOLTAGE, \ .differential = 1, \ .indexed = 1, \ @@ -208,15 +213,19 @@ static const struct iio_event_spec ads1015_events[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = _addr, \ .scan_type = { \ .sign = 's', \ - .realbits = 16, \ - .storagebits = 16, \ + .realbits = (_realbits), \ + .storagebits = FIT_CHECK((_realbits) + (_shift), 16), \ + .shift = (_shift), \ .endianness = IIO_CPU, \ }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ + .event_spec = (_event_spec), \ + .num_event_specs = (_num_event_specs), \ .datasheet_name = "AIN"#_chan"-AIN"#_chan2, \ } @@ -245,7 +254,7 @@ struct ads1015_data { unsigned int comp_mode; struct ads1015_thresh_data thresh_data[ADS1015_CHANNELS]; - unsigned int *data_rate; + const struct ads1015_chip_data *chip; /* * 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 @@ -273,49 +282,91 @@ 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) -{ - 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_range ads1015_writeable_ranges[] = { + regmap_reg_range(ADS1015_CFG_REG, ADS1015_HI_THRESH_REG), +}; + +static const struct regmap_access_table ads1015_writeable_table = { + .yes_ranges = ads1015_writeable_ranges, + .n_yes_ranges = ARRAY_SIZE(ads1015_writeable_ranges), +}; static const struct regmap_config ads1015_regmap_config = { .reg_bits = 8, .val_bits = 16, .max_register = ADS1015_HI_THRESH_REG, - .writeable_reg = ads1015_is_writeable_reg, + .wr_table = &ads1015_writeable_table, +}; + +static const struct regmap_range tla2024_writeable_ranges[] = { + regmap_reg_range(ADS1015_CFG_REG, ADS1015_CFG_REG), +}; + +static const struct regmap_access_table tla2024_writeable_table = { + .yes_ranges = tla2024_writeable_ranges, + .n_yes_ranges = ARRAY_SIZE(tla2024_writeable_ranges), +}; + +static const struct regmap_config tla2024_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .max_register = ADS1015_CFG_REG, + .wr_table = &tla2024_writeable_table, }; static const struct iio_chan_spec ads1015_channels[] = { - ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1), - ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3), - ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3), - ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3), - ADS1015_V_CHAN(0, ADS1015_AIN0), - ADS1015_V_CHAN(1, ADS1015_AIN1), - ADS1015_V_CHAN(2, ADS1015_AIN2), - ADS1015_V_CHAN(3, ADS1015_AIN3), + ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(0, ADS1015_AIN0, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(1, ADS1015_AIN1, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(2, ADS1015_AIN2, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(3, ADS1015_AIN3, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP), }; static const struct iio_chan_spec ads1115_channels[] = { - ADS1115_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1), - ADS1115_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3), - ADS1115_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3), - ADS1115_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3), - ADS1115_V_CHAN(0, ADS1015_AIN0), - ADS1115_V_CHAN(1, ADS1015_AIN1), - ADS1115_V_CHAN(2, ADS1015_AIN2), - ADS1115_V_CHAN(3, ADS1015_AIN3), + ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(0, ADS1015_AIN0, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(1, ADS1015_AIN1, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(2, ADS1015_AIN2, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(3, ADS1015_AIN3, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP), }; +static const struct iio_chan_spec tla2024_channels[] = { + ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 12, 4, NULL, 0), + ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 12, 4, NULL, 0), + ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 12, 4, NULL, 0), + ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 12, 4, NULL, 0), + ADS1015_V_CHAN(0, ADS1015_AIN0, 12, 4, NULL, 0), + ADS1015_V_CHAN(1, ADS1015_AIN1, 12, 4, NULL, 0), + ADS1015_V_CHAN(2, ADS1015_AIN2, 12, 4, NULL, 0), + ADS1015_V_CHAN(3, ADS1015_AIN3, 12, 4, NULL, 0), + IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP), +}; + + #ifdef CONFIG_PM static int ads1015_set_power_state(struct ads1015_data *data, bool on) { @@ -344,6 +395,7 @@ static int ads1015_set_power_state(struct ads1015_data *data, bool on) static int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val) { + const int *data_rate = data->chip->data_rate; int ret, pga, dr, dr_old, conv_time; unsigned int old, mask, cfg; @@ -378,8 +430,8 @@ int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val) } 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 = DIV_ROUND_UP(USEC_PER_SEC, data_rate[dr_old]); + conv_time += DIV_ROUND_UP(USEC_PER_SEC, data_rate[dr]); conv_time += conv_time / 10; /* 10% internal clock inaccuracy */ usleep_range(conv_time, conv_time + 1); data->conv_invalid = false; @@ -445,8 +497,8 @@ static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate) { int i; - for (i = 0; i < ARRAY_SIZE(ads1015_data_rate); i++) { - if (data->data_rate[i] == rate) { + for (i = 0; i < data->chip->data_rate_len; i++) { + if (data->chip->data_rate[i] == rate) { data->channel_data[chan].data_rate = i; return 0; } @@ -455,6 +507,32 @@ static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate) return -EINVAL; } +static int ads1015_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct ads1015_data *data = iio_priv(indio_dev); + + if (chan->type != IIO_VOLTAGE) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + *type = IIO_VAL_FRACTIONAL_LOG2; + *vals = data->chip->scale; + *length = data->chip->scale_len; + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + *type = IIO_VAL_INT; + *vals = data->chip->data_rate; + *length = data->chip->data_rate_len; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + static int ads1015_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -504,7 +582,7 @@ release_direct: break; case IIO_CHAN_INFO_SAMP_FREQ: idx = data->channel_data[chan->address].data_rate; - *val = data->data_rate[idx]; + *val = data->chip->data_rate[idx]; ret = IIO_VAL_INT; break; default: @@ -564,7 +642,7 @@ static int ads1015_read_event(struct iio_dev *indio_dev, 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]; + USEC_PER_SEC / data->chip->data_rate[dr]; *val = period / USEC_PER_SEC; *val2 = period % USEC_PER_SEC; @@ -586,6 +664,7 @@ static int ads1015_write_event(struct iio_dev *indio_dev, int val2) { struct ads1015_data *data = iio_priv(indio_dev); + const int *data_rate = data->chip->data_rate; int realbits = chan->scan_type.realbits; int ret = 0; long long period; @@ -611,7 +690,7 @@ static int ads1015_write_event(struct iio_dev *indio_dev, for (i = 0; i < ARRAY_SIZE(ads1015_comp_queue) - 1; i++) { if (period <= ads1015_comp_queue[i] * - USEC_PER_SEC / data->data_rate[dr]) + USEC_PER_SEC / data_rate[dr]) break; } data->thresh_data[chan->address].comp_queue = i; @@ -802,54 +881,20 @@ static const struct iio_buffer_setup_ops ads1015_buffer_setup_ops = { .validate_scan_mask = &iio_validate_scan_mask_onehot, }; -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"); -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_ads1015_scale_available.dev_attr.attr, - &iio_const_attr_ads1015_sampling_frequency_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ads1015_attribute_group = { - .attrs = ads1015_attributes, -}; - -static struct attribute *ads1115_attributes[] = { - &iio_const_attr_ads1115_scale_available.dev_attr.attr, - &iio_const_attr_ads1115_sampling_frequency_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ads1115_attribute_group = { - .attrs = ads1115_attributes, -}; - static const struct iio_info ads1015_info = { + .read_avail = ads1015_read_avail, .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 = { +static const struct iio_info tla2024_info = { + .read_avail = ads1015_read_avail, .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, }; static int ads1015_client_get_channels_config(struct i2c_client *client) @@ -932,12 +977,18 @@ static int ads1015_set_conv_mode(struct ads1015_data *data, int mode) static int ads1015_probe(struct i2c_client *client, const struct i2c_device_id *id) { + const struct ads1015_chip_data *chip; struct iio_dev *indio_dev; struct ads1015_data *data; int ret; - enum chip_ids chip; int i; + chip = device_get_match_data(&client->dev); + if (!chip) + chip = (const struct ads1015_chip_data *)id->driver_data; + if (!chip) + return dev_err_probe(&client->dev, -EINVAL, "Unknown chip\n"); + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; @@ -950,28 +1001,12 @@ static int ads1015_probe(struct i2c_client *client, indio_dev->name = ADS1015_DRV_NAME; indio_dev->modes = INDIO_DIRECT_MODE; - chip = (uintptr_t)device_get_match_data(&client->dev); - if (chip == ADSXXXX) - chip = id->driver_data; - switch (chip) { - case ADS1015: - indio_dev->channels = ads1015_channels; - indio_dev->num_channels = ARRAY_SIZE(ads1015_channels); - indio_dev->info = &ads1015_info; - data->data_rate = (unsigned int *) &ads1015_data_rate; - break; - case ADS1115: - indio_dev->channels = ads1115_channels; - indio_dev->num_channels = ARRAY_SIZE(ads1115_channels); - indio_dev->info = &ads1115_info; - data->data_rate = (unsigned int *) &ads1115_data_rate; - break; - default: - dev_err(&client->dev, "Unknown chip %d\n", chip); - return -EINVAL; - } - + indio_dev->channels = chip->channels; + indio_dev->num_channels = chip->num_channels; + indio_dev->info = chip->info; + data->chip = chip; data->event_channel = ADS1015_CHANNELS; + /* * Set default lower and upper threshold to min and max value * respectively. @@ -986,7 +1021,9 @@ static int ads1015_probe(struct i2c_client *client, /* we need to keep this ABI the same as used by hwmon ADS1015 driver */ ads1015_get_channels_config(client); - data->regmap = devm_regmap_init_i2c(client, &ads1015_regmap_config); + data->regmap = devm_regmap_init_i2c(client, chip->has_comparator ? + &ads1015_regmap_config : + &tla2024_regmap_config); if (IS_ERR(data->regmap)) { dev_err(&client->dev, "Failed to allocate register map\n"); return PTR_ERR(data->regmap); @@ -1000,7 +1037,7 @@ static int ads1015_probe(struct i2c_client *client, return ret; } - if (client->irq) { + if (client->irq && chip->has_comparator) { unsigned long irq_trig = irqd_get_trigger_type(irq_get_irq_data(client->irq)); unsigned int cfg_comp_mask = ADS1015_CFG_COMP_QUE_MASK | @@ -1099,22 +1136,51 @@ static const struct dev_pm_ops ads1015_pm_ops = { ads1015_runtime_resume, NULL) }; +static const struct ads1015_chip_data ads1015_data = { + .channels = ads1015_channels, + .num_channels = ARRAY_SIZE(ads1015_channels), + .info = &ads1015_info, + .data_rate = ads1015_data_rate, + .data_rate_len = ARRAY_SIZE(ads1015_data_rate), + .scale = ads1015_scale, + .scale_len = ARRAY_SIZE(ads1015_scale), + .has_comparator = true, +}; + +static const struct ads1015_chip_data ads1115_data = { + .channels = ads1115_channels, + .num_channels = ARRAY_SIZE(ads1115_channels), + .info = &ads1015_info, + .data_rate = ads1115_data_rate, + .data_rate_len = ARRAY_SIZE(ads1115_data_rate), + .scale = ads1115_scale, + .scale_len = ARRAY_SIZE(ads1115_scale), + .has_comparator = true, +}; + +static const struct ads1015_chip_data tla2024_data = { + .channels = tla2024_channels, + .num_channels = ARRAY_SIZE(tla2024_channels), + .info = &tla2024_info, + .data_rate = ads1015_data_rate, + .data_rate_len = ARRAY_SIZE(ads1015_data_rate), + .scale = ads1015_scale, + .scale_len = ARRAY_SIZE(ads1015_scale), + .has_comparator = false, +}; + static const struct i2c_device_id ads1015_id[] = { - {"ads1015", ADS1015}, - {"ads1115", ADS1115}, + { "ads1015", (kernel_ulong_t)&ads1015_data }, + { "ads1115", (kernel_ulong_t)&ads1115_data }, + { "tla2024", (kernel_ulong_t)&tla2024_data }, {} }; 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 - }, + { .compatible = "ti,ads1015", .data = &ads1015_data }, + { .compatible = "ti,ads1115", .data = &ads1115_data }, + { .compatible = "ti,tla2024", .data = &tla2024_data }, {} }; MODULE_DEVICE_TABLE(of, ads1015_of_match); diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c index 22c2583eedd0..708cca0a63be 100644 --- a/drivers/iio/adc/ti-ads8688.c +++ b/drivers/iio/adc/ti-ads8688.c @@ -508,6 +508,7 @@ MODULE_DEVICE_TABLE(of, ads8688_of_match); static struct spi_driver ads8688_driver = { .driver = { .name = "ads8688", + .of_match_table = ads8688_of_match, }, .probe = ads8688_probe, .remove = ads8688_remove, diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index dbdc1ef48566..567d43a30955 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -376,9 +376,7 @@ static int tiadc_iio_buffered_hardware_setup(struct device *dev, { int ret; - ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, - INDIO_BUFFER_SOFTWARE, - setup_ops); + ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, setup_ops); if (ret) return ret; diff --git a/drivers/iio/afe/Kconfig b/drivers/iio/afe/Kconfig index 4fa397822cff..9a1d95c1c7ed 100644 --- a/drivers/iio/afe/Kconfig +++ b/drivers/iio/afe/Kconfig @@ -8,7 +8,6 @@ menu "Analog Front Ends" config IIO_RESCALE tristate "IIO rescale" - depends on OF || COMPILE_TEST help Say yes here to build support for the IIO rescaling that handles voltage dividers, current sense shunts and diff --git a/drivers/iio/afe/iio-rescale.c b/drivers/iio/afe/iio-rescale.c index 7e511293d6d1..c6cf709f0f05 100644 --- a/drivers/iio/afe/iio-rescale.c +++ b/drivers/iio/afe/iio-rescale.c @@ -10,9 +10,8 @@ #include <linux/err.h> #include <linux/gcd.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/property.h> @@ -536,7 +535,7 @@ static int rescale_probe(struct platform_device *pdev) rescale = iio_priv(indio_dev); - rescale->cfg = of_device_get_match_data(dev); + rescale->cfg = device_get_match_data(dev); rescale->numerator = 1; rescale->denominator = 1; rescale->offset = 0; diff --git a/drivers/iio/buffer/kfifo_buf.c b/drivers/iio/buffer/kfifo_buf.c index 416d35a61ae2..35d8b4077376 100644 --- a/drivers/iio/buffer/kfifo_buf.c +++ b/drivers/iio/buffer/kfifo_buf.c @@ -259,8 +259,6 @@ static struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev) * devm_iio_kfifo_buffer_setup_ext - Allocate a kfifo buffer & attach it to an IIO device * @dev: Device object to which to attach the life-time of this kfifo buffer * @indio_dev: The device the buffer should be attached to - * @mode_flags: The mode flags for this buffer (INDIO_BUFFER_SOFTWARE and/or - * INDIO_BUFFER_TRIGGERED). * @setup_ops: The setup_ops required to configure the HW part of the buffer (optional) * @buffer_attrs: Extra sysfs buffer attributes for this IIO buffer * @@ -271,22 +269,16 @@ static struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev) */ int devm_iio_kfifo_buffer_setup_ext(struct device *dev, struct iio_dev *indio_dev, - int mode_flags, const struct iio_buffer_setup_ops *setup_ops, const struct attribute **buffer_attrs) { struct iio_buffer *buffer; - if (!mode_flags) - return -EINVAL; - buffer = devm_iio_kfifo_allocate(dev); if (!buffer) return -ENOMEM; - mode_flags &= kfifo_access_funcs.modes; - - indio_dev->modes |= mode_flags; + indio_dev->modes |= INDIO_BUFFER_SOFTWARE; indio_dev->setup_ops = setup_ops; buffer->attrs = buffer_attrs; diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c index b2725c6adc7f..5976aca48e3b 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c @@ -333,8 +333,7 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, * We can not use trigger here, as events are generated * as soon as sample_frequency is set. */ - ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev, - INDIO_BUFFER_SOFTWARE, NULL, + ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev, NULL, cros_ec_sensor_fifo_attributes); if (ret) return ret; @@ -413,7 +412,7 @@ static ssize_t cros_ec_sensors_calibrate(struct iio_dev *indio_dev, int ret, i; bool calibrate; - ret = strtobool(buf, &calibrate); + ret = kstrtobool(buf, &calibrate); if (ret < 0) return ret; if (!calibrate) diff --git a/drivers/iio/common/scmi_sensors/scmi_iio.c b/drivers/iio/common/scmi_sensors/scmi_iio.c index d538bf3ab1ef..793d628db55f 100644 --- a/drivers/iio/common/scmi_sensors/scmi_iio.c +++ b/drivers/iio/common/scmi_sensors/scmi_iio.c @@ -686,7 +686,6 @@ static int scmi_iio_dev_probe(struct scmi_device *sdev) err = devm_iio_kfifo_buffer_setup(&scmi_iio_dev->dev, scmi_iio_dev, - INDIO_BUFFER_SOFTWARE, &scmi_iio_buffer_ops); if (err < 0) { dev_err(dev, diff --git a/drivers/iio/common/ssp_sensors/ssp_spi.c b/drivers/iio/common/ssp_sensors/ssp_spi.c index 769bd9280524..f32b04b63ea1 100644 --- a/drivers/iio/common/ssp_sensors/ssp_spi.c +++ b/drivers/iio/common/ssp_sensors/ssp_spi.c @@ -331,12 +331,11 @@ static int ssp_parse_dataframe(struct ssp_data *data, char *dataframe, int len) /* threaded irq */ int ssp_irq_msg(struct ssp_data *data) { - bool found = false; char *buffer; u8 msg_type; int ret; u16 length, msg_options; - struct ssp_msg *msg, *n; + struct ssp_msg *msg = NULL, *iter, *n; ret = spi_read(data->spi, data->header_buffer, SSP_HEADER_BUFFER_SIZE); if (ret < 0) { @@ -362,15 +361,15 @@ int ssp_irq_msg(struct ssp_data *data) * received with no order */ mutex_lock(&data->pending_lock); - list_for_each_entry_safe(msg, n, &data->pending_list, list) { - if (msg->options == msg_options) { - list_del(&msg->list); - found = true; + list_for_each_entry_safe(iter, n, &data->pending_list, list) { + if (iter->options == msg_options) { + list_del(&iter->list); + msg = iter; break; } } - if (!found) { + if (!msg) { /* * here can be implemented dead messages handling * but the slave should not send such ones - it is to diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index fa9bcdf0d190..9910ba1da085 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -71,16 +71,18 @@ st_sensors_match_odr_error: int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr) { - int err; + int err = 0; struct st_sensor_odr_avl odr_out = {0, 0}; struct st_sensor_data *sdata = iio_priv(indio_dev); + mutex_lock(&sdata->odr_lock); + if (!sdata->sensor_settings->odr.mask) - return 0; + goto unlock_mutex; err = st_sensors_match_odr(sdata->sensor_settings, odr, &odr_out); if (err < 0) - goto st_sensors_match_odr_error; + goto unlock_mutex; if ((sdata->sensor_settings->odr.addr == sdata->sensor_settings->pw.addr) && @@ -103,7 +105,9 @@ int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr) if (err >= 0) sdata->odr = odr_out.hz; -st_sensors_match_odr_error: +unlock_mutex: + mutex_unlock(&sdata->odr_lock); + return err; } EXPORT_SYMBOL_NS(st_sensors_set_odr, IIO_ST_SENSORS); @@ -361,6 +365,8 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev, struct st_sensors_platform_data *of_pdata; int err = 0; + mutex_init(&sdata->odr_lock); + /* If OF/DT pdata exists, it will take precedence of anything else */ of_pdata = st_sensors_dev_probe(indio_dev->dev.parent, pdata); if (IS_ERR(of_pdata)) @@ -549,26 +555,28 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev, int err; struct st_sensor_data *sdata = iio_priv(indio_dev); - mutex_lock(&indio_dev->mlock); - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { - err = -EBUSY; + err = iio_device_claim_direct_mode(indio_dev); + if (err) + return err; + + mutex_lock(&sdata->odr_lock); + + err = st_sensors_set_enable(indio_dev, true); + if (err < 0) goto out; - } else { - err = st_sensors_set_enable(indio_dev, true); - if (err < 0) - goto out; - msleep((sdata->sensor_settings->bootime * 1000) / sdata->odr); - err = st_sensors_read_axis_data(indio_dev, ch, val); - if (err < 0) - goto out; + msleep((sdata->sensor_settings->bootime * 1000) / sdata->odr); + err = st_sensors_read_axis_data(indio_dev, ch, val); + if (err < 0) + goto out; - *val = *val >> ch->scan_type.shift; + *val = *val >> ch->scan_type.shift; + + err = st_sensors_set_enable(indio_dev, false); - err = st_sensors_set_enable(indio_dev, false); - } out: - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&sdata->odr_lock); + iio_device_release_direct_mode(indio_dev); return err; } @@ -641,7 +649,6 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev, struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct st_sensor_data *sdata = iio_priv(indio_dev); - mutex_lock(&indio_dev->mlock); for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) { if (sdata->sensor_settings->odr.odr_avl[i].hz == 0) break; @@ -649,7 +656,6 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev, len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", sdata->sensor_settings->odr.odr_avl[i].hz); } - mutex_unlock(&indio_dev->mlock); buf[len - 1] = '\n'; return len; @@ -663,7 +669,6 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev, struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct st_sensor_data *sdata = iio_priv(indio_dev); - mutex_lock(&indio_dev->mlock); for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) { if (sdata->sensor_settings->fs.fs_avl[i].num == 0) break; @@ -673,7 +678,6 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev, len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ", q, r); } - mutex_unlock(&indio_dev->mlock); buf[len - 1] = '\n'; return len; diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index c0bf0d84197f..d1c7bde8aece 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -285,7 +285,6 @@ config CIO_DAC config DPOT_DAC tristate "DAC emulation using a DPOT" - depends on OF help Say yes here to build support for DAC emulation using a digital potentiometer. @@ -305,7 +304,7 @@ config DS4424 config LPC18XX_DAC tristate "NXP LPC18xx DAC driver" depends on ARCH_LPC18XX || COMPILE_TEST - depends on OF && HAS_IOMEM + depends on HAS_IOMEM help Say yes here to build support for NXP LPC18XX DAC. @@ -442,7 +441,6 @@ config TI_DAC7612 config VF610_DAC tristate "Vybrid vf610 DAC driver" - depends on OF depends on HAS_IOMEM help Say yes here to support Vybrid board digital-to-analog converter. diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index 27ee2c63c5d4..d87cf14daabe 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -288,7 +288,7 @@ static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev, bool pwr_down; int ret; - ret = strtobool(buf, &pwr_down); + ret = kstrtobool(buf, &pwr_down); if (ret) return ret; diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c index ecbc6a51d60f..22b000a40828 100644 --- a/drivers/iio/dac/ad5360.c +++ b/drivers/iio/dac/ad5360.c @@ -284,7 +284,7 @@ static ssize_t ad5360_write_dac_powerdown(struct device *dev, bool pwr_down; int ret; - ret = strtobool(buf, &pwr_down); + ret = kstrtobool(buf, &pwr_down); if (ret) return ret; diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c index 82e1d9bd773e..a44c83242fb1 100644 --- a/drivers/iio/dac/ad5380.c +++ b/drivers/iio/dac/ad5380.c @@ -96,7 +96,7 @@ static ssize_t ad5380_write_dac_powerdown(struct iio_dev *indio_dev, bool pwr_down; int ret; - ret = strtobool(buf, &pwr_down); + ret = kstrtobool(buf, &pwr_down); if (ret) return ret; diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index fdf824041497..09e242949cd0 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -114,7 +114,7 @@ static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev, bool powerdown; int ret; - ret = strtobool(buf, &powerdown); + ret = kstrtobool(buf, &powerdown); if (ret) return ret; diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c index 8507573aa13e..a0817e799cc0 100644 --- a/drivers/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c @@ -182,7 +182,7 @@ static ssize_t ad5504_write_dac_powerdown(struct iio_dev *indio_dev, int ret; struct ad5504_state *st = iio_priv(indio_dev); - ret = strtobool(buf, &pwr_down); + ret = kstrtobool(buf, &pwr_down); if (ret) return ret; diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c index 371e812850eb..7e6f824de299 100644 --- a/drivers/iio/dac/ad5624r_spi.c +++ b/drivers/iio/dac/ad5624r_spi.c @@ -129,7 +129,7 @@ static ssize_t ad5624r_write_dac_powerdown(struct iio_dev *indio_dev, int ret; struct ad5624r_state *st = iio_priv(indio_dev); - ret = strtobool(buf, &pwr_down); + ret = kstrtobool(buf, &pwr_down); if (ret) return ret; diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index f78dd3f33199..15361d8bbf94 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -73,7 +73,7 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, unsigned int val, ref_bit_msk; u8 shift, address = 0; - ret = strtobool(buf, &readin); + ret = kstrtobool(buf, &readin); if (ret) return ret; diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c index 7a62e6e1d5f1..1a63b8456725 100644 --- a/drivers/iio/dac/ad5755.c +++ b/drivers/iio/dac/ad5755.c @@ -502,7 +502,7 @@ static ssize_t ad5755_write_powerdown(struct iio_dev *indio_dev, uintptr_t priv, bool pwr_down; int ret; - ret = strtobool(buf, &pwr_down); + ret = kstrtobool(buf, &pwr_down); if (ret) return ret; diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c index 2b14914b4050..339564fe47d1 100644 --- a/drivers/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c @@ -188,7 +188,7 @@ static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev, int ret; struct ad5791_state *st = iio_priv(indio_dev); - ret = strtobool(buf, &pwr_down); + ret = kstrtobool(buf, &pwr_down); if (ret) return ret; diff --git a/drivers/iio/dac/ad7303.c b/drivers/iio/dac/ad7303.c index 91eaaf793b3e..03edf046dec6 100644 --- a/drivers/iio/dac/ad7303.c +++ b/drivers/iio/dac/ad7303.c @@ -77,7 +77,7 @@ static ssize_t ad7303_write_dac_powerdown(struct iio_dev *indio_dev, bool pwr_down; int ret; - ret = strtobool(buf, &pwr_down); + ret = kstrtobool(buf, &pwr_down); if (ret) return ret; diff --git a/drivers/iio/dac/ltc2632.c b/drivers/iio/dac/ltc2632.c index aed46c80757e..3a3c4f4874e4 100644 --- a/drivers/iio/dac/ltc2632.c +++ b/drivers/iio/dac/ltc2632.c @@ -10,6 +10,7 @@ #include <linux/spi/spi.h> #include <linux/module.h> #include <linux/iio/iio.h> +#include <linux/property.h> #include <linux/regulator/consumer.h> #include <asm/unaligned.h> @@ -149,7 +150,7 @@ static ssize_t ltc2632_write_dac_powerdown(struct iio_dev *indio_dev, int ret; struct ltc2632_state *st = iio_priv(indio_dev); - ret = strtobool(buf, &pwr_down); + ret = kstrtobool(buf, &pwr_down); if (ret) return ret; @@ -362,8 +363,7 @@ static int ltc2632_probe(struct spi_device *spi) } } - indio_dev->name = dev_of_node(&spi->dev) ? dev_of_node(&spi->dev)->name - : spi_get_device_id(spi)->name; + indio_dev->name = fwnode_get_name(dev_fwnode(&spi->dev)) ?: spi_get_device_id(spi)->name; indio_dev->info = <c2632_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = chip_info->channels; @@ -469,7 +469,7 @@ MODULE_DEVICE_TABLE(of, ltc2632_of_match); static struct spi_driver ltc2632_driver = { .driver = { .name = "ltc2632", - .of_match_table = of_match_ptr(ltc2632_of_match), + .of_match_table = ltc2632_of_match, }, .probe = ltc2632_probe, .remove = ltc2632_remove, diff --git a/drivers/iio/dac/ltc2688.c b/drivers/iio/dac/ltc2688.c index 2f9c384885f4..937b0d25a11c 100644 --- a/drivers/iio/dac/ltc2688.c +++ b/drivers/iio/dac/ltc2688.c @@ -703,21 +703,20 @@ static int ltc2688_tgp_clk_setup(struct ltc2688_state *st, struct ltc2688_chan *chan, struct fwnode_handle *node, int tgp) { + struct device *dev = &st->spi->dev; unsigned long rate; struct clk *clk; int ret, f; - clk = devm_get_clk_from_child(&st->spi->dev, to_of_node(node), NULL); + clk = devm_get_clk_from_child(dev, to_of_node(node), NULL); if (IS_ERR(clk)) - return dev_err_probe(&st->spi->dev, PTR_ERR(clk), - "failed to get tgp clk.\n"); + return dev_err_probe(dev, PTR_ERR(clk), "failed to get tgp clk.\n"); ret = clk_prepare_enable(clk); if (ret) - return dev_err_probe(&st->spi->dev, ret, - "failed to enable tgp clk.\n"); + return dev_err_probe(dev, ret, "failed to enable tgp clk.\n"); - ret = devm_add_action_or_reset(&st->spi->dev, ltc2688_clk_disable, clk); + ret = devm_add_action_or_reset(dev, ltc2688_clk_disable, clk); if (ret) return ret; @@ -858,6 +857,7 @@ static int ltc2688_channel_config(struct ltc2688_state *st) static int ltc2688_setup(struct ltc2688_state *st, struct regulator *vref) { + struct device *dev = &st->spi->dev; struct gpio_desc *gpio; int ret; @@ -865,10 +865,9 @@ static int ltc2688_setup(struct ltc2688_state *st, struct regulator *vref) * If we have a reset pin, use that to reset the board, If not, use * the reset bit. */ - gpio = devm_gpiod_get_optional(&st->spi->dev, "clr", GPIOD_OUT_HIGH); + gpio = devm_gpiod_get_optional(dev, "clr", GPIOD_OUT_HIGH); if (IS_ERR(gpio)) - return dev_err_probe(&st->spi->dev, PTR_ERR(gpio), - "Failed to get reset gpio"); + return dev_err_probe(dev, PTR_ERR(gpio), "Failed to get reset gpio"); if (gpio) { usleep_range(1000, 1200); /* bring device out of reset */ @@ -887,7 +886,7 @@ static int ltc2688_setup(struct ltc2688_state *st, struct regulator *vref) * Duplicate the default channel configuration as it can change during * @ltc2688_channel_config() */ - st->iio_chan = devm_kmemdup(&st->spi->dev, ltc2688_channels, + st->iio_chan = devm_kmemdup(dev, ltc2688_channels, sizeof(ltc2688_channels), GFP_KERNEL); if (!st->iio_chan) return -ENOMEM; diff --git a/drivers/iio/dac/max5821.c b/drivers/iio/dac/max5821.c index fce640b7f1c8..540f9ea7cada 100644 --- a/drivers/iio/dac/max5821.c +++ b/drivers/iio/dac/max5821.c @@ -116,7 +116,7 @@ static ssize_t max5821_write_dac_powerdown(struct iio_dev *indio_dev, bool powerdown; int ret; - ret = strtobool(buf, &powerdown); + ret = kstrtobool(buf, &powerdown); if (ret) return ret; diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index 842bad57cb88..7fcb86288823 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -80,7 +80,7 @@ static ssize_t mcp4725_store_eeprom(struct device *dev, bool state; int ret; - ret = strtobool(buf, &state); + ret = kstrtobool(buf, &state); if (ret < 0) return ret; @@ -178,7 +178,7 @@ static ssize_t mcp4725_write_powerdown(struct iio_dev *indio_dev, bool state; int ret; - ret = strtobool(buf, &state); + ret = kstrtobool(buf, &state); if (ret) return ret; diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c index b20192a071cb..daa42bcbae83 100644 --- a/drivers/iio/dac/stm32-dac.c +++ b/drivers/iio/dac/stm32-dac.c @@ -220,7 +220,7 @@ static ssize_t stm32_dac_write_powerdown(struct iio_dev *indio_dev, bool powerdown; int ret; - ret = strtobool(buf, &powerdown); + ret = kstrtobool(buf, &powerdown); if (ret) return ret; diff --git a/drivers/iio/dac/ti-dac082s085.c b/drivers/iio/dac/ti-dac082s085.c index 4e1156e6deb2..106ce3546419 100644 --- a/drivers/iio/dac/ti-dac082s085.c +++ b/drivers/iio/dac/ti-dac082s085.c @@ -133,7 +133,7 @@ static ssize_t ti_dac_write_powerdown(struct iio_dev *indio_dev, bool powerdown; int ret; - ret = strtobool(buf, &powerdown); + ret = kstrtobool(buf, &powerdown); if (ret) return ret; diff --git a/drivers/iio/dac/ti-dac5571.c b/drivers/iio/dac/ti-dac5571.c index 0b775f943db3..4b6b04038e94 100644 --- a/drivers/iio/dac/ti-dac5571.c +++ b/drivers/iio/dac/ti-dac5571.c @@ -179,7 +179,7 @@ static ssize_t dac5571_write_powerdown(struct iio_dev *indio_dev, bool powerdown; int ret; - ret = strtobool(buf, &powerdown); + ret = kstrtobool(buf, &powerdown); if (ret) return ret; diff --git a/drivers/iio/dac/ti-dac7311.c b/drivers/iio/dac/ti-dac7311.c index e10d17e60ed3..4afc411725d9 100644 --- a/drivers/iio/dac/ti-dac7311.c +++ b/drivers/iio/dac/ti-dac7311.c @@ -123,7 +123,7 @@ static ssize_t ti_dac_write_powerdown(struct iio_dev *indio_dev, u8 power; int ret; - ret = strtobool(buf, &powerdown); + ret = kstrtobool(buf, &powerdown); if (ret) return ret; diff --git a/drivers/iio/dummy/iio_simple_dummy.c b/drivers/iio/dummy/iio_simple_dummy.c index c0b7ef900735..c24f609c2ade 100644 --- a/drivers/iio/dummy/iio_simple_dummy.c +++ b/drivers/iio/dummy/iio_simple_dummy.c @@ -575,10 +575,9 @@ static struct iio_sw_device *iio_dummy_probe(const char *name) */ swd = kzalloc(sizeof(*swd), GFP_KERNEL); - if (!swd) { - ret = -ENOMEM; - goto error_kzalloc; - } + if (!swd) + return ERR_PTR(-ENOMEM); + /* * Allocate an IIO device. * @@ -590,7 +589,7 @@ static struct iio_sw_device *iio_dummy_probe(const char *name) indio_dev = iio_device_alloc(parent, sizeof(*st)); if (!indio_dev) { ret = -ENOMEM; - goto error_ret; + goto error_free_swd; } st = iio_priv(indio_dev); @@ -616,6 +615,10 @@ static struct iio_sw_device *iio_dummy_probe(const char *name) * indio_dev->name = spi_get_device_id(spi)->name; */ indio_dev->name = kstrdup(name, GFP_KERNEL); + if (!indio_dev->name) { + ret = -ENOMEM; + goto error_free_device; + } /* Provide description of available channels */ indio_dev->channels = iio_dummy_channels; @@ -632,7 +635,7 @@ static struct iio_sw_device *iio_dummy_probe(const char *name) ret = iio_simple_dummy_events_register(indio_dev); if (ret < 0) - goto error_free_device; + goto error_free_name; ret = iio_simple_dummy_configure_buffer(indio_dev); if (ret < 0) @@ -649,11 +652,12 @@ error_unconfigure_buffer: iio_simple_dummy_unconfigure_buffer(indio_dev); error_unregister_events: iio_simple_dummy_events_unregister(indio_dev); +error_free_name: + kfree(indio_dev->name); error_free_device: iio_device_free(indio_dev); -error_ret: +error_free_swd: kfree(swd); -error_kzalloc: return ERR_PTR(ret); } diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c index a0f92c336fc4..942870539268 100644 --- a/drivers/iio/frequency/ad9523.c +++ b/drivers/iio/frequency/ad9523.c @@ -516,7 +516,7 @@ static ssize_t ad9523_store(struct device *dev, bool state; int ret; - ret = strtobool(buf, &state); + ret = kstrtobool(buf, &state); if (ret < 0) return ret; diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c index 410e5e9f2672..0923fd793492 100644 --- a/drivers/iio/gyro/fxas21002c_core.c +++ b/drivers/iio/gyro/fxas21002c_core.c @@ -7,9 +7,9 @@ #include <linux/interrupt.h> #include <linux/module.h> -#include <linux/of_irq.h> #include <linux/pm.h> #include <linux/pm_runtime.h> +#include <linux/property.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> @@ -822,7 +822,6 @@ static int fxas21002c_trigger_probe(struct fxas21002c_data *data) { struct device *dev = regmap_get_device(data->regmap); struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct device_node *np = indio_dev->dev.of_node; unsigned long irq_trig; bool irq_open_drain; int irq1; @@ -831,8 +830,7 @@ static int fxas21002c_trigger_probe(struct fxas21002c_data *data) if (!data->irq) return 0; - irq1 = of_irq_get_byname(np, "INT1"); - + irq1 = fwnode_irq_get_byname(dev_fwnode(dev), "INT1"); if (irq1 == data->irq) { dev_info(dev, "using interrupt line INT1\n"); ret = regmap_field_write(data->regmap_fields[F_INT_CFG_DRDY], @@ -843,7 +841,7 @@ static int fxas21002c_trigger_probe(struct fxas21002c_data *data) dev_info(dev, "using interrupt line INT2\n"); - irq_open_drain = of_property_read_bool(np, "drive-open-drain"); + irq_open_drain = device_property_read_bool(dev, "drive-open-drain"); data->dready_trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c index ea387efab62d..4f19dc7ffe57 100644 --- a/drivers/iio/gyro/mpu3050-core.c +++ b/drivers/iio/gyro/mpu3050-core.c @@ -26,6 +26,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/property.h> #include <linux/random.h> #include <linux/slab.h> @@ -1050,6 +1051,7 @@ static const struct iio_trigger_ops mpu3050_trigger_ops = { static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq) { struct mpu3050 *mpu3050 = iio_priv(indio_dev); + struct device *dev = mpu3050->dev; unsigned long irq_trig; int ret; @@ -1061,8 +1063,7 @@ static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq) return -ENOMEM; /* Check if IRQ is open drain */ - if (of_property_read_bool(mpu3050->dev->of_node, "drive-open-drain")) - mpu3050->irq_opendrain = true; + mpu3050->irq_opendrain = device_property_read_bool(dev, "drive-open-drain"); irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq)); /* @@ -1118,13 +1119,12 @@ static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq) mpu3050->trig->name, mpu3050->trig); if (ret) { - dev_err(mpu3050->dev, - "can't get IRQ %d, error %d\n", irq, ret); + dev_err(dev, "can't get IRQ %d, error %d\n", irq, ret); return ret; } mpu3050->irq = irq; - mpu3050->trig->dev.parent = mpu3050->dev; + mpu3050->trig->dev.parent = dev; mpu3050->trig->ops = &mpu3050_trigger_ops; iio_trigger_set_drvdata(mpu3050->trig, indio_dev); @@ -1263,7 +1263,7 @@ err_power_down: } EXPORT_SYMBOL(mpu3050_common_probe); -int mpu3050_common_remove(struct device *dev) +void mpu3050_common_remove(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct mpu3050 *mpu3050 = iio_priv(indio_dev); @@ -1276,8 +1276,6 @@ int mpu3050_common_remove(struct device *dev) free_irq(mpu3050->irq, mpu3050); iio_device_unregister(indio_dev); mpu3050_power_down(mpu3050); - - return 0; } EXPORT_SYMBOL(mpu3050_common_remove); diff --git a/drivers/iio/gyro/mpu3050-i2c.c b/drivers/iio/gyro/mpu3050-i2c.c index ef5bcbc4b45b..5b5f58baaf7f 100644 --- a/drivers/iio/gyro/mpu3050-i2c.c +++ b/drivers/iio/gyro/mpu3050-i2c.c @@ -86,7 +86,9 @@ static int mpu3050_i2c_remove(struct i2c_client *client) if (mpu3050->i2cmux) i2c_mux_del_adapters(mpu3050->i2cmux); - return mpu3050_common_remove(&client->dev); + mpu3050_common_remove(&client->dev); + + return 0; } /* diff --git a/drivers/iio/gyro/mpu3050.h b/drivers/iio/gyro/mpu3050.h index 835b0249c376..faf4168a3b07 100644 --- a/drivers/iio/gyro/mpu3050.h +++ b/drivers/iio/gyro/mpu3050.h @@ -91,7 +91,7 @@ int mpu3050_common_probe(struct device *dev, struct regmap *map, int irq, const char *name); -int mpu3050_common_remove(struct device *dev); +void mpu3050_common_remove(struct device *dev); /* PM ops */ extern const struct dev_pm_ops mpu3050_dev_pm_ops; diff --git a/drivers/iio/gyro/ssp_gyro_sensor.c b/drivers/iio/gyro/ssp_gyro_sensor.c index 5fd1bf9902ea..d332474bc484 100644 --- a/drivers/iio/gyro/ssp_gyro_sensor.c +++ b/drivers/iio/gyro/ssp_gyro_sensor.c @@ -113,7 +113,6 @@ static int ssp_gyro_probe(struct platform_device *pdev) indio_dev->available_scan_masks = ssp_gyro_scan_mask; ret = devm_iio_kfifo_buffer_setup(&pdev->dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &ssp_gyro_buffer_ops); if (ret) return ret; diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index 62172e18d0d8..eaa35da42b33 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c @@ -406,24 +406,17 @@ read_error: static int st_gyro_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { - int err; - switch (mask) { case IIO_CHAN_INFO_SCALE: - err = st_sensors_set_fullscale_by_gain(indio_dev, val2); - break; + return st_sensors_set_fullscale_by_gain(indio_dev, val2); case IIO_CHAN_INFO_SAMP_FREQ: if (val2) return -EINVAL; - mutex_lock(&indio_dev->mlock); - err = st_sensors_set_odr(indio_dev, val); - mutex_unlock(&indio_dev->mlock); - return err; + + return st_sensors_set_odr(indio_dev, val); default: - err = -EINVAL; + return -EINVAL; } - - return err; } static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL(); diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c index 36ba7611d9ce..ad5717965223 100644 --- a/drivers/iio/health/max30100.c +++ b/drivers/iio/health/max30100.c @@ -433,7 +433,6 @@ static int max30100_probe(struct i2c_client *client, indio_dev->modes = INDIO_DIRECT_MODE; ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &max30100_buffer_setup_ops); if (ret) return ret; diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index 2292876c55e2..abbcef563807 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -542,7 +542,6 @@ static int max30102_probe(struct i2c_client *client, } ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &max30102_buffer_setup_ops); if (ret) return ret; diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c index 44bbe3d19907..fe520194a837 100644 --- a/drivers/iio/imu/adis16480.c +++ b/drivers/iio/imu/adis16480.c @@ -7,14 +7,16 @@ #include <linux/clk.h> #include <linux/bitfield.h> -#include <linux/of_irq.h> #include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/math.h> #include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/lcm.h> +#include <linux/property.h> #include <linux/swab.h> #include <linux/crc32.h> @@ -1119,6 +1121,7 @@ static irqreturn_t adis16480_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct adis16480 *st = iio_priv(indio_dev); struct adis *adis = &st->adis; + struct device *dev = &adis->spi->dev; int ret, bit, offset, i = 0; __be16 *buffer; u32 crc; @@ -1130,7 +1133,7 @@ static irqreturn_t adis16480_trigger_handler(int irq, void *p) adis->tx[1] = 0; ret = spi_write(adis->spi, adis->tx, 2); if (ret) { - dev_err(&adis->spi->dev, "Failed to change device page: %d\n", ret); + dev_err(dev, "Failed to change device page: %d\n", ret); adis_dev_unlock(adis); goto irq_done; } @@ -1140,7 +1143,7 @@ static irqreturn_t adis16480_trigger_handler(int irq, void *p) ret = spi_sync(adis->spi, &adis->msg); if (ret) { - dev_err(&adis->spi->dev, "Failed to read data: %d\n", ret); + dev_err(dev, "Failed to read data: %d\n", ret); adis_dev_unlock(adis); goto irq_done; } @@ -1168,14 +1171,14 @@ static irqreturn_t adis16480_trigger_handler(int irq, void *p) } if (offset == 4) { - dev_err(&adis->spi->dev, "Invalid burst data\n"); + dev_err(dev, "Invalid burst data\n"); goto irq_done; } crc = be16_to_cpu(buffer[offset + 16]) << 16 | be16_to_cpu(buffer[offset + 15]); valid = adis16480_validate_crc((u16 *)&buffer[offset], 15, crc); if (!valid) { - dev_err(&adis->spi->dev, "Invalid crc\n"); + dev_err(dev, "Invalid crc\n"); goto irq_done; } @@ -1214,12 +1217,12 @@ static const struct iio_info adis16480_info = { static int adis16480_stop_device(struct iio_dev *indio_dev) { struct adis16480 *st = iio_priv(indio_dev); + struct device *dev = &st->adis.spi->dev; int ret; ret = adis_write_reg_16(&st->adis, ADIS16480_REG_SLP_CNT, BIT(9)); if (ret) - dev_err(&indio_dev->dev, - "Could not power down device: %d\n", ret); + dev_err(dev, "Could not power down device: %d\n", ret); return ret; } @@ -1239,9 +1242,10 @@ static int adis16480_enable_irq(struct adis *adis, bool enable) return __adis_write_reg_16(adis, ADIS16480_REG_FNCTIO_CTRL, val); } -static int adis16480_config_irq_pin(struct device_node *of_node, - struct adis16480 *st) +static int adis16480_config_irq_pin(struct adis16480 *st) { + struct device *dev = &st->adis.spi->dev; + struct fwnode_handle *fwnode = dev_fwnode(dev); struct irq_data *desc; enum adis16480_int_pin pin; unsigned int irq_type; @@ -1250,7 +1254,7 @@ static int adis16480_config_irq_pin(struct device_node *of_node, desc = irq_get_irq_data(st->adis.spi->irq); if (!desc) { - dev_err(&st->adis.spi->dev, "Could not find IRQ %d\n", irq); + dev_err(dev, "Could not find IRQ %d\n", irq); return -EINVAL; } @@ -1267,7 +1271,7 @@ static int adis16480_config_irq_pin(struct device_node *of_node, */ pin = ADIS16480_PIN_DIO1; for (i = 0; i < ARRAY_SIZE(adis16480_int_pin_names); i++) { - irq = of_irq_get_byname(of_node, adis16480_int_pin_names[i]); + irq = fwnode_irq_get_byname(fwnode, adis16480_int_pin_names[i]); if (irq > 0) { pin = i; break; @@ -1287,23 +1291,22 @@ static int adis16480_config_irq_pin(struct device_node *of_node, } else if (irq_type == IRQ_TYPE_EDGE_FALLING) { val |= ADIS16480_DRDY_POL(0); } else { - dev_err(&st->adis.spi->dev, - "Invalid interrupt type 0x%x specified\n", irq_type); + dev_err(dev, "Invalid interrupt type 0x%x specified\n", irq_type); return -EINVAL; } /* Write the data ready configuration to the FNCTIO_CTRL register */ return adis_write_reg_16(&st->adis, ADIS16480_REG_FNCTIO_CTRL, val); } -static int adis16480_of_get_ext_clk_pin(struct adis16480 *st, - struct device_node *of_node) +static int adis16480_fw_get_ext_clk_pin(struct adis16480 *st) { + struct device *dev = &st->adis.spi->dev; const char *ext_clk_pin; enum adis16480_int_pin pin; int i; pin = ADIS16480_PIN_DIO2; - if (of_property_read_string(of_node, "adi,ext-clk-pin", &ext_clk_pin)) + if (device_property_read_string(dev, "adi,ext-clk-pin", &ext_clk_pin)) goto clk_input_not_found; for (i = 0; i < ARRAY_SIZE(adis16480_int_pin_names); i++) { @@ -1312,15 +1315,13 @@ static int adis16480_of_get_ext_clk_pin(struct adis16480 *st, } clk_input_not_found: - dev_info(&st->adis.spi->dev, - "clk input line not specified, using DIO2\n"); + dev_info(dev, "clk input line not specified, using DIO2\n"); return pin; } -static int adis16480_ext_clk_config(struct adis16480 *st, - struct device_node *of_node, - bool enable) +static int adis16480_ext_clk_config(struct adis16480 *st, bool enable) { + struct device *dev = &st->adis.spi->dev; unsigned int mode, mask; enum adis16480_int_pin pin; uint16_t val; @@ -1330,16 +1331,14 @@ static int adis16480_ext_clk_config(struct adis16480 *st, if (ret) return ret; - pin = adis16480_of_get_ext_clk_pin(st, of_node); + pin = adis16480_fw_get_ext_clk_pin(st); /* * Each DIOx pin supports only one function at a time. When a single pin * has two assignments, the enable bit for a lower priority function * automatically resets to zero (disabling the lower priority function). */ if (pin == ADIS16480_DRDY_SEL(val)) - dev_warn(&st->adis.spi->dev, - "DIO%x pin supports only one function at a time\n", - pin + 1); + dev_warn(dev, "DIO%x pin supports only one function at a time\n", pin + 1); mode = ADIS16480_SYNC_EN(enable) | ADIS16480_SYNC_SEL(pin); mask = ADIS16480_SYNC_EN_MSK | ADIS16480_SYNC_SEL_MSK; @@ -1361,31 +1360,27 @@ static int adis16480_ext_clk_config(struct adis16480 *st, static int adis16480_get_ext_clocks(struct adis16480 *st) { - st->clk_mode = ADIS16480_CLK_INT; - st->ext_clk = devm_clk_get(&st->adis.spi->dev, "sync"); - if (!IS_ERR_OR_NULL(st->ext_clk)) { + struct device *dev = &st->adis.spi->dev; + + st->ext_clk = devm_clk_get_optional(dev, "sync"); + if (IS_ERR(st->ext_clk)) + return dev_err_probe(dev, PTR_ERR(st->ext_clk), "failed to get ext clk\n"); + if (st->ext_clk) { st->clk_mode = ADIS16480_CLK_SYNC; return 0; } - if (PTR_ERR(st->ext_clk) != -ENOENT) { - dev_err(&st->adis.spi->dev, "failed to get ext clk\n"); - return PTR_ERR(st->ext_clk); - } - if (st->chip_info->has_pps_clk_mode) { - st->ext_clk = devm_clk_get(&st->adis.spi->dev, "pps"); - if (!IS_ERR_OR_NULL(st->ext_clk)) { + st->ext_clk = devm_clk_get_optional(dev, "pps"); + if (IS_ERR(st->ext_clk)) + return dev_err_probe(dev, PTR_ERR(st->ext_clk), "failed to get ext clk\n"); + if (st->ext_clk) { st->clk_mode = ADIS16480_CLK_PPS; return 0; } - - if (PTR_ERR(st->ext_clk) != -ENOENT) { - dev_err(&st->adis.spi->dev, "failed to get ext clk\n"); - return PTR_ERR(st->ext_clk); - } } + st->clk_mode = ADIS16480_CLK_INT; return 0; } @@ -1404,11 +1399,12 @@ static int adis16480_probe(struct spi_device *spi) const struct spi_device_id *id = spi_get_device_id(spi); const struct adis_data *adis16480_data; irq_handler_t trigger_handler = NULL; + struct device *dev = &spi->dev; struct iio_dev *indio_dev; struct adis16480 *st; int ret; - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -1432,13 +1428,12 @@ static int adis16480_probe(struct spi_device *spi) return ret; if (st->chip_info->has_sleep_cnt) { - ret = devm_add_action_or_reset(&spi->dev, adis16480_stop, - indio_dev); + ret = devm_add_action_or_reset(dev, adis16480_stop, indio_dev); if (ret) return ret; } - ret = adis16480_config_irq_pin(spi->dev.of_node, st); + ret = adis16480_config_irq_pin(st); if (ret) return ret; @@ -1446,12 +1441,12 @@ static int adis16480_probe(struct spi_device *spi) if (ret) return ret; - if (!IS_ERR_OR_NULL(st->ext_clk)) { - ret = adis16480_ext_clk_config(st, spi->dev.of_node, true); + if (st->ext_clk) { + ret = adis16480_ext_clk_config(st, true); if (ret) return ret; - ret = devm_add_action_or_reset(&spi->dev, adis16480_clk_disable, st->ext_clk); + ret = devm_add_action_or_reset(dev, adis16480_clk_disable, st->ext_clk); if (ret) return ret; @@ -1484,7 +1479,7 @@ static int adis16480_probe(struct spi_device *spi) if (ret) return ret; - ret = devm_iio_device_register(&spi->dev, indio_dev); + ret = devm_iio_device_register(dev, indio_dev); if (ret) return ret; diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c index 01336105792e..e7aec56ea136 100644 --- a/drivers/iio/imu/bmi160/bmi160_core.c +++ b/drivers/iio/imu/bmi160/bmi160_core.c @@ -11,10 +11,9 @@ */ #include <linux/module.h> #include <linux/regmap.h> -#include <linux/acpi.h> #include <linux/delay.h> #include <linux/irq.h> -#include <linux/of_irq.h> +#include <linux/property.h> #include <linux/regulator/consumer.h> #include <linux/iio/iio.h> @@ -525,17 +524,6 @@ static const struct iio_info bmi160_info = { .attrs = &bmi160_attrs_group, }; -static const char *bmi160_match_acpi_device(struct device *dev) -{ - const struct acpi_device_id *id; - - id = acpi_match_device(dev->driver->acpi_match_table, dev); - if (!id) - return NULL; - - return dev_name(dev); -} - static int bmi160_write_conf_reg(struct regmap *regmap, unsigned int reg, unsigned int mask, unsigned int bits, unsigned int write_usleep) @@ -647,18 +635,18 @@ int bmi160_enable_irq(struct regmap *regmap, bool enable) } EXPORT_SYMBOL(bmi160_enable_irq); -static int bmi160_get_irq(struct device_node *of_node, enum bmi160_int_pin *pin) +static int bmi160_get_irq(struct fwnode_handle *fwnode, enum bmi160_int_pin *pin) { int irq; /* Use INT1 if possible, otherwise fall back to INT2. */ - irq = of_irq_get_byname(of_node, "INT1"); + irq = fwnode_irq_get_byname(fwnode, "INT1"); if (irq > 0) { *pin = BMI160_PIN_INT1; return irq; } - irq = of_irq_get_byname(of_node, "INT2"); + irq = fwnode_irq_get_byname(fwnode, "INT2"); if (irq > 0) *pin = BMI160_PIN_INT2; @@ -688,7 +676,7 @@ static int bmi160_config_device_irq(struct iio_dev *indio_dev, int irq_type, return -EINVAL; } - open_drain = of_property_read_bool(dev->of_node, "drive-open-drain"); + open_drain = device_property_read_bool(dev, "drive-open-drain"); return bmi160_config_pin(data->regmap, pin, open_drain, irq_mask, BMI160_NORMAL_WRITE_USLEEP); @@ -872,9 +860,6 @@ int bmi160_core_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; - if (!name && ACPI_HANDLE(dev)) - name = bmi160_match_acpi_device(dev); - indio_dev->channels = bmi160_channels; indio_dev->num_channels = ARRAY_SIZE(bmi160_channels); indio_dev->name = name; @@ -887,7 +872,7 @@ int bmi160_core_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; - irq = bmi160_get_irq(dev->of_node, &int_pin); + irq = bmi160_get_irq(dev_fwnode(dev), &int_pin); if (irq > 0) { ret = bmi160_setup_irq(indio_dev, irq, int_pin); if (ret) diff --git a/drivers/iio/imu/bmi160/bmi160_i2c.c b/drivers/iio/imu/bmi160/bmi160_i2c.c index 26398614eddf..02f149d37b17 100644 --- a/drivers/iio/imu/bmi160/bmi160_i2c.c +++ b/drivers/iio/imu/bmi160/bmi160_i2c.c @@ -8,10 +8,9 @@ * - 0x68 if SDO is pulled to GND * - 0x69 if SDO is pulled to VDDIO */ -#include <linux/acpi.h> #include <linux/i2c.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> #include <linux/regmap.h> #include "bmi160.h" @@ -20,7 +19,7 @@ static int bmi160_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct regmap *regmap; - const char *name = NULL; + const char *name; regmap = devm_regmap_init_i2c(client, &bmi160_regmap_config); if (IS_ERR(regmap)) { @@ -31,6 +30,8 @@ static int bmi160_i2c_probe(struct i2c_client *client, if (id) name = id->name; + else + name = dev_name(&client->dev); return bmi160_core_probe(&client->dev, regmap, name, false); } @@ -47,19 +48,17 @@ static const struct acpi_device_id bmi160_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match); -#ifdef CONFIG_OF static const struct of_device_id bmi160_of_match[] = { { .compatible = "bosch,bmi160" }, { }, }; MODULE_DEVICE_TABLE(of, bmi160_of_match); -#endif static struct i2c_driver bmi160_i2c_driver = { .driver = { .name = "bmi160_i2c", - .acpi_match_table = ACPI_PTR(bmi160_acpi_match), - .of_match_table = of_match_ptr(bmi160_of_match), + .acpi_match_table = bmi160_acpi_match, + .of_match_table = bmi160_of_match, }, .probe = bmi160_i2c_probe, .id_table = bmi160_i2c_id, diff --git a/drivers/iio/imu/bmi160/bmi160_spi.c b/drivers/iio/imu/bmi160/bmi160_spi.c index 61389b41c6d9..24f7d75c7903 100644 --- a/drivers/iio/imu/bmi160/bmi160_spi.c +++ b/drivers/iio/imu/bmi160/bmi160_spi.c @@ -5,9 +5,8 @@ * Copyright (c) 2016, Intel Corporation. * */ -#include <linux/acpi.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> #include <linux/regmap.h> #include <linux/spi/spi.h> @@ -17,6 +16,7 @@ static int bmi160_spi_probe(struct spi_device *spi) { struct regmap *regmap; const struct spi_device_id *id = spi_get_device_id(spi); + const char *name; regmap = devm_regmap_init_spi(spi, &bmi160_regmap_config); if (IS_ERR(regmap)) { @@ -24,7 +24,13 @@ static int bmi160_spi_probe(struct spi_device *spi) regmap); return PTR_ERR(regmap); } - return bmi160_core_probe(&spi->dev, regmap, id->name, true); + + if (id) + name = id->name; + else + name = dev_name(&spi->dev); + + return bmi160_core_probe(&spi->dev, regmap, name, true); } static const struct spi_device_id bmi160_spi_id[] = { @@ -39,20 +45,18 @@ static const struct acpi_device_id bmi160_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match); -#ifdef CONFIG_OF static const struct of_device_id bmi160_of_match[] = { { .compatible = "bosch,bmi160" }, { }, }; MODULE_DEVICE_TABLE(of, bmi160_of_match); -#endif static struct spi_driver bmi160_spi_driver = { .probe = bmi160_spi_probe, .id_table = bmi160_spi_id, .driver = { - .acpi_match_table = ACPI_PTR(bmi160_acpi_match), - .of_match_table = of_match_ptr(bmi160_of_match), + .acpi_match_table = bmi160_acpi_match, + .of_match_table = bmi160_of_match, .name = "bmi160_spi", }, }; diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c index 383cc3250342..c3f433ad3af6 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c @@ -731,7 +731,6 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st) indio_dev->available_scan_masks = inv_icm42600_accel_scan_masks; ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &inv_icm42600_buffer_ops); if (ret) return ERR_PTR(ret); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c index cec1dd0e0464..9d94a8518e3c 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c @@ -743,7 +743,6 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st) indio_dev->setup_ops = &inv_icm42600_buffer_ops; ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &inv_icm42600_buffer_ops); if (ret) return ERR_PTR(ret); diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig index 9c625517173a..3636b1bc90f1 100644 --- a/drivers/iio/imu/inv_mpu6050/Kconfig +++ b/drivers/iio/imu/inv_mpu6050/Kconfig @@ -16,7 +16,7 @@ config INV_MPU6050_I2C select REGMAP_I2C help This driver supports the Invensense MPU6050/9150, - MPU6500/6515/6880/9250/9255, ICM20608/20609/20689, ICM20602/ICM20690 + MPU6500/6515/6880/9250/9255, ICM20608(D)/20609/20689, ICM20602/ICM20690 and IAM20680 motion tracking devices over I2C. This driver can be built as a module. The module will be called inv-mpu6050-i2c. @@ -28,7 +28,7 @@ config INV_MPU6050_SPI select REGMAP_SPI help This driver supports the Invensense MPU6000, - MPU6500/6515/6880/9250/9255, ICM20608/20609/20689, ICM20602/ICM20690 + MPU6500/6515/6880/9250/9255, ICM20608(D)/20609/20689, ICM20602/ICM20690 and IAM20680 motion tracking devices over SPI. This driver can be built as a module. The module will be called inv-mpu6050-spi. diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 597768c29a72..86fbbe904050 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -218,6 +218,15 @@ static const struct inv_mpu6050_hw hw_info[] = { .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME}, }, { + .whoami = INV_ICM20608D_WHOAMI_VALUE, + .name = "ICM20608D", + .reg = ®_set_6500, + .config = &chip_config_6500, + .fifo_size = 512, + .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE}, + .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME}, + }, + { .whoami = INV_ICM20609_WHOAMI_VALUE, .name = "ICM20609", .reg = ®_set_6500, diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c index 55cffb5fa115..2aa647704a79 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c @@ -29,6 +29,7 @@ static bool inv_mpu_i2c_aux_bus(struct device *dev) switch (st->chip_type) { case INV_ICM20608: + case INV_ICM20608D: case INV_ICM20609: case INV_ICM20689: case INV_ICM20602: @@ -182,6 +183,7 @@ static const struct i2c_device_id inv_mpu_id[] = { {"mpu9250", INV_MPU9250}, {"mpu9255", INV_MPU9255}, {"icm20608", INV_ICM20608}, + {"icm20608d", INV_ICM20608D}, {"icm20609", INV_ICM20609}, {"icm20689", INV_ICM20689}, {"icm20602", INV_ICM20602}, @@ -226,6 +228,10 @@ static const struct of_device_id inv_of_match[] = { .data = (void *)INV_ICM20608 }, { + .compatible = "invensense,icm20608d", + .data = (void *)INV_ICM20608D + }, + { .compatible = "invensense,icm20609", .data = (void *)INV_ICM20609 }, diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index c6aa36ee966a..8e14f20b1314 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -76,6 +76,7 @@ enum inv_devices { INV_MPU9250, INV_MPU9255, INV_ICM20608, + INV_ICM20608D, INV_ICM20609, INV_ICM20689, INV_ICM20602, @@ -394,6 +395,7 @@ struct inv_mpu6050_state { #define INV_MPU9255_WHOAMI_VALUE 0x73 #define INV_MPU6515_WHOAMI_VALUE 0x74 #define INV_ICM20608_WHOAMI_VALUE 0xAF +#define INV_ICM20608D_WHOAMI_VALUE 0xAE #define INV_ICM20609_WHOAMI_VALUE 0xA6 #define INV_ICM20689_WHOAMI_VALUE 0x98 #define INV_ICM20602_WHOAMI_VALUE 0x12 diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c index 26a7c2521dc4..e6107b0cc38f 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c @@ -73,6 +73,7 @@ static const struct spi_device_id inv_mpu_id[] = { {"mpu9250", INV_MPU9250}, {"mpu9255", INV_MPU9255}, {"icm20608", INV_ICM20608}, + {"icm20608d", INV_ICM20608D}, {"icm20609", INV_ICM20609}, {"icm20689", INV_ICM20689}, {"icm20602", INV_ICM20602}, @@ -113,6 +114,10 @@ static const struct of_device_id inv_of_match[] = { .data = (void *)INV_ICM20608 }, { + .compatible = "invensense,icm20608d", + .data = (void *)INV_ICM20608D + }, + { .compatible = "invensense,icm20609", .data = (void *)INV_ICM20609 }, diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig index 85860217aaf3..fefd0b939100 100644 --- a/drivers/iio/imu/st_lsm6dsx/Kconfig +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig @@ -11,9 +11,9 @@ config IIO_ST_LSM6DSX help Say yes here to build support for STMicroelectronics LSM6DSx imu sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm, - ism330dlc, lsm6dso, lsm6dsox, asm330lhh, lsm6dsr, lsm6ds3tr-c, - ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop, the accelerometer/gyroscope - of lsm9ds1 and lsm6dst. + ism330dlc, lsm6dso, lsm6dsox, asm330lhh, asm330lhhx, lsm6dsr, + lsm6ds3tr-c, ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop, + the accelerometer/gyroscope of lsm9ds1 and lsm6dst. To compile this driver as a module, choose M here: the module will be called st_lsm6dsx. diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 6ac4eac36458..a86dd29a4738 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -31,6 +31,7 @@ #define ST_LSM6DSRX_DEV_NAME "lsm6dsrx" #define ST_LSM6DST_DEV_NAME "lsm6dst" #define ST_LSM6DSOP_DEV_NAME "lsm6dsop" +#define ST_ASM330LHHX_DEV_NAME "asm330lhhx" enum st_lsm6dsx_hw_id { ST_LSM6DS3_ID, @@ -49,6 +50,7 @@ enum st_lsm6dsx_hw_id { ST_LSM6DSRX_ID, ST_LSM6DST_ID, ST_LSM6DSOP_ID, + ST_ASM330LHHX_ID, ST_LSM6DSX_MAX_ID, }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index 16730a780964..c7d3730ab1c5 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -14,7 +14,8 @@ * (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated depending on the * value of the decimation factor and ODR set for each FIFO data set. * - * LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/LSM6DSRX/ISM330DHCX/LSM6DST/LSM6DSOP: + * LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/LSM6DSRX/ISM330DHCX/ + * LSM6DST/LSM6DSOP: * The FIFO buffer can be configured to store data from gyroscope and * accelerometer. Each sample is queued with a tag (1B) indicating data * source (gyroscope, accelerometer, hw timer). @@ -746,7 +747,6 @@ int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw) continue; ret = devm_iio_kfifo_buffer_setup(hw->dev, hw->iio_devs[i], - INDIO_BUFFER_SOFTWARE, &st_lsm6dsx_buffer_ops); if (ret) return ret; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index b1d8d5a66f01..910397716833 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -26,7 +26,7 @@ * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 * - FIFO size: 4KB * - * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP: + * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP: * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416, * 833 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 @@ -786,6 +786,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .hw_id = ST_LSM6DST_ID, .name = ST_LSM6DST_DEV_NAME, .wai = 0x6d, + }, { + .hw_id = ST_ASM330LHHX_ID, + .name = ST_ASM330LHHX_DEV_NAME, + .wai = 0x6b, }, }, .channels = { diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 8b4fc2c15622..715fbdc8190e 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c @@ -101,6 +101,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { .compatible = "st,lsm6dsop", .data = (void *)ST_LSM6DSOP_ID, }, + { + .compatible = "st,asm330lhhx", + .data = (void *)ST_ASM330LHHX_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); @@ -122,6 +126,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { { ST_LSM6DSRX_DEV_NAME, ST_LSM6DSRX_ID }, { ST_LSM6DST_DEV_NAME, ST_LSM6DST_ID }, { ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID }, + { ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID }, {}, }; MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table); diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c index e80110b6b280..f5767cf76c1d 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c @@ -101,6 +101,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = { .compatible = "st,lsm6dsop", .data = (void *)ST_LSM6DSOP_ID, }, + { + .compatible = "st,asm330lhhx", + .data = (void *)ST_ASM330LHHX_ID, + }, {}, }; MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); @@ -122,6 +126,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = { { ST_LSM6DSRX_DEV_NAME, ST_LSM6DSRX_ID }, { ST_LSM6DST_DEV_NAME, ST_LSM6DST_ID }, { ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID }, + { ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID }, {}, }; MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index b078eb2f3c9d..06141ca27e1f 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -510,7 +510,7 @@ static ssize_t iio_scan_el_store(struct device *dev, struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_buffer *buffer = this_attr->buffer; - ret = strtobool(buf, &state); + ret = kstrtobool(buf, &state); if (ret < 0) return ret; mutex_lock(&indio_dev->mlock); @@ -557,7 +557,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer; bool state; - ret = strtobool(buf, &state); + ret = kstrtobool(buf, &state); if (ret < 0) return ret; @@ -915,7 +915,7 @@ static int iio_verify_update(struct iio_dev *indio_dev, if (scan_mask == NULL) return -EINVAL; } else { - scan_mask = compound_mask; + scan_mask = compound_mask; } config->scan_bytes = iio_compute_scan_bytes(indio_dev, @@ -1059,13 +1059,13 @@ static int iio_enable_buffers(struct iio_dev *indio_dev, struct iio_device_config *config) { struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); - struct iio_buffer *buffer; + struct iio_buffer *buffer, *tmp = NULL; int ret; indio_dev->active_scan_mask = config->scan_mask; indio_dev->scan_timestamp = config->scan_timestamp; indio_dev->scan_bytes = config->scan_bytes; - indio_dev->currentmode = config->mode; + iio_dev_opaque->currentmode = config->mode; iio_update_demux(indio_dev); @@ -1097,11 +1097,13 @@ static int iio_enable_buffers(struct iio_dev *indio_dev, list_for_each_entry(buffer, &iio_dev_opaque->buffer_list, buffer_list) { ret = iio_buffer_enable(buffer, indio_dev); - if (ret) + if (ret) { + tmp = buffer; goto err_disable_buffers; + } } - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { + if (iio_dev_opaque->currentmode == INDIO_BUFFER_TRIGGERED) { ret = iio_trigger_attach_poll_func(indio_dev->trig, indio_dev->pollfunc); if (ret) @@ -1120,11 +1122,12 @@ static int iio_enable_buffers(struct iio_dev *indio_dev, return 0; err_detach_pollfunc: - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { + if (iio_dev_opaque->currentmode == INDIO_BUFFER_TRIGGERED) { iio_trigger_detach_poll_func(indio_dev->trig, indio_dev->pollfunc); } err_disable_buffers: + buffer = list_prepare_entry(tmp, &iio_dev_opaque->buffer_list, buffer_list); list_for_each_entry_continue_reverse(buffer, &iio_dev_opaque->buffer_list, buffer_list) iio_buffer_disable(buffer, indio_dev); @@ -1132,7 +1135,7 @@ err_run_postdisable: if (indio_dev->setup_ops->postdisable) indio_dev->setup_ops->postdisable(indio_dev); err_undo_config: - indio_dev->currentmode = INDIO_DIRECT_MODE; + iio_dev_opaque->currentmode = INDIO_DIRECT_MODE; indio_dev->active_scan_mask = NULL; return ret; @@ -1162,7 +1165,7 @@ static int iio_disable_buffers(struct iio_dev *indio_dev) ret = ret2; } - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { + if (iio_dev_opaque->currentmode == INDIO_BUFFER_TRIGGERED) { iio_trigger_detach_poll_func(indio_dev->trig, indio_dev->pollfunc); } @@ -1181,7 +1184,7 @@ static int iio_disable_buffers(struct iio_dev *indio_dev) iio_free_scan_mask(indio_dev, indio_dev->active_scan_mask); indio_dev->active_scan_mask = NULL; - indio_dev->currentmode = INDIO_DIRECT_MODE; + iio_dev_opaque->currentmode = INDIO_DIRECT_MODE; return ret; } @@ -1300,7 +1303,7 @@ static ssize_t iio_buffer_store_enable(struct device *dev, struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer; bool inlist; - ret = strtobool(buf, &requested_state); + ret = kstrtobool(buf, &requested_state); if (ret < 0) return ret; @@ -1629,6 +1632,19 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, if (channels[i].scan_index < 0) continue; + /* Verify that sample bits fit into storage */ + if (channels[i].scan_type.storagebits < + channels[i].scan_type.realbits + + channels[i].scan_type.shift) { + dev_err(&indio_dev->dev, + "Channel %d storagebits (%d) < shifted realbits (%d + %d)\n", + i, channels[i].scan_type.storagebits, + channels[i].scan_type.realbits, + channels[i].scan_type.shift); + ret = -EINVAL; + goto error_cleanup_dynamic; + } + ret = iio_buffer_add_channel_sysfs(indio_dev, buffer, &channels[i]); if (ret < 0) @@ -1649,7 +1665,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, } attrn = buffer_attrcount + scan_el_attrcount + ARRAY_SIZE(iio_buffer_attrs); - attr = kcalloc(attrn + 1, sizeof(* attr), GFP_KERNEL); + attr = kcalloc(attrn + 1, sizeof(*attr), GFP_KERNEL); if (!attr) { ret = -ENOMEM; goto error_free_scan_mask; diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index e1ed44dec2ab..adf054c7a75e 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -185,6 +185,20 @@ int iio_device_id(struct iio_dev *indio_dev) EXPORT_SYMBOL_GPL(iio_device_id); /** + * iio_buffer_enabled() - helper function to test if the buffer is enabled + * @indio_dev: IIO device structure for device + */ +bool iio_buffer_enabled(struct iio_dev *indio_dev) +{ + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + + return iio_dev_opaque->currentmode + & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE | + INDIO_BUFFER_SOFTWARE); +} +EXPORT_SYMBOL_GPL(iio_buffer_enabled); + +/** * iio_sysfs_match_string_with_gaps - matches given string in an array with gaps * @array: array of strings * @n: number of strings in the array @@ -892,8 +906,7 @@ static int __iio_str_to_fixpoint(const char *str, int fract_mult, } else if (*str == '\n') { if (*(str + 1) == '\0') break; - else - return -EINVAL; + return -EINVAL; } else if (!strncmp(str, " dB", sizeof(" dB") - 1) && scale_db) { /* Ignore the dB suffix */ str += sizeof(" dB") - 1; @@ -1894,20 +1907,22 @@ static const struct iio_buffer_setup_ops noop_ring_setup_ops; int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) { struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); - const char *label; + struct fwnode_handle *fwnode; int ret; if (!indio_dev->info) return -EINVAL; iio_dev_opaque->driver_module = this_mod; - /* If the calling driver did not initialize of_node, do it here */ - if (!indio_dev->dev.of_node && indio_dev->dev.parent) - indio_dev->dev.of_node = indio_dev->dev.parent->of_node; - label = of_get_property(indio_dev->dev.of_node, "label", NULL); - if (label) - indio_dev->label = label; + /* If the calling driver did not initialize firmware node, do it here */ + if (dev_fwnode(&indio_dev->dev)) + fwnode = dev_fwnode(&indio_dev->dev); + else + fwnode = dev_fwnode(indio_dev->dev.parent); + device_set_node(&indio_dev->dev, fwnode); + + fwnode_property_read_string(fwnode, "label", &indio_dev->label); ret = iio_check_unique_scan_index(indio_dev); if (ret < 0) @@ -2059,6 +2074,19 @@ void iio_device_release_direct_mode(struct iio_dev *indio_dev) } EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); +/** + * iio_device_get_current_mode() - helper function providing read-only access to + * the opaque @currentmode variable + * @indio_dev: IIO device structure for device + */ +int iio_device_get_current_mode(struct iio_dev *indio_dev) +{ + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); + + return iio_dev_opaque->currentmode; +} +EXPORT_SYMBOL_GPL(iio_device_get_current_mode); + subsys_initcall(iio_init); module_exit(iio_exit); diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index ce8b102ce52f..b5e059e15b0a 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -274,7 +274,7 @@ static ssize_t iio_ev_state_store(struct device *dev, int ret; bool val; - ret = strtobool(buf, &val); + ret = kstrtobool(buf, &val); if (ret < 0) return ret; diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index f504ed351b3e..585b6cef8fcc 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -444,7 +444,7 @@ static ssize_t iio_trigger_write_current(struct device *dev, int ret; mutex_lock(&indio_dev->mlock); - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { + if (iio_dev_opaque->currentmode == INDIO_BUFFER_TRIGGERED) { mutex_unlock(&indio_dev->mlock); return -EBUSY; } diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index a62c7b4b8678..8537e88f02e3 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -155,7 +155,6 @@ config CM3323 config CM3605 tristate "Capella CM3605 ambient light and proximity sensor" - depends on OF help Say Y here if you want to build a driver for Capella CM3605 ambient light and short range proximity sensor. diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c index 4141c0fa7bc4..09b831f9f40b 100644 --- a/drivers/iio/light/apds9960.c +++ b/drivers/iio/light/apds9960.c @@ -1003,7 +1003,6 @@ static int apds9960_probe(struct i2c_client *client, indio_dev->modes = INDIO_DIRECT_MODE; ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &apds9960_buffer_setup_ops); if (ret) return ret; diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c index 1d02dfbc29d1..b578b46276cc 100644 --- a/drivers/iio/light/stk3310.c +++ b/drivers/iio/light/stk3310.c @@ -106,6 +106,7 @@ struct stk3310_data { struct mutex lock; bool als_enabled; bool ps_enabled; + uint32_t ps_near_level; u64 timestamp; struct regmap *regmap; struct regmap_field *reg_state; @@ -135,6 +136,25 @@ static const struct iio_event_spec stk3310_events[] = { }, }; +static ssize_t stk3310_read_near_level(struct iio_dev *indio_dev, + uintptr_t priv, + const struct iio_chan_spec *chan, + char *buf) +{ + struct stk3310_data *data = iio_priv(indio_dev); + + return sprintf(buf, "%u\n", data->ps_near_level); +} + +static const struct iio_chan_spec_ext_info stk3310_ext_info[] = { + { + .name = "nearlevel", + .shared = IIO_SEPARATE, + .read = stk3310_read_near_level, + }, + { /* sentinel */ } +}; + static const struct iio_chan_spec stk3310_channels[] = { { .type = IIO_LIGHT, @@ -151,6 +171,7 @@ static const struct iio_chan_spec stk3310_channels[] = { BIT(IIO_CHAN_INFO_INT_TIME), .event_spec = stk3310_events, .num_event_specs = ARRAY_SIZE(stk3310_events), + .ext_info = stk3310_ext_info, } }; @@ -581,6 +602,10 @@ static int stk3310_probe(struct i2c_client *client, data = iio_priv(indio_dev); data->client = client; i2c_set_clientdata(client, indio_dev); + + device_property_read_u32(&client->dev, "proximity-near-level", + &data->ps_near_level); + mutex_init(&data->lock); ret = stk3310_regmap_init(data); diff --git a/drivers/iio/light/tsl2772.c b/drivers/iio/light/tsl2772.c index 729f14d9f2a4..dd9051f1cc1a 100644 --- a/drivers/iio/light/tsl2772.c +++ b/drivers/iio/light/tsl2772.c @@ -15,7 +15,9 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/property.h> #include <linux/slab.h> + #include <linux/iio/events.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -549,10 +551,10 @@ prox_poll_err: static int tsl2772_read_prox_led_current(struct tsl2772_chip *chip) { - struct device_node *of_node = chip->client->dev.of_node; + struct device *dev = &chip->client->dev; int ret, tmp, i; - ret = of_property_read_u32(of_node, "led-max-microamp", &tmp); + ret = device_property_read_u32(dev, "led-max-microamp", &tmp); if (ret < 0) return ret; @@ -563,20 +565,18 @@ static int tsl2772_read_prox_led_current(struct tsl2772_chip *chip) } } - dev_err(&chip->client->dev, "Invalid value %d for led-max-microamp\n", - tmp); + dev_err(dev, "Invalid value %d for led-max-microamp\n", tmp); return -EINVAL; - } static int tsl2772_read_prox_diodes(struct tsl2772_chip *chip) { - struct device_node *of_node = chip->client->dev.of_node; + struct device *dev = &chip->client->dev; int i, ret, num_leds, prox_diode_mask; u32 leds[TSL2772_MAX_PROX_LEDS]; - ret = of_property_count_u32_elems(of_node, "amstaos,proximity-diodes"); + ret = device_property_count_u32(dev, "amstaos,proximity-diodes"); if (ret < 0) return ret; @@ -584,12 +584,9 @@ static int tsl2772_read_prox_diodes(struct tsl2772_chip *chip) if (num_leds > TSL2772_MAX_PROX_LEDS) num_leds = TSL2772_MAX_PROX_LEDS; - ret = of_property_read_u32_array(of_node, "amstaos,proximity-diodes", - leds, num_leds); + ret = device_property_read_u32_array(dev, "amstaos,proximity-diodes", leds, num_leds); if (ret < 0) { - dev_err(&chip->client->dev, - "Invalid value for amstaos,proximity-diodes: %d.\n", - ret); + dev_err(dev, "Invalid value for amstaos,proximity-diodes: %d.\n", ret); return ret; } @@ -600,9 +597,7 @@ static int tsl2772_read_prox_diodes(struct tsl2772_chip *chip) else if (leds[i] == 1) prox_diode_mask |= TSL2772_DIODE1; else { - dev_err(&chip->client->dev, - "Invalid value %d in amstaos,proximity-diodes.\n", - leds[i]); + dev_err(dev, "Invalid value %d in amstaos,proximity-diodes.\n", leds[i]); return -EINVAL; } } diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig index 54445365c4bc..07eb619bcfe8 100644 --- a/drivers/iio/magnetometer/Kconfig +++ b/drivers/iio/magnetometer/Kconfig @@ -9,7 +9,6 @@ menu "Magnetometer sensors" config AK8974 tristate "Asahi Kasei AK8974 3-Axis Magnetometer" depends on I2C - depends on OF select REGMAP_I2C select IIO_BUFFER select IIO_TRIGGERED_BUFFER diff --git a/drivers/iio/magnetometer/rm3100-core.c b/drivers/iio/magnetometer/rm3100-core.c index 26195733ea3e..707ba25360b8 100644 --- a/drivers/iio/magnetometer/rm3100-core.c +++ b/drivers/iio/magnetometer/rm3100-core.c @@ -141,18 +141,10 @@ static irqreturn_t rm3100_irq_handler(int irq, void *d) struct iio_dev *indio_dev = d; struct rm3100_data *data = iio_priv(indio_dev); - switch (indio_dev->currentmode) { - case INDIO_DIRECT_MODE: + if (!iio_buffer_enabled(indio_dev)) complete(&data->measuring_done); - break; - case INDIO_BUFFER_TRIGGERED: + else iio_trigger_poll(data->drdy_trig); - break; - default: - dev_err(indio_dev->dev.parent, - "device mode out of control, current mode: %d", - indio_dev->currentmode); - } return IRQ_WAKE_THREAD; } @@ -377,7 +369,7 @@ static int rm3100_set_samp_freq(struct iio_dev *indio_dev, int val, int val2) goto unlock_return; } - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { + if (iio_buffer_enabled(indio_dev)) { /* Writing TMRC registers requires CMM reset. */ ret = regmap_write(regmap, RM3100_REG_CMM, 0); if (ret < 0) @@ -553,7 +545,6 @@ int rm3100_common_probe(struct device *dev, struct regmap *regmap, int irq) indio_dev->channels = rm3100_channels; indio_dev->num_channels = ARRAY_SIZE(rm3100_channels); indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_TRIGGERED; - indio_dev->currentmode = INDIO_DIRECT_MODE; if (!irq) data->use_interrupt = false; diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 74435f4a427d..e2fd233b3626 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -540,24 +540,17 @@ read_error: static int st_magn_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { - int err; - switch (mask) { case IIO_CHAN_INFO_SCALE: - err = st_sensors_set_fullscale_by_gain(indio_dev, val2); - break; + return st_sensors_set_fullscale_by_gain(indio_dev, val2); case IIO_CHAN_INFO_SAMP_FREQ: if (val2) return -EINVAL; - mutex_lock(&indio_dev->mlock); - err = st_sensors_set_odr(indio_dev, val); - mutex_unlock(&indio_dev->mlock); - return err; + + return st_sensors_set_odr(indio_dev, val); default: - err = -EINVAL; + return -EINVAL; } - - return err; } static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL(); diff --git a/drivers/iio/multiplexer/Kconfig b/drivers/iio/multiplexer/Kconfig index a1e1332d1206..928f424a1ed3 100644 --- a/drivers/iio/multiplexer/Kconfig +++ b/drivers/iio/multiplexer/Kconfig @@ -9,7 +9,6 @@ menu "Multiplexers" config IIO_MUX tristate "IIO multiplexer driver" select MULTIPLEXER - depends on OF || COMPILE_TEST help Say yes here to build support for the IIO multiplexer. diff --git a/drivers/iio/multiplexer/iio-mux.c b/drivers/iio/multiplexer/iio-mux.c index f422d44377df..93558fddfa9b 100644 --- a/drivers/iio/multiplexer/iio-mux.c +++ b/drivers/iio/multiplexer/iio-mux.c @@ -10,11 +10,12 @@ #include <linux/err.h> #include <linux/iio/consumer.h> #include <linux/iio/iio.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/mux/consumer.h> -#include <linux/of.h> #include <linux/platform_device.h> +#include <linux/property.h> struct mux_ext_info_cache { char *data; @@ -324,37 +325,21 @@ static int mux_configure_channel(struct device *dev, struct mux *mux, return 0; } -/* - * Same as of_property_for_each_string(), but also keeps track of the - * index of each string. - */ -#define of_property_for_each_string_index(np, propname, prop, s, i) \ - for (prop = of_find_property(np, propname, NULL), \ - s = of_prop_next_string(prop, NULL), \ - i = 0; \ - s; \ - s = of_prop_next_string(prop, s), \ - i++) - static int mux_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *np = pdev->dev.of_node; struct iio_dev *indio_dev; struct iio_channel *parent; struct mux *mux; - struct property *prop; - const char *label; + const char **labels; + int all_children; + int children; u32 state; int sizeof_ext_info; - int children; int sizeof_priv; int i; int ret; - if (!np) - return -ENODEV; - parent = devm_iio_channel_get(dev, "parent"); if (IS_ERR(parent)) return dev_err_probe(dev, PTR_ERR(parent), @@ -366,9 +351,21 @@ static int mux_probe(struct platform_device *pdev) sizeof_ext_info *= sizeof(*mux->ext_info); } + all_children = device_property_string_array_count(dev, "channels"); + if (all_children < 0) + return all_children; + + labels = devm_kmalloc_array(dev, all_children, sizeof(*labels), GFP_KERNEL); + if (!labels) + return -ENOMEM; + + ret = device_property_read_string_array(dev, "channels", labels, all_children); + if (ret < 0) + return ret; + children = 0; - of_property_for_each_string(np, "channels", prop, label) { - if (*label) + for (state = 0; state < all_children; state++) { + if (*labels[state]) children++; } if (children <= 0) { @@ -395,7 +392,7 @@ static int mux_probe(struct platform_device *pdev) mux->cached_state = -1; mux->delay_us = 0; - of_property_read_u32(np, "settle-time-us", &mux->delay_us); + device_property_read_u32(dev, "settle-time-us", &mux->delay_us); indio_dev->name = dev_name(dev); indio_dev->info = &mux_info; @@ -426,11 +423,11 @@ static int mux_probe(struct platform_device *pdev) } i = 0; - of_property_for_each_string_index(np, "channels", prop, label, state) { - if (!*label) + for (state = 0; state < all_children; state++) { + if (!*labels[state]) continue; - ret = mux_configure_channel(dev, mux, state, label, i++); + ret = mux_configure_channel(dev, mux, state, labels[state], i++); if (ret < 0) return ret; } diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 5b93933a2e27..76913a2028d2 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -560,16 +560,12 @@ static int st_press_write_raw(struct iio_dev *indio_dev, int val2, long mask) { - int err; - switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: if (val2) return -EINVAL; - mutex_lock(&indio_dev->mlock); - err = st_sensors_set_odr(indio_dev, val); - mutex_unlock(&indio_dev->mlock); - return err; + + return st_sensors_set_odr(indio_dev, val); default: return -EINVAL; } diff --git a/drivers/iio/proximity/mb1232.c b/drivers/iio/proximity/mb1232.c index ad4b1fb2607a..0bca5f74de68 100644 --- a/drivers/iio/proximity/mb1232.c +++ b/drivers/iio/proximity/mb1232.c @@ -10,12 +10,14 @@ * https://www.maxbotix.com/documents/I2CXL-MaxSonar-EZ_Datasheet.pdf */ +#include <linux/bitops.h> #include <linux/err.h> #include <linux/i2c.h> -#include <linux/of_irq.h> #include <linux/delay.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/bitops.h> +#include <linux/property.h> + #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/buffer.h> @@ -209,7 +211,7 @@ static int mb1232_probe(struct i2c_client *client, init_completion(&data->ranging); - data->irqnr = irq_of_parse_and_map(dev->of_node, 0); + data->irqnr = fwnode_irq_get(dev_fwnode(&client->dev), 0); if (data->irqnr <= 0) { /* usage of interrupt is optional */ data->irqnr = -1; diff --git a/drivers/iio/proximity/ping.c b/drivers/iio/proximity/ping.c index 24a97d41e115..d56e037378de 100644 --- a/drivers/iio/proximity/ping.c +++ b/drivers/iio/proximity/ping.c @@ -29,9 +29,8 @@ #include <linux/err.h> #include <linux/gpio/consumer.h> #include <linux/kernel.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/property.h> #include <linux/sched.h> @@ -288,7 +287,7 @@ static int ping_probe(struct platform_device *pdev) data = iio_priv(indio_dev); data->dev = dev; - data->cfg = of_device_get_match_data(dev); + data->cfg = device_get_match_data(dev); mutex_init(&data->lock); init_completion(&data->rising); diff --git a/drivers/iio/proximity/vl53l0x-i2c.c b/drivers/iio/proximity/vl53l0x-i2c.c index 661a79ea200d..a284b20529fb 100644 --- a/drivers/iio/proximity/vl53l0x-i2c.c +++ b/drivers/iio/proximity/vl53l0x-i2c.c @@ -104,6 +104,7 @@ static int vl53l0x_read_proximity(struct vl53l0x_data *data, u16 tries = 20; u8 buffer[12]; int ret; + unsigned long time_left; ret = i2c_smbus_write_byte_data(client, VL_REG_SYSRANGE_START, 1); if (ret < 0) @@ -112,10 +113,8 @@ static int vl53l0x_read_proximity(struct vl53l0x_data *data, if (data->client->irq) { reinit_completion(&data->completion); - ret = wait_for_completion_timeout(&data->completion, HZ/10); - if (ret < 0) - return ret; - else if (ret == 0) + time_left = wait_for_completion_timeout(&data->completion, HZ/10); + if (time_left == 0) return -ETIMEDOUT; vl53l0x_clear_irq(data); diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c index 301c3f13fb26..4fc654275155 100644 --- a/drivers/iio/temperature/ltc2983.c +++ b/drivers/iio/temperature/ltc2983.c @@ -12,11 +12,15 @@ #include <linux/iio/iio.h> #include <linux/interrupt.h> #include <linux/list.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_gpio.h> +#include <linux/property.h> #include <linux/regmap.h> #include <linux/spi/spi.h> +#include <asm/byteorder.h> +#include <asm/unaligned.h> + /* register map */ #define LTC2983_STATUS_REG 0x0000 #define LTC2983_TEMP_RES_START_REG 0x0010 @@ -219,7 +223,7 @@ struct ltc2983_sensor { struct ltc2983_custom_sensor { /* raw table sensor data */ - u8 *table; + void *table; size_t size; /* address offset */ s8 offset; @@ -377,25 +381,25 @@ static int __ltc2983_chan_custom_sensor_assign(struct ltc2983_data *st, return regmap_bulk_write(st->regmap, reg, custom->table, custom->size); } -static struct ltc2983_custom_sensor *__ltc2983_custom_sensor_new( - struct ltc2983_data *st, - const struct device_node *np, - const char *propname, - const bool is_steinhart, - const u32 resolution, - const bool has_signed) +static struct ltc2983_custom_sensor * +__ltc2983_custom_sensor_new(struct ltc2983_data *st, const struct fwnode_handle *fn, + const char *propname, const bool is_steinhart, + const u32 resolution, const bool has_signed) { struct ltc2983_custom_sensor *new_custom; - u8 index, n_entries, tbl = 0; struct device *dev = &st->spi->dev; /* * For custom steinhart, the full u32 is taken. For all the others * the MSB is discarded. */ const u8 n_size = is_steinhart ? 4 : 3; - const u8 e_size = is_steinhart ? sizeof(u32) : sizeof(u64); + u8 index, n_entries; + int ret; - n_entries = of_property_count_elems_of_size(np, propname, e_size); + if (is_steinhart) + n_entries = fwnode_property_count_u32(fn, propname); + else + n_entries = fwnode_property_count_u64(fn, propname); /* n_entries must be an even number */ if (!n_entries || (n_entries % 2) != 0) { dev_err(dev, "Number of entries either 0 or not even\n"); @@ -409,8 +413,8 @@ static struct ltc2983_custom_sensor *__ltc2983_custom_sensor_new( new_custom->size = n_entries * n_size; /* check Steinhart size */ if (is_steinhart && new_custom->size != LTC2983_CUSTOM_STEINHART_SIZE) { - dev_err(dev, "Steinhart sensors size(%zu) must be 24", - new_custom->size); + dev_err(dev, "Steinhart sensors size(%zu) must be %u\n", new_custom->size, + LTC2983_CUSTOM_STEINHART_SIZE); return ERR_PTR(-EINVAL); } /* Check space on the table. */ @@ -423,21 +427,33 @@ static struct ltc2983_custom_sensor *__ltc2983_custom_sensor_new( } /* allocate the table */ - new_custom->table = devm_kzalloc(dev, new_custom->size, GFP_KERNEL); + if (is_steinhart) + new_custom->table = devm_kcalloc(dev, n_entries, sizeof(u32), GFP_KERNEL); + else + new_custom->table = devm_kcalloc(dev, n_entries, sizeof(u64), GFP_KERNEL); if (!new_custom->table) return ERR_PTR(-ENOMEM); - for (index = 0; index < n_entries; index++) { - u64 temp = 0, j; - /* - * Steinhart sensors are configured with raw values in the - * devicetree. For the other sensors we must convert the - * value to raw. The odd index's correspond to temperarures - * and always have 1/1024 of resolution. Temperatures also - * come in kelvin, so signed values is not possible - */ - if (!is_steinhart) { - of_property_read_u64_index(np, propname, index, &temp); + /* + * Steinhart sensors are configured with raw values in the firmware + * node. For the other sensors we must convert the value to raw. + * The odd index's correspond to temperatures and always have 1/1024 + * of resolution. Temperatures also come in Kelvin, so signed values + * are not possible. + */ + if (is_steinhart) { + ret = fwnode_property_read_u32_array(fn, propname, new_custom->table, n_entries); + if (ret < 0) + return ERR_PTR(ret); + + cpu_to_be32_array(new_custom->table, new_custom->table, n_entries); + } else { + ret = fwnode_property_read_u64_array(fn, propname, new_custom->table, n_entries); + if (ret < 0) + return ERR_PTR(ret); + + for (index = 0; index < n_entries; index++) { + u64 temp = ((u64 *)new_custom->table)[index]; if ((index % 2) != 0) temp = __convert_to_raw(temp, 1024); @@ -445,16 +461,9 @@ static struct ltc2983_custom_sensor *__ltc2983_custom_sensor_new( temp = __convert_to_raw_sign(temp, resolution); else temp = __convert_to_raw(temp, resolution); - } else { - u32 t32; - of_property_read_u32_index(np, propname, index, &t32); - temp = t32; + put_unaligned_be24(temp, new_custom->table + index * 3); } - - for (j = 0; j < n_size; j++) - new_custom->table[tbl++] = - temp >> (8 * (n_size - j - 1)); } new_custom->is_steinhart = is_steinhart; @@ -597,13 +606,12 @@ static int ltc2983_adc_assign_chan(struct ltc2983_data *st, return __ltc2983_chan_assign_common(st, sensor, chan_val); } -static struct ltc2983_sensor *ltc2983_thermocouple_new( - const struct device_node *child, - struct ltc2983_data *st, - const struct ltc2983_sensor *sensor) +static struct ltc2983_sensor * +ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data *st, + const struct ltc2983_sensor *sensor) { struct ltc2983_thermocouple *thermo; - struct device_node *phandle; + struct fwnode_handle *ref; u32 oc_current; int ret; @@ -611,11 +619,10 @@ static struct ltc2983_sensor *ltc2983_thermocouple_new( if (!thermo) return ERR_PTR(-ENOMEM); - if (of_property_read_bool(child, "adi,single-ended")) + if (fwnode_property_read_bool(child, "adi,single-ended")) thermo->sensor_config = LTC2983_THERMOCOUPLE_SGL(1); - ret = of_property_read_u32(child, "adi,sensor-oc-current-microamp", - &oc_current); + ret = fwnode_property_read_u32(child, "adi,sensor-oc-current-microamp", &oc_current); if (!ret) { switch (oc_current) { case 10: @@ -651,20 +658,18 @@ static struct ltc2983_sensor *ltc2983_thermocouple_new( return ERR_PTR(-EINVAL); } - phandle = of_parse_phandle(child, "adi,cold-junction-handle", 0); - if (phandle) { - int ret; - - ret = of_property_read_u32(phandle, "reg", - &thermo->cold_junction_chan); + ref = fwnode_find_reference(child, "adi,cold-junction-handle", 0); + if (IS_ERR(ref)) { + ref = NULL; + } else { + ret = fwnode_property_read_u32(ref, "reg", &thermo->cold_junction_chan); if (ret) { /* * This would be catched later but we can just return * the error right away. */ dev_err(&st->spi->dev, "Property reg must be given\n"); - of_node_put(phandle); - return ERR_PTR(-EINVAL); + goto fail; } } @@ -676,8 +681,8 @@ static struct ltc2983_sensor *ltc2983_thermocouple_new( propname, false, 16384, true); if (IS_ERR(thermo->custom)) { - of_node_put(phandle); - return ERR_CAST(thermo->custom); + ret = PTR_ERR(thermo->custom); + goto fail; } } @@ -685,37 +690,41 @@ static struct ltc2983_sensor *ltc2983_thermocouple_new( thermo->sensor.fault_handler = ltc2983_thermocouple_fault_handler; thermo->sensor.assign_chan = ltc2983_thermocouple_assign_chan; - of_node_put(phandle); + fwnode_handle_put(ref); return &thermo->sensor; + +fail: + fwnode_handle_put(ref); + return ERR_PTR(ret); } -static struct ltc2983_sensor *ltc2983_rtd_new(const struct device_node *child, - struct ltc2983_data *st, - const struct ltc2983_sensor *sensor) +static struct ltc2983_sensor * +ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st, + const struct ltc2983_sensor *sensor) { struct ltc2983_rtd *rtd; int ret = 0; struct device *dev = &st->spi->dev; - struct device_node *phandle; + struct fwnode_handle *ref; u32 excitation_current = 0, n_wires = 0; rtd = devm_kzalloc(dev, sizeof(*rtd), GFP_KERNEL); if (!rtd) return ERR_PTR(-ENOMEM); - phandle = of_parse_phandle(child, "adi,rsense-handle", 0); - if (!phandle) { + ref = fwnode_find_reference(child, "adi,rsense-handle", 0); + if (IS_ERR(ref)) { dev_err(dev, "Property adi,rsense-handle missing or invalid"); - return ERR_PTR(-EINVAL); + return ERR_CAST(ref); } - ret = of_property_read_u32(phandle, "reg", &rtd->r_sense_chan); + ret = fwnode_property_read_u32(ref, "reg", &rtd->r_sense_chan); if (ret) { dev_err(dev, "Property reg must be given\n"); goto fail; } - ret = of_property_read_u32(child, "adi,number-of-wires", &n_wires); + ret = fwnode_property_read_u32(child, "adi,number-of-wires", &n_wires); if (!ret) { switch (n_wires) { case 2: @@ -738,9 +747,9 @@ static struct ltc2983_sensor *ltc2983_rtd_new(const struct device_node *child, } } - if (of_property_read_bool(child, "adi,rsense-share")) { + if (fwnode_property_read_bool(child, "adi,rsense-share")) { /* Current rotation is only available with rsense sharing */ - if (of_property_read_bool(child, "adi,current-rotate")) { + if (fwnode_property_read_bool(child, "adi,current-rotate")) { if (n_wires == 2 || n_wires == 3) { dev_err(dev, "Rotation not allowed for 2/3 Wire RTDs"); @@ -803,8 +812,8 @@ static struct ltc2983_sensor *ltc2983_rtd_new(const struct device_node *child, "adi,custom-rtd", false, 2048, false); if (IS_ERR(rtd->custom)) { - of_node_put(phandle); - return ERR_CAST(rtd->custom); + ret = PTR_ERR(rtd->custom); + goto fail; } } @@ -812,8 +821,8 @@ static struct ltc2983_sensor *ltc2983_rtd_new(const struct device_node *child, rtd->sensor.fault_handler = ltc2983_common_fault_handler; rtd->sensor.assign_chan = ltc2983_rtd_assign_chan; - ret = of_property_read_u32(child, "adi,excitation-current-microamp", - &excitation_current); + ret = fwnode_property_read_u32(child, "adi,excitation-current-microamp", + &excitation_current); if (ret) { /* default to 5uA */ rtd->excitation_current = 1; @@ -852,23 +861,22 @@ static struct ltc2983_sensor *ltc2983_rtd_new(const struct device_node *child, } } - of_property_read_u32(child, "adi,rtd-curve", &rtd->rtd_curve); + fwnode_property_read_u32(child, "adi,rtd-curve", &rtd->rtd_curve); - of_node_put(phandle); + fwnode_handle_put(ref); return &rtd->sensor; fail: - of_node_put(phandle); + fwnode_handle_put(ref); return ERR_PTR(ret); } -static struct ltc2983_sensor *ltc2983_thermistor_new( - const struct device_node *child, - struct ltc2983_data *st, - const struct ltc2983_sensor *sensor) +static struct ltc2983_sensor * +ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *st, + const struct ltc2983_sensor *sensor) { struct ltc2983_thermistor *thermistor; struct device *dev = &st->spi->dev; - struct device_node *phandle; + struct fwnode_handle *ref; u32 excitation_current = 0; int ret = 0; @@ -876,23 +884,23 @@ static struct ltc2983_sensor *ltc2983_thermistor_new( if (!thermistor) return ERR_PTR(-ENOMEM); - phandle = of_parse_phandle(child, "adi,rsense-handle", 0); - if (!phandle) { + ref = fwnode_find_reference(child, "adi,rsense-handle", 0); + if (IS_ERR(ref)) { dev_err(dev, "Property adi,rsense-handle missing or invalid"); - return ERR_PTR(-EINVAL); + return ERR_CAST(ref); } - ret = of_property_read_u32(phandle, "reg", &thermistor->r_sense_chan); + ret = fwnode_property_read_u32(ref, "reg", &thermistor->r_sense_chan); if (ret) { dev_err(dev, "rsense channel must be configured...\n"); goto fail; } - if (of_property_read_bool(child, "adi,single-ended")) { + if (fwnode_property_read_bool(child, "adi,single-ended")) { thermistor->sensor_config = LTC2983_THERMISTOR_SGL(1); - } else if (of_property_read_bool(child, "adi,rsense-share")) { + } else if (fwnode_property_read_bool(child, "adi,rsense-share")) { /* rotation is only possible if sharing rsense */ - if (of_property_read_bool(child, "adi,current-rotate")) + if (fwnode_property_read_bool(child, "adi,current-rotate")) thermistor->sensor_config = LTC2983_THERMISTOR_C_ROTATE(1); else @@ -926,16 +934,16 @@ static struct ltc2983_sensor *ltc2983_thermistor_new( steinhart, 64, false); if (IS_ERR(thermistor->custom)) { - of_node_put(phandle); - return ERR_CAST(thermistor->custom); + ret = PTR_ERR(thermistor->custom); + goto fail; } } /* set common parameters */ thermistor->sensor.fault_handler = ltc2983_common_fault_handler; thermistor->sensor.assign_chan = ltc2983_thermistor_assign_chan; - ret = of_property_read_u32(child, "adi,excitation-current-nanoamp", - &excitation_current); + ret = fwnode_property_read_u32(child, "adi,excitation-current-nanoamp", + &excitation_current); if (ret) { /* Auto range is not allowed for custom sensors */ if (sensor->type >= LTC2983_SENSOR_THERMISTOR_STEINHART) @@ -999,17 +1007,16 @@ static struct ltc2983_sensor *ltc2983_thermistor_new( } } - of_node_put(phandle); + fwnode_handle_put(ref); return &thermistor->sensor; fail: - of_node_put(phandle); + fwnode_handle_put(ref); return ERR_PTR(ret); } -static struct ltc2983_sensor *ltc2983_diode_new( - const struct device_node *child, - const struct ltc2983_data *st, - const struct ltc2983_sensor *sensor) +static struct ltc2983_sensor * +ltc2983_diode_new(const struct fwnode_handle *child, const struct ltc2983_data *st, + const struct ltc2983_sensor *sensor) { struct ltc2983_diode *diode; u32 temp = 0, excitation_current = 0; @@ -1019,13 +1026,13 @@ static struct ltc2983_sensor *ltc2983_diode_new( if (!diode) return ERR_PTR(-ENOMEM); - if (of_property_read_bool(child, "adi,single-ended")) + if (fwnode_property_read_bool(child, "adi,single-ended")) diode->sensor_config = LTC2983_DIODE_SGL(1); - if (of_property_read_bool(child, "adi,three-conversion-cycles")) + if (fwnode_property_read_bool(child, "adi,three-conversion-cycles")) diode->sensor_config |= LTC2983_DIODE_3_CONV_CYCLE(1); - if (of_property_read_bool(child, "adi,average-on")) + if (fwnode_property_read_bool(child, "adi,average-on")) diode->sensor_config |= LTC2983_DIODE_AVERAGE_ON(1); /* validate channel index */ @@ -1040,8 +1047,8 @@ static struct ltc2983_sensor *ltc2983_diode_new( diode->sensor.fault_handler = ltc2983_common_fault_handler; diode->sensor.assign_chan = ltc2983_diode_assign_chan; - ret = of_property_read_u32(child, "adi,excitation-current-microamp", - &excitation_current); + ret = fwnode_property_read_u32(child, "adi,excitation-current-microamp", + &excitation_current); if (!ret) { switch (excitation_current) { case 10: @@ -1064,7 +1071,7 @@ static struct ltc2983_sensor *ltc2983_diode_new( } } - of_property_read_u32(child, "adi,ideal-factor-value", &temp); + fwnode_property_read_u32(child, "adi,ideal-factor-value", &temp); /* 2^20 resolution */ diode->ideal_factor_value = __convert_to_raw(temp, 1048576); @@ -1072,7 +1079,7 @@ static struct ltc2983_sensor *ltc2983_diode_new( return &diode->sensor; } -static struct ltc2983_sensor *ltc2983_r_sense_new(struct device_node *child, +static struct ltc2983_sensor *ltc2983_r_sense_new(struct fwnode_handle *child, struct ltc2983_data *st, const struct ltc2983_sensor *sensor) { @@ -1091,7 +1098,7 @@ static struct ltc2983_sensor *ltc2983_r_sense_new(struct device_node *child, return ERR_PTR(-EINVAL); } - ret = of_property_read_u32(child, "adi,rsense-val-milli-ohms", &temp); + ret = fwnode_property_read_u32(child, "adi,rsense-val-milli-ohms", &temp); if (ret) { dev_err(&st->spi->dev, "Property adi,rsense-val-milli-ohms missing\n"); return ERR_PTR(-EINVAL); @@ -1110,7 +1117,7 @@ static struct ltc2983_sensor *ltc2983_r_sense_new(struct device_node *child, return &rsense->sensor; } -static struct ltc2983_sensor *ltc2983_adc_new(struct device_node *child, +static struct ltc2983_sensor *ltc2983_adc_new(struct fwnode_handle *child, struct ltc2983_data *st, const struct ltc2983_sensor *sensor) { @@ -1120,7 +1127,7 @@ static struct ltc2983_sensor *ltc2983_adc_new(struct device_node *child, if (!adc) return ERR_PTR(-ENOMEM); - if (of_property_read_bool(child, "adi,single-ended")) + if (fwnode_property_read_bool(child, "adi,single-ended")) adc->single_ended = true; if (!adc->single_ended && @@ -1264,17 +1271,15 @@ static irqreturn_t ltc2983_irq_handler(int irq, void *data) static int ltc2983_parse_dt(struct ltc2983_data *st) { - struct device_node *child; struct device *dev = &st->spi->dev; + struct fwnode_handle *child; int ret = 0, chan = 0, channel_avail_mask = 0; - of_property_read_u32(dev->of_node, "adi,mux-delay-config-us", - &st->mux_delay_config); + device_property_read_u32(dev, "adi,mux-delay-config-us", &st->mux_delay_config); - of_property_read_u32(dev->of_node, "adi,filter-notch-freq", - &st->filter_notch_freq); + device_property_read_u32(dev, "adi,filter-notch-freq", &st->filter_notch_freq); - st->num_channels = of_get_available_child_count(dev->of_node); + st->num_channels = device_get_child_node_count(dev); if (!st->num_channels) { dev_err(&st->spi->dev, "At least one channel must be given!"); return -EINVAL; @@ -1286,10 +1291,10 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) return -ENOMEM; st->iio_channels = st->num_channels; - for_each_available_child_of_node(dev->of_node, child) { + device_for_each_child_node(dev, child) { struct ltc2983_sensor sensor; - ret = of_property_read_u32(child, "reg", &sensor.chan); + ret = fwnode_property_read_u32(child, "reg", &sensor.chan); if (ret) { dev_err(dev, "reg property must given for child nodes\n"); goto put_child; @@ -1299,8 +1304,8 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) if (sensor.chan < LTC2983_MIN_CHANNELS_NR || sensor.chan > LTC2983_MAX_CHANNELS_NR) { ret = -EINVAL; - dev_err(dev, - "chan:%d must be from 1 to 20\n", sensor.chan); + dev_err(dev, "chan:%d must be from %u to %u\n", sensor.chan, + LTC2983_MIN_CHANNELS_NR, LTC2983_MAX_CHANNELS_NR); goto put_child; } else if (channel_avail_mask & BIT(sensor.chan)) { ret = -EINVAL; @@ -1308,8 +1313,7 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) goto put_child; } - ret = of_property_read_u32(child, "adi,sensor-type", - &sensor.type); + ret = fwnode_property_read_u32(child, "adi,sensor-type", &sensor.type); if (ret) { dev_err(dev, "adi,sensor-type property must given for child nodes\n"); @@ -1363,7 +1367,7 @@ static int ltc2983_parse_dt(struct ltc2983_data *st) return 0; put_child: - of_node_put(child); + fwnode_handle_put(child); return ret; } diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c index 54840881259a..8307aae2cb45 100644 --- a/drivers/iio/temperature/max31856.c +++ b/drivers/iio/temperature/max31856.c @@ -7,9 +7,11 @@ */ #include <linux/ctype.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/init.h> #include <linux/err.h> +#include <linux/property.h> #include <linux/spi/spi.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -422,9 +424,7 @@ static int max31856_probe(struct spi_device *spi) indio_dev->channels = max31856_channels; indio_dev->num_channels = ARRAY_SIZE(max31856_channels); - ret = of_property_read_u32(spi->dev.of_node, "thermocouple-type", - &data->thermocouple_type); - + ret = device_property_read_u32(&spi->dev, "thermocouple-type", &data->thermocouple_type); if (ret) { dev_info(&spi->dev, "Could not read thermocouple type DT property, configuring as a K-Type\n"); diff --git a/drivers/iio/temperature/max31865.c b/drivers/iio/temperature/max31865.c index 86c3f3509a26..e3bb78184c6e 100644 --- a/drivers/iio/temperature/max31865.c +++ b/drivers/iio/temperature/max31865.c @@ -12,9 +12,11 @@ #include <linux/delay.h> #include <linux/err.h> #include <linux/init.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> +#include <linux/property.h> #include <linux/spi/spi.h> #include <asm/unaligned.h> @@ -305,7 +307,7 @@ static int max31865_probe(struct spi_device *spi) indio_dev->channels = max31865_channels; indio_dev->num_channels = ARRAY_SIZE(max31865_channels); - if (of_property_read_bool(spi->dev.of_node, "maxim,3-wire")) { + if (device_property_read_bool(&spi->dev, "maxim,3-wire")) { /* select 3 wire */ data->three_wire = 1; } else { diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c index 2a4b75897910..f1a8704e6cc1 100644 --- a/drivers/iio/trigger/iio-trig-sysfs.c +++ b/drivers/iio/trigger/iio-trig-sysfs.c @@ -176,16 +176,15 @@ out1: static int iio_sysfs_trigger_remove(int id) { - bool foundit = false; - struct iio_sysfs_trig *t; + struct iio_sysfs_trig *t = NULL, *iter; mutex_lock(&iio_sysfs_trig_list_mut); - list_for_each_entry(t, &iio_sysfs_trig_list, l) - if (id == t->id) { - foundit = true; + list_for_each_entry(iter, &iio_sysfs_trig_list, l) + if (id == iter->id) { + t = iter; break; } - if (!foundit) { + if (!t) { mutex_unlock(&iio_sysfs_trig_list_mut); return -EINVAL; } diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 71c709771676..52b8957c19c9 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -290,7 +290,7 @@ static inline ssize_t ad7746_start_calib(struct device *dev, int ret, timeout = 10; bool doit; - ret = strtobool(buf, &doit); + ret = kstrtobool(buf, &doit); if (ret < 0) return ret; diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 793918e1c45f..f177b20f0f2d 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -749,7 +749,6 @@ static int ad5933_probe(struct i2c_client *client, indio_dev->num_channels = ARRAY_SIZE(ad5933_channels); ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev, - INDIO_BUFFER_SOFTWARE, &ad5933_ring_setup_ops); if (ret) return ret; diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index 74adb82f37c3..c0b2716d0511 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -499,7 +499,6 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev, ret = IIO_VAL_INT; break; case IIO_ANGL_VEL: - negative = st->rx[0] & 0x80; vel = be16_to_cpup((__be16 *)st->rx); vel >>= 16 - st->resolution; if (vel & 0x8000) { diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h index c525fd51652f..7852f6c9a714 100644 --- a/include/linux/iio/adc/ad_sigma_delta.h +++ b/include/linux/iio/adc/ad_sigma_delta.h @@ -32,26 +32,34 @@ struct iio_dev; /** * struct ad_sigma_delta_info - Sigma Delta driver specific callbacks and options * @set_channel: Will be called to select the current channel, may be NULL. + * @append_status: Will be called to enable status append at the end of the sample, may be NULL. * @set_mode: Will be called to select the current mode, may be NULL. + * @disable_all: Will be called to disable all channels, may be NULL. * @postprocess_sample: Is called for each sampled data word, can be used to * modify or drop the sample data, it, may be NULL. * @has_registers: true if the device has writable and readable registers, false * if there is just one read-only sample data shift register. * @addr_shift: Shift of the register address in the communications register. * @read_mask: Mask for the communications register having the read bit set. + * @status_ch_mask: Mask for the channel number stored in status register. * @data_reg: Address of the data register, if 0 the default address of 0x3 will * be used. * @irq_flags: flags for the interrupt used by the triggered buffer + * @num_slots: Number of sequencer slots */ struct ad_sigma_delta_info { int (*set_channel)(struct ad_sigma_delta *, unsigned int channel); + int (*append_status)(struct ad_sigma_delta *, bool append); int (*set_mode)(struct ad_sigma_delta *, enum ad_sigma_delta_mode mode); + int (*disable_all)(struct ad_sigma_delta *); int (*postprocess_sample)(struct ad_sigma_delta *, unsigned int raw_sample); bool has_registers; unsigned int addr_shift; unsigned int read_mask; + unsigned int status_ch_mask; unsigned int data_reg; unsigned long irq_flags; + unsigned int num_slots; }; /** @@ -76,6 +84,13 @@ struct ad_sigma_delta { uint8_t comm; const struct ad_sigma_delta_info *info; + unsigned int active_slots; + unsigned int current_slot; + unsigned int num_slots; + bool status_appended; + /* map slots to channels in order to know what to expect from devices */ + unsigned int *slots; + uint8_t *samples_buf; /* * DMA (thus cache coherency maintenance) requires the @@ -97,6 +112,29 @@ static inline int ad_sigma_delta_set_channel(struct ad_sigma_delta *sd, return 0; } +static inline int ad_sigma_delta_append_status(struct ad_sigma_delta *sd, bool append) +{ + int ret; + + if (sd->info->append_status) { + ret = sd->info->append_status(sd, append); + if (ret < 0) + return ret; + + sd->status_appended = append; + } + + return 0; +} + +static inline int ad_sigma_delta_disable_all(struct ad_sigma_delta *sd) +{ + if (sd->info->disable_all) + return sd->info->disable_all(sd); + + return 0; +} + static inline int ad_sigma_delta_set_mode(struct ad_sigma_delta *sd, unsigned int mode) { diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index 22f67845cdd3..db4a1b260348 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -237,6 +237,7 @@ struct st_sensor_settings { * @hw_irq_trigger: if we're using the hardware interrupt on the sensor. * @hw_timestamp: Latest timestamp from the interrupt handler, when in use. * @buffer_data: Data used by buffer part. + * @odr_lock: Local lock for preventing concurrent ODR accesses/changes */ struct st_sensor_data { struct iio_trigger *trig; @@ -261,6 +262,8 @@ struct st_sensor_data { s64 hw_timestamp; char buffer_data[ST_SENSORS_MAX_BUFFER_SIZE] ____cacheline_aligned; + + struct mutex odr_lock; }; #ifdef CONFIG_IIO_BUFFER diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index 2be12b7b5dc5..6b3586b3f952 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -7,6 +7,9 @@ * struct iio_dev_opaque - industrial I/O device opaque information * @indio_dev: public industrial I/O device information * @id: used to identify device internally + * @currentmode: operating mode currently in use, may be eventually + * checked by device drivers but should be considered + * read-only as this is a core internal bit * @driver_module: used to make it harder to undercut users * @info_exist_lock: lock to prevent use during removal * @trig_readonly: mark the current trigger immutable @@ -36,6 +39,7 @@ */ struct iio_dev_opaque { struct iio_dev indio_dev; + int currentmode; int id; struct module *driver_module; struct mutex info_exist_lock; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index faf00f2c0be6..233d2e6b7721 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -315,7 +315,54 @@ static inline bool iio_channel_has_available(const struct iio_chan_spec *chan, s64 iio_get_time_ns(const struct iio_dev *indio_dev); unsigned int iio_get_time_res(const struct iio_dev *indio_dev); -/* Device operating modes */ +/* + * Device operating modes + * @INDIO_DIRECT_MODE: There is an access to either: + * a) The last single value available for devices that do not provide + * on-demand reads. + * b) A new value after performing an on-demand read otherwise. + * On most devices, this is a single-shot read. On some devices with data + * streams without an 'on-demand' function, this might also be the 'last value' + * feature. Above all, this mode internally means that we are not in any of the + * other modes, and sysfs reads should work. + * Device drivers should inform the core if they support this mode. + * @INDIO_BUFFER_TRIGGERED: Common mode when dealing with kfifo buffers. + * It indicates that an explicit trigger is required. This requests the core to + * attach a poll function when enabling the buffer, which is indicated by the + * _TRIGGERED suffix. + * The core will ensure this mode is set when registering a triggered buffer + * with iio_triggered_buffer_setup(). + * @INDIO_BUFFER_SOFTWARE: Another kfifo buffer mode, but not event triggered. + * No poll function can be attached because there is no triggered infrastructure + * we can use to cause capture. There is a kfifo that the driver will fill, but + * not "only one scan at a time". Typically, hardware will have a buffer that + * can hold multiple scans. Software may read one or more scans at a single time + * and push the available data to a Kfifo. This means the core will not attach + * any poll function when enabling the buffer. + * The core will ensure this mode is set when registering a simple kfifo buffer + * with devm_iio_kfifo_buffer_setup(). + * @INDIO_BUFFER_HARDWARE: For specific hardware, if unsure do not use this mode. + * Same as above but this time the buffer is not a kfifo where we have direct + * access to the data. Instead, the consumer driver must access the data through + * non software visible channels (or DMA when there is no demux possible in + * software) + * The core will ensure this mode is set when registering a dmaengine buffer + * with devm_iio_dmaengine_buffer_setup(). + * @INDIO_EVENT_TRIGGERED: Very unusual mode. + * Triggers usually refer to an external event which will start data capture. + * Here it is kind of the opposite as, a particular state of the data might + * produce an event which can be considered as an event. We don't necessarily + * have access to the data itself, but to the event produced. For example, this + * can be a threshold detector. The internal path of this mode is very close to + * the INDIO_BUFFER_TRIGGERED mode. + * The core will ensure this mode is set when registering a triggered event. + * @INDIO_HARDWARE_TRIGGERED: Very unusual mode. + * Here, triggers can result in data capture and can be routed to multiple + * hardware components, which make them close to regular triggers in the way + * they must be managed by the core, but without the entire interrupts/poll + * functions burden. Interrupts are irrelevant as the data flow is hardware + * mediated and distributed. + */ #define INDIO_DIRECT_MODE 0x01 #define INDIO_BUFFER_TRIGGERED 0x02 #define INDIO_BUFFER_SOFTWARE 0x04 @@ -488,8 +535,12 @@ struct iio_buffer_setup_ops { /** * struct iio_dev - industrial I/O device - * @modes: [DRIVER] operating modes supported by device - * @currentmode: [INTERN] current operating mode + * @modes: [DRIVER] bitmask listing all the operating modes + * supported by the IIO device. This list should be + * initialized before registering the IIO device. It can + * also be filed up by the IIO core, as a result of + * enabling particular features in the driver + * (see iio_triggered_event_setup()). * @dev: [DRIVER] device structure, should be assigned a parent * and owner * @buffer: [DRIVER] any buffer present @@ -516,7 +567,6 @@ struct iio_buffer_setup_ops { */ struct iio_dev { int modes; - int currentmode; struct device dev; struct iio_buffer *buffer; @@ -543,6 +593,8 @@ struct iio_dev { }; int iio_device_id(struct iio_dev *indio_dev); +int iio_device_get_current_mode(struct iio_dev *indio_dev); +bool iio_buffer_enabled(struct iio_dev *indio_dev); const struct iio_chan_spec *iio_find_channel_from_si(struct iio_dev *indio_dev, int si); @@ -672,16 +724,6 @@ struct iio_dev *devm_iio_device_alloc(struct device *parent, int sizeof_priv); __printf(2, 3) struct iio_trigger *devm_iio_trigger_alloc(struct device *parent, const char *fmt, ...); -/** - * iio_buffer_enabled() - helper function to test if the buffer is enabled - * @indio_dev: IIO device structure for device - **/ -static inline bool iio_buffer_enabled(struct iio_dev *indio_dev) -{ - return indio_dev->currentmode - & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE | - INDIO_BUFFER_SOFTWARE); -} /** * iio_get_debugfs_dentry() - helper function to get the debugfs_dentry diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h index ccd2ceae7b25..8a83fb58232d 100644 --- a/include/linux/iio/kfifo_buf.h +++ b/include/linux/iio/kfifo_buf.h @@ -12,11 +12,10 @@ void iio_kfifo_free(struct iio_buffer *r); int devm_iio_kfifo_buffer_setup_ext(struct device *dev, struct iio_dev *indio_dev, - int mode_flags, const struct iio_buffer_setup_ops *setup_ops, const struct attribute **buffer_attrs); -#define devm_iio_kfifo_buffer_setup(dev, indio_dev, mode_flags, setup_ops) \ - devm_iio_kfifo_buffer_setup_ext((dev), (indio_dev), (mode_flags), (setup_ops), NULL) +#define devm_iio_kfifo_buffer_setup(dev, indio_dev, setup_ops) \ + devm_iio_kfifo_buffer_setup_ext((dev), (indio_dev), (setup_ops), NULL) #endif |