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:
committed by
Jonathan Cameron
parent
5d64ac92c7
commit
3a54586171
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user