iio: light: vl6180: Added Interrupt support for single shot access

The interrupts are serviced in the `vl6180_measure` function when the
irq_handler signals that the reading is complete. We now can read
asynchronously if `client->irq` is set.

Signed-off-by: Abhash Jha <abhashkumarjha123@gmail.com>
Link: https://patch.msgid.link/20241007152223.59008-3-abhashkumarjha123@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
Abhash Jha
2024-10-07 20:52:22 +05:30
committed by Jonathan Cameron
parent 5d64ac92c7
commit 3a54586171

View File

@@ -86,6 +86,7 @@
struct vl6180_data {
struct i2c_client *client;
struct mutex lock;
struct completion completion;
unsigned int als_gain_milli;
unsigned int als_it_ms;
unsigned int als_meas_rate;
@@ -211,29 +212,40 @@ static int vl6180_write_word(struct i2c_client *client, u16 cmd, u16 val)
static int vl6180_measure(struct vl6180_data *data, int addr)
{
struct i2c_client *client = data->client;
unsigned long time_left;
int tries = 20, ret;
u16 value;
mutex_lock(&data->lock);
reinit_completion(&data->completion);
/* Start single shot measurement */
ret = vl6180_write_byte(client,
vl6180_chan_regs_table[addr].start_reg, VL6180_STARTSTOP);
if (ret < 0)
goto fail;
while (tries--) {
ret = vl6180_read_byte(client, VL6180_INTR_STATUS);
if (ret < 0)
if (client->irq) {
time_left = wait_for_completion_timeout(&data->completion, HZ / 10);
if (time_left == 0) {
ret = -ETIMEDOUT;
goto fail;
}
} else {
while (tries--) {
ret = vl6180_read_byte(client, VL6180_INTR_STATUS);
if (ret < 0)
goto fail;
if (ret & vl6180_chan_regs_table[addr].drdy_mask)
break;
msleep(20);
}
if (ret & vl6180_chan_regs_table[addr].drdy_mask)
break;
msleep(20);
}
if (tries < 0) {
ret = -EIO;
goto fail;
if (tries < 0) {
ret = -EIO;
goto fail;
}
}
/* Read result value from appropriate registers */
@@ -484,6 +496,15 @@ static int vl6180_write_raw(struct iio_dev *indio_dev,
}
}
static irqreturn_t vl6180_threaded_irq(int irq, void *priv)
{
struct iio_dev *indio_dev = priv;
struct vl6180_data *data = iio_priv(indio_dev);
complete(&data->completion);
return IRQ_HANDLED;
}
static const struct iio_info vl6180_info = {
.read_raw = vl6180_read_raw,
.write_raw = vl6180_write_raw,
@@ -583,6 +604,17 @@ static int vl6180_probe(struct i2c_client *client)
if (ret < 0)
return ret;
if (client->irq) {
ret = devm_request_threaded_irq(&client->dev, client->irq,
NULL, vl6180_threaded_irq,
IRQF_ONESHOT,
indio_dev->name, indio_dev);
if (ret)
return dev_err_probe(&client->dev, ret, "devm_request_irq error \n");
init_completion(&data->completion);
}
return devm_iio_device_register(&client->dev, indio_dev);
}