summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio11
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio-meas-spec1
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio-timer-stm3248
-rw-r--r--Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt2
-rw-r--r--Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt7
-rw-r--r--Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt19
-rw-r--r--Documentation/devicetree/bindings/iio/adc/ti-adc108s102.txt18
-rw-r--r--Documentation/devicetree/bindings/trivial-devices.txt1
-rw-r--r--drivers/iio/accel/bma180.c45
-rw-r--r--drivers/iio/accel/hid-sensor-accel-3d.c2
-rw-r--r--drivers/iio/accel/st_accel_core.c7
-rw-r--r--drivers/iio/adc/Kconfig24
-rw-r--r--drivers/iio/adc/Makefile2
-rw-r--r--drivers/iio/adc/hi8435.c50
-rw-r--r--drivers/iio/adc/ina2xx-adc.c12
-rw-r--r--drivers/iio/adc/meson_saradc.c86
-rw-r--r--drivers/iio/adc/rcar-gyroadc.c16
-rw-r--r--drivers/iio/adc/ti-adc084s021.c275
-rw-r--r--drivers/iio/adc/ti-adc108s102.c348
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-attributes.c54
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-trigger.c80
-rw-r--r--drivers/iio/dac/Kconfig3
-rw-r--r--drivers/iio/dac/ad5064.c71
-rw-r--r--drivers/iio/humidity/hts221.h3
-rw-r--r--drivers/iio/humidity/hts221_core.c54
-rw-r--r--drivers/iio/humidity/hts221_i2c.c1
-rw-r--r--drivers/iio/humidity/hts221_spi.c1
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h5
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c6
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c52
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c1
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c1
-rw-r--r--drivers/iio/industrialio-core.c4
-rw-r--r--drivers/iio/inkern.c4
-rw-r--r--drivers/iio/light/Kconfig10
-rw-r--r--drivers/iio/light/Makefile1
-rw-r--r--drivers/iio/light/isl29018.c2
-rw-r--r--drivers/iio/light/isl29028.c (renamed from drivers/staging/iio/light/isl29028.c)76
-rw-r--r--drivers/iio/light/rpr0521.c307
-rw-r--r--drivers/iio/light/tsl2583.c106
-rw-r--r--drivers/iio/orientation/hid-sensor-rotation.c55
-rw-r--r--drivers/iio/pressure/Kconfig2
-rw-r--r--drivers/iio/pressure/st_pressure_core.c8
-rw-r--r--drivers/iio/pressure/zpa2326.c18
-rw-r--r--drivers/iio/proximity/as3935.c6
-rw-r--r--drivers/iio/temperature/maxim_thermocouple.c1
-rw-r--r--drivers/iio/trigger/stm32-timer-trigger.c113
-rw-r--r--drivers/staging/iio/frequency/ad9834.c22
-rw-r--r--drivers/staging/iio/frequency/dds.h2
-rw-r--r--drivers/staging/iio/light/Kconfig10
-rw-r--r--drivers/staging/iio/light/Makefile3
-rw-r--r--drivers/staging/iio/light/tsl2x7x.c (renamed from drivers/staging/iio/light/tsl2x7x_core.c)66
-rw-r--r--drivers/staging/iio/meter/ade7753.c101
-rw-r--r--drivers/staging/iio/meter/ade7754.c56
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c50
-rw-r--r--drivers/staging/iio/meter/ade7854.c88
-rw-r--r--include/linux/hid-sensor-hub.h5
-rw-r--r--include/linux/hid-sensor-ids.h5
-rw-r--r--include/linux/iio/timer/stm32-timer-trigger.h2
-rw-r--r--include/linux/mfd/stm32-timers.h2
-rw-r--r--tools/iio/Makefile2
-rw-r--r--tools/iio/iio_utils.h2
62 files changed, 2010 insertions, 425 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 8c24d0892f61..2db2cdf42d54 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -1425,6 +1425,17 @@ Description:
guarantees that the hardware fifo is flushed to the device
buffer.
+What: /sys/bus/iio/devices/iio:device*/buffer/hwfifo_timeout
+KernelVersion: 4.12
+Contact: linux-iio@vger.kernel.org
+Description:
+ A read/write property to provide capability to delay reporting of
+ samples till a timeout is reached. This allows host processors to
+ sleep, while the sensor is storing samples in its internal fifo.
+ The maximum timeout in seconds can be specified by setting
+ hwfifo_timeout.The current delay can be read by reading
+ hwfifo_timeout. A value of 0 means that there is no timeout.
+
What: /sys/bus/iio/devices/iio:deviceX/buffer/hwfifo_watermark
KernelVersion: 4.2
Contact: linux-iio@vger.kernel.org
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-meas-spec b/Documentation/ABI/testing/sysfs-bus-iio-meas-spec
index 1a6265e92e2f..6d47e548eee5 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio-meas-spec
+++ b/Documentation/ABI/testing/sysfs-bus-iio-meas-spec
@@ -5,4 +5,3 @@ Description:
Reading returns either '1' or '0'. '1' means that the
battery level supplied to sensor is below 2.25V.
This ABI is available for tsys02d, htu21, ms8607
- This ABI is available for htu21, ms8607
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
index 230020e06677..deb015935683 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
+++ b/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
@@ -16,6 +16,54 @@ Description:
- "OC2REF" : OC2REF signal is used as trigger output.
- "OC3REF" : OC3REF signal is used as trigger output.
- "OC4REF" : OC4REF signal is used as trigger output.
+ Additional modes (on TRGO2 only):
+ - "OC5REF" : OC5REF signal is used as trigger output.
+ - "OC6REF" : OC6REF signal is used as trigger output.
+ - "compare_pulse_OC4REF":
+ OC4REF rising or falling edges generate pulses.
+ - "compare_pulse_OC6REF":
+ OC6REF rising or falling edges generate pulses.
+ - "compare_pulse_OC4REF_r_or_OC6REF_r":
+ OC4REF or OC6REF rising edges generate pulses.
+ - "compare_pulse_OC4REF_r_or_OC6REF_f":
+ OC4REF rising or OC6REF falling edges generate pulses.
+ - "compare_pulse_OC5REF_r_or_OC6REF_r":
+ OC5REF or OC6REF rising edges generate pulses.
+ - "compare_pulse_OC5REF_r_or_OC6REF_f":
+ OC5REF rising or OC6REF falling edges generate pulses.
+
+ +-----------+ +-------------+ +---------+
+ | Prescaler +-> | Counter | +-> | Master | TRGO(2)
+ +-----------+ +--+--------+-+ |-> | Control +-->
+ | | || +---------+
+ +--v--------+-+ OCxREF || +---------+
+ | Chx compare +----------> | Output | ChX
+ +-----------+-+ | | Control +-->
+ . | | +---------+
+ . | | .
+ +-----------v-+ OC6REF | .
+ | Ch6 compare +---------+>
+ +-------------+
+
+ Example with: "compare_pulse_OC4REF_r_or_OC6REF_r":
+
+ X
+ X X
+ X . . X
+ X . . X
+ X . . X
+ count X . . . . X
+ . . . .
+ . . . .
+ +---------------+
+ OC4REF | . . |
+ +-+ . . +-+
+ . +---+ .
+ OC6REF . | | .
+ +-------+ +-------+
+ +-+ +-+
+ TRGO2 | | | |
+ +-+ +---+ +---------+
What: /sys/bus/iio/devices/triggerX/master_mode
KernelVersion: 4.11
diff --git a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt
index 047189192aec..f413e82c8b83 100644
--- a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt
+++ b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt
@@ -2,6 +2,8 @@
Required properties:
- compatible: depending on the SoC this should be one of:
+ - "amlogic,meson8-saradc" for Meson8
+ - "amlogic,meson8b-saradc" for Meson8b
- "amlogic,meson-gxbb-saradc" for GXBB
- "amlogic,meson-gxl-saradc" for GXL
- "amlogic,meson-gxm-saradc" for GXM
diff --git a/Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt b/Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt
index f5b0adae6010..2a62908a774a 100644
--- a/Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt
+++ b/Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt
@@ -16,8 +16,7 @@ Required properties:
- clocks: References to all the clocks specified in the clock-names
property as specified in
Documentation/devicetree/bindings/clock/clock-bindings.txt.
-- clock-names: Shall contain "fck" and "if". The "fck" is the GyroADC block
- clock, the "if" is the interface clock.
+- clock-names: Shall contain "fck". The "fck" is the GyroADC block clock.
- power-domains: Must contain a reference to the PM domain, if available.
- #address-cells: Should be <1> (setting for the subnodes) for all ADCs
except for "fujitsu,mb88101a". Should be <0> (setting for
@@ -75,8 +74,8 @@ Example:
adc@e6e54000 {
compatible = "renesas,r8a7791-gyroadc", "renesas,rcar-gyroadc";
reg = <0 0xe6e54000 0 64>;
- clocks = <&mstp9_clks R8A7791_CLK_GYROADC>, <&clk_65m>;
- clock-names = "fck", "if";
+ clocks = <&mstp9_clks R8A7791_CLK_GYROADC>;
+ clock-names = "fck";
power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
pinctrl-0 = <&adc_pins>;
diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt
new file mode 100644
index 000000000000..4259e50620bc
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt
@@ -0,0 +1,19 @@
+* Texas Instruments' ADC084S021
+
+Required properties:
+ - compatible : Must be "ti,adc084s021"
+ - reg : SPI chip select number for the device
+ - vref-supply : The regulator supply for ADC reference voltage
+ - spi-cpol : Per spi-bus bindings
+ - spi-cpha : Per spi-bus bindings
+ - spi-max-frequency : Per spi-bus bindings
+
+Example:
+adc@0 {
+ compatible = "ti,adc084s021";
+ reg = <0>;
+ vref-supply = <&adc_vref>;
+ spi-cpol;
+ spi-cpha;
+ spi-max-frequency = <16000000>;
+};
diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc108s102.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc108s102.txt
new file mode 100644
index 000000000000..bbbbb4a9f58f
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/ti-adc108s102.txt
@@ -0,0 +1,18 @@
+* Texas Instruments' ADC108S102 and ADC128S102 ADC chip
+
+Required properties:
+ - compatible: Should be "ti,adc108s102"
+ - reg: spi chip select number for the device
+ - vref-supply: The regulator supply for ADC reference voltage
+
+Recommended properties:
+ - spi-max-frequency: Definition as per
+ Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Example:
+adc@0 {
+ compatible = "ti,adc108s102";
+ reg = <0>;
+ vref-supply = <&vdd_supply>;
+ spi-max-frequency = <1000000>;
+};
diff --git a/Documentation/devicetree/bindings/trivial-devices.txt b/Documentation/devicetree/bindings/trivial-devices.txt
index 3e0a34c88e07..35f406dd86b6 100644
--- a/Documentation/devicetree/bindings/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/trivial-devices.txt
@@ -55,6 +55,7 @@ gmt,g751 G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire In
infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz)
infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz)
isil,isl29028 Intersil ISL29028 Ambient Light and Proximity Sensor
+isil,isl29030 Intersil ISL29030 Ambient Light and Proximity Sensor
maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index efc67739c28f..17b7953f2502 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -14,6 +14,7 @@
* BMA250: 7-bit I2C slave address 0x18 or 0x19
*/
+#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
@@ -36,6 +37,7 @@
enum chip_ids {
BMA180,
BMA250,
+ BMA250E,
};
struct bma180_data;
@@ -55,6 +57,7 @@ struct bma180_part_info {
u8 power_reg, power_mask, lowpower_val;
u8 int_enable_reg, int_enable_mask;
u8 softreset_reg;
+ u8 chip_id;
int (*chip_config)(struct bma180_data *data);
void (*chip_disable)(struct bma180_data *data);
@@ -112,6 +115,8 @@ struct bma180_part_info {
#define BMA250_INT1_DATA_MASK BIT(0)
#define BMA250_INT_RESET_MASK BIT(7) /* Reset pending interrupts */
+#define BMA250E_CHIP_ID 0xf9
+
struct bma180_data {
struct i2c_client *client;
struct iio_trigger *trig;
@@ -309,7 +314,7 @@ static int bma180_chip_init(struct bma180_data *data)
if (ret < 0)
return ret;
- if (ret != BMA180_ID_REG_VAL)
+ if (ret != data->part_info->chip_id)
return -ENODEV;
ret = bma180_soft_reset(data);
@@ -632,6 +637,7 @@ static const struct bma180_part_info bma180_part_info[] = {
BMA180_TCO_Z, BMA180_MODE_CONFIG, BMA180_LOW_POWER,
BMA180_CTRL_REG3, BMA180_NEW_DATA_INT,
BMA180_RESET,
+ BMA180_CHIP_ID,
bma180_chip_config,
bma180_chip_disable,
},
@@ -646,6 +652,22 @@ static const struct bma180_part_info bma180_part_info[] = {
BMA250_POWER_REG, BMA250_LOWPOWER_MASK, 1,
BMA250_INT_ENABLE_REG, BMA250_DATA_INTEN_MASK,
BMA250_RESET_REG,
+ BMA180_CHIP_ID,
+ bma250_chip_config,
+ bma250_chip_disable,
+ },
+ [BMA250E] = {
+ bma250_channels, ARRAY_SIZE(bma250_channels),
+ bma250_scale_table, ARRAY_SIZE(bma250_scale_table),
+ bma250_bw_table, ARRAY_SIZE(bma250_bw_table),
+ BMA250_INT_RESET_REG, BMA250_INT_RESET_MASK,
+ BMA250_POWER_REG, BMA250_SUSPEND_MASK,
+ BMA250_BW_REG, BMA250_BW_MASK,
+ BMA250_RANGE_REG, BMA250_RANGE_MASK,
+ BMA250_POWER_REG, BMA250_LOWPOWER_MASK, 1,
+ BMA250_INT_ENABLE_REG, BMA250_DATA_INTEN_MASK,
+ BMA250_RESET_REG,
+ BMA250E_CHIP_ID,
bma250_chip_config,
bma250_chip_disable,
},
@@ -706,6 +728,8 @@ static const struct iio_trigger_ops bma180_trigger_ops = {
static int bma180_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
+ const struct acpi_device_id *acpi_id;
struct bma180_data *data;
struct iio_dev *indio_dev;
enum chip_ids chip;
@@ -718,10 +742,17 @@ static int bma180_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
- if (client->dev.of_node)
+ if (dev->of_node) {
chip = (enum chip_ids)of_device_get_match_data(&client->dev);
- else
+ } else if (id) {
chip = id->driver_data;
+ } else {
+ acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!acpi_id)
+ return -ENODEV;
+
+ chip = acpi_id->driver_data;
+ }
data->part_info = &bma180_part_info[chip];
ret = data->part_info->chip_config(data);
@@ -842,9 +873,16 @@ static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
#define BMA180_PM_OPS NULL
#endif
+static const struct acpi_device_id bma180_acpi_match[] = {
+ { "BMA250E", BMA250E },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, bma180_acpi_match);
+
static struct i2c_device_id bma180_ids[] = {
{ "bma180", BMA180 },
{ "bma250", BMA250 },
+ { "bma250e", BMA250E },
{ }
};
@@ -866,6 +904,7 @@ MODULE_DEVICE_TABLE(of, bma180_of_match);
static struct i2c_driver bma180_driver = {
.driver = {
.name = "bma180",
+ .acpi_match_table = ACPI_PTR(bma180_acpi_match),
.pm = BMA180_PM_OPS,
.of_match_table = bma180_of_match,
},
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index 43a6cb078193..2238a26aba63 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -347,7 +347,7 @@ static int accel_3d_parse_report(struct platform_device *pdev,
static int hid_accel_3d_probe(struct platform_device *pdev)
{
int ret = 0;
- static const char *name;
+ const char *name;
struct iio_dev *indio_dev;
struct accel_3d_state *accel_state;
const struct iio_chan_spec *channel_spec;
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index 784670e2736b..07d1489cd457 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -710,6 +710,8 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
int st_accel_common_probe(struct iio_dev *indio_dev)
{
struct st_sensor_data *adata = iio_priv(indio_dev);
+ struct st_sensors_platform_data *pdata =
+ (struct st_sensors_platform_data *)adata->dev->platform_data;
int irq = adata->get_irq_data_ready(indio_dev);
int err;
@@ -736,9 +738,8 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
&adata->sensor_settings->fs.fs_avl[0];
adata->odr = adata->sensor_settings->odr.odr_avl[0].hz;
- if (!adata->dev->platform_data)
- adata->dev->platform_data =
- (struct st_sensors_platform_data *)&default_accel_pdata;
+ if (!pdata)
+ pdata = (struct st_sensors_platform_data *)&default_accel_pdata;
err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data);
if (err < 0)
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 401f47b51d83..614fa41559b1 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -679,6 +679,18 @@ config TI_ADC0832
This driver can also be built as a module. If so, the module will be
called ti-adc0832.
+config TI_ADC084S021
+ tristate "Texas Instruments ADC084S021"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ If you say yes here you get support for Texas Instruments ADC084S021
+ chips.
+
+ This driver can also be built as a module. If so, the module will be
+ called ti-adc084s021.
+
config TI_ADC12138
tristate "Texas Instruments ADC12130/ADC12132/ADC12138"
depends on SPI
@@ -691,6 +703,18 @@ config TI_ADC12138
This driver can also be built as a module. If so, the module will be
called ti-adc12138.
+config TI_ADC108S102
+ tristate "Texas Instruments ADC108S102 and ADC128S102 driver"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for Texas Instruments ADC108S102 and
+ ADC128S102 ADC.
+
+ To compile this driver as a module, choose M here: the module will
+ be called ti-adc108s102.
+
config TI_ADC128S052
tristate "Texas Instruments ADC128S052/ADC122S021/ADC124S021"
depends on SPI
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 9339bec4babe..b546736a5541 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -62,7 +62,9 @@ obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
obj-$(CONFIG_STM32_ADC) += stm32-adc.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
+obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o
obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
+obj-$(CONFIG_TI_ADC108S102) += ti-adc108s102.o
obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o
diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
index 678e8c7ea763..ab59969b7c49 100644
--- a/drivers/iio/adc/hi8435.c
+++ b/drivers/iio/adc/hi8435.c
@@ -105,6 +105,26 @@ static int hi8435_writew(struct hi8435_priv *priv, u8 reg, u16 val)
return spi_write(priv->spi, priv->reg_buffer, 3);
}
+static int hi8435_read_raw(struct iio_dev *idev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long mask)
+{
+ struct hi8435_priv *priv = iio_priv(idev);
+ u32 tmp;
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp);
+ if (ret < 0)
+ return ret;
+ *val = !!(tmp & BIT(chan->channel));
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
static int hi8435_read_event_config(struct iio_dev *idev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
@@ -121,10 +141,21 @@ static int hi8435_write_event_config(struct iio_dev *idev,
enum iio_event_direction dir, int state)
{
struct hi8435_priv *priv = iio_priv(idev);
+ int ret;
+ u32 tmp;
+
+ if (state) {
+ ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp);
+ if (ret < 0)
+ return ret;
+ if (tmp & BIT(chan->channel))
+ priv->event_prev_val |= BIT(chan->channel);
+ else
+ priv->event_prev_val &= ~BIT(chan->channel);
- priv->event_scan_mask &= ~BIT(chan->channel);
- if (state)
priv->event_scan_mask |= BIT(chan->channel);
+ } else
+ priv->event_scan_mask &= ~BIT(chan->channel);
return 0;
}
@@ -325,6 +356,7 @@ static const struct iio_enum hi8435_sensing_mode = {
static const struct iio_chan_spec_ext_info hi8435_ext_info[] = {
IIO_ENUM("sensing_mode", IIO_SEPARATE, &hi8435_sensing_mode),
+ IIO_ENUM_AVAILABLE("sensing_mode", &hi8435_sensing_mode),
{},
};
@@ -333,6 +365,7 @@ static const struct iio_chan_spec_ext_info hi8435_ext_info[] = {
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = num, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.event_spec = hi8435_events, \
.num_event_specs = ARRAY_SIZE(hi8435_events), \
.ext_info = hi8435_ext_info, \
@@ -376,6 +409,7 @@ static const struct iio_chan_spec hi8435_channels[] = {
static const struct iio_info hi8435_info = {
.driver_module = THIS_MODULE,
+ .read_raw = hi8435_read_raw,
.read_event_config = &hi8435_read_event_config,
.write_event_config = hi8435_write_event_config,
.read_event_value = &hi8435_read_event_value,
@@ -442,13 +476,15 @@ static int hi8435_probe(struct spi_device *spi)
priv->spi = spi;
reset_gpio = devm_gpiod_get(&spi->dev, NULL, GPIOD_OUT_LOW);
- if (IS_ERR(reset_gpio)) {
- /* chip s/w reset if h/w reset failed */
+ if (!IS_ERR(reset_gpio)) {
+ /* need >=100ns low pulse to reset chip */
+ gpiod_set_raw_value_cansleep(reset_gpio, 0);
+ udelay(1);
+ gpiod_set_raw_value_cansleep(reset_gpio, 1);
+ } else {
+ /* s/w reset chip if h/w reset is not available */
hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST);
hi8435_writeb(priv, HI8435_CTRL_REG, 0);
- } else {
- udelay(5);
- gpiod_set_value(reset_gpio, 1);
}
spi_set_drvdata(spi, idev);
diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c
index db9838230257..6b588ac3130c 100644
--- a/drivers/iio/adc/ina2xx-adc.c
+++ b/drivers/iio/adc/ina2xx-adc.c
@@ -42,8 +42,8 @@
#define INA2XX_CURRENT 0x04 /* readonly */
#define INA2XX_CALIBRATION 0x05
-#define INA226_ALERT_MASK GENMASK(2, 1)
-#define INA266_CVRF BIT(3)
+#define INA226_MASK_ENABLE 0x06
+#define INA226_CVRF BIT(3)
#define INA2XX_MAX_REGISTERS 8
@@ -417,8 +417,8 @@ static ssize_t ina2xx_shunt_resistor_store(struct device *dev,
.address = (_address), \
.indexed = 1, \
.channel = (_index), \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \
- | BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.scan_index = (_index), \
@@ -481,12 +481,12 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)
*/
if (!chip->allow_async_readout)
do {
- ret = regmap_read(chip->regmap, INA226_ALERT_MASK,
+ ret = regmap_read(chip->regmap, INA226_MASK_ENABLE,
&alert);
if (ret < 0)
return ret;
- alert &= INA266_CVRF;
+ alert &= INA226_CVRF;
} while (!alert);
/*
diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c
index dd4190b50df6..81cd39a57fe3 100644
--- a/drivers/iio/adc/meson_saradc.c
+++ b/drivers/iio/adc/meson_saradc.c
@@ -220,6 +220,7 @@ enum meson_sar_adc_chan7_mux_sel {
};
struct meson_sar_adc_data {
+ bool has_bl30_integration;
unsigned int resolution;
const char *name;
};
@@ -437,19 +438,24 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev)
mutex_lock(&indio_dev->mlock);
- /* prevent BL30 from using the SAR ADC while we are using it */
- regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
- MESON_SAR_ADC_DELAY_KERNEL_BUSY,
- MESON_SAR_ADC_DELAY_KERNEL_BUSY);
-
- /* wait until BL30 releases it's lock (so we can use the SAR ADC) */
- do {
- udelay(1);
- regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val);
- } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--);
-
- if (timeout < 0)
- return -ETIMEDOUT;
+ if (priv->data->has_bl30_integration) {
+ /* prevent BL30 from using the SAR ADC while we are using it */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_KERNEL_BUSY,
+ MESON_SAR_ADC_DELAY_KERNEL_BUSY);
+
+ /*
+ * wait until BL30 releases it's lock (so we can use the SAR
+ * ADC)
+ */
+ do {
+ udelay(1);
+ regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val);
+ } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--);
+
+ if (timeout < 0)
+ return -ETIMEDOUT;
+ }
return 0;
}
@@ -458,9 +464,10 @@ static void meson_sar_adc_unlock(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
- /* allow BL30 to use the SAR ADC again */
- regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
- MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
+ if (priv->data->has_bl30_integration)
+ /* allow BL30 to use the SAR ADC again */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
mutex_unlock(&indio_dev->mlock);
}
@@ -614,14 +621,16 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev)
*/
meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT);
- /*
- * leave sampling delay and the input clocks as configured by BL30 to
- * make sure BL30 gets the values it expects when reading the
- * temperature sensor.
- */
- regmap_read(priv->regmap, MESON_SAR_ADC_REG3, &regval);
- if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED)
- return 0;
+ if (priv->data->has_bl30_integration) {
+ /*
+ * leave sampling delay and the input clocks as configured by
+ * BL30 to make sure BL30 gets the values it expects when
+ * reading the temperature sensor.
+ */
+ regmap_read(priv->regmap, MESON_SAR_ADC_REG3, &regval);
+ if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED)
+ return 0;
+ }
meson_sar_adc_stop_sample_engine(indio_dev);
@@ -834,23 +843,46 @@ static const struct iio_info meson_sar_adc_iio_info = {
.driver_module = THIS_MODULE,
};
-struct meson_sar_adc_data meson_sar_adc_gxbb_data = {
+static const struct meson_sar_adc_data meson_sar_adc_meson8_data = {
+ .has_bl30_integration = false,
+ .resolution = 10,
+ .name = "meson-meson8-saradc",
+};
+
+static const struct meson_sar_adc_data meson_sar_adc_meson8b_data = {
+ .has_bl30_integration = false,
+ .resolution = 10,
+ .name = "meson-meson8b-saradc",
+};
+
+static const struct meson_sar_adc_data meson_sar_adc_gxbb_data = {
+ .has_bl30_integration = true,
.resolution = 10,
.name = "meson-gxbb-saradc",
};
-struct meson_sar_adc_data meson_sar_adc_gxl_data = {
+static const struct meson_sar_adc_data meson_sar_adc_gxl_data = {
+ .has_bl30_integration = true,
.resolution = 12,
.name = "meson-gxl-saradc",
};
-struct meson_sar_adc_data meson_sar_adc_gxm_data = {
+static const struct meson_sar_adc_data meson_sar_adc_gxm_data = {
+ .has_bl30_integration = true,
.resolution = 12,
.name = "meson-gxm-saradc",
};
static const struct of_device_id meson_sar_adc_of_match[] = {
{
+ .compatible = "amlogic,meson8-saradc",
+ .data = &meson_sar_adc_meson8_data,
+ },
+ {
+ .compatible = "amlogic,meson8b-saradc",
+ .data = &meson_sar_adc_meson8b_data,
+ },
+ {
.compatible = "amlogic,meson-gxbb-saradc",
.data = &meson_sar_adc_gxbb_data,
}, {
diff --git a/drivers/iio/adc/rcar-gyroadc.c b/drivers/iio/adc/rcar-gyroadc.c
index 018ed360e717..27a318164619 100644
--- a/drivers/iio/adc/rcar-gyroadc.c
+++ b/drivers/iio/adc/rcar-gyroadc.c
@@ -73,7 +73,7 @@ enum rcar_gyroadc_model {
struct rcar_gyroadc {
struct device *dev;
void __iomem *regs;
- struct clk *iclk;
+ struct clk *clk;
struct regulator *vref[8];
unsigned int num_channels;
enum rcar_gyroadc_model model;
@@ -83,7 +83,7 @@ struct rcar_gyroadc {
static void rcar_gyroadc_hw_init(struct rcar_gyroadc *priv)
{
- const unsigned long clk_mhz = clk_get_rate(priv->iclk) / 1000000;
+ const unsigned long clk_mhz = clk_get_rate(priv->clk) / 1000000;
const unsigned long clk_mul =
(priv->mode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) ? 10 : 5;
unsigned long clk_len = clk_mhz * clk_mul;
@@ -510,9 +510,9 @@ static int rcar_gyroadc_probe(struct platform_device *pdev)
if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs);
- priv->iclk = devm_clk_get(dev, "if");
- if (IS_ERR(priv->iclk)) {
- ret = PTR_ERR(priv->iclk);
+ priv->clk = devm_clk_get(dev, "fck");
+ if (IS_ERR(priv->clk)) {
+ ret = PTR_ERR(priv->clk);
if (ret != -EPROBE_DEFER)
dev_err(dev, "Failed to get IF clock (ret=%i)\n", ret);
return ret;
@@ -536,7 +536,7 @@ static int rcar_gyroadc_probe(struct platform_device *pdev)
indio_dev->info = &rcar_gyroadc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE;
- ret = clk_prepare_enable(priv->iclk);
+ ret = clk_prepare_enable(priv->clk);
if (ret) {
dev_err(dev, "Could not prepare or enable the IF clock.\n");
goto err_clk_if_enable;
@@ -565,7 +565,7 @@ err_iio_device_register:
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
- clk_disable_unprepare(priv->iclk);
+ clk_disable_unprepare(priv->clk);
err_clk_if_enable:
rcar_gyroadc_deinit_supplies(indio_dev);
@@ -584,7 +584,7 @@ static int rcar_gyroadc_remove(struct platform_device *pdev)
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
- clk_disable_unprepare(priv->iclk);
+ clk_disable_unprepare(priv->clk);
rcar_gyroadc_deinit_supplies(indio_dev);
return 0;
diff --git a/drivers/iio/adc/ti-adc084s021.c b/drivers/iio/adc/ti-adc084s021.c
new file mode 100644
index 000000000000..a355121c11a4
--- /dev/null
+++ b/drivers/iio/adc/ti-adc084s021.c
@@ -0,0 +1,275 @@
+/**
+ * Copyright (C) 2017 Axis Communications AB
+ *
+ * Driver for Texas Instruments' ADC084S021 ADC chip.
+ * Datasheets can be found here:
+ * http://www.ti.com/lit/ds/symlink/adc084s021.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/regulator/consumer.h>
+
+#define ADC084S021_DRIVER_NAME "adc084s021"
+
+struct adc084s021 {
+ struct spi_device *spi;
+ struct spi_message message;
+ struct spi_transfer spi_trans;
+ struct regulator *reg;
+ struct mutex lock;
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache line.
+ */
+ u16 tx_buf[4] ____cacheline_aligned;
+ __be16 rx_buf[5]; /* First 16-bits are trash */
+};
+
+#define ADC084S021_VOLTAGE_CHANNEL(num) \
+ { \
+ .type = IIO_VOLTAGE, \
+ .channel = (num), \
+ .indexed = 1, \
+ .scan_index = (num), \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = 8, \
+ .storagebits = 16, \
+ .shift = 4, \
+ .endianness = IIO_BE, \
+ }, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
+ }
+
+static const struct iio_chan_spec adc084s021_channels[] = {
+ ADC084S021_VOLTAGE_CHANNEL(0),
+ ADC084S021_VOLTAGE_CHANNEL(1),
+ ADC084S021_VOLTAGE_CHANNEL(2),
+ ADC084S021_VOLTAGE_CHANNEL(3),
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+/**
+ * Read an ADC channel and return its value.
+ *
+ * @adc: The ADC SPI data.
+ * @data: Buffer for converted data.
+ */
+static int adc084s021_adc_conversion(struct adc084s021 *adc, void *data)
+{
+ int n_words = (adc->spi_trans.len >> 1) - 1; /* Discard first word */
+ int ret, i = 0;
+ u16 *p = data;
+
+ /* Do the transfer */
+ ret = spi_sync(adc->spi, &adc->message);
+ if (ret < 0)
+ return ret;
+
+ for (; i < n_words; i++)
+ *(p + i) = adc->rx_buf[i + 1];
+
+ return ret;
+}
+
+static int adc084s021_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *channel, int *val,
+ int *val2, long mask)
+{
+ struct adc084s021 *adc = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret < 0)
+ return ret;
+
+ ret = regulator_enable(adc->reg);
+ if (ret) {
+ iio_device_release_direct_mode(indio_dev);
+ return ret;
+ }
+
+ adc->tx_buf[0] = channel->channel << 3;
+ ret = adc084s021_adc_conversion(adc, val);
+ iio_device_release_direct_mode(indio_dev);
+ regulator_disable(adc->reg);
+ if (ret < 0)
+ return ret;
+
+ *val = be16_to_cpu(*val);
+ *val = (*val >> channel->scan_type.shift) & 0xff;
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ ret = regulator_enable(adc->reg);
+ if (ret)
+ return ret;
+
+ ret = regulator_get_voltage(adc->reg);
+ regulator_disable(adc->reg);
+ if (ret < 0)
+ return ret;
+
+ *val = ret / 1000;
+
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+/**
+ * Read enabled ADC channels and push data to the buffer.
+ *
+ * @irq: The interrupt number (not used).
+ * @pollfunc: Pointer to the poll func.
+ */
+static irqreturn_t adc084s021_buffer_trigger_handler(int irq, void *pollfunc)
+{
+ struct iio_poll_func *pf = pollfunc;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct adc084s021 *adc = iio_priv(indio_dev);
+ __be16 data[8] = {0}; /* 4 * 16-bit words of data + 8 bytes timestamp */
+
+ mutex_lock(&adc->lock);
+
+ if (adc084s021_adc_conversion(adc, &data) < 0)
+ dev_err(&adc->spi->dev, "Failed to read data\n");
+
+ iio_push_to_buffers_with_timestamp(indio_dev, data,
+ iio_get_time_ns(indio_dev));
+ mutex_unlock(&adc->lock);
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int adc084s021_buffer_preenable(struct iio_dev *indio_dev)
+{
+ struct adc084s021 *adc = iio_priv(indio_dev);
+ int scan_index;
+ int i = 0;
+
+ for_each_set_bit(scan_index, indio_dev->active_scan_mask,
+ indio_dev->masklength) {
+ const struct iio_chan_spec *channel =
+ &indio_dev->channels[scan_index];
+ adc->tx_buf[i++] = channel->channel << 3;
+ }
+ adc->spi_trans.len = 2 + (i * sizeof(__be16)); /* Trash + channels */
+
+ return regulator_enable(adc->reg);
+}
+
+static int adc084s021_buffer_postdisable(struct iio_dev *indio_dev)
+{
+ struct adc084s021 *adc = iio_priv(indio_dev);
+
+ adc->spi_trans.len = 4; /* Trash + single channel */
+
+ return regulator_disable(adc->reg);
+}
+
+static const struct iio_info adc084s021_info = {
+ .read_raw = adc084s021_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static const struct iio_buffer_setup_ops adc084s021_buffer_setup_ops = {
+ .preenable = adc084s021_buffer_preenable,
+ .postenable = iio_triggered_buffer_postenable,
+ .predisable = iio_triggered_buffer_predisable,
+ .postdisable = adc084s021_buffer_postdisable,
+};
+
+static int adc084s021_probe(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev;
+ struct adc084s021 *adc;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
+ if (!indio_dev) {
+ dev_err(&spi->dev, "Failed to allocate IIO device\n");
+ return -ENOMEM;
+ }
+
+ adc = iio_priv(indio_dev);
+ adc->spi = spi;
+
+ /* Connect the SPI device and the iio dev */
+ spi_set_drvdata(spi, indio_dev);
+
+ /* Initiate the Industrial I/O device */
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->dev.of_node = spi->dev.of_node;
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &adc084s021_info;
+ indio_dev->channels = adc084s021_channels;
+ indio_dev->num_channels = ARRAY_SIZE(adc084s021_channels);
+
+ /* Create SPI transfer for channel reads */
+ adc->spi_trans.tx_buf = adc->tx_buf;
+ adc->spi_trans.rx_buf = adc->rx_buf;
+ adc->spi_trans.len = 4; /* Trash + single channel */
+ spi_message_init_with_transfers(&adc->message, &adc->spi_trans, 1);
+
+ adc->reg = devm_regulator_get(&spi->dev, "vref");
+ if (IS_ERR(adc->reg))
+ return PTR_ERR(adc->reg);
+
+ mutex_init(&adc->lock);
+
+ /* Setup triggered buffer with pollfunction */
+ ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL,
+ adc084s021_buffer_trigger_handler,
+ &adc084s021_buffer_setup_ops);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to setup triggered buffer\n");
+ return ret;
+ }
+
+ return devm_iio_device_register(&spi->dev, indio_dev);
+}
+
+static const struct of_device_id adc084s021_of_match[] = {
+ { .compatible = "ti,adc084s021", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, adc084s021_of_match);
+
+static const struct spi_device_id adc084s021_id[] = {
+ { ADC084S021_DRIVER_NAME, 0},
+ {}
+};
+MODULE_DEVICE_TABLE(spi, adc084s021_id);
+
+static struct spi_driver adc084s021_driver = {
+ .driver = {
+ .name = ADC084S021_DRIVER_NAME,
+ .of_match_table = of_match_ptr(adc084s021_of_match),
+ },
+ .probe = adc084s021_probe,
+ .id_table = adc084s021_id,
+};
+module_spi_driver(adc084s021_driver);
+
+MODULE_AUTHOR("Mårten Lindahl <martenli@axis.com>");
+MODULE_DESCRIPTION("Texas Instruments ADC084S021");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
diff --git a/drivers/iio/adc/ti-adc108s102.c b/drivers/iio/adc/ti-adc108s102.c
new file mode 100644
index 000000000000..de4e5ac98c6e
--- /dev/null
+++ b/drivers/iio/adc/ti-adc108s102.c
@@ -0,0 +1,348 @@
+/*
+ * TI ADC108S102 SPI ADC driver
+ *
+ * Copyright (c) 2013-2015 Intel Corporation.
+ * Copyright (c) 2017 Siemens AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * This IIO device driver is designed to work with the following
+ * analog to digital converters from Texas Instruments:
+ * ADC108S102
+ * ADC128S102
+ * The communication with ADC chip is via the SPI bus (mode 3).
+ */
+
+#include <linux/acpi.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/types.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+
+/*
+ * In case of ACPI, we use the hard-wired 5000 mV of the Galileo and IOT2000
+ * boards as default for the reference pin VA. Device tree users encode that
+ * via the vref-supply regulator.
+ */
+#define ADC108S102_VA_MV_ACPI_DEFAULT 5000
+
+/*
+ * Defining the ADC resolution being 12 bits, we can use the same driver for
+ * both ADC108S102 (10 bits resolution) and ADC128S102 (12 bits resolution)
+ * chips. The ADC108S102 effectively returns a 12-bit result with the 2
+ * least-significant bits unset.
+ */
+#define ADC108S102_BITS 12
+#define ADC108S102_MAX_CHANNELS 8
+
+/*
+ * 16-bit SPI command format:
+ * [15:14] Ignored
+ * [13:11] 3-bit channel address
+ * [10:0] Ignored
+ */
+#define ADC108S102_CMD(ch) ((u16)(ch) << 11)
+
+/*
+ * 16-bit SPI response format:
+ * [15:12] Zeros
+ * [11:0] 12-bit ADC sample (for ADC108S102, [1:0] will always be 0).
+ */
+#define ADC108S102_RES_DATA(res) ((u16)res & GENMASK(11, 0))
+
+struct adc108s102_state {
+ struct spi_device *spi;
+ struct regulator *reg;
+ u32 va_millivolt;
+ /* SPI transfer used by triggered buffer handler*/
+ struct spi_transfer ring_xfer;
+ /* SPI transfer used by direct scan */
+ struct spi_transfer scan_single_xfer;
+ /* SPI message used by ring_xfer SPI transfer */
+ struct spi_message ring_msg;
+ /* SPI message used by scan_single_xfer SPI transfer */
+ struct spi_message scan_single_msg;
+
+ /*
+ * SPI message buffers:
+ * tx_buf: |C0|C1|C2|C3|C4|C5|C6|C7|XX|
+ * rx_buf: |XX|R0|R1|R2|R3|R4|R5|R6|R7|tt|tt|tt|tt|
+ *
+ * tx_buf: 8 channel read commands, plus 1 dummy command
+ * rx_buf: 1 dummy response, 8 channel responses, plus 64-bit timestamp
+ */
+ __be16 rx_buf[13] ____cacheline_aligned;
+ __be16 tx_buf[9] ____cacheline_aligned;
+};
+
+#define ADC108S102_V_CHAN(index) \
+ { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = index, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .address = index, \
+ .scan_index = index, \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = ADC108S102_BITS, \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+static const struct iio_chan_spec adc108s102_channels[] = {
+ ADC108S102_V_CHAN(0),
+ ADC108S102_V_CHAN(1),
+ ADC108S102_V_CHAN(2),
+ ADC108S102_V_CHAN(3),
+ ADC108S102_V_CHAN(4),
+ ADC108S102_V_CHAN(5),
+ ADC108S102_V_CHAN(6),
+ ADC108S102_V_CHAN(7),
+ IIO_CHAN_SOFT_TIMESTAMP(8),
+};
+
+static int adc108s102_update_scan_mode(struct iio_dev *indio_dev,
+ unsigned long const *active_scan_mask)
+{
+ struct adc108s102_state *st = iio_priv(indio_dev);
+ unsigned int bit, cmds;
+
+ /*
+ * Fill in the first x shorts of tx_buf with the number of channels
+ * enabled for sampling by the triggered buffer.
+ */
+ cmds = 0;
+ for_each_set_bit(bit, active_scan_mask, ADC108S102_MAX_CHANNELS)
+ st->tx_buf[cmds++] = cpu_to_be16(ADC108S102_CMD(bit));
+
+ /* One dummy command added, to clock in the last response */
+ st->tx_buf[cmds++] = 0x00;
+
+ /* build SPI ring message */
+ st->ring_xfer.tx_buf = &st->tx_buf[0];
+ st->ring_xfer.rx_buf = &st->rx_buf[0];
+ st->ring_xfer.len = cmds * sizeof(st->tx_buf[0]);
+
+ spi_message_init_with_transfers(&st->ring_msg, &st->ring_xfer, 1);
+
+ return 0;
+}
+
+static irqreturn_t adc108s102_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct adc108s102_state *st = iio_priv(indio_dev);
+ int ret;
+
+ ret = spi_sync(st->spi, &st->ring_msg);
+ if (ret < 0)
+ goto out_notify;
+
+ /* Skip the dummy response in the first slot */
+ iio_push_to_buffers_with_timestamp(indio_dev,
+ (u8 *)&st->rx_buf[1],
+ iio_get_time_ns(indio_dev));
+
+out_notify:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int adc108s102_scan_direct(struct adc108s102_state *st, unsigned int ch)
+{
+ int ret;
+
+ st->tx_buf[0] = cpu_to_be16(ADC108S102_CMD(ch));
+ ret = spi_sync(st->spi, &st->scan_single_msg);
+ if (ret)
+ return ret;
+
+ /* Skip the dummy response in the first slot */
+ return be16_to_cpu(st->rx_buf[1]);
+}
+
+static int adc108s102_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long m)
+{
+ struct adc108s102_state *st = iio_priv(indio_dev);
+ int ret;
+
+ switch (m) {
+ case IIO_CHAN_INFO_RAW:
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ ret = adc108s102_scan_direct(st, chan->address);
+
+ iio_device_release_direct_mode(indio_dev);
+
+ if (ret < 0)
+ return ret;
+
+ *val = ADC108S102_RES_DATA(ret);
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ if (chan->type != IIO_VOLTAGE)
+ break;
+
+ *val = st->va_millivolt;
+ *val2 = chan->scan_type.realbits;
+
+ return IIO_VAL_FRACTIONAL_LOG2;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static const struct iio_info adc108s102_info = {
+ .read_raw = &adc108s102_read_raw,
+ .update_scan_mode = &adc108s102_update_scan_mode,
+ .driver_module = THIS_MODULE,
+};
+
+static int adc108s102_probe(struct spi_device *spi)
+{
+ struct adc108s102_state *st;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+
+ if (ACPI_COMPANION(&spi->dev)) {
+ st->va_millivolt = ADC108S102_VA_MV_ACPI_DEFAULT;
+ } else {
+ st->reg = devm_regulator_get(&spi->dev, "vref");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
+
+ ret = regulator_enable(st->reg);
+ if (ret < 0) {
+ dev_err(&spi->dev, "Cannot enable vref regulator\n");
+ return ret;
+ }
+
+ ret = regulator_get_voltage(st->reg);
+ if (ret < 0) {
+ dev_err(&spi->dev, "vref get voltage failed\n");
+ return ret;
+ }
+
+ st->va_millivolt = ret / 1000;
+ }
+
+ spi_set_drvdata(spi, indio_dev);
+ st->spi = spi;
+
+ indio_dev->name = spi->modalias;
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = adc108s102_channels;
+ indio_dev->num_channels = ARRAY_SIZE(adc108s102_channels);
+ indio_dev->info = &adc108s102_info;
+
+ /* Setup default message */
+ st->scan_single_xfer.tx_buf = st->tx_buf;
+ st->scan_single_xfer.rx_buf = st->rx_buf;
+ st->scan_single_xfer.len = 2 * sizeof(st->tx_buf[0]);
+
+ spi_message_init_with_transfers(&st->scan_single_msg,
+ &st->scan_single_xfer, 1);
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ &adc108s102_trigger_handler, NULL);
+ if (ret)
+ goto error_disable_reg;
+
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to register IIO device\n");
+ goto error_cleanup_triggered_buffer;
+ }
+ return 0;
+
+error_cleanup_triggered_buffer:
+ iio_triggered_buffer_cleanup(indio_dev);
+
+error_disable_reg:
+ regulator_disable(st->reg);
+
+ return ret;
+}
+
+static int adc108s102_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct adc108s102_state *st = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ regulator_disable(st->reg);
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id adc108s102_of_match[] = {
+ { .compatible = "ti,adc108s102" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, adc108s102_of_match);
+#endif
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id adc108s102_acpi_ids[] = {
+ { "INT3495", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, adc108s102_acpi_ids);
+#endif
+
+static const struct spi_device_id adc108s102_id[] = {
+ { "adc108s102", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, adc108s102_id);
+
+static struct spi_driver adc108s102_driver = {
+ .driver = {
+ .name = "adc108s102",
+ .of_match_table = of_match_ptr(adc108s102_of_match),
+ .acpi_match_table = ACPI_PTR(adc108s102_acpi_ids),
+ },
+ .probe = adc108s102_probe,
+ .remove = adc108s102_remove,
+ .id_table = adc108s102_id,
+};
+module_spi_driver(adc108s102_driver);
+
+MODULE_AUTHOR("Bogdan Pricop <bogdan.pricop@emutex.com>");
+MODULE_DESCRIPTION("Texas Instruments ADC108S102 and ADC128S102 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
index 1c0874cdf665..f5d4d786e193 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
@@ -69,6 +69,12 @@ static struct {
{HID_USAGE_SENSOR_TIME_TIMESTAMP, HID_USAGE_SENSOR_UNITS_MILLISECOND,
1000000, 0},
+ {HID_USAGE_SENSOR_DEVICE_ORIENTATION, 0, 1, 0},
+
+ {HID_USAGE_SENSOR_RELATIVE_ORIENTATION, 0, 1, 0},
+
+ {HID_USAGE_SENSOR_GEOMAGNETIC_ORIENTATION, 0, 1, 0},
+
{HID_USAGE_SENSOR_TEMPERATURE, 0, 1000, 0},
{HID_USAGE_SENSOR_TEMPERATURE, HID_USAGE_SENSOR_UNITS_DEGREES, 1000, 0},
@@ -230,7 +236,7 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st,
ret = sensor_hub_set_feature(st->hsdev, st->poll.report_id,
st->poll.index, sizeof(value), &value);
if (ret < 0 || value < 0)
- ret = -EINVAL;
+ return -EINVAL;
ret = sensor_hub_get_feature(st->hsdev,
st->poll.report_id,
@@ -283,7 +289,7 @@ int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st,
st->sensitivity.index, sizeof(value),
&value);
if (ret < 0 || value < 0)
- ret = -EINVAL;
+ return -EINVAL;
ret = sensor_hub_get_feature(st->hsdev,
st->sensitivity.report_id,
@@ -404,6 +410,48 @@ int hid_sensor_get_reporting_interval(struct hid_sensor_hub_device *hsdev,
}
+static void hid_sensor_get_report_latency_info(struct hid_sensor_hub_device *hsdev,
+ u32 usage_id,
+ struct hid_sensor_common *st)
+{
+ sensor_hub_input_get_attribute_info(hsdev, HID_FEATURE_REPORT,
+ usage_id,
+ HID_USAGE_SENSOR_PROP_REPORT_LATENCY,
+ &st->report_latency);
+
+ hid_dbg(hsdev->hdev, "Report latency attributes: %x:%x\n",
+ st->report_latency.index, st->report_latency.report_id);
+}
+
+int hid_sensor_get_report_latency(struct hid_sensor_common *st)
+{
+ int ret;
+ int value;
+
+ ret = sensor_hub_get_feature(st->hsdev, st->report_latency.report_id,
+ st->report_latency.index, sizeof(value),
+ &value);
+ if (ret < 0)
+ return ret;
+
+ return value;
+}
+EXPORT_SYMBOL(hid_sensor_get_report_latency);
+
+int hid_sensor_set_report_latency(struct hid_sensor_common *st, int latency_ms)
+{
+ return sensor_hub_set_feature(st->hsdev, st->report_latency.report_id,
+ st->report_latency.index,
+ sizeof(latency_ms), &latency_ms);
+}
+EXPORT_SYMBOL(hid_sensor_set_report_latency);
+
+bool hid_sensor_batch_mode_supported(struct hid_sensor_common *st)
+{
+ return st->report_latency.index > 0 && st->report_latency.report_id > 0;
+}
+EXPORT_SYMBOL(hid_sensor_batch_mode_supported);
+
int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
u32 usage_id,
struct hid_sensor_common *st)
@@ -445,6 +493,8 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
} else
st->timestamp_ns_scale = 1000000000;
+ hid_sensor_get_report_latency_info(hsdev, usage_id, st);
+
hid_dbg(hsdev->hdev, "common attributes: %x:%x, %x:%x, %x:%x %x:%x %x:%x\n",
st->poll.index, st->poll.report_id,
st->report_state.index, st->report_state.report_id,
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 0b5dea050239..16ade0a0327b 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -26,9 +26,84 @@
#include <linux/hid-sensor-hub.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
+#include <linux/iio/buffer.h>
#include <linux/iio/sysfs.h>
#include "hid-sensor-trigger.h"
+static ssize_t _hid_sensor_set_report_latency(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
+ int integer, fract, ret;
+ int latency;
+
+ ret = iio_str_to_fixpoint(buf, 100000, &integer, &fract);
+ if (ret)
+ return ret;
+
+ latency = integer * 1000 + fract / 1000;
+ ret = hid_sensor_set_report_latency(attrb, latency);
+ if (ret < 0)
+ return len;
+
+ attrb->latency_ms = hid_sensor_get_report_latency(attrb);
+
+ return len;
+}
+
+static ssize_t _hid_sensor_get_report_latency(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
+ int latency;
+
+ latency = hid_sensor_get_report_latency(attrb);
+ if (latency < 0)
+ return latency;
+
+ return sprintf(buf, "%d.%06u\n", latency / 1000, (latency % 1000) * 1000);
+}
+
+static ssize_t _hid_sensor_get_fifo_state(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
+ int latency;
+
+ latency = hid_sensor_get_report_latency(attrb);
+ if (latency < 0)
+ return latency;
+
+ return sprintf(buf, "%d\n", !!latency);
+}
+
+static IIO_DEVICE_ATTR(hwfifo_timeout, 0644,
+ _hid_sensor_get_report_latency,
+ _hid_sensor_set_report_latency, 0);
+static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
+ _hid_sensor_get_fifo_state, NULL, 0);
+
+static const struct attribute *hid_sensor_fifo_attributes[] = {
+ &iio_dev_attr_hwfifo_timeout.dev_attr.attr,
+ &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+ NULL,
+};
+
+static void hid_sensor_setup_batch_mode(struct iio_dev *indio_dev,
+ struct hid_sensor_common *st)
+{
+ if (!hid_sensor_batch_mode_supported(st))
+ return;
+
+ iio_buffer_set_attrs(indio_dev->buffer, hid_sensor_fifo_attributes);
+}
+
static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
{
int state_val;
@@ -141,6 +216,9 @@ static void hid_sensor_set_power_work(struct work_struct *work)
sizeof(attrb->raw_hystersis),
&attrb->raw_hystersis);
+ if (attrb->latency_ms > 0)
+ hid_sensor_set_report_latency(attrb, attrb->latency_ms);
+
_hid_sensor_power_state(attrb, true);
}
@@ -192,6 +270,8 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
attrb->trigger = trig;
indio_dev->trig = iio_trigger_get(trig);
+ hid_sensor_setup_batch_mode(indio_dev, attrb);
+
ret = pm_runtime_set_active(&indio_dev->dev);
if (ret)
goto error_unreg_trigger;
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index df5abc46cd3f..25bed2d7d2b9 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -13,7 +13,8 @@ config AD5064
AD5045, AD5064, AD5064-1, AD5065, AD5625, AD5625R, AD5627, AD5627R,
AD5628, AD5629R, AD5645R, AD5647R, AD5648, AD5665, AD5665R, AD5666,
AD5667, AD5667R, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616,
- LTC2617, LTC2619, LTC2626, LTC2627, LTC2629 Digital to Analog Converter.
+ LTC2617, LTC2619, LTC2626, LTC2627, LTC2629, LTC2631, LTC2633, LTC2635
+ Digital to Analog Converter.
To compile this driver as a module, choose M here: the
module will be called ad5064.
diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c
index 6803e4a137cd..3f9399c27869 100644
--- a/drivers/iio/dac/ad5064.c
+++ b/drivers/iio/dac/ad5064.c
@@ -2,8 +2,8 @@
* AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5625, AD5625R,
* AD5627, AD5627R, AD5628, AD5629R, AD5645R, AD5647R, AD5648, AD5665, AD5665R,
* AD5666, AD5667, AD5667R, AD5668, AD5669R, LTC2606, LTC2607, LTC2609, LTC2616,
- * LTC2617, LTC2619, LTC2626, LTC2627, LTC2629 Digital to analog converters
- * driver
+ * LTC2617, LTC2619, LTC2626, LTC2627, LTC2629, LTC2631, LTC2633, LTC2635
+ * Digital to analog converters driver
*
* Copyright 2011 Analog Devices Inc.
*
@@ -168,6 +168,24 @@ enum ad5064_type {
ID_LTC2626,
ID_LTC2627,
ID_LTC2629,
+ ID_LTC2631_L12,
+ ID_LTC2631_H12,
+ ID_LTC2631_L10,
+ ID_LTC2631_H10,
+ ID_LTC2631_L8,
+ ID_LTC2631_H8,
+ ID_LTC2633_L12,
+ ID_LTC2633_H12,
+ ID_LTC2633_L10,
+ ID_LTC2633_H10,
+ ID_LTC2633_L8,
+ ID_LTC2633_H8,
+ ID_LTC2635_L12,
+ ID_LTC2635_H12,
+ ID_LTC2635_L10,
+ ID_LTC2635_H10,
+ ID_LTC2635_L8,
+ ID_LTC2635_H8,
};
static int ad5064_write(struct ad5064_state *st, unsigned int cmd,
@@ -425,6 +443,19 @@ static DECLARE_AD5064_CHANNELS(ad5669_channels, 16, 0, ad5064_ext_info);
static DECLARE_AD5064_CHANNELS(ltc2607_channels, 16, 0, ltc2617_ext_info);
static DECLARE_AD5064_CHANNELS(ltc2617_channels, 14, 2, ltc2617_ext_info);
static DECLARE_AD5064_CHANNELS(ltc2627_channels, 12, 4, ltc2617_ext_info);
+#define ltc2631_12_channels ltc2627_channels
+static DECLARE_AD5064_CHANNELS(ltc2631_10_channels, 10, 6, ltc2617_ext_info);
+static DECLARE_AD5064_CHANNELS(ltc2631_8_channels, 8, 8, ltc2617_ext_info);
+
+#define LTC2631_INFO(vref, pchannels, nchannels) \
+ { \
+ .shared_vref = true, \
+ .internal_vref = vref, \
+ .channels = pchannels, \
+ .num_channels = nchannels, \
+ .regmap_type = AD5064_REGMAP_LTC, \
+ }
+
static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
[ID_AD5024] = {
@@ -724,6 +755,24 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
.num_channels = 4,
.regmap_type = AD5064_REGMAP_LTC,
},
+ [ID_LTC2631_L12] = LTC2631_INFO(2500000, ltc2631_12_channels, 1),
+ [ID_LTC2631_H12] = LTC2631_INFO(4096000, ltc2631_12_channels, 1),
+ [ID_LTC2631_L10] = LTC2631_INFO(2500000, ltc2631_10_channels, 1),
+ [ID_LTC2631_H10] = LTC2631_INFO(4096000, ltc2631_10_channels, 1),
+ [ID_LTC2631_L8] = LTC2631_INFO(2500000, ltc2631_8_channels, 1),
+ [ID_LTC2631_H8] = LTC2631_INFO(4096000, ltc2631_8_channels, 1),
+ [ID_LTC2633_L12] = LTC2631_INFO(2500000, ltc2631_12_channels, 2),
+ [ID_LTC2633_H12] = LTC2631_INFO(4096000, ltc2631_12_channels, 2),
+ [ID_LTC2633_L10] = LTC2631_INFO(2500000, ltc2631_10_channels, 2),
+ [ID_LTC2633_H10] = LTC2631_INFO(4096000, ltc2631_10_channels, 2),
+ [ID_LTC2633_L8] = LTC2631_INFO(2500000, ltc2631_8_channels, 2),
+ [ID_LTC2633_H8] = LTC2631_INFO(4096000, ltc2631_8_channels, 2),
+ [ID_LTC2635_L12] = LTC2631_INFO(2500000, ltc2631_12_channels, 4),
+ [ID_LTC2635_H12] = LTC2631_INFO(4096000, ltc2631_12_channels, 4),
+ [ID_LTC2635_L10] = LTC2631_INFO(2500000, ltc2631_10_channels, 4),
+ [ID_LTC2635_H10] = LTC2631_INFO(4096000, ltc2631_10_channels, 4),
+ [ID_LTC2635_L8] = LTC2631_INFO(2500000, ltc2631_8_channels, 4),
+ [ID_LTC2635_H8] = LTC2631_INFO(4096000, ltc2631_8_channels, 4),
};
static inline unsigned int ad5064_num_vref(struct ad5064_state *st)
@@ -982,6 +1031,24 @@ static const struct i2c_device_id ad5064_i2c_ids[] = {
{"ltc2626", ID_LTC2626},
{"ltc2627", ID_LTC2627},
{"ltc2629", ID_LTC2629},
+ {"ltc2631-l12", ID_LTC2631_L12},
+ {"ltc2631-h12", ID_LTC2631_H12},
+ {"ltc2631-l10", ID_LTC2631_L10},
+ {"ltc2631-h10", ID_LTC2631_H10},
+ {"ltc2631-l8", ID_LTC2631_L8},
+ {"ltc2631-h8", ID_LTC2631_H8},
+ {"ltc2633-l12", ID_LTC2633_L12},
+ {"ltc2633-h12", ID_LTC2633_H12},
+ {"ltc2633-l10", ID_LTC2633_L10},
+ {"ltc2633-h10", ID_LTC2633_H10},
+ {"ltc2633-l8", ID_LTC2633_L8},
+ {"ltc2633-h8", ID_LTC2633_H8},
+ {"ltc2635-l12", ID_LTC2635_L12},
+ {"ltc2635-h12", ID_LTC2635_H12},
+ {"ltc2635-l10", ID_LTC2635_L10},
+ {"ltc2635-h10", ID_LTC2635_H10},
+ {"ltc2635-l8", ID_LTC2635_L8},
+ {"ltc2635-h8", ID_LTC2635_H8},
{}
};
MODULE_DEVICE_TABLE(i2c, ad5064_i2c_ids);
diff --git a/drivers/iio/humidity/hts221.h b/drivers/iio/humidity/hts221.h
index c7154665512e..94510266e0a5 100644
--- a/drivers/iio/humidity/hts221.h
+++ b/drivers/iio/humidity/hts221.h
@@ -57,12 +57,15 @@ struct hts221_hw {
struct hts221_sensor sensors[HTS221_SENSOR_MAX];
+ bool enabled;
u8 odr;
const struct hts221_transfer_function *tf;
struct hts221_transfer_buffer tb;
};
+extern const struct dev_pm_ops hts221_pm_ops;
+
int hts221_config_drdy(struct hts221_hw *hw, bool enable);
int hts221_probe(struct iio_dev *iio_dev);
int hts221_power_on(struct hts221_hw *hw);
diff --git a/drivers/iio/humidity/hts221_core.c b/drivers/iio/humidity/hts221_core.c
index 3f3ef4a1a474..a56da3999e00 100644
--- a/drivers/iio/humidity/hts221_core.c
+++ b/drivers/iio/humidity/hts221_core.c
@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/iio/sysfs.h>
#include <linux/delay.h>
+#include <linux/pm.h>
#include <asm/unaligned.h>
#include "hts221.h"
@@ -307,15 +308,30 @@ hts221_sysfs_temp_oversampling_avail(struct device *dev,
int hts221_power_on(struct hts221_hw *hw)
{
- return hts221_update_odr(hw, hw->odr);
+ int err;
+
+ err = hts221_update_odr(hw, hw->odr);
+ if (err < 0)
+ return err;
+
+ hw->enabled = true;
+
+ return 0;
}
int hts221_power_off(struct hts221_hw *hw)
{
- u8 data[] = {0x00, 0x00};
+ __le16 data = 0;
+ int err;
- return hw->tf->write(hw->dev, HTS221_REG_CNTRL1_ADDR, sizeof(data),
- data);
+ err = hw->tf->write(hw->dev, HTS221_REG_CNTRL1_ADDR, sizeof(data),
+ (u8 *)&data);
+ if (err < 0)
+ return err;
+
+ hw->enabled = false;
+
+ return 0;
}
static int hts221_parse_temp_caldata(struct hts221_hw *hw)
@@ -682,6 +698,36 @@ int hts221_probe(struct iio_dev *iio_dev)
}
EXPORT_SYMBOL(hts221_probe);
+static int __maybe_unused hts221_suspend(struct device *dev)
+{
+ struct iio_dev *iio_dev = dev_get_drvdata(dev);
+ struct hts221_hw *hw = iio_priv(iio_dev);
+ __le16 data = 0;
+ int err;
+
+ err = hw->tf->write(hw->dev, HTS221_REG_CNTRL1_ADDR, sizeof(data),
+ (u8 *)&data);
+
+ return err < 0 ? err : 0;
+}
+
+static int __maybe_unused hts221_resume(struct device *dev)
+{
+ struct iio_dev *iio_dev = dev_get_drvdata(dev);
+ struct hts221_hw *hw = iio_priv(iio_dev);
+ int err = 0;
+
+ if (hw->enabled)
+ err = hts221_update_odr(hw, hw->odr);
+
+ return err;
+}
+
+const struct dev_pm_ops hts221_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(hts221_suspend, hts221_resume)
+};
+EXPORT_SYMBOL(hts221_pm_ops);
+
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
MODULE_DESCRIPTION("STMicroelectronics hts221 sensor driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/humidity/hts221_i2c.c b/drivers/iio/humidity/hts221_i2c.c
index 8333c0296c0e..f38e4b7e0160 100644
--- a/drivers/iio/humidity/hts221_i2c.c
+++ b/drivers/iio/humidity/hts221_i2c.c
@@ -105,6 +105,7 @@ MODULE_DEVICE_TABLE(i2c, hts221_i2c_id_table);
static struct i2c_driver hts221_driver = {
.driver = {
.name = "hts221_i2c",
+ .pm = &hts221_pm_ops,
.of_match_table = of_match_ptr(hts221_i2c_of_match),
.acpi_match_table = ACPI_PTR(hts221_acpi_match),
},
diff --git a/drivers/iio/humidity/hts221_spi.c b/drivers/iio/humidity/hts221_spi.c
index 70df5e7150c1..57cbc256771b 100644
--- a/drivers/iio/humidity/hts221_spi.c
+++ b/drivers/iio/humidity/hts221_spi.c
@@ -113,6 +113,7 @@ MODULE_DEVICE_TABLE(spi, hts221_spi_id_table);
static struct spi_driver hts221_driver = {
.driver = {
.name = "hts221_spi",
+ .pm = &hts221_pm_ops,
.of_match_table = of_match_ptr(hts221_spi_of_match),
},
.probe = hts221_spi_probe,
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
index 4839db7b9690..46352c7bff43 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
@@ -135,6 +135,8 @@ struct st_lsm6dsx_hw {
#endif /* CONFIG_SPI_MASTER */
};
+extern const struct dev_pm_ops st_lsm6dsx_pm_ops;
+
int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,
const struct st_lsm6dsx_transfer_function *tf_ops);
int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor);
@@ -144,5 +146,8 @@ int st_lsm6dsx_write_with_mask(struct st_lsm6dsx_hw *hw, u8 addr, u8 mask,
u8 val);
int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor,
u16 watermark);
+int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw);
+int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
+ enum st_lsm6dsx_fifo_mode fifo_mode);
#endif /* ST_LSM6DSX_H */
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
index c8e5cfd0ef0b..b19a62d8c884 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
@@ -130,8 +130,8 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
return 0;
}
-static int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
- enum st_lsm6dsx_fifo_mode fifo_mode)
+int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
+ enum st_lsm6dsx_fifo_mode fifo_mode)
{
u8 data;
int err;
@@ -303,7 +303,7 @@ static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
return read_len;
}
-static int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
+int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
{
int err;
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
index 462a27b70453..b485540da89e 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -36,6 +36,7 @@
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/pm.h>
#include <linux/platform_data/st_sensors_pdata.h>
@@ -731,6 +732,57 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,
}
EXPORT_SYMBOL(st_lsm6dsx_probe);
+static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)
+{
+ struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
+ struct st_lsm6dsx_sensor *sensor;
+ int i, err = 0;
+
+ for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+ sensor = iio_priv(hw->iio_devs[i]);
+ if (!(hw->enable_mask & BIT(sensor->id)))
+ continue;
+
+ err = st_lsm6dsx_write_with_mask(hw,
+ st_lsm6dsx_odr_table[sensor->id].reg.addr,
+ st_lsm6dsx_odr_table[sensor->id].reg.mask, 0);
+ if (err < 0)
+ return err;
+ }
+
+ if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS)
+ err = st_lsm6dsx_flush_fifo(hw);
+
+ return err;
+}
+
+static int __maybe_unused st_lsm6dsx_resume(struct device *dev)
+{
+ struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
+ struct st_lsm6dsx_sensor *sensor;
+ int i, err = 0;
+
+ for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+ sensor = iio_priv(hw->iio_devs[i]);
+ if (!(hw->enable_mask & BIT(sensor->id)))
+ continue;
+
+ err = st_lsm6dsx_set_odr(sensor, sensor->odr);
+ if (err < 0)
+ return err;
+ }
+
+ if (hw->enable_mask)
+ err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
+
+ return err;
+}
+
+const struct dev_pm_ops st_lsm6dsx_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume)
+};
+EXPORT_SYMBOL(st_lsm6dsx_pm_ops);
+
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
index 09a51cfb9b5e..305fec712ab0 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
@@ -98,6 +98,7 @@ MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);
static struct i2c_driver st_lsm6dsx_driver = {
.driver = {
.name = "st_lsm6dsx_i2c",
+ .pm = &st_lsm6dsx_pm_ops,
.of_match_table = of_match_ptr(st_lsm6dsx_i2c_of_match),
},
.probe = st_lsm6dsx_i2c_probe,
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
index f765a5058488..95472f153ad2 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
@@ -115,6 +115,7 @@ MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
static struct spi_driver st_lsm6dsx_driver = {
.driver = {
.name = "st_lsm6dsx_spi",
+ .pm = &st_lsm6dsx_pm_ops,
.of_match_table = of_match_ptr(st_lsm6dsx_spi_of_match),
},
.probe = st_lsm6dsx_spi_probe,
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 57c14da5708f..4a1de59d153a 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -1089,7 +1089,7 @@ static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
{
int i, ret, attrcount = 0;
- for_each_set_bit(i, infomask, sizeof(infomask)*8) {
+ for_each_set_bit(i, infomask, sizeof(*infomask)*8) {
if (i >= ARRAY_SIZE(iio_chan_info_postfix))
return -EINVAL;
ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
@@ -1118,7 +1118,7 @@ static int iio_device_add_info_mask_type_avail(struct iio_dev *indio_dev,
int i, ret, attrcount = 0;
char *avail_postfix;
- for_each_set_bit(i, infomask, sizeof(infomask) * 8) {
+ for_each_set_bit(i, infomask, sizeof(*infomask) * 8) {
avail_postfix = kasprintf(GFP_KERNEL,
"%s_available",
iio_chan_info_postfix[i]);
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 7a13535dc3e9..a3941bade6a7 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -750,11 +750,9 @@ int iio_read_avail_channel_raw(struct iio_channel *chan,
err_unlock:
mutex_unlock(&chan->indio_dev->info_exist_lock);
- if (ret >= 0 && type != IIO_VAL_INT) {
+ if (ret >= 0 && type != IIO_VAL_INT)
/* raw values are assumed to be IIO_VAL_INT */
ret = -EINVAL;
- goto err_unlock;
- }
return ret;
}
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index 33e755d8d825..2356ed9285df 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -172,6 +172,16 @@ config SENSORS_ISL29018
in lux, proximity infrared sensing and normal infrared sensing.
Data from sensor is accessible via sysfs.
+config SENSORS_ISL29028
+ tristate "Intersil ISL29028 Concurrent Light and Proximity Sensor"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ Provides driver for the Intersil's ISL29028 device.
+ This driver supports the sysfs interface to get the ALS, IR intensity,
+ Proximity value via iio. The ISL29028 provides the concurrent sensing
+ of ambient light and proximity.
+
config ISL29125
tristate "Intersil ISL29125 digital color light sensor"
depends on I2C
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 681363c2b298..fa32fa459e2e 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o
obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
obj-$(CONFIG_HID_SENSOR_PROX) += hid-sensor-prox.o
obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o
+obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o
obj-$(CONFIG_ISL29125) += isl29125.o
obj-$(CONFIG_JSA1212) += jsa1212.o
obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c
index 917dd8b43e72..61f5924b472d 100644
--- a/drivers/iio/light/isl29018.c
+++ b/drivers/iio/light/isl29018.c
@@ -807,6 +807,7 @@ static SIMPLE_DEV_PM_OPS(isl29018_pm_ops, isl29018_suspend, isl29018_resume);
#define ISL29018_PM_OPS NULL
#endif
+#ifdef CONFIG_ACPI
static const struct acpi_device_id isl29018_acpi_match[] = {
{"ISL29018", isl29018},
{"ISL29023", isl29023},
@@ -814,6 +815,7 @@ static const struct acpi_device_id isl29018_acpi_match[] = {
{},
};
MODULE_DEVICE_TABLE(acpi, isl29018_acpi_match);
+#endif
static const struct i2c_device_id isl29018_id[] = {
{"isl29018", isl29018},
diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/iio/light/isl29028.c
index 5375e7a81205..3d09c1fc4dad 100644
--- a/drivers/staging/iio/light/isl29028.c
+++ b/drivers/iio/light/isl29028.c
@@ -16,6 +16,10 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Datasheets:
+ * - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29028.pdf
+ * - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29030.pdf
*/
#include <linux/module.h>
@@ -64,8 +68,25 @@
#define ISL29028_POWER_OFF_DELAY_MS 2000
-static const unsigned int isl29028_prox_sleep_time[] = {800, 400, 200, 100, 75,
- 50, 12, 0};
+struct isl29028_prox_data {
+ int sampling_int;
+ int sampling_fract;
+ int sleep_time;
+};
+
+static const struct isl29028_prox_data isl29028_prox_data[] = {
+ { 1, 250000, 800 },
+ { 2, 500000, 400 },
+ { 5, 0, 200 },
+ { 10, 0, 100 },
+ { 13, 300000, 75 },
+ { 20, 0, 50 },
+ { 80, 0, 13 }, /*
+ * Note: Data sheet lists 12.5 ms sleep time.
+ * Round up a half millisecond for msleep().
+ */
+ { 100, 0, 0 }
+};
enum isl29028_als_ir_mode {
ISL29028_MODE_NONE = 0,
@@ -76,32 +97,37 @@ enum isl29028_als_ir_mode {
struct isl29028_chip {
struct mutex lock;
struct regmap *regmap;
- unsigned int prox_sampling;
+ int prox_sampling_int;
+ int prox_sampling_frac;
bool enable_prox;
int lux_scale;
enum isl29028_als_ir_mode als_ir_mode;
};
-static int isl29028_find_prox_sleep_time_index(int sampling)
+static int isl29028_find_prox_sleep_index(int sampling_int, int sampling_fract)
{
- unsigned int period = DIV_ROUND_UP(1000, sampling);
int i;
- for (i = 0; i < ARRAY_SIZE(isl29028_prox_sleep_time); ++i) {
- if (period >= isl29028_prox_sleep_time[i])
- break;
+ for (i = 0; i < ARRAY_SIZE(isl29028_prox_data); ++i) {
+ if (isl29028_prox_data[i].sampling_int == sampling_int &&
+ isl29028_prox_data[i].sampling_fract == sampling_fract)
+ return i;
}
- return i;
+ return -EINVAL;
}
static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
- unsigned int sampling)
+ int sampling_int, int sampling_fract)
{
struct device *dev = regmap_get_device(chip->regmap);
int sleep_index, ret;
- sleep_index = isl29028_find_prox_sleep_time_index(sampling);
+ sleep_index = isl29028_find_prox_sleep_index(sampling_int,
+ sampling_fract);
+ if (sleep_index < 0)
+ return sleep_index;
+
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
ISL29028_CONF_PROX_SLP_MASK,
sleep_index << ISL29028_CONF_PROX_SLP_SH);
@@ -112,16 +138,18 @@ static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
return ret;
}
- chip->prox_sampling = sampling;
+ chip->prox_sampling_int = sampling_int;
+ chip->prox_sampling_frac = sampling_fract;
return ret;
}
static int isl29028_enable_proximity(struct isl29028_chip *chip)
{
- int sleep_index, ret;
+ int prox_index, ret;
- ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling);
+ ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling_int,
+ chip->prox_sampling_frac);
if (ret < 0)
return ret;
@@ -132,8 +160,12 @@ static int isl29028_enable_proximity(struct isl29028_chip *chip)
return ret;
/* Wait for conversion to be complete for first sample */
- sleep_index = isl29028_find_prox_sleep_time_index(chip->prox_sampling);
- msleep(isl29028_prox_sleep_time[sleep_index]);
+ prox_index = isl29028_find_prox_sleep_index(chip->prox_sampling_int,
+ chip->prox_sampling_frac);
+ if (prox_index < 0)
+ return prox_index;
+
+ msleep(isl29028_prox_data[prox_index].sleep_time);
return 0;
}
@@ -361,7 +393,7 @@ static int isl29028_write_raw(struct iio_dev *indio_dev,
break;
}
- ret = isl29028_set_proxim_sampling(chip, val);
+ ret = isl29028_set_proxim_sampling(chip, val, val2);
break;
case IIO_LIGHT:
if (mask != IIO_CHAN_INFO_SCALE) {
@@ -439,7 +471,8 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
if (chan->type != IIO_PROXIMITY)
break;
- *val = chip->prox_sampling;
+ *val = chip->prox_sampling_int;
+ *val2 = chip->prox_sampling_frac;
ret = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
@@ -472,7 +505,7 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
}
static IIO_CONST_ATTR(in_proximity_sampling_frequency_available,
- "1 3 5 10 13 20 83 100");
+ "1.25 2.5 5 10 13.3 20 80 100");
static IIO_CONST_ATTR(in_illuminance_scale_available, "125 2000");
#define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
@@ -571,7 +604,8 @@ static int isl29028_probe(struct i2c_client *client,
}
chip->enable_prox = false;
- chip->prox_sampling = 20;
+ chip->prox_sampling_int = 20;
+ chip->prox_sampling_frac = 0;
chip->lux_scale = 2000;
ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0);
@@ -664,6 +698,7 @@ static const struct dev_pm_ops isl29028_pm_ops = {
static const struct i2c_device_id isl29028_id[] = {
{"isl29028", 0},
+ {"isl29030", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, isl29028_id);
@@ -671,6 +706,7 @@ MODULE_DEVICE_TABLE(i2c, isl29028_id);
static const struct of_device_id isl29028_of_match[] = {
{ .compatible = "isl,isl29028", }, /* for backward compat., don't use */
{ .compatible = "isil,isl29028", },
+ { .compatible = "isil,isl29030", },
{ },
};
MODULE_DEVICE_TABLE(of, isl29028_of_match);
diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c
index 7de0f397194b..9d0c2e859bb2 100644
--- a/drivers/iio/light/rpr0521.c
+++ b/drivers/iio/light/rpr0521.c
@@ -9,7 +9,7 @@
*
* IIO driver for RPR-0521RS (7-bit I2C slave address 0x38).
*
- * TODO: illuminance channel, PM support, buffer
+ * TODO: illuminance channel, buffer
*/
#include <linux/module.h>
@@ -30,6 +30,7 @@
#define RPR0521_REG_PXS_DATA 0x44 /* 16-bit, little endian */
#define RPR0521_REG_ALS_DATA0 0x46 /* 16-bit, little endian */
#define RPR0521_REG_ALS_DATA1 0x48 /* 16-bit, little endian */
+#define RPR0521_REG_PS_OFFSET_LSB 0x53
#define RPR0521_REG_ID 0x92
#define RPR0521_MODE_ALS_MASK BIT(7)
@@ -77,9 +78,9 @@ static const struct rpr0521_gain rpr0521_pxs_gain[3] = {
};
enum rpr0521_channel {
+ RPR0521_CHAN_PXS,
RPR0521_CHAN_ALS_DATA0,
RPR0521_CHAN_ALS_DATA1,
- RPR0521_CHAN_PXS,
};
struct rpr0521_reg_desc {
@@ -88,6 +89,10 @@ struct rpr0521_reg_desc {
};
static const struct rpr0521_reg_desc rpr0521_data_reg[] = {
+ [RPR0521_CHAN_PXS] = {
+ .address = RPR0521_REG_PXS_DATA,
+ .device_mask = RPR0521_MODE_PXS_MASK,
+ },
[RPR0521_CHAN_ALS_DATA0] = {
.address = RPR0521_REG_ALS_DATA0,
.device_mask = RPR0521_MODE_ALS_MASK,
@@ -96,10 +101,6 @@ static const struct rpr0521_reg_desc rpr0521_data_reg[] = {
.address = RPR0521_REG_ALS_DATA1,
.device_mask = RPR0521_MODE_ALS_MASK,
},
- [RPR0521_CHAN_PXS] = {
- .address = RPR0521_REG_PXS_DATA,
- .device_mask = RPR0521_MODE_PXS_MASK,
- },
};
static const struct rpr0521_gain_info {
@@ -109,6 +110,13 @@ static const struct rpr0521_gain_info {
const struct rpr0521_gain *gain;
int size;
} rpr0521_gain[] = {
+ [RPR0521_CHAN_PXS] = {
+ .reg = RPR0521_REG_PXS_CTRL,
+ .mask = RPR0521_PXS_GAIN_MASK,
+ .shift = RPR0521_PXS_GAIN_SHIFT,
+ .gain = rpr0521_pxs_gain,
+ .size = ARRAY_SIZE(rpr0521_pxs_gain),
+ },
[RPR0521_CHAN_ALS_DATA0] = {
.reg = RPR0521_REG_ALS_CTRL,
.mask = RPR0521_ALS_DATA0_GAIN_MASK,
@@ -123,13 +131,30 @@ static const struct rpr0521_gain_info {
.gain = rpr0521_als_gain,
.size = ARRAY_SIZE(rpr0521_als_gain),
},
- [RPR0521_CHAN_PXS] = {
- .reg = RPR0521_REG_PXS_CTRL,
- .mask = RPR0521_PXS_GAIN_MASK,
- .shift = RPR0521_PXS_GAIN_SHIFT,
- .gain = rpr0521_pxs_gain,
- .size = ARRAY_SIZE(rpr0521_pxs_gain),
- },
+};
+
+struct rpr0521_samp_freq {
+ int als_hz;
+ int als_uhz;
+ int pxs_hz;
+ int pxs_uhz;
+};
+
+static const struct rpr0521_samp_freq rpr0521_samp_freq_i[13] = {
+/* {ALS, PXS}, W==currently writable option */
+ {0, 0, 0, 0}, /* W0000, 0=standby */
+ {0, 0, 100, 0}, /* 0001 */
+ {0, 0, 25, 0}, /* 0010 */
+ {0, 0, 10, 0}, /* 0011 */
+ {0, 0, 2, 500000}, /* 0100 */
+ {10, 0, 20, 0}, /* 0101 */
+ {10, 0, 10, 0}, /* W0110 */
+ {10, 0, 2, 500000}, /* 0111 */
+ {2, 500000, 20, 0}, /* 1000, measurement 100ms, sleep 300ms */
+ {2, 500000, 10, 0}, /* 1001, measurement 100ms, sleep 300ms */
+ {2, 500000, 0, 0}, /* 1010, high sensitivity mode */
+ {2, 500000, 2, 500000}, /* W1011, high sensitivity mode */
+ {20, 0, 20, 0} /* 1100, ALS_data x 0.5, see specification P.18 */
};
struct rpr0521_data {
@@ -142,9 +167,11 @@ struct rpr0521_data {
bool als_dev_en;
bool pxs_dev_en;
- /* optimize runtime pm ops - enable device only if needed */
+ /* optimize runtime pm ops - enable/disable device only if needed */
bool als_ps_need_en;
bool pxs_ps_need_en;
+ bool als_need_dis;
+ bool pxs_need_dis;
struct regmap *regmap;
};
@@ -152,9 +179,16 @@ struct rpr0521_data {
static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL);
static IIO_CONST_ATTR(in_proximity_scale_available, RPR0521_PXS_SCALE_AVAIL);
+/*
+ * Start with easy freq first, whole table of freq combinations is more
+ * complicated.
+ */
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("2.5 10");
+
static struct attribute *rpr0521_attributes[] = {
&iio_const_attr_in_intensity_scale_available.dev_attr.attr,
&iio_const_attr_in_proximity_scale_available.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
NULL,
};
@@ -164,12 +198,21 @@ static const struct attribute_group rpr0521_attribute_group = {
static const struct iio_chan_spec rpr0521_channels[] = {
{
+ .type = IIO_PROXIMITY,
+ .address = RPR0521_CHAN_PXS,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ },
+ {
.type = IIO_INTENSITY,
.modified = 1,
.address = RPR0521_CHAN_ALS_DATA0,
.channel2 = IIO_MOD_LIGHT_BOTH,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
},
{
.type = IIO_INTENSITY,
@@ -178,13 +221,8 @@ static const struct iio_chan_spec rpr0521_channels[] = {
.channel2 = IIO_MOD_LIGHT_IR,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
},
- {
- .type = IIO_PROXIMITY,
- .address = RPR0521_CHAN_PXS,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
- BIT(IIO_CHAN_INFO_SCALE),
- }
};
static int rpr0521_als_enable(struct rpr0521_data *data, u8 status)
@@ -197,7 +235,10 @@ static int rpr0521_als_enable(struct rpr0521_data *data, u8 status)
if (ret < 0)
return ret;
- data->als_dev_en = true;
+ if (status & RPR0521_MODE_ALS_MASK)
+ data->als_dev_en = true;
+ else
+ data->als_dev_en = false;
return 0;
}
@@ -212,7 +253,10 @@ static int rpr0521_pxs_enable(struct rpr0521_data *data, u8 status)
if (ret < 0)
return ret;
- data->pxs_dev_en = true;
+ if (status & RPR0521_MODE_PXS_MASK)
+ data->pxs_dev_en = true;
+ else
+ data->pxs_dev_en = false;
return 0;
}
@@ -224,40 +268,32 @@ static int rpr0521_pxs_enable(struct rpr0521_data *data, u8 status)
* @on: state to be set for devices in @device_mask
* @device_mask: bitmask specifying for which device we need to update @on state
*
- * We rely on rpr0521_runtime_resume to enable our @device_mask devices, but
- * if (for example) PXS was enabled (pxs_dev_en = true) by a previous call to
- * rpr0521_runtime_resume and we want to enable ALS we MUST set ALS enable
- * bit of RPR0521_REG_MODE_CTRL here because rpr0521_runtime_resume will not
- * be called twice.
+ * Calls for this function must be balanced so that each ON should have matching
+ * OFF. Otherwise pm usage_count gets out of sync.
*/
static int rpr0521_set_power_state(struct rpr0521_data *data, bool on,
u8 device_mask)
{
#ifdef CONFIG_PM
int ret;
- u8 update_mask = 0;
if (device_mask & RPR0521_MODE_ALS_MASK) {
- if (on && !data->als_ps_need_en && data->pxs_dev_en)
- update_mask |= RPR0521_MODE_ALS_MASK;
- else
- data->als_ps_need_en = on;
+ data->als_ps_need_en = on;
+ data->als_need_dis = !on;
}
if (device_mask & RPR0521_MODE_PXS_MASK) {
- if (on && !data->pxs_ps_need_en && data->als_dev_en)
- update_mask |= RPR0521_MODE_PXS_MASK;
- else
- data->pxs_ps_need_en = on;
- }
-
- if (update_mask) {
- ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
- update_mask, update_mask);
- if (ret < 0)
- return ret;
+ data->pxs_ps_need_en = on;
+ data->pxs_need_dis = !on;
}
+ /*
+ * On: _resume() is called only when we are suspended
+ * Off: _suspend() is called after delay if _resume() is not
+ * called before that.
+ * Note: If either measurement is re-enabled before _suspend(),
+ * both stay enabled until _suspend().
+ */
if (on) {
ret = pm_runtime_get_sync(&data->client->dev);
} else {
@@ -273,6 +309,23 @@ static int rpr0521_set_power_state(struct rpr0521_data *data, bool on,
return ret;
}
+
+ if (on) {
+ /* If _resume() was not called, enable measurement now. */
+ if (data->als_ps_need_en) {
+ ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
+ if (ret)
+ return ret;
+ data->als_ps_need_en = false;
+ }
+
+ if (data->pxs_ps_need_en) {
+ ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
+ if (ret)
+ return ret;
+ data->pxs_ps_need_en = false;
+ }
+ }
#endif
return 0;
}
@@ -314,6 +367,106 @@ static int rpr0521_set_gain(struct rpr0521_data *data, int chan,
idx << rpr0521_gain[chan].shift);
}
+static int rpr0521_read_samp_freq(struct rpr0521_data *data,
+ enum iio_chan_type chan_type,
+ int *val, int *val2)
+{
+ int reg, ret;
+
+ ret = regmap_read(data->regmap, RPR0521_REG_MODE_CTRL, &reg);
+ if (ret < 0)
+ return ret;
+
+ reg &= RPR0521_MODE_MEAS_TIME_MASK;
+ if (reg >= ARRAY_SIZE(rpr0521_samp_freq_i))
+ return -EINVAL;
+
+ switch (chan_type) {
+ case IIO_INTENSITY:
+ *val = rpr0521_samp_freq_i[reg].als_hz;
+ *val2 = rpr0521_samp_freq_i[reg].als_uhz;
+ return 0;
+
+ case IIO_PROXIMITY:
+ *val = rpr0521_samp_freq_i[reg].pxs_hz;
+ *val2 = rpr0521_samp_freq_i[reg].pxs_uhz;
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int rpr0521_write_samp_freq_common(struct rpr0521_data *data,
+ enum iio_chan_type chan_type,
+ int val, int val2)
+{
+ int i;
+
+ /*
+ * Ignore channel
+ * both pxs and als are setup only to same freq because of simplicity
+ */
+ switch (val) {
+ case 0:
+ i = 0;
+ break;
+
+ case 2:
+ if (val2 != 500000)
+ return -EINVAL;
+
+ i = 11;
+ break;
+
+ case 10:
+ i = 6;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return regmap_update_bits(data->regmap,
+ RPR0521_REG_MODE_CTRL,
+ RPR0521_MODE_MEAS_TIME_MASK,
+ i);
+}
+
+static int rpr0521_read_ps_offset(struct rpr0521_data *data, int *offset)
+{
+ int ret;
+ __le16 buffer;
+
+ ret = regmap_bulk_read(data->regmap,
+ RPR0521_REG_PS_OFFSET_LSB, &buffer, sizeof(buffer));
+
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Failed to read PS OFFSET register\n");
+ return ret;
+ }
+ *offset = le16_to_cpu(buffer);
+
+ return ret;
+}
+
+static int rpr0521_write_ps_offset(struct rpr0521_data *data, int offset)
+{
+ int ret;
+ __le16 buffer;
+
+ buffer = cpu_to_le16(offset & 0x3ff);
+ ret = regmap_raw_write(data->regmap,
+ RPR0521_REG_PS_OFFSET_LSB, &buffer, sizeof(buffer));
+
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Failed to write PS OFFSET register\n");
+ return ret;
+ }
+
+ return ret;
+}
+
static int rpr0521_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
@@ -339,7 +492,7 @@ static int rpr0521_read_raw(struct iio_dev *indio_dev,
ret = regmap_bulk_read(data->regmap,
rpr0521_data_reg[chan->address].address,
- &raw_data, 2);
+ &raw_data, sizeof(raw_data));
if (ret < 0) {
rpr0521_set_power_state(data, false, device_mask);
mutex_unlock(&data->lock);
@@ -354,6 +507,7 @@ static int rpr0521_read_raw(struct iio_dev *indio_dev,
*val = le16_to_cpu(raw_data);
return IIO_VAL_INT;
+
case IIO_CHAN_INFO_SCALE:
mutex_lock(&data->lock);
ret = rpr0521_get_gain(data, chan->address, val, val2);
@@ -362,6 +516,25 @@ static int rpr0521_read_raw(struct iio_dev *indio_dev,
return ret;
return IIO_VAL_INT_PLUS_MICRO;
+
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&data->lock);
+ ret = rpr0521_read_samp_freq(data, chan->type, val, val2);
+ mutex_unlock(&data->lock);
+ if (ret < 0)
+ return ret;
+
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ case IIO_CHAN_INFO_OFFSET:
+ mutex_lock(&data->lock);
+ ret = rpr0521_read_ps_offset(data, val);
+ mutex_unlock(&data->lock);
+ if (ret < 0)
+ return ret;
+
+ return IIO_VAL_INT;
+
default:
return -EINVAL;
}
@@ -381,6 +554,22 @@ static int rpr0521_write_raw(struct iio_dev *indio_dev,
mutex_unlock(&data->lock);
return ret;
+
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&data->lock);
+ ret = rpr0521_write_samp_freq_common(data, chan->type,
+ val, val2);
+ mutex_unlock(&data->lock);
+
+ return ret;
+
+ case IIO_CHAN_INFO_OFFSET:
+ mutex_lock(&data->lock);
+ ret = rpr0521_write_ps_offset(data, val);
+ mutex_unlock(&data->lock);
+
+ return ret;
+
default:
return -EINVAL;
}
@@ -419,12 +608,14 @@ static int rpr0521_init(struct rpr0521_data *data)
return ret;
}
+#ifndef CONFIG_PM
ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
if (ret < 0)
return ret;
ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
if (ret < 0)
return ret;
+#endif
return 0;
}
@@ -510,13 +701,26 @@ static int rpr0521_probe(struct i2c_client *client,
ret = pm_runtime_set_active(&client->dev);
if (ret < 0)
- return ret;
+ goto err_poweroff;
pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);
- return iio_device_register(indio_dev);
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto err_pm_disable;
+
+ return 0;
+
+err_pm_disable:
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ pm_runtime_put_noidle(&client->dev);
+err_poweroff:
+ rpr0521_poweroff(data);
+
+ return ret;
}
static int rpr0521_remove(struct i2c_client *client)
@@ -541,9 +745,16 @@ static int rpr0521_runtime_suspend(struct device *dev)
struct rpr0521_data *data = iio_priv(indio_dev);
int ret;
- /* disable channels and sets {als,pxs}_dev_en to false */
mutex_lock(&data->lock);
+ /* If measurements are enabled, enable them on resume */
+ if (!data->als_need_dis)
+ data->als_ps_need_en = data->als_dev_en;
+ if (!data->pxs_need_dis)
+ data->pxs_ps_need_en = data->pxs_dev_en;
+
+ /* disable channels and sets {als,pxs}_dev_en to false */
ret = rpr0521_poweroff(data);
+ regcache_mark_dirty(data->regmap);
mutex_unlock(&data->lock);
return ret;
@@ -555,6 +766,7 @@ static int rpr0521_runtime_resume(struct device *dev)
struct rpr0521_data *data = iio_priv(indio_dev);
int ret;
+ regcache_sync(data->regmap);
if (data->als_ps_need_en) {
ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
if (ret < 0)
@@ -568,6 +780,7 @@ static int rpr0521_runtime_resume(struct device *dev)
return ret;
data->pxs_ps_need_en = false;
}
+ msleep(100); //wait for first measurement result
return 0;
}
diff --git a/drivers/iio/light/tsl2583.c b/drivers/iio/light/tsl2583.c
index a78b6025c465..1679181d2bdd 100644
--- a/drivers/iio/light/tsl2583.c
+++ b/drivers/iio/light/tsl2583.c
@@ -3,7 +3,7 @@
* within the TAOS tsl258x family of devices (tsl2580, tsl2581, tsl2583).
*
* Copyright (c) 2011, TAOS Corporation.
- * Copyright (c) 2016 Brian Masney <masneyb@onstation.org>
+ * Copyright (c) 2016-2017 Brian Masney <masneyb@onstation.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
#include <linux/module.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/pm_runtime.h>
/* Device Registers and Masks */
#define TSL2583_CNTRL 0x00
@@ -64,6 +65,8 @@
#define TSL2583_CHIP_ID 0x90
#define TSL2583_CHIP_ID_MASK 0xf0
+#define TSL2583_POWER_OFF_DELAY_MS 2000
+
/* Per-device data */
struct tsl2583_als_info {
u16 als_ch0;
@@ -108,7 +111,6 @@ struct tsl2583_chip {
struct tsl2583_settings als_settings;
int als_time_scale;
int als_saturation;
- bool suspended;
};
struct gainadj {
@@ -460,8 +462,6 @@ static int tsl2583_chip_init_and_power_on(struct iio_dev *indio_dev)
if (ret < 0)
return ret;
- chip->suspended = false;
-
return ret;
}
@@ -513,11 +513,6 @@ static ssize_t in_illuminance_calibrate_store(struct device *dev,
mutex_lock(&chip->als_mutex);
- if (chip->suspended) {
- ret = -EBUSY;
- goto done;
- }
-
ret = tsl2583_als_calibrate(indio_dev);
if (ret < 0)
goto done;
@@ -645,20 +640,36 @@ static const struct iio_chan_spec tsl2583_channels[] = {
},
};
+static int tsl2583_set_pm_runtime_busy(struct tsl2583_chip *chip, bool on)
+{
+ int ret;
+
+ if (on) {
+ ret = pm_runtime_get_sync(&chip->client->dev);
+ if (ret < 0)
+ pm_runtime_put_noidle(&chip->client->dev);
+ } else {
+ pm_runtime_mark_last_busy(&chip->client->dev);
+ ret = pm_runtime_put_autosuspend(&chip->client->dev);
+ }
+
+ return ret;
+}
+
static int tsl2583_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct tsl2583_chip *chip = iio_priv(indio_dev);
- int ret = -EINVAL;
+ int ret, pm_ret;
- mutex_lock(&chip->als_mutex);
+ ret = tsl2583_set_pm_runtime_busy(chip, true);
+ if (ret < 0)
+ return ret;
- if (chip->suspended) {
- ret = -EBUSY;
- goto read_done;
- }
+ mutex_lock(&chip->als_mutex);
+ ret = -EINVAL;
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (chan->type == IIO_LIGHT) {
@@ -719,6 +730,18 @@ static int tsl2583_read_raw(struct iio_dev *indio_dev,
read_done:
mutex_unlock(&chip->als_mutex);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Preserve the ret variable if the call to
+ * tsl2583_set_pm_runtime_busy() is successful so the reading
+ * (if applicable) is returned to user space.
+ */
+ pm_ret = tsl2583_set_pm_runtime_busy(chip, false);
+ if (pm_ret < 0)
+ return pm_ret;
+
return ret;
}
@@ -727,15 +750,15 @@ static int tsl2583_write_raw(struct iio_dev *indio_dev,
int val, int val2, long mask)
{
struct tsl2583_chip *chip = iio_priv(indio_dev);
- int ret = -EINVAL;
+ int ret;
- mutex_lock(&chip->als_mutex);
+ ret = tsl2583_set_pm_runtime_busy(chip, true);
+ if (ret < 0)
+ return ret;
- if (chip->suspended) {
- ret = -EBUSY;
- goto write_done;
- }
+ mutex_lock(&chip->als_mutex);
+ ret = -EINVAL;
switch (mask) {
case IIO_CHAN_INFO_CALIBBIAS:
if (chan->type == IIO_LIGHT) {
@@ -767,9 +790,15 @@ static int tsl2583_write_raw(struct iio_dev *indio_dev,
break;
}
-write_done:
mutex_unlock(&chip->als_mutex);
+ if (ret < 0)
+ return ret;
+
+ ret = tsl2583_set_pm_runtime_busy(chip, false);
+ if (ret < 0)
+ return ret;
+
return ret;
}
@@ -803,7 +832,6 @@ static int tsl2583_probe(struct i2c_client *clientp,
i2c_set_clientdata(clientp, indio_dev);
mutex_init(&chip->als_mutex);
- chip->suspended = true;
ret = i2c_smbus_read_byte_data(clientp,
TSL2583_CMD_REG | TSL2583_CHIPID);
@@ -826,6 +854,11 @@ static int tsl2583_probe(struct i2c_client *clientp,
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->name = chip->client->name;
+ pm_runtime_enable(&clientp->dev);
+ pm_runtime_set_autosuspend_delay(&clientp->dev,
+ TSL2583_POWER_OFF_DELAY_MS);
+ pm_runtime_use_autosuspend(&clientp->dev);
+
ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
if (ret) {
dev_err(&clientp->dev, "%s: iio registration failed\n",
@@ -836,16 +869,25 @@ static int tsl2583_probe(struct i2c_client *clientp,
/* Load up the V2 defaults (these are hard coded defaults for now) */
tsl2583_defaults(chip);
- /* Make sure the chip is on */
- ret = tsl2583_chip_init_and_power_on(indio_dev);
- if (ret < 0)
- return ret;
-
dev_info(&clientp->dev, "Light sensor found.\n");
return 0;
}
+static int tsl2583_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct tsl2583_chip *chip = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ pm_runtime_put_noidle(&client->dev);
+
+ return tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_OFF);
+}
+
static int __maybe_unused tsl2583_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
@@ -855,7 +897,6 @@ static int __maybe_unused tsl2583_suspend(struct device *dev)
mutex_lock(&chip->als_mutex);
ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_OFF);
- chip->suspended = true;
mutex_unlock(&chip->als_mutex);
@@ -877,7 +918,11 @@ static int __maybe_unused tsl2583_resume(struct device *dev)
return ret;
}
-static SIMPLE_DEV_PM_OPS(tsl2583_pm_ops, tsl2583_suspend, tsl2583_resume);
+static const struct dev_pm_ops tsl2583_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(tsl2583_suspend, tsl2583_resume, NULL)
+};
static struct i2c_device_id tsl2583_idtable[] = {
{ "tsl2580", 0 },
@@ -904,6 +949,7 @@ static struct i2c_driver tsl2583_driver = {
},
.id_table = tsl2583_idtable,
.probe = tsl2583_probe,
+ .remove = tsl2583_remove,
};
module_i2c_driver(tsl2583_driver);
diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c
index a97e802ca523..e9fa86c87db5 100644
--- a/drivers/iio/orientation/hid-sensor-rotation.c
+++ b/drivers/iio/orientation/hid-sensor-rotation.c
@@ -31,6 +31,10 @@ struct dev_rot_state {
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info quaternion;
u32 sampled_vals[4];
+ int scale_pre_decml;
+ int scale_post_decml;
+ int scale_precision;
+ int value_offset;
};
/* Channel definitions */
@@ -41,6 +45,8 @@ static const struct iio_chan_spec dev_rot_channels[] = {
.channel2 = IIO_MOD_QUATERNION,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_HYSTERESIS)
}
};
@@ -80,6 +86,15 @@ static int dev_rot_read_raw(struct iio_dev *indio_dev,
} else
ret_type = -EINVAL;
break;
+ case IIO_CHAN_INFO_SCALE:
+ vals[0] = rot_state->scale_pre_decml;
+ vals[1] = rot_state->scale_post_decml;
+ return rot_state->scale_precision;
+
+ case IIO_CHAN_INFO_OFFSET:
+ *vals = rot_state->value_offset;
+ return IIO_VAL_INT;
+
case IIO_CHAN_INFO_SAMP_FREQ:
ret_type = hid_sensor_read_samp_freq_value(
&rot_state->common_attributes, &vals[0], &vals[1]);
@@ -199,6 +214,11 @@ static int dev_rot_parse_report(struct platform_device *pdev,
dev_dbg(&pdev->dev, "dev_rot: attrib size %d\n",
st->quaternion.size);
+ st->scale_precision = hid_sensor_format_scale(
+ hsdev->usage,
+ &st->quaternion,
+ &st->scale_pre_decml, &st->scale_post_decml);
+
/* Set Sensitivity field ids, when there is no individual modifier */
if (st->common_attributes.sensitivity.index < 0) {
sensor_hub_input_get_attribute_info(hsdev,
@@ -218,7 +238,7 @@ static int dev_rot_parse_report(struct platform_device *pdev,
static int hid_dev_rot_probe(struct platform_device *pdev)
{
int ret;
- static char *name = "dev_rotation";
+ static char *name;
struct iio_dev *indio_dev;
struct dev_rot_state *rot_state;
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
@@ -234,8 +254,21 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
rot_state->common_attributes.hsdev = hsdev;
rot_state->common_attributes.pdev = pdev;
- ret = hid_sensor_parse_common_attributes(hsdev,
- HID_USAGE_SENSOR_DEVICE_ORIENTATION,
+ switch (hsdev->usage) {
+ case HID_USAGE_SENSOR_DEVICE_ORIENTATION:
+ name = "dev_rotation";
+ break;
+ case HID_USAGE_SENSOR_RELATIVE_ORIENTATION:
+ name = "relative_orientation";
+ break;
+ case HID_USAGE_SENSOR_GEOMAGNETIC_ORIENTATION:
+ name = "geomagnetic_orientation";
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = hid_sensor_parse_common_attributes(hsdev, hsdev->usage,
&rot_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "failed to setup common attributes\n");
@@ -252,8 +285,7 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
ret = dev_rot_parse_report(pdev, hsdev,
(struct iio_chan_spec *)indio_dev->channels,
- HID_USAGE_SENSOR_DEVICE_ORIENTATION,
- rot_state);
+ hsdev->usage, rot_state);
if (ret) {
dev_err(&pdev->dev, "failed to setup attributes\n");
return ret;
@@ -288,8 +320,7 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
rot_state->callbacks.send_event = dev_rot_proc_event;
rot_state->callbacks.capture_sample = dev_rot_capture_sample;
rot_state->callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev,
- HID_USAGE_SENSOR_DEVICE_ORIENTATION,
+ ret = sensor_hub_register_callback(hsdev, hsdev->usage,
&rot_state->callbacks);
if (ret) {
dev_err(&pdev->dev, "callback reg failed\n");
@@ -314,7 +345,7 @@ static int hid_dev_rot_remove(struct platform_device *pdev)
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct dev_rot_state *rot_state = iio_priv(indio_dev);
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_DEVICE_ORIENTATION);
+ sensor_hub_remove_callback(hsdev, hsdev->usage);
iio_device_unregister(indio_dev);
hid_sensor_remove_trigger(&rot_state->common_attributes);
iio_triggered_buffer_cleanup(indio_dev);
@@ -327,6 +358,14 @@ static const struct platform_device_id hid_dev_rot_ids[] = {
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
.name = "HID-SENSOR-20008a",
},
+ {
+ /* Relative orientation(AG) sensor */
+ .name = "HID-SENSOR-20008e",
+ },
+ {
+ /* Geomagnetic orientation(AM) sensor */
+ .name = "HID-SENSOR-2000c1",
+ },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, hid_dev_rot_ids);
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index 5d16b252ab6b..eaa7cfcb4c2a 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -23,7 +23,7 @@ config BMP280
select BMP280_SPI if (SPI_MASTER)
help
Say yes here to build support for Bosch Sensortec BMP180 and BMP280
- pressure and temperature sensors. Also supports the BE280 with
+ pressure and temperature sensors. Also supports the BME280 with
an additional humidity sensor channel.
To compile this driver as a module, choose M here: the core module
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index fd0edca0e656..aa61ec15c139 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -568,6 +568,8 @@ static const struct iio_trigger_ops st_press_trigger_ops = {
int st_press_common_probe(struct iio_dev *indio_dev)
{
struct st_sensor_data *press_data = iio_priv(indio_dev);
+ struct st_sensors_platform_data *pdata =
+ (struct st_sensors_platform_data *)press_data->dev->platform_data;
int irq = press_data->get_irq_data_ready(indio_dev);
int err;
@@ -603,10 +605,8 @@ int st_press_common_probe(struct iio_dev *indio_dev)
press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz;
/* Some devices don't support a data ready pin. */
- if (!press_data->dev->platform_data &&
- press_data->sensor_settings->drdy_irq.addr)
- press_data->dev->platform_data =
- (struct st_sensors_platform_data *)&default_press_pdata;
+ if (!pdata && press_data->sensor_settings->drdy_irq.addr)
+ pdata = (struct st_sensors_platform_data *)&default_press_pdata;
err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data);
if (err < 0)
diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c
index e58a0ad07477..c92a95f9f52c 100644
--- a/drivers/iio/pressure/zpa2326.c
+++ b/drivers/iio/pressure/zpa2326.c
@@ -867,12 +867,13 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev,
{
int ret;
unsigned int val;
+ long timeout;
zpa2326_dbg(indio_dev, "waiting for one shot completion interrupt");
- ret = wait_for_completion_interruptible_timeout(
+ timeout = wait_for_completion_interruptible_timeout(
&private->data_ready, ZPA2326_CONVERSION_JIFFIES);
- if (ret > 0)
+ if (timeout > 0)
/*
* Interrupt handler completed before timeout: return operation
* status.
@@ -882,13 +883,16 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev,
/* Clear all interrupts just to be sure. */
regmap_read(private->regmap, ZPA2326_INT_SOURCE_REG, &val);
- if (!ret)
+ if (!timeout) {
/* Timed out. */
+ zpa2326_warn(indio_dev, "no one shot interrupt occurred (%ld)",
+ timeout);
ret = -ETIME;
-
- if (ret != -ERESTARTSYS)
- zpa2326_warn(indio_dev, "no one shot interrupt occurred (%d)",
- ret);
+ } else if (timeout < 0) {
+ zpa2326_warn(indio_dev,
+ "wait for one shot interrupt cancelled");
+ ret = -ERESTARTSYS;
+ }
return ret;
}
diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c
index ddf9bee89f77..aa0d0be1a608 100644
--- a/drivers/iio/proximity/as3935.c
+++ b/drivers/iio/proximity/as3935.c
@@ -176,13 +176,13 @@ static int as3935_read_raw(struct iio_dev *indio_dev,
if (ret)
return ret;
- if (m == IIO_CHAN_INFO_RAW)
- return IIO_VAL_INT;
-
/* storm out of range */
if (*val == AS3935_DATA_MASK)
return -EINVAL;
+ if (m == IIO_CHAN_INFO_RAW)
+ return IIO_VAL_INT;
+
if (m == IIO_CHAN_INFO_PROCESSED)
*val *= 1000;
break;
diff --git a/drivers/iio/temperature/maxim_thermocouple.c b/drivers/iio/temperature/maxim_thermocouple.c
index 557214202eff..d70e2e53d6a7 100644
--- a/drivers/iio/temperature/maxim_thermocouple.c
+++ b/drivers/iio/temperature/maxim_thermocouple.c
@@ -267,6 +267,7 @@ static int maxim_thermocouple_remove(struct spi_device *spi)
static const struct spi_device_id maxim_thermocouple_id[] = {
{"max6675", MAX6675},
{"max31855", MAX31855},
+ {"max31856", MAX31855},
{},
};
MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c
index 25248d644e7c..0797f2fe584f 100644
--- a/drivers/iio/trigger/stm32-timer-trigger.c
+++ b/drivers/iio/trigger/stm32-timer-trigger.c
@@ -14,19 +14,19 @@
#include <linux/module.h>
#include <linux/platform_device.h>
-#define MAX_TRIGGERS 6
+#define MAX_TRIGGERS 7
#define MAX_VALIDS 5
/* List the triggers created by each timer */
static const void *triggers_table[][MAX_TRIGGERS] = {
- { TIM1_TRGO, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4,},
+ { TIM1_TRGO, TIM1_TRGO2, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4,},
{ TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4,},
{ TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4,},
{ TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4,},
{ TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4,},
{ TIM6_TRGO,},
{ TIM7_TRGO,},
- { TIM8_TRGO, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,},
+ { TIM8_TRGO, TIM8_TRGO2, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,},
{ TIM9_TRGO, TIM9_CH1, TIM9_CH2,},
{ }, /* timer 10 */
{ }, /* timer 11 */
@@ -56,9 +56,16 @@ struct stm32_timer_trigger {
u32 max_arr;
const void *triggers;
const void *valids;
+ bool has_trgo2;
};
+static bool stm32_timer_is_trgo2_name(const char *name)
+{
+ return !!strstr(name, "trgo2");
+}
+
static int stm32_timer_start(struct stm32_timer_trigger *priv,
+ struct iio_trigger *trig,
unsigned int frequency)
{
unsigned long long prd, div;
@@ -102,7 +109,12 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv,
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE);
/* Force master mode to update mode */
- regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, 0x20);
+ if (stm32_timer_is_trgo2_name(trig->name))
+ regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2,
+ 0x2 << TIM_CR2_MMS2_SHIFT);
+ else
+ regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS,
+ 0x2 << TIM_CR2_MMS_SHIFT);
/* Make sure that registers are updated */
regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
@@ -150,7 +162,7 @@ static ssize_t stm32_tt_store_frequency(struct device *dev,
if (freq == 0) {
stm32_timer_stop(priv);
} else {
- ret = stm32_timer_start(priv, freq);
+ ret = stm32_timer_start(priv, trig, freq);
if (ret)
return ret;
}
@@ -183,6 +195,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(0660,
stm32_tt_read_frequency,
stm32_tt_store_frequency);
+#define MASTER_MODE_MAX 7
+#define MASTER_MODE2_MAX 15
+
static char *master_mode_table[] = {
"reset",
"enable",
@@ -191,7 +206,16 @@ static char *master_mode_table[] = {
"OC1REF",
"OC2REF",
"OC3REF",
- "OC4REF"
+ "OC4REF",
+ /* Master mode selection 2 only */
+ "OC5REF",
+ "OC6REF",
+ "compare_pulse_OC4REF",
+ "compare_pulse_OC6REF",
+ "compare_pulse_OC4REF_r_or_OC6REF_r",
+ "compare_pulse_OC4REF_r_or_OC6REF_f",
+ "compare_pulse_OC5REF_r_or_OC6REF_r",
+ "compare_pulse_OC5REF_r_or_OC6REF_f",
};
static ssize_t stm32_tt_show_master_mode(struct device *dev,
@@ -199,10 +223,15 @@ static ssize_t stm32_tt_show_master_mode(struct device *dev,
char *buf)
{
struct stm32_timer_trigger *priv = dev_get_drvdata(dev);
+ struct iio_trigger *trig = to_iio_trigger(dev);
u32 cr2;
regmap_read(priv->regmap, TIM_CR2, &cr2);
- cr2 = (cr2 & TIM_CR2_MMS) >> TIM_CR2_MMS_SHIFT;
+
+ if (stm32_timer_is_trgo2_name(trig->name))
+ cr2 = (cr2 & TIM_CR2_MMS2) >> TIM_CR2_MMS2_SHIFT;
+ else
+ cr2 = (cr2 & TIM_CR2_MMS) >> TIM_CR2_MMS_SHIFT;
return snprintf(buf, PAGE_SIZE, "%s\n", master_mode_table[cr2]);
}
@@ -212,13 +241,25 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev,
const char *buf, size_t len)
{
struct stm32_timer_trigger *priv = dev_get_drvdata(dev);
+ struct iio_trigger *trig = to_iio_trigger(dev);
+ u32 mask, shift, master_mode_max;
int i;
- for (i = 0; i < ARRAY_SIZE(master_mode_table); i++) {
+ if (stm32_timer_is_trgo2_name(trig->name)) {
+ mask = TIM_CR2_MMS2;
+ shift = TIM_CR2_MMS2_SHIFT;
+ master_mode_max = MASTER_MODE2_MAX;
+ } else {
+ mask = TIM_CR2_MMS;
+ shift = TIM_CR2_MMS_SHIFT;
+ master_mode_max = MASTER_MODE_MAX;
+ }
+
+ for (i = 0; i <= master_mode_max; i++) {
if (!strncmp(master_mode_table[i], buf,
strlen(master_mode_table[i]))) {
- regmap_update_bits(priv->regmap, TIM_CR2,
- TIM_CR2_MMS, i << TIM_CR2_MMS_SHIFT);
+ regmap_update_bits(priv->regmap, TIM_CR2, mask,
+ i << shift);
/* Make sure that registers are updated */
regmap_update_bits(priv->regmap, TIM_EGR,
TIM_EGR_UG, TIM_EGR_UG);
@@ -229,8 +270,31 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev,
return -EINVAL;
}
-static IIO_CONST_ATTR(master_mode_available,
- "reset enable update compare_pulse OC1REF OC2REF OC3REF OC4REF");
+static ssize_t stm32_tt_show_master_mode_avail(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_trigger *trig = to_iio_trigger(dev);
+ unsigned int i, master_mode_max;
+ size_t len = 0;
+
+ if (stm32_timer_is_trgo2_name(trig->name))
+ master_mode_max = MASTER_MODE2_MAX;
+ else
+ master_mode_max = MASTER_MODE_MAX;
+
+ for (i = 0; i <= master_mode_max; i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "%s ", master_mode_table[i]);
+
+ /* replace trailing space by newline */
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(master_mode_available, 0444,
+ stm32_tt_show_master_mode_avail, NULL, 0);
static IIO_DEVICE_ATTR(master_mode, 0660,
stm32_tt_show_master_mode,
@@ -240,7 +304,7 @@ static IIO_DEVICE_ATTR(master_mode, 0660,
static struct attribute *stm32_trigger_attrs[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_dev_attr_master_mode.dev_attr.attr,
- &iio_const_attr_master_mode_available.dev_attr.attr,
+ &iio_dev_attr_master_mode_available.dev_attr.attr,
NULL,
};
@@ -264,6 +328,12 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv)
while (cur && *cur) {
struct iio_trigger *trig;
+ bool cur_is_trgo2 = stm32_timer_is_trgo2_name(*cur);
+
+ if (cur_is_trgo2 && !priv->has_trgo2) {
+ cur++;
+ continue;
+ }
trig = devm_iio_trigger_alloc(priv->dev, "%s", *cur);
if (!trig)
@@ -277,7 +347,7 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv)
* should only be available on trgo trigger which
* is always the first in the list.
*/
- if (cur == priv->triggers)
+ if (cur == priv->triggers || cur_is_trgo2)
trig->dev.groups = stm32_trigger_attr_groups;
iio_trigger_set_drvdata(trig, priv);
@@ -584,6 +654,20 @@ bool is_stm32_timer_trigger(struct iio_trigger *trig)
}
EXPORT_SYMBOL(is_stm32_timer_trigger);
+static void stm32_timer_detect_trgo2(struct stm32_timer_trigger *priv)
+{
+ u32 val;
+
+ /*
+ * Master mode selection 2 bits can only be written and read back when
+ * timer supports it.
+ */
+ regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, TIM_CR2_MMS2);
+ regmap_read(priv->regmap, TIM_CR2, &val);
+ regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, 0);
+ priv->has_trgo2 = !!val;
+}
+
static int stm32_timer_trigger_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -614,6 +698,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
priv->max_arr = ddata->max_arr;
priv->triggers = triggers_table[index];
priv->valids = valids_table[index];
+ stm32_timer_detect_trgo2(priv);
ret = stm32_setup_iio_triggers(priv);
if (ret)
diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c
index af108e96b3ec..995acdd7c942 100644
--- a/drivers/staging/iio/frequency/ad9834.c
+++ b/drivers/staging/iio/frequency/ad9834.c
@@ -292,7 +292,7 @@ ssize_t ad9834_show_out0_wavetype_available(struct device *dev,
return sprintf(buf, "%s\n", str);
}
-static IIO_DEVICE_ATTR(out_altvoltage0_out0_wavetype_available, S_IRUGO,
+static IIO_DEVICE_ATTR(out_altvoltage0_out0_wavetype_available, 0444,
ad9834_show_out0_wavetype_available, NULL, 0);
static
@@ -312,27 +312,27 @@ ssize_t ad9834_show_out1_wavetype_available(struct device *dev,
return sprintf(buf, "%s\n", str);
}
-static IIO_DEVICE_ATTR(out_altvoltage0_out1_wavetype_available, S_IRUGO,
+static IIO_DEVICE_ATTR(out_altvoltage0_out1_wavetype_available, 0444,
ad9834_show_out1_wavetype_available, NULL, 0);
/**
* see dds.h for further information
*/
-static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ0);
-static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ1);
-static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_FSEL);
+static IIO_DEV_ATTR_FREQ(0, 0, 0200, NULL, ad9834_write, AD9834_REG_FREQ0);
+static IIO_DEV_ATTR_FREQ(0, 1, 0200, NULL, ad9834_write, AD9834_REG_FREQ1);
+static IIO_DEV_ATTR_FREQSYMBOL(0, 0200, NULL, ad9834_write, AD9834_FSEL);
static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */
-static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE0);
-static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE1);
-static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_PSEL);
+static IIO_DEV_ATTR_PHASE(0, 0, 0200, NULL, ad9834_write, AD9834_REG_PHASE0);
+static IIO_DEV_ATTR_PHASE(0, 1, 0200, NULL, ad9834_write, AD9834_REG_PHASE1);
+static IIO_DEV_ATTR_PHASESYMBOL(0, 0200, NULL, ad9834_write, AD9834_PSEL);
static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/
-static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL,
+static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL,
ad9834_write, AD9834_PIN_SW);
-static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, ad9834_write, AD9834_RESET);
-static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, S_IWUSR, NULL,
+static IIO_DEV_ATTR_OUT_ENABLE(0, 0200, NULL, ad9834_write, AD9834_RESET);
+static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, 0200, NULL,
ad9834_write, AD9834_OPBITEN);
static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0);
static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1);
diff --git a/drivers/staging/iio/frequency/dds.h b/drivers/staging/iio/frequency/dds.h
index fe53e7324c94..d6ccd99c14d7 100644
--- a/drivers/staging/iio/frequency/dds.h
+++ b/drivers/staging/iio/frequency/dds.h
@@ -101,7 +101,7 @@
#define IIO_DEV_ATTR_OUT_WAVETYPE(_channel, _output, _store, _addr) \
IIO_DEVICE_ATTR(out_altvoltage##_channel##_out##_output##_wavetype,\
- S_IWUSR, NULL, _store, _addr)
+ 0200, NULL, _store, _addr)
/**
* /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype_available
diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig
index 4fbf6298c0f3..aacb0ae58c0e 100644
--- a/drivers/staging/iio/light/Kconfig
+++ b/drivers/staging/iio/light/Kconfig
@@ -3,16 +3,6 @@
#
menu "Light sensors"
-config SENSORS_ISL29028
- tristate "Intersil ISL29028 Concurrent Light and Proximity Sensor"
- depends on I2C
- select REGMAP_I2C
- help
- Provides driver for the Intersil's ISL29028 device.
- This driver supports the sysfs interface to get the ALS, IR intensity,
- Proximity value via iio. The ISL29028 provides the concurrent sensing
- of ambient light and proximity.
-
config TSL2x7x
tristate "TAOS TSL/TMD2x71 and TSL/TMD2x72 Family of light and proximity sensors"
depends on I2C
diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile
index f8693e9fdc94..ab8dc3a3d10b 100644
--- a/drivers/staging/iio/light/Makefile
+++ b/drivers/staging/iio/light/Makefile
@@ -2,5 +2,4 @@
# Makefile for industrial I/O Light sensors
#
-obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o
-obj-$(CONFIG_TSL2x7x) += tsl2x7x_core.o
+obj-$(CONFIG_TSL2x7x) += tsl2x7x.o
diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x.c
index af3910bc1b4f..146719928fb3 100644
--- a/drivers/staging/iio/light/tsl2x7x_core.c
+++ b/drivers/staging/iio/light/tsl2x7x.c
@@ -13,10 +13,6 @@
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/kernel.h>
@@ -919,7 +915,7 @@ static void tsl2x7x_prox_cal(struct iio_dev *indio_dev)
tsl2x7x_chip_on(indio_dev);
}
-static ssize_t tsl2x7x_power_state_show(struct device *dev,
+static ssize_t power_state_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -928,7 +924,7 @@ static ssize_t tsl2x7x_power_state_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", chip->tsl2x7x_chip_status);
}
-static ssize_t tsl2x7x_power_state_store(struct device *dev,
+static ssize_t power_state_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
@@ -946,7 +942,7 @@ static ssize_t tsl2x7x_power_state_store(struct device *dev,
return len;
}
-static ssize_t tsl2x7x_gain_available_show(struct device *dev,
+static ssize_t in_illuminance0_calibscale_available_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -964,14 +960,14 @@ static ssize_t tsl2x7x_gain_available_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120");
}
-static ssize_t tsl2x7x_prox_gain_available_show(struct device *dev,
+static ssize_t in_proximity0_calibscale_available_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n", "1 2 4 8");
}
-static ssize_t tsl2x7x_als_time_show(struct device *dev,
+static ssize_t in_illuminance0_integration_time_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -986,7 +982,7 @@ static ssize_t tsl2x7x_als_time_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
}
-static ssize_t tsl2x7x_als_time_store(struct device *dev,
+static ssize_t in_illuminance0_integration_time_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
@@ -1014,7 +1010,7 @@ static ssize_t tsl2x7x_als_time_store(struct device *dev,
static IIO_CONST_ATTR(in_illuminance0_integration_time_available,
".00272 - .696");
-static ssize_t tsl2x7x_als_cal_target_show(struct device *dev,
+static ssize_t in_illuminance0_target_input_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -1024,7 +1020,7 @@ static ssize_t tsl2x7x_als_cal_target_show(struct device *dev,
chip->tsl2x7x_settings.als_cal_target);
}
-static ssize_t tsl2x7x_als_cal_target_store(struct device *dev,
+static ssize_t in_illuminance0_target_input_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
@@ -1044,7 +1040,7 @@ static ssize_t tsl2x7x_als_cal_target_store(struct device *dev,
}
/* persistence settings */
-static ssize_t tsl2x7x_als_persistence_show(struct device *dev,
+static ssize_t in_intensity0_thresh_period_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -1061,7 +1057,7 @@ static ssize_t tsl2x7x_als_persistence_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
}
-static ssize_t tsl2x7x_als_persistence_store(struct device *dev,
+static ssize_t in_intensity0_thresh_period_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
@@ -1092,7 +1088,7 @@ static ssize_t tsl2x7x_als_persistence_store(struct device *dev,
return IIO_VAL_INT_PLUS_MICRO;
}
-static ssize_t tsl2x7x_prox_persistence_show(struct device *dev,
+static ssize_t in_proximity0_thresh_period_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -1109,7 +1105,7 @@ static ssize_t tsl2x7x_prox_persistence_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z);
}
-static ssize_t tsl2x7x_prox_persistence_store(struct device *dev,
+static ssize_t in_proximity0_thresh_period_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
@@ -1140,7 +1136,7 @@ static ssize_t tsl2x7x_prox_persistence_store(struct device *dev,
return IIO_VAL_INT_PLUS_MICRO;
}
-static ssize_t tsl2x7x_do_calibrate(struct device *dev,
+static ssize_t in_illuminance0_calibrate_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
@@ -1158,7 +1154,7 @@ static ssize_t tsl2x7x_do_calibrate(struct device *dev,
return len;
}
-static ssize_t tsl2x7x_luxtable_show(struct device *dev,
+static ssize_t in_illuminance0_lux_table_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -1186,7 +1182,7 @@ static ssize_t tsl2x7x_luxtable_show(struct device *dev,
return offset;
}
-static ssize_t tsl2x7x_luxtable_store(struct device *dev,
+static ssize_t in_illuminance0_lux_table_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
@@ -1226,7 +1222,7 @@ static ssize_t tsl2x7x_luxtable_store(struct device *dev,
return len;
}
-static ssize_t tsl2x7x_do_prox_calibrate(struct device *dev,
+static ssize_t in_proximity0_calibrate_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
@@ -1498,35 +1494,25 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
return 0;
}
-static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
- tsl2x7x_power_state_show, tsl2x7x_power_state_store);
+static DEVICE_ATTR_RW(power_state);
-static DEVICE_ATTR(in_proximity0_calibscale_available, S_IRUGO,
- tsl2x7x_prox_gain_available_show, NULL);
+static DEVICE_ATTR_RO(in_proximity0_calibscale_available);
-static DEVICE_ATTR(in_illuminance0_calibscale_available, S_IRUGO,
- tsl2x7x_gain_available_show, NULL);
+static DEVICE_ATTR_RO(in_illuminance0_calibscale_available);
-static DEVICE_ATTR(in_illuminance0_integration_time, S_IRUGO | S_IWUSR,
- tsl2x7x_als_time_show, tsl2x7x_als_time_store);
+static DEVICE_ATTR_RW(in_illuminance0_integration_time);
-static DEVICE_ATTR(in_illuminance0_target_input, S_IRUGO | S_IWUSR,
- tsl2x7x_als_cal_target_show, tsl2x7x_als_cal_target_store);
+static DEVICE_ATTR_RW(in_illuminance0_target_input);
-static DEVICE_ATTR(in_illuminance0_calibrate, S_IWUSR, NULL,
- tsl2x7x_do_calibrate);
+static DEVICE_ATTR_WO(in_illuminance0_calibrate);
-static DEVICE_ATTR(in_proximity0_calibrate, S_IWUSR, NULL,
- tsl2x7x_do_prox_calibrate);
+static DEVICE_ATTR_WO(in_proximity0_calibrate);
-static DEVICE_ATTR(in_illuminance0_lux_table, S_IRUGO | S_IWUSR,
- tsl2x7x_luxtable_show, tsl2x7x_luxtable_store);
+static DEVICE_ATTR_RW(in_illuminance0_lux_table);
-static DEVICE_ATTR(in_intensity0_thresh_period, S_IRUGO | S_IWUSR,
- tsl2x7x_als_persistence_show, tsl2x7x_als_persistence_store);
+static DEVICE_ATTR_RW(in_intensity0_thresh_period);
-static DEVICE_ATTR(in_proximity0_thresh_period, S_IRUGO | S_IWUSR,
- tsl2x7x_prox_persistence_show, tsl2x7x_prox_persistence_store);
+static DEVICE_ATTR_RW(in_proximity0_thresh_period);
/* Use the default register values to identify the Taos device */
static int tsl2x7x_device_id(unsigned char *id, int target)
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index b71fbd313778..ce26abdeab92 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -107,9 +107,8 @@ static int ade7753_spi_write_reg_8(struct device *dev,
return ret;
}
-static int ade7753_spi_write_reg_16(struct device *dev,
- u8 reg_address,
- u16 value)
+static int ade7753_spi_write_reg_16(struct device *dev, u8 reg_address,
+ u16 value)
{
int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -126,8 +125,8 @@ static int ade7753_spi_write_reg_16(struct device *dev,
}
static int ade7753_spi_read_reg_8(struct device *dev,
- u8 reg_address,
- u8 *val)
+ u8 reg_address,
+ u8 *val)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7753_state *st = iio_priv(indio_dev);
@@ -136,7 +135,7 @@ static int ade7753_spi_read_reg_8(struct device *dev,
ret = spi_w8r8(st->us, ADE7753_READ_REG(reg_address));
if (ret < 0) {
dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
- reg_address);
+ reg_address);
return ret;
}
*val = ret;
@@ -145,8 +144,8 @@ static int ade7753_spi_read_reg_8(struct device *dev,
}
static int ade7753_spi_read_reg_16(struct device *dev,
- u8 reg_address,
- u16 *val)
+ u8 reg_address,
+ u16 *val)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7753_state *st = iio_priv(indio_dev);
@@ -165,8 +164,8 @@ static int ade7753_spi_read_reg_16(struct device *dev,
}
static int ade7753_spi_read_reg_24(struct device *dev,
- u8 reg_address,
- u32 *val)
+ u8 reg_address,
+ u32 *val)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7753_state *st = iio_priv(indio_dev);
@@ -189,7 +188,7 @@ static int ade7753_spi_read_reg_24(struct device *dev,
ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
- reg_address);
+ reg_address);
goto error_ret;
}
*val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2];
@@ -200,8 +199,8 @@ error_ret:
}
static ssize_t ade7753_read_8bit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u8 val;
@@ -215,8 +214,8 @@ static ssize_t ade7753_read_8bit(struct device *dev,
}
static ssize_t ade7753_read_16bit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u16 val;
@@ -230,8 +229,8 @@ static ssize_t ade7753_read_16bit(struct device *dev,
}
static ssize_t ade7753_read_24bit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u32 val;
@@ -245,9 +244,9 @@ static ssize_t ade7753_read_24bit(struct device *dev,
}
static ssize_t ade7753_write_8bit(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
@@ -263,9 +262,9 @@ error_ret:
}
static ssize_t ade7753_write_16bit(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
@@ -298,92 +297,92 @@ static IIO_DEV_ATTR_AENERGY(ade7753_read_24bit, ADE7753_AENERGY);
static IIO_DEV_ATTR_LAENERGY(ade7753_read_24bit, ADE7753_LAENERGY);
static IIO_DEV_ATTR_VAENERGY(ade7753_read_24bit, ADE7753_VAENERGY);
static IIO_DEV_ATTR_LVAENERGY(ade7753_read_24bit, ADE7753_LVAENERGY);
-static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CFDEN(0644,
ade7753_read_16bit,
ade7753_write_16bit,
ADE7753_CFDEN);
-static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CFNUM(0644,
ade7753_read_8bit,
ade7753_write_8bit,
ADE7753_CFNUM);
static IIO_DEV_ATTR_CHKSUM(ade7753_read_8bit, ADE7753_CHKSUM);
-static IIO_DEV_ATTR_PHCAL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_PHCAL(0644,
ade7753_read_16bit,
ade7753_write_16bit,
ADE7753_PHCAL);
-static IIO_DEV_ATTR_APOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_APOS(0644,
ade7753_read_16bit,
ade7753_write_16bit,
ADE7753_APOS);
-static IIO_DEV_ATTR_SAGCYC(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_SAGCYC(0644,
ade7753_read_8bit,
ade7753_write_8bit,
ADE7753_SAGCYC);
-static IIO_DEV_ATTR_SAGLVL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_SAGLVL(0644,
ade7753_read_8bit,
ade7753_write_8bit,
ADE7753_SAGLVL);
-static IIO_DEV_ATTR_LINECYC(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_LINECYC(0644,
ade7753_read_8bit,
ade7753_write_8bit,
ADE7753_LINECYC);
-static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_WDIV(0644,
ade7753_read_8bit,
ade7753_write_8bit,
ADE7753_WDIV);
-static IIO_DEV_ATTR_IRMS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_IRMS(0644,
ade7753_read_24bit,
NULL,
ADE7753_IRMS);
-static IIO_DEV_ATTR_VRMS(S_IRUGO,
+static IIO_DEV_ATTR_VRMS(0444,
ade7753_read_24bit,
NULL,
ADE7753_VRMS);
-static IIO_DEV_ATTR_IRMSOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_IRMSOS(0644,
ade7753_read_16bit,
ade7753_write_16bit,
ADE7753_IRMSOS);
-static IIO_DEV_ATTR_VRMSOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_VRMSOS(0644,
ade7753_read_16bit,
ade7753_write_16bit,
ADE7753_VRMSOS);
-static IIO_DEV_ATTR_WGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_WGAIN(0644,
ade7753_read_16bit,
ade7753_write_16bit,
ADE7753_WGAIN);
-static IIO_DEV_ATTR_VAGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_VAGAIN(0644,
ade7753_read_16bit,
ade7753_write_16bit,
ADE7753_VAGAIN);
-static IIO_DEV_ATTR_PGA_GAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_PGA_GAIN(0644,
ade7753_read_16bit,
ade7753_write_16bit,
ADE7753_GAIN);
-static IIO_DEV_ATTR_IPKLVL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_IPKLVL(0644,
ade7753_read_8bit,
ade7753_write_8bit,
ADE7753_IPKLVL);
-static IIO_DEV_ATTR_VPKLVL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_VPKLVL(0644,
ade7753_read_8bit,
ade7753_write_8bit,
ADE7753_VPKLVL);
-static IIO_DEV_ATTR_IPEAK(S_IRUGO,
+static IIO_DEV_ATTR_IPEAK(0444,
ade7753_read_24bit,
NULL,
ADE7753_IPEAK);
-static IIO_DEV_ATTR_VPEAK(S_IRUGO,
+static IIO_DEV_ATTR_VPEAK(0444,
ade7753_read_24bit,
NULL,
ADE7753_VPEAK);
-static IIO_DEV_ATTR_VPERIOD(S_IRUGO,
+static IIO_DEV_ATTR_VPERIOD(0444,
ade7753_read_16bit,
NULL,
ADE7753_PERIOD);
-static IIO_DEV_ATTR_CH_OFF(1, S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CH_OFF(1, 0644,
ade7753_read_8bit,
ade7753_write_8bit,
ADE7753_CH1OS);
-static IIO_DEV_ATTR_CH_OFF(2, S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CH_OFF(2, 0644,
ade7753_read_8bit,
ade7753_write_8bit,
ADE7753_CH2OS);
@@ -450,8 +449,8 @@ err_ret:
}
static ssize_t ade7753_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u16 t;
@@ -468,9 +467,9 @@ static ssize_t ade7753_read_frequency(struct device *dev,
}
static ssize_t ade7753_write_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7753_state *st = iio_priv(indio_dev);
@@ -514,7 +513,7 @@ static IIO_DEV_ATTR_TEMP_RAW(ade7753_read_8bit);
static IIO_CONST_ATTR(in_temp_offset, "-25 C");
static IIO_CONST_ATTR(in_temp_scale, "0.67 C");
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_SAMP_FREQ(0644,
ade7753_read_frequency,
ade7753_write_frequency);
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index 32dc50341746..be0df3fe4230 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -316,111 +316,111 @@ static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY);
static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY);
static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY);
static IIO_DEV_ATTR_LVAENERGY(ade7754_read_24bit, ADE7754_LVAENERGY);
-static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_VPEAK(0644,
ade7754_read_8bit,
ade7754_write_8bit,
ADE7754_VPEAK);
-static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_IPEAK(0644,
ade7754_read_8bit,
ade7754_write_8bit,
ADE7754_VPEAK);
-static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_APHCAL(0644,
ade7754_read_8bit,
ade7754_write_8bit,
ADE7754_APHCAL);
-static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_BPHCAL(0644,
ade7754_read_8bit,
ade7754_write_8bit,
ADE7754_BPHCAL);
-static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CPHCAL(0644,
ade7754_read_8bit,
ade7754_write_8bit,
ADE7754_CPHCAL);
-static IIO_DEV_ATTR_AAPOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_AAPOS(0644,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_AAPOS);
-static IIO_DEV_ATTR_BAPOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_BAPOS(0644,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_BAPOS);
-static IIO_DEV_ATTR_CAPOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CAPOS(0644,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_CAPOS);
-static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_WDIV(0644,
ade7754_read_8bit,
ade7754_write_8bit,
ADE7754_WDIV);
-static IIO_DEV_ATTR_VADIV(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_VADIV(0644,
ade7754_read_8bit,
ade7754_write_8bit,
ADE7754_VADIV);
-static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CFNUM(0644,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_CFNUM);
-static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CFDEN(0644,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_CFDEN);
-static IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(0644,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_AAPGAIN);
-static IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(0644,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_BAPGAIN);
-static IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(0644,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_CAPGAIN);
-static IIO_DEV_ATTR_AIRMS(S_IRUGO,
+static IIO_DEV_ATTR_AIRMS(0444,
ade7754_read_24bit,
NULL,
ADE7754_AIRMS);
-static IIO_DEV_ATTR_BIRMS(S_IRUGO,
+static IIO_DEV_ATTR_BIRMS(0444,
ade7754_read_24bit,
NULL,
ADE7754_BIRMS);
-static IIO_DEV_ATTR_CIRMS(S_IRUGO,
+static IIO_DEV_ATTR_CIRMS(0444,
ade7754_read_24bit,
NULL,
ADE7754_CIRMS);
-static IIO_DEV_ATTR_AVRMS(S_IRUGO,
+static IIO_DEV_ATTR_AVRMS(0444,
ade7754_read_24bit,
NULL,
ADE7754_AVRMS);
-static IIO_DEV_ATTR_BVRMS(S_IRUGO,
+static IIO_DEV_ATTR_BVRMS(0444,
ade7754_read_24bit,
NULL,
ADE7754_BVRMS);
-static IIO_DEV_ATTR_CVRMS(S_IRUGO,
+static IIO_DEV_ATTR_CVRMS(0444,
ade7754_read_24bit,
NULL,
ADE7754_CVRMS);
-static IIO_DEV_ATTR_AIRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_AIRMSOS(0444,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_AIRMSOS);
-static IIO_DEV_ATTR_BIRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_BIRMSOS(0444,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_BIRMSOS);
-static IIO_DEV_ATTR_CIRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_CIRMSOS(0444,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_CIRMSOS);
-static IIO_DEV_ATTR_AVRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_AVRMSOS(0444,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_AVRMSOS);
-static IIO_DEV_ATTR_BVRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_BVRMSOS(0444,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_BVRMSOS);
-static IIO_DEV_ATTR_CVRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_CVRMSOS(0444,
ade7754_read_16bit,
ade7754_write_16bit,
ADE7754_CVRMSOS);
@@ -549,7 +549,7 @@ static IIO_DEV_ATTR_TEMP_RAW(ade7754_read_8bit);
static IIO_CONST_ATTR(in_temp_offset, "129 C");
static IIO_CONST_ATTR(in_temp_scale, "4 C");
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_SAMP_FREQ(0644,
ade7754_read_frequency,
ade7754_write_frequency);
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 99c89e606c8d..40498af4dc46 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -301,103 +301,103 @@ static int ade7758_reset(struct device *dev)
return ret;
}
-static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_VPEAK(0644,
ade7758_read_8bit,
ade7758_write_8bit,
ADE7758_VPEAK);
-static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_IPEAK(0644,
ade7758_read_8bit,
ade7758_write_8bit,
ADE7758_VPEAK);
-static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_APHCAL(0644,
ade7758_read_8bit,
ade7758_write_8bit,
ADE7758_APHCAL);
-static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_BPHCAL(0644,
ade7758_read_8bit,
ade7758_write_8bit,
ADE7758_BPHCAL);
-static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CPHCAL(0644,
ade7758_read_8bit,
ade7758_write_8bit,
ADE7758_CPHCAL);
-static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_WDIV(0644,
ade7758_read_8bit,
ade7758_write_8bit,
ADE7758_WDIV);
-static IIO_DEV_ATTR_VADIV(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_VADIV(0644,
ade7758_read_8bit,
ade7758_write_8bit,
ADE7758_VADIV);
-static IIO_DEV_ATTR_AIRMS(S_IRUGO,
+static IIO_DEV_ATTR_AIRMS(0444,
ade7758_read_24bit,
NULL,
ADE7758_AIRMS);
-static IIO_DEV_ATTR_BIRMS(S_IRUGO,
+static IIO_DEV_ATTR_BIRMS(0444,
ade7758_read_24bit,
NULL,
ADE7758_BIRMS);
-static IIO_DEV_ATTR_CIRMS(S_IRUGO,
+static IIO_DEV_ATTR_CIRMS(0444,
ade7758_read_24bit,
NULL,
ADE7758_CIRMS);
-static IIO_DEV_ATTR_AVRMS(S_IRUGO,
+static IIO_DEV_ATTR_AVRMS(0444,
ade7758_read_24bit,
NULL,
ADE7758_AVRMS);
-static IIO_DEV_ATTR_BVRMS(S_IRUGO,
+static IIO_DEV_ATTR_BVRMS(0444,
ade7758_read_24bit,
NULL,
ADE7758_BVRMS);
-static IIO_DEV_ATTR_CVRMS(S_IRUGO,
+static IIO_DEV_ATTR_CVRMS(0444,
ade7758_read_24bit,
NULL,
ADE7758_CVRMS);
-static IIO_DEV_ATTR_AIRMSOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_AIRMSOS(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_AIRMSOS);
-static IIO_DEV_ATTR_BIRMSOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_BIRMSOS(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_BIRMSOS);
-static IIO_DEV_ATTR_CIRMSOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CIRMSOS(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_CIRMSOS);
-static IIO_DEV_ATTR_AVRMSOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_AVRMSOS(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_AVRMSOS);
-static IIO_DEV_ATTR_BVRMSOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_BVRMSOS(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_BVRMSOS);
-static IIO_DEV_ATTR_CVRMSOS(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CVRMSOS(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_CVRMSOS);
-static IIO_DEV_ATTR_AIGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_AIGAIN(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_AIGAIN);
-static IIO_DEV_ATTR_BIGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_BIGAIN(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_BIGAIN);
-static IIO_DEV_ATTR_CIGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CIGAIN(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_CIGAIN);
-static IIO_DEV_ATTR_AVRMSGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_AVRMSGAIN(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_AVRMSGAIN);
-static IIO_DEV_ATTR_BVRMSGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_BVRMSGAIN(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_BVRMSGAIN);
-static IIO_DEV_ATTR_CVRMSGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CVRMSGAIN(0644,
ade7758_read_16bit,
ade7758_write_16bit,
ADE7758_CVRMSGAIN);
diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c
index c6cffc11b0ba..70612da64a8b 100644
--- a/drivers/staging/iio/meter/ade7854.c
+++ b/drivers/staging/iio/meter/ade7854.c
@@ -186,127 +186,127 @@ static int ade7854_reset(struct device *dev)
return st->write_reg_16(dev, ADE7854_CONFIG, val);
}
-static IIO_DEV_ATTR_AIGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_AIGAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_AIGAIN);
-static IIO_DEV_ATTR_BIGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_BIGAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_BIGAIN);
-static IIO_DEV_ATTR_CIGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CIGAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_CIGAIN);
-static IIO_DEV_ATTR_NIGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_NIGAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_NIGAIN);
-static IIO_DEV_ATTR_AVGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_AVGAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_AVGAIN);
-static IIO_DEV_ATTR_BVGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_BVGAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_BVGAIN);
-static IIO_DEV_ATTR_CVGAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CVGAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_CVGAIN);
-static IIO_DEV_ATTR_APPARENT_POWER_A_GAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_APPARENT_POWER_A_GAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_AVAGAIN);
-static IIO_DEV_ATTR_APPARENT_POWER_B_GAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_APPARENT_POWER_B_GAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_BVAGAIN);
-static IIO_DEV_ATTR_APPARENT_POWER_C_GAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_APPARENT_POWER_C_GAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_CVAGAIN);
-static IIO_DEV_ATTR_ACTIVE_POWER_A_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACTIVE_POWER_A_OFFSET(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_AWATTOS);
-static IIO_DEV_ATTR_ACTIVE_POWER_B_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACTIVE_POWER_B_OFFSET(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_BWATTOS);
-static IIO_DEV_ATTR_ACTIVE_POWER_C_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_ACTIVE_POWER_C_OFFSET(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_CWATTOS);
-static IIO_DEV_ATTR_REACTIVE_POWER_A_GAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_REACTIVE_POWER_A_GAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_AVARGAIN);
-static IIO_DEV_ATTR_REACTIVE_POWER_B_GAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_REACTIVE_POWER_B_GAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_BVARGAIN);
-static IIO_DEV_ATTR_REACTIVE_POWER_C_GAIN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_REACTIVE_POWER_C_GAIN(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_CVARGAIN);
-static IIO_DEV_ATTR_REACTIVE_POWER_A_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_REACTIVE_POWER_A_OFFSET(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_AVAROS);
-static IIO_DEV_ATTR_REACTIVE_POWER_B_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_REACTIVE_POWER_B_OFFSET(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_BVAROS);
-static IIO_DEV_ATTR_REACTIVE_POWER_C_OFFSET(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_REACTIVE_POWER_C_OFFSET(0644,
ade7854_read_24bit,
ade7854_write_24bit,
ADE7854_CVAROS);
-static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_VPEAK(0644,
ade7854_read_32bit,
ade7854_write_32bit,
ADE7854_VPEAK);
-static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_IPEAK(0644,
ade7854_read_32bit,
ade7854_write_32bit,
ADE7854_VPEAK);
-static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_APHCAL(0644,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_APHCAL);
-static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_BPHCAL(0644,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_BPHCAL);
-static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CPHCAL(0644,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_CPHCAL);
-static IIO_DEV_ATTR_CF1DEN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CF1DEN(0644,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_CF1DEN);
-static IIO_DEV_ATTR_CF2DEN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CF2DEN(0644,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_CF2DEN);
-static IIO_DEV_ATTR_CF3DEN(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CF3DEN(0644,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_CF3DEN);
-static IIO_DEV_ATTR_LINECYC(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_LINECYC(0644,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_LINECYC);
-static IIO_DEV_ATTR_SAGCYC(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_SAGCYC(0644,
ade7854_read_8bit,
ade7854_write_8bit,
ADE7854_SAGCYC);
-static IIO_DEV_ATTR_CFCYC(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_CFCYC(0644,
ade7854_read_8bit,
ade7854_write_8bit,
ADE7854_CFCYC);
-static IIO_DEV_ATTR_PEAKCYC(S_IWUSR | S_IRUGO,
+static IIO_DEV_ATTR_PEAKCYC(0644,
ade7854_read_8bit,
ade7854_write_8bit,
ADE7854_PEAKCYC);
@@ -318,55 +318,55 @@ static IIO_DEV_ATTR_ANGLE1(ade7854_read_24bit,
ADE7854_ANGLE1);
static IIO_DEV_ATTR_ANGLE2(ade7854_read_24bit,
ADE7854_ANGLE2);
-static IIO_DEV_ATTR_AIRMS(S_IRUGO,
+static IIO_DEV_ATTR_AIRMS(0444,
ade7854_read_24bit,
NULL,
ADE7854_AIRMS);
-static IIO_DEV_ATTR_BIRMS(S_IRUGO,
+static IIO_DEV_ATTR_BIRMS(0444,
ade7854_read_24bit,
NULL,
ADE7854_BIRMS);
-static IIO_DEV_ATTR_CIRMS(S_IRUGO,
+static IIO_DEV_ATTR_CIRMS(0444,
ade7854_read_24bit,
NULL,
ADE7854_CIRMS);
-static IIO_DEV_ATTR_NIRMS(S_IRUGO,
+static IIO_DEV_ATTR_NIRMS(0444,
ade7854_read_24bit,
NULL,
ADE7854_NIRMS);
-static IIO_DEV_ATTR_AVRMS(S_IRUGO,
+static IIO_DEV_ATTR_AVRMS(0444,
ade7854_read_24bit,
NULL,
ADE7854_AVRMS);
-static IIO_DEV_ATTR_BVRMS(S_IRUGO,
+static IIO_DEV_ATTR_BVRMS(0444,
ade7854_read_24bit,
NULL,
ADE7854_BVRMS);
-static IIO_DEV_ATTR_CVRMS(S_IRUGO,
+static IIO_DEV_ATTR_CVRMS(0444,
ade7854_read_24bit,
NULL,
ADE7854_CVRMS);
-static IIO_DEV_ATTR_AIRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_AIRMSOS(0444,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_AIRMSOS);
-static IIO_DEV_ATTR_BIRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_BIRMSOS(0444,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_BIRMSOS);
-static IIO_DEV_ATTR_CIRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_CIRMSOS(0444,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_CIRMSOS);
-static IIO_DEV_ATTR_AVRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_AVRMSOS(0444,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_AVRMSOS);
-static IIO_DEV_ATTR_BVRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_BVRMSOS(0444,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_BVRMSOS);
-static IIO_DEV_ATTR_CVRMSOS(S_IRUGO,
+static IIO_DEV_ATTR_CVRMSOS(0444,
ade7854_read_16bit,
ade7854_write_16bit,
ADE7854_CVRMSOS);
diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h
index f32d7c392c1e..fc7aae64dcde 100644
--- a/include/linux/hid-sensor-hub.h
+++ b/include/linux/hid-sensor-hub.h
@@ -233,12 +233,14 @@ struct hid_sensor_common {
atomic_t user_requested_state;
int poll_interval;
int raw_hystersis;
+ int latency_ms;
struct iio_trigger *trigger;
int timestamp_ns_scale;
struct hid_sensor_hub_attribute_info poll;
struct hid_sensor_hub_attribute_info report_state;
struct hid_sensor_hub_attribute_info power_state;
struct hid_sensor_hub_attribute_info sensitivity;
+ struct hid_sensor_hub_attribute_info report_latency;
struct work_struct work;
};
@@ -276,5 +278,8 @@ s32 hid_sensor_read_poll_value(struct hid_sensor_common *st);
int64_t hid_sensor_convert_timestamp(struct hid_sensor_common *st,
int64_t raw_value);
+bool hid_sensor_batch_mode_supported(struct hid_sensor_common *st);
+int hid_sensor_set_report_latency(struct hid_sensor_common *st, int latency);
+int hid_sensor_get_report_latency(struct hid_sensor_common *st);
#endif
diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h
index 761f86242473..76033e0420a7 100644
--- a/include/linux/hid-sensor-ids.h
+++ b/include/linux/hid-sensor-ids.h
@@ -90,6 +90,8 @@
#define HID_USAGE_SENSOR_ORIENT_TILT_Z 0x200481
#define HID_USAGE_SENSOR_DEVICE_ORIENTATION 0x20008A
+#define HID_USAGE_SENSOR_RELATIVE_ORIENTATION 0x20008E
+#define HID_USAGE_SENSOR_GEOMAGNETIC_ORIENTATION 0x2000C1
#define HID_USAGE_SENSOR_ORIENT_ROTATION_MATRIX 0x200482
#define HID_USAGE_SENSOR_ORIENT_QUATERNION 0x200483
#define HID_USAGE_SENSOR_ORIENT_MAGN_FLUX 0x200484
@@ -150,6 +152,9 @@
#define HID_USAGE_SENSOR_PROP_REPORT_STATE 0x200316
#define HID_USAGE_SENSOR_PROY_POWER_STATE 0x200319
+/* Batch mode selectors */
+#define HID_USAGE_SENSOR_PROP_REPORT_LATENCY 0x20031B
+
/* Per data field properties */
#define HID_USAGE_SENSOR_DATA_MOD_NONE 0x00
#define HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS 0x1000
diff --git a/include/linux/iio/timer/stm32-timer-trigger.h b/include/linux/iio/timer/stm32-timer-trigger.h
index 55535aef2e6c..fa7d786ed99e 100644
--- a/include/linux/iio/timer/stm32-timer-trigger.h
+++ b/include/linux/iio/timer/stm32-timer-trigger.h
@@ -10,6 +10,7 @@
#define _STM32_TIMER_TRIGGER_H_
#define TIM1_TRGO "tim1_trgo"
+#define TIM1_TRGO2 "tim1_trgo2"
#define TIM1_CH1 "tim1_ch1"
#define TIM1_CH2 "tim1_ch2"
#define TIM1_CH3 "tim1_ch3"
@@ -44,6 +45,7 @@
#define TIM7_TRGO "tim7_trgo"
#define TIM8_TRGO "tim8_trgo"
+#define TIM8_TRGO2 "tim8_trgo2"
#define TIM8_CH1 "tim8_ch1"
#define TIM8_CH2 "tim8_ch2"
#define TIM8_CH3 "tim8_ch3"
diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h
index 4a0abbc10ef6..ce7346e7f77a 100644
--- a/include/linux/mfd/stm32-timers.h
+++ b/include/linux/mfd/stm32-timers.h
@@ -34,6 +34,7 @@
#define TIM_CR1_DIR BIT(4) /* Counter Direction */
#define TIM_CR1_ARPE BIT(7) /* Auto-reload Preload Ena */
#define TIM_CR2_MMS (BIT(4) | BIT(5) | BIT(6)) /* Master mode selection */
+#define TIM_CR2_MMS2 GENMASK(23, 20) /* Master mode selection 2 */
#define TIM_SMCR_SMS (BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */
#define TIM_SMCR_TS (BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */
#define TIM_DIER_UIE BIT(0) /* Update interrupt */
@@ -60,6 +61,7 @@
#define MAX_TIM_PSC 0xFFFF
#define TIM_CR2_MMS_SHIFT 4
+#define TIM_CR2_MMS2_SHIFT 20
#define TIM_SMCR_TS_SHIFT 4
#define TIM_BDTR_BKF_MASK 0xF
#define TIM_BDTR_BKF_SHIFT 16
diff --git a/tools/iio/Makefile b/tools/iio/Makefile
index 5446d625e17d..8f08e03a9a5e 100644
--- a/tools/iio/Makefile
+++ b/tools/iio/Makefile
@@ -1,5 +1,5 @@
CC = $(CROSS_COMPILE)gcc
-CFLAGS += -Wall -g -D_GNU_SOURCE
+CFLAGS += -Wall -g -D_GNU_SOURCE -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include
BINDIR=usr/bin
INSTALL_PROGRAM=install -m 755 -p
diff --git a/tools/iio/iio_utils.h b/tools/iio/iio_utils.h
index 780f2014f8fa..8b379da26e35 100644
--- a/tools/iio/iio_utils.h
+++ b/tools/iio/iio_utils.h
@@ -13,7 +13,7 @@
#include <stdint.h>
/* Made up value to limit allocation sizes */
-#define IIO_MAX_NAME_LENGTH 30
+#define IIO_MAX_NAME_LENGTH 64
#define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements"
#define FORMAT_TYPE_FILE "%s_type"