summaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/accel/bmc150-accel-core.c6
-rw-r--r--drivers/iio/accel/hid-sensor-accel-3d.c2
-rw-r--r--drivers/iio/adc/axp20x_adc.c8
-rw-r--r--drivers/iio/chemical/ccs811.c6
-rw-r--r--drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c1
-rw-r--r--drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c49
-rw-r--r--drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.h2
-rw-r--r--drivers/iio/dac/ad5380.c2
-rw-r--r--drivers/iio/dac/ad5764.c2
-rw-r--r--drivers/iio/dummy/Kconfig27
-rw-r--r--drivers/iio/gyro/hid-sensor-gyro-3d.c2
-rw-r--r--drivers/iio/light/Kconfig10
-rw-r--r--drivers/iio/light/Makefile1
-rw-r--r--drivers/iio/light/cros_ec_light_prox.c1
-rw-r--r--drivers/iio/light/hid-sensor-als.c2
-rw-r--r--drivers/iio/light/lm3533-als.c2
-rw-r--r--drivers/iio/light/lv0104cs.c531
-rw-r--r--drivers/iio/magnetometer/hid-sensor-magn-3d.c2
-rw-r--r--drivers/iio/potentiometer/Kconfig11
-rw-r--r--drivers/iio/potentiometer/Makefile1
-rw-r--r--drivers/iio/potentiometer/ds1803.c2
-rw-r--r--drivers/iio/potentiometer/mcp4018.c194
-rw-r--r--drivers/iio/proximity/sx9500.c25
-rw-r--r--drivers/iio/temperature/mlx90632.c2
24 files changed, 857 insertions, 34 deletions
diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c
index 870f92ef61c2..208f2d9f0e8a 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -336,8 +336,7 @@ static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
return ret;
}
- dev_dbg(dev, "%s: %x %x\n", __func__, data->slope_thres,
- data->slope_dur);
+ dev_dbg(dev, "%x %x\n", data->slope_thres, data->slope_dur);
return ret;
}
@@ -1716,7 +1715,6 @@ static int bmc150_accel_runtime_suspend(struct device *dev)
struct bmc150_accel_data *data = iio_priv(indio_dev);
int ret;
- dev_dbg(dev, __func__);
ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0);
if (ret < 0)
return -EAGAIN;
@@ -1731,8 +1729,6 @@ static int bmc150_accel_runtime_resume(struct device *dev)
int ret;
int sleep_val;
- dev_dbg(dev, __func__);
-
ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
if (ret < 0)
return ret;
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index c066a3bdbff7..41d97faf5013 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -155,7 +155,7 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,
*val = 0;
*val2 = 0;
switch (mask) {
- case 0:
+ case IIO_CHAN_INFO_RAW:
hid_sensor_power_state(&accel_state->common_attributes, true);
report_id = accel_state->accel[chan->scan_index].report_id;
address = accel_3d_addresses[chan->scan_index];
diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c
index 7cdb8bc8cde6..5be789269353 100644
--- a/drivers/iio/adc/axp20x_adc.c
+++ b/drivers/iio/adc/axp20x_adc.c
@@ -445,7 +445,7 @@ static int axp20x_adc_offset_voltage(struct iio_dev *indio_dev, int channel,
return -EINVAL;
}
- *val = !!(*val) * 700000;
+ *val = *val ? 700000 : 0;
return IIO_VAL_INT;
}
@@ -542,15 +542,17 @@ static int axp20x_write_raw(struct iio_dev *indio_dev,
if (val != 0 && val != 700000)
return -EINVAL;
+ val = val ? 1 : 0;
+
switch (chan->channel) {
case AXP20X_GPIO0_V:
reg = AXP20X_GPIO10_IN_RANGE_GPIO0;
- regval = AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(!!val);
+ regval = AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(val);
break;
case AXP20X_GPIO1_V:
reg = AXP20X_GPIO10_IN_RANGE_GPIO1;
- regval = AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(!!val);
+ regval = AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(val);
break;
default:
diff --git a/drivers/iio/chemical/ccs811.c b/drivers/iio/chemical/ccs811.c
index cfaf86b248d9..e092ffe1431e 100644
--- a/drivers/iio/chemical/ccs811.c
+++ b/drivers/iio/chemical/ccs811.c
@@ -69,7 +69,7 @@ struct ccs811_reading {
__be16 voc;
u8 status;
u8 error;
- __be16 resistance;
+ __be16 raw_data;
} __attribute__((__packed__));
struct ccs811_data {
@@ -210,12 +210,12 @@ static int ccs811_read_raw(struct iio_dev *indio_dev,
switch (chan->type) {
case IIO_VOLTAGE:
- *val = be16_to_cpu(data->buffer.resistance) &
+ *val = be16_to_cpu(data->buffer.raw_data) &
CCS811_VOLTAGE_MASK;
ret = IIO_VAL_INT;
break;
case IIO_CURRENT:
- *val = be16_to_cpu(data->buffer.resistance) >> 10;
+ *val = be16_to_cpu(data->buffer.raw_data) >> 10;
ret = IIO_VAL_INT;
break;
case IIO_CONCENTRATION:
diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
index 7d30c59da3e2..705cb3e72663 100644
--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
@@ -289,6 +289,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_sensors_ids);
static struct platform_driver cros_ec_sensors_platform_driver = {
.driver = {
.name = "cros-ec-sensors",
+ .pm = &cros_ec_sensors_pm_ops,
},
.probe = cros_ec_sensors_probe,
.id_table = cros_ec_sensors_ids,
diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
index 416cae5ebbd0..a620eb5ce202 100644
--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
@@ -446,5 +446,54 @@ int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
}
EXPORT_SYMBOL_GPL(cros_ec_sensors_core_write);
+static int __maybe_unused cros_ec_sensors_prepare(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
+
+ if (st->curr_sampl_freq == 0)
+ return 0;
+
+ /*
+ * If the sensors are sampled at high frequency, we will not be able to
+ * sleep. Set sampling to a long period if necessary.
+ */
+ if (st->curr_sampl_freq < CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY) {
+ mutex_lock(&st->cmd_lock);
+ st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
+ st->param.ec_rate.data = CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY;
+ cros_ec_motion_send_host_cmd(st, 0);
+ mutex_unlock(&st->cmd_lock);
+ }
+ return 0;
+}
+
+static void __maybe_unused cros_ec_sensors_complete(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
+
+ if (st->curr_sampl_freq == 0)
+ return;
+
+ if (st->curr_sampl_freq < CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY) {
+ mutex_lock(&st->cmd_lock);
+ st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
+ st->param.ec_rate.data = st->curr_sampl_freq;
+ cros_ec_motion_send_host_cmd(st, 0);
+ mutex_unlock(&st->cmd_lock);
+ }
+}
+
+const struct dev_pm_ops cros_ec_sensors_pm_ops = {
+#ifdef CONFIG_PM_SLEEP
+ .prepare = cros_ec_sensors_prepare,
+ .complete = cros_ec_sensors_complete
+#endif
+};
+EXPORT_SYMBOL_GPL(cros_ec_sensors_pm_ops);
+
MODULE_DESCRIPTION("ChromeOS EC sensor hub core functions");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.h b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.h
index 8bc2ca3c2e2e..2edf68dc7336 100644
--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.h
+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.h
@@ -169,6 +169,8 @@ int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
struct iio_chan_spec const *chan,
int val, int val2, long mask);
+extern const struct dev_pm_ops cros_ec_sensors_pm_ops;
+
/* List of extended channel specification for all sensors */
extern const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[];
diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c
index 845fd1c0fd9d..873c2bf637c0 100644
--- a/drivers/iio/dac/ad5380.c
+++ b/drivers/iio/dac/ad5380.c
@@ -158,7 +158,7 @@ static unsigned int ad5380_info_to_reg(struct iio_chan_spec const *chan,
long info)
{
switch (info) {
- case 0:
+ case IIO_CHAN_INFO_RAW:
return AD5380_REG_DATA(chan->address);
case IIO_CHAN_INFO_CALIBBIAS:
return AD5380_REG_OFFSET(chan->address);
diff --git a/drivers/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c
index 033f20eca616..9333177062c0 100644
--- a/drivers/iio/dac/ad5764.c
+++ b/drivers/iio/dac/ad5764.c
@@ -168,7 +168,7 @@ static int ad5764_read(struct iio_dev *indio_dev, unsigned int reg,
static int ad5764_chan_info_to_reg(struct iio_chan_spec const *chan, long info)
{
switch (info) {
- case 0:
+ case IIO_CHAN_INFO_RAW:
return AD5764_REG_DATA(chan->address);
case IIO_CHAN_INFO_CALIBBIAS:
return AD5764_REG_OFFSET(chan->address);
diff --git a/drivers/iio/dummy/Kconfig b/drivers/iio/dummy/Kconfig
index 5a29fbd3c531..c4fd108e91d3 100644
--- a/drivers/iio/dummy/Kconfig
+++ b/drivers/iio/dummy/Kconfig
@@ -9,20 +9,24 @@ config IIO_DUMMY_EVGEN
tristate
config IIO_SIMPLE_DUMMY
- tristate "An example driver with no hardware requirements"
- depends on IIO_SW_DEVICE
- help
- Driver intended mainly as documentation for how to write
- a driver. May also be useful for testing userspace code
- without hardware.
+ tristate "An example driver with no hardware requirements"
+ depends on IIO_SW_DEVICE
+ help
+ Driver intended mainly as documentation for how to write
+ a driver. May also be useful for testing userspace code
+ without hardware.
if IIO_SIMPLE_DUMMY
config IIO_SIMPLE_DUMMY_EVENTS
- bool "Event generation support"
- select IIO_DUMMY_EVGEN
- help
- Add some dummy events to the simple dummy driver.
+ bool "Event generation support"
+ select IIO_DUMMY_EVGEN
+ help
+ Add some dummy events to the simple dummy driver.
+
+ The purpose of this is to generate 'fake' event interrupts thus
+ allowing that driver's code to be as close as possible to that
+ a normal driver talking to hardware.
config IIO_SIMPLE_DUMMY_BUFFER
bool "Buffered capture support"
@@ -32,6 +36,9 @@ config IIO_SIMPLE_DUMMY_BUFFER
help
Add buffered data capture to the simple dummy driver.
+ Buffer handling elements of industrial I/O reference driver.
+ Uses the kfifo buffer.
+
endif # IIO_SIMPLE_DUMMY
endmenu
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index f59995a90387..36941e69f959 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -115,7 +115,7 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev,
*val = 0;
*val2 = 0;
switch (mask) {
- case 0:
+ case IIO_CHAN_INFO_RAW:
hid_sensor_power_state(&gyro_state->common_attributes, true);
report_id = gyro_state->gyro[chan->scan_index].report_id;
address = gyro_3d_addresses[chan->scan_index];
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index 93fd421b10d7..074e50657366 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -275,6 +275,16 @@ config LTR501
This driver can also be built as a module. If so, the module
will be called ltr501.
+config LV0104CS
+ tristate "LV0104CS Ambient Light Sensor"
+ depends on I2C
+ help
+ Say Y here if you want to build support for the On Semiconductor
+ LV0104CS ambient light sensor.
+
+ To compile this driver as a module, choose M here:
+ the module will be called lv0104cs.
+
config MAX44000
tristate "MAX44000 Ambient and Infrared Proximity Sensor"
depends on I2C
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index f714067a7816..f1777036d4f8 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_ISL29125) += isl29125.o
obj-$(CONFIG_JSA1212) += jsa1212.o
obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
obj-$(CONFIG_LTR501) += ltr501.o
+obj-$(CONFIG_LV0104CS) += lv0104cs.o
obj-$(CONFIG_MAX44000) += max44000.o
obj-$(CONFIG_OPT3001) += opt3001.o
obj-$(CONFIG_PA12203001) += pa12203001.o
diff --git a/drivers/iio/light/cros_ec_light_prox.c b/drivers/iio/light/cros_ec_light_prox.c
index acfad4aeb27a..8e8a0e7f78d1 100644
--- a/drivers/iio/light/cros_ec_light_prox.c
+++ b/drivers/iio/light/cros_ec_light_prox.c
@@ -276,6 +276,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_light_prox_ids);
static struct platform_driver cros_ec_light_prox_platform_driver = {
.driver = {
.name = "cros-ec-light-prox",
+ .pm = &cros_ec_sensors_pm_ops,
},
.probe = cros_ec_light_prox_probe,
.id_table = cros_ec_light_prox_ids,
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index befd693a4a31..406caaee9a3c 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -97,7 +97,7 @@ static int als_read_raw(struct iio_dev *indio_dev,
*val = 0;
*val2 = 0;
switch (mask) {
- case 0:
+ case IIO_CHAN_INFO_RAW:
switch (chan->scan_index) {
case CHANNEL_SCAN_INDEX_INTENSITY:
case CHANNEL_SCAN_INDEX_ILLUM:
diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c
index 36208a3652e9..ff5a3324b489 100644
--- a/drivers/iio/light/lm3533-als.c
+++ b/drivers/iio/light/lm3533-als.c
@@ -199,7 +199,7 @@ static int lm3533_als_read_raw(struct iio_dev *indio_dev,
int ret;
switch (mask) {
- case 0:
+ case IIO_CHAN_INFO_RAW:
switch (chan->type) {
case IIO_LIGHT:
ret = lm3533_als_get_adc(indio_dev, false, val);
diff --git a/drivers/iio/light/lv0104cs.c b/drivers/iio/light/lv0104cs.c
new file mode 100644
index 000000000000..55b8e2855647
--- /dev/null
+++ b/drivers/iio/light/lv0104cs.c
@@ -0,0 +1,531 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * lv0104cs.c: LV0104CS Ambient Light Sensor Driver
+ *
+ * Copyright (C) 2018
+ * Author: Jeff LaBundy <jeff@labundy.com>
+ *
+ * 7-bit I2C slave address: 0x13
+ *
+ * Link to data sheet: http://www.onsemi.com/pub/Collateral/LV0104CS-D.PDF
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define LV0104CS_REGVAL_MEASURE 0xE0
+#define LV0104CS_REGVAL_SLEEP 0x00
+
+#define LV0104CS_SCALE_0_25X 0
+#define LV0104CS_SCALE_1X 1
+#define LV0104CS_SCALE_2X 2
+#define LV0104CS_SCALE_8X 3
+#define LV0104CS_SCALE_SHIFT 3
+
+#define LV0104CS_INTEG_12_5MS 0
+#define LV0104CS_INTEG_100MS 1
+#define LV0104CS_INTEG_200MS 2
+#define LV0104CS_INTEG_SHIFT 1
+
+#define LV0104CS_CALIBSCALE_UNITY 31
+
+struct lv0104cs_private {
+ struct i2c_client *client;
+ struct mutex lock;
+ u8 calibscale;
+ u8 scale;
+ u8 int_time;
+};
+
+struct lv0104cs_mapping {
+ int val;
+ int val2;
+ u8 regval;
+};
+
+static const struct lv0104cs_mapping lv0104cs_calibscales[] = {
+ { 0, 666666, 0x81 },
+ { 0, 800000, 0x82 },
+ { 0, 857142, 0x83 },
+ { 0, 888888, 0x84 },
+ { 0, 909090, 0x85 },
+ { 0, 923076, 0x86 },
+ { 0, 933333, 0x87 },
+ { 0, 941176, 0x88 },
+ { 0, 947368, 0x89 },
+ { 0, 952380, 0x8A },
+ { 0, 956521, 0x8B },
+ { 0, 960000, 0x8C },
+ { 0, 962962, 0x8D },
+ { 0, 965517, 0x8E },
+ { 0, 967741, 0x8F },
+ { 0, 969696, 0x90 },
+ { 0, 971428, 0x91 },
+ { 0, 972972, 0x92 },
+ { 0, 974358, 0x93 },
+ { 0, 975609, 0x94 },
+ { 0, 976744, 0x95 },
+ { 0, 977777, 0x96 },
+ { 0, 978723, 0x97 },
+ { 0, 979591, 0x98 },
+ { 0, 980392, 0x99 },
+ { 0, 981132, 0x9A },
+ { 0, 981818, 0x9B },
+ { 0, 982456, 0x9C },
+ { 0, 983050, 0x9D },
+ { 0, 983606, 0x9E },
+ { 0, 984126, 0x9F },
+ { 1, 0, 0x80 },
+ { 1, 16129, 0xBF },
+ { 1, 16666, 0xBE },
+ { 1, 17241, 0xBD },
+ { 1, 17857, 0xBC },
+ { 1, 18518, 0xBB },
+ { 1, 19230, 0xBA },
+ { 1, 20000, 0xB9 },
+ { 1, 20833, 0xB8 },
+ { 1, 21739, 0xB7 },
+ { 1, 22727, 0xB6 },
+ { 1, 23809, 0xB5 },
+ { 1, 24999, 0xB4 },
+ { 1, 26315, 0xB3 },
+ { 1, 27777, 0xB2 },
+ { 1, 29411, 0xB1 },
+ { 1, 31250, 0xB0 },
+ { 1, 33333, 0xAF },
+ { 1, 35714, 0xAE },
+ { 1, 38461, 0xAD },
+ { 1, 41666, 0xAC },
+ { 1, 45454, 0xAB },
+ { 1, 50000, 0xAA },
+ { 1, 55555, 0xA9 },
+ { 1, 62500, 0xA8 },
+ { 1, 71428, 0xA7 },
+ { 1, 83333, 0xA6 },
+ { 1, 100000, 0xA5 },
+ { 1, 125000, 0xA4 },
+ { 1, 166666, 0xA3 },
+ { 1, 250000, 0xA2 },
+ { 1, 500000, 0xA1 },
+};
+
+static const struct lv0104cs_mapping lv0104cs_scales[] = {
+ { 0, 250000, LV0104CS_SCALE_0_25X << LV0104CS_SCALE_SHIFT },
+ { 1, 0, LV0104CS_SCALE_1X << LV0104CS_SCALE_SHIFT },
+ { 2, 0, LV0104CS_SCALE_2X << LV0104CS_SCALE_SHIFT },
+ { 8, 0, LV0104CS_SCALE_8X << LV0104CS_SCALE_SHIFT },
+};
+
+static const struct lv0104cs_mapping lv0104cs_int_times[] = {
+ { 0, 12500, LV0104CS_INTEG_12_5MS << LV0104CS_INTEG_SHIFT },
+ { 0, 100000, LV0104CS_INTEG_100MS << LV0104CS_INTEG_SHIFT },
+ { 0, 200000, LV0104CS_INTEG_200MS << LV0104CS_INTEG_SHIFT },
+};
+
+static int lv0104cs_write_reg(struct i2c_client *client, u8 regval)
+{
+ int ret;
+
+ ret = i2c_master_send(client, (char *)&regval, sizeof(regval));
+ if (ret < 0)
+ return ret;
+ if (ret != sizeof(regval))
+ return -EIO;
+
+ return 0;
+}
+
+static int lv0104cs_read_adc(struct i2c_client *client, u16 *adc_output)
+{
+ __be16 regval;
+ int ret;
+
+ ret = i2c_master_recv(client, (char *)&regval, sizeof(regval));
+ if (ret < 0)
+ return ret;
+ if (ret != sizeof(regval))
+ return -EIO;
+
+ *adc_output = be16_to_cpu(regval);
+
+ return 0;
+}
+
+static int lv0104cs_get_lux(struct lv0104cs_private *lv0104cs,
+ int *val, int *val2)
+{
+ u8 regval = LV0104CS_REGVAL_MEASURE;
+ u16 adc_output;
+ int ret;
+
+ regval |= lv0104cs_scales[lv0104cs->scale].regval;
+ regval |= lv0104cs_int_times[lv0104cs->int_time].regval;
+ ret = lv0104cs_write_reg(lv0104cs->client, regval);
+ if (ret)
+ return ret;
+
+ /* wait for integration time to pass (with margin) */
+ switch (lv0104cs->int_time) {
+ case LV0104CS_INTEG_12_5MS:
+ msleep(50);
+ break;
+
+ case LV0104CS_INTEG_100MS:
+ msleep(150);
+ break;
+
+ case LV0104CS_INTEG_200MS:
+ msleep(250);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ ret = lv0104cs_read_adc(lv0104cs->client, &adc_output);
+ if (ret)
+ return ret;
+
+ ret = lv0104cs_write_reg(lv0104cs->client, LV0104CS_REGVAL_SLEEP);
+ if (ret)
+ return ret;
+
+ /* convert ADC output to lux */
+ switch (lv0104cs->scale) {
+ case LV0104CS_SCALE_0_25X:
+ *val = adc_output * 4;
+ *val2 = 0;
+ return 0;
+
+ case LV0104CS_SCALE_1X:
+ *val = adc_output;
+ *val2 = 0;
+ return 0;
+
+ case LV0104CS_SCALE_2X:
+ *val = adc_output / 2;
+ *val2 = (adc_output % 2) * 500000;
+ return 0;
+
+ case LV0104CS_SCALE_8X:
+ *val = adc_output / 8;
+ *val2 = (adc_output % 8) * 125000;
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int lv0104cs_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct lv0104cs_private *lv0104cs = iio_priv(indio_dev);
+ int ret;
+
+ if (chan->type != IIO_LIGHT)
+ return -EINVAL;
+
+ mutex_lock(&lv0104cs->lock);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_PROCESSED:
+ ret = lv0104cs_get_lux(lv0104cs, val, val2);
+ if (ret)
+ goto err_mutex;
+ ret = IIO_VAL_INT_PLUS_MICRO;
+ break;
+
+ case IIO_CHAN_INFO_CALIBSCALE:
+ *val = lv0104cs_calibscales[lv0104cs->calibscale].val;
+ *val2 = lv0104cs_calibscales[lv0104cs->calibscale].val2;
+ ret = IIO_VAL_INT_PLUS_MICRO;
+ break;
+
+ case IIO_CHAN_INFO_SCALE:
+ *val = lv0104cs_scales[lv0104cs->scale].val;
+ *val2 = lv0104cs_scales[lv0104cs->scale].val2;
+ ret = IIO_VAL_INT_PLUS_MICRO;
+ break;
+
+ case IIO_CHAN_INFO_INT_TIME:
+ *val = lv0104cs_int_times[lv0104cs->int_time].val;
+ *val2 = lv0104cs_int_times[lv0104cs->int_time].val2;
+ ret = IIO_VAL_INT_PLUS_MICRO;
+ break;
+
+ default:
+ ret = -EINVAL;
+ }
+
+err_mutex:
+ mutex_unlock(&lv0104cs->lock);
+
+ return ret;
+}
+
+static int lv0104cs_set_calibscale(struct lv0104cs_private *lv0104cs,
+ int val, int val2)
+{
+ int calibscale = val * 1000000 + val2;
+ int floor, ceil, mid;
+ int ret, i, index;
+
+ /* round to nearest quantized calibscale (sensitivity) */
+ for (i = 0; i < ARRAY_SIZE(lv0104cs_calibscales) - 1; i++) {
+ floor = lv0104cs_calibscales[i].val * 1000000
+ + lv0104cs_calibscales[i].val2;
+ ceil = lv0104cs_calibscales[i + 1].val * 1000000
+ + lv0104cs_calibscales[i + 1].val2;
+ mid = (floor + ceil) / 2;
+
+ /* round down */
+ if (calibscale >= floor && calibscale < mid) {
+ index = i;
+ break;
+ }
+
+ /* round up */
+ if (calibscale >= mid && calibscale <= ceil) {
+ index = i + 1;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(lv0104cs_calibscales) - 1)
+ return -EINVAL;
+
+ mutex_lock(&lv0104cs->lock);
+
+ /* set calibscale (sensitivity) */
+ ret = lv0104cs_write_reg(lv0104cs->client,
+ lv0104cs_calibscales[index].regval);
+ if (ret)
+ goto err_mutex;
+
+ lv0104cs->calibscale = index;
+
+err_mutex:
+ mutex_unlock(&lv0104cs->lock);
+
+ return ret;
+}
+
+static int lv0104cs_set_scale(struct lv0104cs_private *lv0104cs,
+ int val, int val2)
+{
+ int i;
+
+ /* hard matching */
+ for (i = 0; i < ARRAY_SIZE(lv0104cs_scales); i++) {
+ if (val != lv0104cs_scales[i].val)
+ continue;
+
+ if (val2 == lv0104cs_scales[i].val2)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(lv0104cs_scales))
+ return -EINVAL;
+
+ mutex_lock(&lv0104cs->lock);
+ lv0104cs->scale = i;
+ mutex_unlock(&lv0104cs->lock);
+
+ return 0;
+}
+
+static int lv0104cs_set_int_time(struct lv0104cs_private *lv0104cs,
+ int val, int val2)
+{
+ int i;
+
+ /* hard matching */
+ for (i = 0; i < ARRAY_SIZE(lv0104cs_int_times); i++) {
+ if (val != lv0104cs_int_times[i].val)
+ continue;
+
+ if (val2 == lv0104cs_int_times[i].val2)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(lv0104cs_int_times))
+ return -EINVAL;
+
+ mutex_lock(&lv0104cs->lock);
+ lv0104cs->int_time = i;
+ mutex_unlock(&lv0104cs->lock);
+
+ return 0;
+}
+
+static int lv0104cs_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct lv0104cs_private *lv0104cs = iio_priv(indio_dev);
+
+ if (chan->type != IIO_LIGHT)
+ return -EINVAL;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_CALIBSCALE:
+ return lv0104cs_set_calibscale(lv0104cs, val, val2);
+
+ case IIO_CHAN_INFO_SCALE:
+ return lv0104cs_set_scale(lv0104cs, val, val2);
+
+ case IIO_CHAN_INFO_INT_TIME:
+ return lv0104cs_set_int_time(lv0104cs, val, val2);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static ssize_t lv0104cs_show_calibscale_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t len = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(lv0104cs_calibscales); i++) {
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
+ lv0104cs_calibscales[i].val,
+ lv0104cs_calibscales[i].val2);
+ }
+
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static ssize_t lv0104cs_show_scale_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t len = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(lv0104cs_scales); i++) {
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
+ lv0104cs_scales[i].val,
+ lv0104cs_scales[i].val2);
+ }
+
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static ssize_t lv0104cs_show_int_time_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t len = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(lv0104cs_int_times); i++) {
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
+ lv0104cs_int_times[i].val,
+ lv0104cs_int_times[i].val2);
+ }
+
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(calibscale_available, 0444,
+ lv0104cs_show_calibscale_avail, NULL, 0);
+static IIO_DEVICE_ATTR(scale_available, 0444,
+ lv0104cs_show_scale_avail, NULL, 0);
+static IIO_DEV_ATTR_INT_TIME_AVAIL(lv0104cs_show_int_time_avail);
+
+static struct attribute *lv0104cs_attributes[] = {
+ &iio_dev_attr_calibscale_available.dev_attr.attr,
+ &iio_dev_attr_scale_available.dev_attr.attr,
+ &iio_dev_attr_integration_time_available.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group lv0104cs_attribute_group = {
+ .attrs = lv0104cs_attributes,
+};
+
+static const struct iio_info lv0104cs_info = {
+ .attrs = &lv0104cs_attribute_group,
+ .read_raw = &lv0104cs_read_raw,
+ .write_raw = &lv0104cs_write_raw,
+};
+
+static const struct iio_chan_spec lv0104cs_channels[] = {
+ {
+ .type = IIO_LIGHT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
+ BIT(IIO_CHAN_INFO_CALIBSCALE) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_INT_TIME),
+ },
+};
+
+static int lv0104cs_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct iio_dev *indio_dev;
+ struct lv0104cs_private *lv0104cs;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*lv0104cs));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ lv0104cs = iio_priv(indio_dev);
+
+ i2c_set_clientdata(client, lv0104cs);
+ lv0104cs->client = client;
+
+ mutex_init(&lv0104cs->lock);
+
+ lv0104cs->calibscale = LV0104CS_CALIBSCALE_UNITY;
+ lv0104cs->scale = LV0104CS_SCALE_1X;
+ lv0104cs->int_time = LV0104CS_INTEG_200MS;
+
+ ret = lv0104cs_write_reg(lv0104cs->client,
+ lv0104cs_calibscales[LV0104CS_CALIBSCALE_UNITY].regval);
+ if (ret)
+ return ret;
+
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->channels = lv0104cs_channels;
+ indio_dev->num_channels = ARRAY_SIZE(lv0104cs_channels);
+ indio_dev->name = client->name;
+ indio_dev->info = &lv0104cs_info;
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct i2c_device_id lv0104cs_id[] = {
+ { "lv0104cs", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, lv0104cs_id);
+
+static struct i2c_driver lv0104cs_i2c_driver = {
+ .driver = {
+ .name = "lv0104cs",
+ },
+ .id_table = lv0104cs_id,
+ .probe = lv0104cs_probe,
+};
+module_i2c_driver(lv0104cs_i2c_driver);
+
+MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
+MODULE_DESCRIPTION("LV0104CS Ambient Light Sensor Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index a1fd9d591818..d55c4885211a 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -167,7 +167,7 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
*val = 0;
*val2 = 0;
switch (mask) {
- case 0:
+ case IIO_CHAN_INFO_RAW:
hid_sensor_power_state(&magn_state->magn_flux_attributes, true);
report_id =
magn_state->magn[chan->address].report_id;
diff --git a/drivers/iio/potentiometer/Kconfig b/drivers/iio/potentiometer/Kconfig
index 8daf6d1f4e05..79ec2eba4969 100644
--- a/drivers/iio/potentiometer/Kconfig
+++ b/drivers/iio/potentiometer/Kconfig
@@ -47,6 +47,17 @@ config MAX5487
To compile this driver as a module, choose M here: the
module will be called max5487.
+config MCP4018
+ tristate "Microchip MCP4017/18/19 Digital Potentiometer driver"
+ depends on I2C
+ help
+ Say yes here to build support for the Microchip
+ MCP4017, MCP4018, MCP4019
+ digital potentiometer chips.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mcp4018.
+
config MCP4131
tristate "Microchip MCP413X/414X/415X/416X/423X/424X/425X/426X Digital Potentiometer driver"
depends on SPI
diff --git a/drivers/iio/potentiometer/Makefile b/drivers/iio/potentiometer/Makefile
index dbc139cec376..4af657883c3f 100644
--- a/drivers/iio/potentiometer/Makefile
+++ b/drivers/iio/potentiometer/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_AD5272) += ad5272.o
obj-$(CONFIG_DS1803) += ds1803.o
obj-$(CONFIG_MAX5481) += max5481.o
obj-$(CONFIG_MAX5487) += max5487.o
+obj-$(CONFIG_MCP4018) += mcp4018.o
obj-$(CONFIG_MCP4131) += mcp4131.o
obj-$(CONFIG_MCP4531) += mcp4531.o
obj-$(CONFIG_TPL0102) += tpl0102.o
diff --git a/drivers/iio/potentiometer/ds1803.c b/drivers/iio/potentiometer/ds1803.c
index 9b0ff4ab2f9c..6bf12c9eccbd 100644
--- a/drivers/iio/potentiometer/ds1803.c
+++ b/drivers/iio/potentiometer/ds1803.c
@@ -64,7 +64,7 @@ static int ds1803_read_raw(struct iio_dev *indio_dev,
struct ds1803_data *data = iio_priv(indio_dev);
int pot = chan->channel;
int ret;
- u8 result[indio_dev->num_channels];
+ u8 result[ARRAY_SIZE(ds1803_channels)];
switch (mask) {
case IIO_CHAN_INFO_RAW:
diff --git a/drivers/iio/potentiometer/mcp4018.c b/drivers/iio/potentiometer/mcp4018.c
new file mode 100644
index 000000000000..601b25d1f387
--- /dev/null
+++ b/drivers/iio/potentiometer/mcp4018.c
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Industrial I/O driver for Microchip digital potentiometers
+ * Copyright (c) 2018 Axentia Technologies AB
+ * Author: Peter Rosin <peda@axentia.se>
+ *
+ * Datasheet: http://www.microchip.com/downloads/en/DeviceDoc/22147a.pdf
+ *
+ * DEVID #Wipers #Positions Resistor Opts (kOhm)
+ * mcp4017 1 128 5, 10, 50, 100
+ * mcp4018 1 128 5, 10, 50, 100
+ * mcp4019 1 128 5, 10, 50, 100
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#define MCP4018_WIPER_MAX 127
+
+struct mcp4018_cfg {
+ int kohms;
+};
+
+enum mcp4018_type {
+ MCP4018_502,
+ MCP4018_103,
+ MCP4018_503,
+ MCP4018_104,
+};
+
+static const struct mcp4018_cfg mcp4018_cfg[] = {
+ [MCP4018_502] = { .kohms = 5, },
+ [MCP4018_103] = { .kohms = 10, },
+ [MCP4018_503] = { .kohms = 50, },
+ [MCP4018_104] = { .kohms = 100, },
+};
+
+struct mcp4018_data {
+ struct i2c_client *client;
+ const struct mcp4018_cfg *cfg;
+};
+
+static const struct iio_chan_spec mcp4018_channel = {
+ .type = IIO_RESISTANCE,
+ .indexed = 1,
+ .output = 1,
+ .channel = 0,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+};
+
+static int mcp4018_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct mcp4018_data *data = iio_priv(indio_dev);
+ s32 ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = i2c_smbus_read_byte(data->client);
+ if (ret < 0)
+ return ret;
+ *val = ret;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 1000 * data->cfg->kohms;
+ *val2 = MCP4018_WIPER_MAX;
+ return IIO_VAL_FRACTIONAL;
+ }
+
+ return -EINVAL;
+}
+
+static int mcp4018_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct mcp4018_data *data = iio_priv(indio_dev);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (val > MCP4018_WIPER_MAX || val < 0)
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return i2c_smbus_write_byte(data->client, val);
+}
+
+static const struct iio_info mcp4018_info = {
+ .read_raw = mcp4018_read_raw,
+ .write_raw = mcp4018_write_raw,
+};
+
+#ifdef CONFIG_OF
+
+#define MCP4018_COMPATIBLE(of_compatible, cfg) { \
+ .compatible = of_compatible, \
+ .data = &mcp4018_cfg[cfg], \
+}
+
+static const struct of_device_id mcp4018_of_match[] = {
+ MCP4018_COMPATIBLE("microchip,mcp4017-502", MCP4018_502),
+ MCP4018_COMPATIBLE("microchip,mcp4017-103", MCP4018_103),
+ MCP4018_COMPATIBLE("microchip,mcp4017-503", MCP4018_503),
+ MCP4018_COMPATIBLE("microchip,mcp4017-104", MCP4018_104),
+ MCP4018_COMPATIBLE("microchip,mcp4018-502", MCP4018_502),
+ MCP4018_COMPATIBLE("microchip,mcp4018-103", MCP4018_103),
+ MCP4018_COMPATIBLE("microchip,mcp4018-503", MCP4018_503),
+ MCP4018_COMPATIBLE("microchip,mcp4018-104", MCP4018_104),
+ MCP4018_COMPATIBLE("microchip,mcp4019-502", MCP4018_502),
+ MCP4018_COMPATIBLE("microchip,mcp4019-103", MCP4018_103),
+ MCP4018_COMPATIBLE("microchip,mcp4019-503", MCP4018_503),
+ MCP4018_COMPATIBLE("microchip,mcp4019-104", MCP4018_104),
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mcp4018_of_match);
+
+#endif
+
+static int mcp4018_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct mcp4018_data *data;
+ struct iio_dev *indio_dev;
+ const struct of_device_id *match;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE)) {
+ dev_err(dev, "SMBUS Byte transfers not supported\n");
+ return -EOPNOTSUPP;
+ }
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+
+ match = of_match_device(of_match_ptr(mcp4018_of_match), dev);
+ if (match)
+ data->cfg = of_device_get_match_data(dev);
+ else
+ data->cfg = &mcp4018_cfg[id->driver_data];
+
+ indio_dev->dev.parent = dev;
+ indio_dev->info = &mcp4018_info;
+ indio_dev->channels = &mcp4018_channel;
+ indio_dev->num_channels = 1;
+ indio_dev->name = client->name;
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct i2c_device_id mcp4018_id[] = {
+ { "mcp4017-502", MCP4018_502 },
+ { "mcp4017-103", MCP4018_103 },
+ { "mcp4017-503", MCP4018_503 },
+ { "mcp4017-104", MCP4018_104 },
+ { "mcp4018-502", MCP4018_502 },
+ { "mcp4018-103", MCP4018_103 },
+ { "mcp4018-503", MCP4018_503 },
+ { "mcp4018-104", MCP4018_104 },
+ { "mcp4019-502", MCP4018_502 },
+ { "mcp4019-103", MCP4018_103 },
+ { "mcp4019-503", MCP4018_503 },
+ { "mcp4019-104", MCP4018_104 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, mcp4018_id);
+
+static struct i2c_driver mcp4018_driver = {
+ .driver = {
+ .name = "mcp4018",
+ .of_match_table = of_match_ptr(mcp4018_of_match),
+ },
+ .probe = mcp4018_probe,
+ .id_table = mcp4018_id,
+};
+
+module_i2c_driver(mcp4018_driver);
+
+MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
+MODULE_DESCRIPTION("MCP4018 digital potentiometer");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c
index b8a2c2c8cac5..ff80409e0c44 100644
--- a/drivers/iio/proximity/sx9500.c
+++ b/drivers/iio/proximity/sx9500.c
@@ -32,9 +32,6 @@
#define SX9500_DRIVER_NAME "sx9500"
#define SX9500_IRQ_NAME "sx9500_event"
-#define SX9500_GPIO_INT "interrupt"
-#define SX9500_GPIO_RESET "reset"
-
/* Register definitions. */
#define SX9500_REG_IRQ_SRC 0x00
#define SX9500_REG_STAT 0x01
@@ -866,26 +863,44 @@ static int sx9500_init_device(struct iio_dev *indio_dev)
return sx9500_init_compensation(indio_dev);
}
+static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
+static const struct acpi_gpio_params interrupt_gpios = { 2, 0, false };
+
+static const struct acpi_gpio_mapping acpi_sx9500_gpios[] = {
+ { "reset-gpios", &reset_gpios, 1 },
+ /*
+ * Some platforms have a bug in ACPI GPIO description making IRQ
+ * GPIO to be output only. Ask the GPIO core to ignore this limit.
+ */
+ { "interrupt-gpios", &interrupt_gpios, 1, ACPI_GPIO_QUIRK_NO_IO_RESTRICTION },
+ { },
+};
+
static void sx9500_gpio_probe(struct i2c_client *client,
struct sx9500_data *data)
{
struct gpio_desc *gpiod_int;
struct device *dev;
+ int ret;
if (!client)
return;
dev = &client->dev;
+ ret = devm_acpi_dev_add_driver_gpios(dev, acpi_sx9500_gpios);
+ if (ret)
+ dev_dbg(dev, "Unable to add GPIO mapping table\n");
+
if (client->irq <= 0) {
- gpiod_int = devm_gpiod_get(dev, SX9500_GPIO_INT, GPIOD_IN);
+ gpiod_int = devm_gpiod_get(dev, "interrupt", GPIOD_IN);
if (IS_ERR(gpiod_int))
dev_err(dev, "gpio get irq failed\n");
else
client->irq = gpiod_to_irq(gpiod_int);
}
- data->gpiod_rst = devm_gpiod_get(dev, SX9500_GPIO_RESET, GPIOD_OUT_HIGH);
+ data->gpiod_rst = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(data->gpiod_rst)) {
dev_warn(dev, "gpio get reset pin failed\n");
data->gpiod_rst = NULL;
diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c
index d695ab97d27f..9851311aa3fd 100644
--- a/drivers/iio/temperature/mlx90632.c
+++ b/drivers/iio/temperature/mlx90632.c
@@ -506,6 +506,8 @@ static int mlx90632_calc_ambient_dsp105(struct mlx90632_data *data, int *val)
ret = mlx90632_read_ambient_raw(data->regmap, &ambient_new_raw,
&ambient_old_raw);
+ if (ret < 0)
+ return ret;
*val = mlx90632_calc_temp_ambient(ambient_new_raw, ambient_old_raw,
PT, PR, PG, PO, Gb);
return ret;