summaryrefslogtreecommitdiff
path: root/drivers/iio/light/vcnl4000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/light/vcnl4000.c')
-rw-r--r--drivers/iio/light/vcnl4000.c109
1 files changed, 56 insertions, 53 deletions
diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
index 4e3641ff2ed4..4dbb2294a843 100644
--- a/drivers/iio/light/vcnl4000.c
+++ b/drivers/iio/light/vcnl4000.c
@@ -576,16 +576,11 @@ static bool vcnl4010_is_in_periodic_mode(struct vcnl4000_data *data)
static int vcnl4000_set_pm_runtime_state(struct vcnl4000_data *data, bool on)
{
struct device *dev = &data->client->dev;
- int ret;
- if (on) {
- ret = pm_runtime_resume_and_get(dev);
- } else {
- pm_runtime_mark_last_busy(dev);
- ret = pm_runtime_put_autosuspend(dev);
- }
+ if (on)
+ return pm_runtime_resume_and_get(dev);
- return ret;
+ return pm_runtime_put_autosuspend(dev);
}
static int vcnl4040_read_als_it(struct vcnl4000_data *data, int *val, int *val2)
@@ -1084,9 +1079,8 @@ static int vcnl4010_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
case IIO_CHAN_INFO_SCALE:
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
/* Protect against event capture. */
if (vcnl4010_is_in_periodic_mode(data)) {
@@ -1096,7 +1090,7 @@ static int vcnl4010_read_raw(struct iio_dev *indio_dev,
mask);
}
- iio_device_release_direct_mode(indio_dev);
+ iio_device_release_direct(indio_dev);
return ret;
case IIO_CHAN_INFO_SAMP_FREQ:
switch (chan->type) {
@@ -1157,9 +1151,8 @@ static int vcnl4010_write_raw(struct iio_dev *indio_dev,
int ret;
struct vcnl4000_data *data = iio_priv(indio_dev);
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
/* Protect against event capture. */
if (vcnl4010_is_in_periodic_mode(data)) {
@@ -1183,7 +1176,7 @@ static int vcnl4010_write_raw(struct iio_dev *indio_dev,
}
end:
- iio_device_release_direct_mode(indio_dev);
+ iio_device_release_direct(indio_dev);
return ret;
}
@@ -1410,53 +1403,59 @@ static int vcnl4010_read_event_config(struct iio_dev *indio_dev,
}
}
-static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state)
+static int vcnl4010_config_threshold_enable(struct vcnl4000_data *data)
{
- struct vcnl4000_data *data = iio_priv(indio_dev);
int ret;
- int icr;
- int command;
- if (state) {
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
+ /* Enable periodic measurement of proximity data. */
+ ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
+ VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN);
+ if (ret < 0)
+ return ret;
- /* Enable periodic measurement of proximity data. */
- command = VCNL4000_SELF_TIMED_EN | VCNL4000_PROX_EN;
+ /*
+ * Enable interrupts on threshold, for proximity data by
+ * default.
+ */
+ return i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL,
+ VCNL4010_INT_THR_EN);
+}
- /*
- * Enable interrupts on threshold, for proximity data by
- * default.
- */
- icr = VCNL4010_INT_THR_EN;
- } else {
- if (!vcnl4010_is_thr_enabled(data))
- return 0;
+static int vcnl4010_config_threshold_disable(struct vcnl4000_data *data)
+{
+ int ret;
- command = 0;
- icr = 0;
- }
+ if (!vcnl4010_is_thr_enabled(data))
+ return 0;
- ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
- command);
+ ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, 0);
if (ret < 0)
- goto end;
+ return ret;
- ret = i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, icr);
+ return i2c_smbus_write_byte_data(data->client, VCNL4010_INT_CTRL, 0);
+}
-end:
- if (state)
- iio_device_release_direct_mode(indio_dev);
+static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state)
+{
+ struct vcnl4000_data *data = iio_priv(indio_dev);
+ int ret;
- return ret;
+ if (state) {
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
+ ret = vcnl4010_config_threshold_enable(data);
+ iio_device_release_direct(indio_dev);
+ return ret;
+ } else {
+ return vcnl4010_config_threshold_disable(data);
+ }
}
static int vcnl4010_write_event_config(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
enum iio_event_direction dir,
- int state)
+ bool state)
{
switch (chan->type) {
case IIO_PROXIMITY:
@@ -1501,7 +1500,8 @@ static int vcnl4040_read_event_config(struct iio_dev *indio_dev,
static int vcnl4040_write_event_config(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
- enum iio_event_direction dir, int state)
+ enum iio_event_direction dir,
+ bool state)
{
int ret = -EINVAL;
u16 val, mask;
@@ -1657,7 +1657,10 @@ static irqreturn_t vcnl4010_trigger_handler(int irq, void *p)
struct iio_dev *indio_dev = pf->indio_dev;
struct vcnl4000_data *data = iio_priv(indio_dev);
const unsigned long *active_scan_mask = indio_dev->active_scan_mask;
- u16 buffer[8] __aligned(8) = {0}; /* 1x16-bit + naturally aligned ts */
+ struct {
+ u16 chan;
+ aligned_s64 ts;
+ } scan = { };
bool data_read = false;
unsigned long isr;
int val = 0;
@@ -1677,7 +1680,7 @@ static irqreturn_t vcnl4010_trigger_handler(int irq, void *p)
if (ret < 0)
goto end;
- buffer[0] = val;
+ scan.chan = val;
data_read = true;
}
}
@@ -1690,8 +1693,8 @@ static irqreturn_t vcnl4010_trigger_handler(int irq, void *p)
if (!data_read)
goto end;
- iio_push_to_buffers_with_timestamp(indio_dev, buffer,
- iio_get_time_ns(indio_dev));
+ iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan),
+ iio_get_time_ns(indio_dev));
end:
iio_trigger_notify_done(indio_dev->trig);
@@ -1740,7 +1743,7 @@ static const struct iio_chan_spec_ext_info vcnl4000_ext_info[] = {
.shared = IIO_SEPARATE,
.read = vcnl4000_read_near_level,
},
- { /* sentinel */ }
+ { }
};
static const struct iio_event_spec vcnl4000_event_spec[] = {
@@ -2063,7 +2066,7 @@ static const struct of_device_id vcnl_4000_of_match[] = {
.compatible = "vishay,vcnl4200",
.data = (void *)VCNL4200,
},
- {},
+ { }
};
MODULE_DEVICE_TABLE(of, vcnl_4000_of_match);