summaryrefslogtreecommitdiff
path: root/drivers/iio/light/si1145.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/light/si1145.c')
-rw-r--r--drivers/iio/light/si1145.c136
1 files changed, 46 insertions, 90 deletions
diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c
index 096034c126a4..f8eb251eca8d 100644
--- a/drivers/iio/light/si1145.c
+++ b/drivers/iio/light/si1145.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* si1145.c - Support for Silabs SI1132 and SI1141/2/3/5/6/7 combined ambient
* light, UV index and proximity sensors
@@ -5,10 +6,6 @@
* Copyright 2014-16 Peter Meerwald-Stadler <pmeerw@pmeerw.net>
* Copyright 2016 Crestez Dan Leonard <leonard.crestez@intel.com>
*
- * This file is subject to the terms and conditions of version 2 of
- * the GNU General Public License. See the file COPYING in the main
- * directory of this archive for more details.
- *
* SI1132 (7-bit I2C slave address 0x60)
* SI1141/2/3 (7-bit I2C slave address 0x5a)
* SI1145/6/6 (7-bit I2C slave address 0x60)
@@ -20,7 +17,6 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/irq.h>
-#include <linux/gpio.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@@ -172,6 +168,7 @@ struct si1145_part_info {
* @part_info: Part information
* @trig: Pointer to iio trigger
* @meas_rate: Value of MEAS_RATE register. Only set in HW in auto mode
+ * @buffer: Used to pack data read from sensor.
*/
struct si1145_data {
struct i2c_client *client;
@@ -183,9 +180,17 @@ struct si1145_data {
bool autonomous;
struct iio_trigger *trig;
int meas_rate;
+ /*
+ * Ensure timestamp will be naturally aligned if present.
+ * Maximum buffer size (may be only partly used if not all
+ * channels are enabled):
+ * 6*2 bytes channels data + 4 bytes alignment +
+ * 8 bytes timestamp
+ */
+ u8 buffer[24] __aligned(8);
};
-/**
+/*
* __si1145_command_reset() - Send CMD_NOP and wait for response 0
*
* Does not modify data->rsp_seq
@@ -215,11 +220,10 @@ static int __si1145_command_reset(struct si1145_data *data)
return -ETIMEDOUT;
}
msleep(SI1145_COMMAND_MINSLEEP_MS);
- continue;
}
}
-/**
+/*
* si1145_command() - Execute a command and poll the response register
*
* All conversion overflows are reported as -EOVERFLOW
@@ -266,7 +270,7 @@ static int si1145_command(struct si1145_data *data, u8 cmd)
if ((ret & ~SI1145_RSP_COUNTER_MASK) == 0) {
if (ret == data->rsp_seq) {
if (time_after(jiffies, stop_jiffies)) {
- dev_warn(dev, "timeout on command %#02hhx\n",
+ dev_warn(dev, "timeout on command 0x%02x\n",
cmd);
ret = -ETIMEDOUT;
break;
@@ -286,12 +290,12 @@ static int si1145_command(struct si1145_data *data, u8 cmd)
ret = -EIO;
} else {
if (ret == SI1145_RSP_INVALID_SETTING) {
- dev_warn(dev, "INVALID_SETTING error on command %#02hhx\n",
+ dev_warn(dev, "INVALID_SETTING error on command 0x%02x\n",
cmd);
ret = -EINVAL;
} else {
/* All overflows are treated identically */
- dev_dbg(dev, "overflow, ret=%d, cmd=%#02hhx\n",
+ dev_dbg(dev, "overflow, ret=%d, cmd=0x%02x\n",
ret, cmd);
ret = -EOVERFLOW;
}
@@ -444,12 +448,6 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private)
struct iio_poll_func *pf = private;
struct iio_dev *indio_dev = pf->indio_dev;
struct si1145_data *data = iio_priv(indio_dev);
- /*
- * Maximum buffer size:
- * 6*2 bytes channels data + 4 bytes alignment +
- * 8 bytes timestamp
- */
- u8 buffer[24];
int i, j = 0;
int ret;
u8 irq_status = 0;
@@ -467,11 +465,10 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private)
goto done;
}
- for_each_set_bit(i, indio_dev->active_scan_mask,
- indio_dev->masklength) {
+ iio_for_each_active_channel(indio_dev, i) {
int run = 1;
- while (i + run < indio_dev->masklength) {
+ while (i + run < iio_get_masklength(indio_dev)) {
if (!test_bit(i + run, indio_dev->active_scan_mask))
break;
if (indio_dev->channels[i + run].address !=
@@ -482,7 +479,7 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private)
ret = i2c_smbus_read_i2c_block_data_or_emulated(
data->client, indio_dev->channels[i].address,
- sizeof(u16) * run, &buffer[j]);
+ sizeof(u16) * run, &data->buffer[j]);
if (ret < 0)
goto done;
j += run * sizeof(u16);
@@ -497,8 +494,9 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private)
goto done;
}
- iio_push_to_buffers_with_timestamp(indio_dev, buffer,
- iio_get_time_ns(indio_dev));
+ iio_push_to_buffers_with_ts(indio_dev, data->buffer,
+ sizeof(data->buffer),
+ iio_get_time_ns(indio_dev));
done:
iio_trigger_notify_done(indio_dev->trig);
@@ -516,7 +514,7 @@ static int si1145_set_chlist(struct iio_dev *indio_dev, unsigned long scan_mask)
if (data->scan_mask == scan_mask)
return 0;
- for_each_set_bit(i, &scan_mask, indio_dev->masklength) {
+ for_each_set_bit(i, &scan_mask, iio_get_masklength(indio_dev)) {
switch (indio_dev->channels[i].address) {
case SI1145_REG_ALSVIS_DATA:
reg |= SI1145_CHLIST_EN_ALSVIS;
@@ -636,11 +634,10 @@ static int si1145_read_raw(struct iio_dev *indio_dev,
case IIO_VOLTAGE:
case IIO_TEMP:
case IIO_UVINDEX:
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
ret = si1145_measure(indio_dev, chan);
- iio_device_release_direct_mode(indio_dev);
+ iio_device_release_direct(indio_dev);
if (ret < 0)
return ret;
@@ -753,18 +750,17 @@ static int si1145_write_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
ret = si1145_param_set(data, reg1, val);
if (ret < 0) {
- iio_device_release_direct_mode(indio_dev);
+ iio_device_release_direct(indio_dev);
return ret;
}
/* Set recovery period to one's complement of gain */
ret = si1145_param_set(data, reg2, (~val & 0x07) << 4);
- iio_device_release_direct_mode(indio_dev);
+ iio_device_release_direct(indio_dev);
return ret;
case IIO_CHAN_INFO_RAW:
if (chan->type != IIO_CURRENT)
@@ -776,19 +772,18 @@ static int si1145_write_raw(struct iio_dev *indio_dev,
reg1 = SI1145_PS_LED_REG(chan->channel);
shift = SI1145_PS_LED_SHIFT(chan->channel);
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
ret = i2c_smbus_read_byte_data(data->client, reg1);
if (ret < 0) {
- iio_device_release_direct_mode(indio_dev);
+ iio_device_release_direct(indio_dev);
return ret;
}
ret = i2c_smbus_write_byte_data(data->client, reg1,
(ret & ~(0x0f << shift)) |
((val & 0x0f) << shift));
- iio_device_release_direct_mode(indio_dev);
+ iio_device_release_direct(indio_dev);
return ret;
case IIO_CHAN_INFO_SAMP_FREQ:
return si1145_store_samp_freq(data, val);
@@ -989,14 +984,12 @@ static const struct attribute_group si114x_attribute_group = {
static const struct iio_info si1132_info = {
.read_raw = si1145_read_raw,
.write_raw = si1145_write_raw,
- .driver_module = THIS_MODULE,
.attrs = &si1132_attribute_group,
};
static const struct iio_info si114x_info = {
.read_raw = si1145_read_raw,
.write_raw = si1145_write_raw,
- .driver_module = THIS_MODULE,
.attrs = &si114x_attribute_group,
};
@@ -1048,7 +1041,7 @@ static int si1145_initialize(struct si1145_data *data)
SI1145_LED_CURRENT_45mA);
if (ret < 0)
return ret;
- /* fallthrough */
+ fallthrough;
case 2:
ret = i2c_smbus_write_byte_data(client,
SI1145_REG_PS_LED21,
@@ -1177,12 +1170,10 @@ static bool si1145_validate_scan_mask(struct iio_dev *indio_dev,
static const struct iio_buffer_setup_ops si1145_buffer_setup_ops = {
.preenable = si1145_buffer_preenable,
- .postenable = iio_triggered_buffer_postenable,
- .predisable = iio_triggered_buffer_predisable,
.validate_scan_mask = si1145_validate_scan_mask,
};
-/**
+/*
* si1145_trigger_set_state() - Set trigger state
*
* When not using triggers interrupts are disabled and measurement rate is
@@ -1237,7 +1228,6 @@ disable:
}
static const struct iio_trigger_ops si1145_trigger_ops = {
- .owner = THIS_MODULE,
.set_trigger_state = si1145_trigger_set_state,
};
@@ -1249,11 +1239,10 @@ static int si1145_probe_trigger(struct iio_dev *indio_dev)
int ret;
trig = devm_iio_trigger_alloc(&client->dev,
- "%s-dev%d", indio_dev->name, indio_dev->id);
+ "%s-dev%d", indio_dev->name, iio_device_id(indio_dev));
if (!trig)
return -ENOMEM;
- trig->dev.parent = &client->dev;
trig->ops = &si1145_trigger_ops;
iio_trigger_set_drvdata(trig, indio_dev);
@@ -1267,7 +1256,7 @@ static int si1145_probe_trigger(struct iio_dev *indio_dev)
return ret;
}
- ret = iio_trigger_register(trig);
+ ret = devm_iio_trigger_register(&client->dev, trig);
if (ret)
return ret;
@@ -1277,19 +1266,9 @@ static int si1145_probe_trigger(struct iio_dev *indio_dev)
return 0;
}
-static void si1145_remove_trigger(struct iio_dev *indio_dev)
-{
- struct si1145_data *data = iio_priv(indio_dev);
-
- if (data->trig) {
- iio_trigger_unregister(data->trig);
- data->trig = NULL;
- }
-}
-
-static int si1145_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int si1145_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct si1145_data *data;
struct iio_dev *indio_dev;
u8 part_id, rev_id, seq_id;
@@ -1316,15 +1295,14 @@ static int si1145_probe(struct i2c_client *client,
SI1145_REG_SEQ_ID);
if (ret < 0)
return ret;
- dev_info(&client->dev, "device ID part %#02hhx rev %#02hhx seq %#02hhx\n",
+ dev_info(&client->dev, "device ID part 0x%02x rev 0x%02x seq 0x%02x\n",
part_id, rev_id, seq_id);
if (part_id != data->part_info->part) {
- dev_err(&client->dev, "part ID mismatch got %#02hhx, expected %#02x\n",
+ dev_err(&client->dev, "part ID mismatch got 0x%02x, expected 0x%02x\n",
part_id, data->part_info->part);
return -ENODEV;
}
- indio_dev->dev.parent = &client->dev;
indio_dev->name = id->name;
indio_dev->channels = data->part_info->channels;
indio_dev->num_channels = data->part_info->num_channels;
@@ -1338,7 +1316,8 @@ static int si1145_probe(struct i2c_client *client,
if (ret < 0)
return ret;
- ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ ret = devm_iio_triggered_buffer_setup(&client->dev,
+ indio_dev, NULL,
si1145_trigger_handler, &si1145_buffer_setup_ops);
if (ret < 0)
return ret;
@@ -1346,23 +1325,12 @@ static int si1145_probe(struct i2c_client *client,
if (client->irq) {
ret = si1145_probe_trigger(indio_dev);
if (ret < 0)
- goto error_free_buffer;
+ return ret;
} else {
dev_info(&client->dev, "no irq, using polling\n");
}
- ret = iio_device_register(indio_dev);
- if (ret < 0)
- goto error_free_trigger;
-
- return 0;
-
-error_free_trigger:
- si1145_remove_trigger(indio_dev);
-error_free_buffer:
- iio_triggered_buffer_cleanup(indio_dev);
-
- return ret;
+ return devm_iio_device_register(&client->dev, indio_dev);
}
static const struct i2c_device_id si1145_ids[] = {
@@ -1377,23 +1345,11 @@ static const struct i2c_device_id si1145_ids[] = {
};
MODULE_DEVICE_TABLE(i2c, si1145_ids);
-static int si1145_remove(struct i2c_client *client)
-{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
-
- iio_device_unregister(indio_dev);
- si1145_remove_trigger(indio_dev);
- iio_triggered_buffer_cleanup(indio_dev);
-
- return 0;
-}
-
static struct i2c_driver si1145_driver = {
.driver = {
.name = "si1145",
},
- .probe = si1145_probe,
- .remove = si1145_remove,
+ .probe = si1145_probe,
.id_table = si1145_ids,
};