Commit 3a545861 authored by Abhash Jha's avatar Abhash Jha Committed by Jonathan Cameron
Browse files

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: default avatarAbhash Jha <abhashkumarjha123@gmail.com>
Link: https://patch.msgid.link/20241007152223.59008-3-abhashkumarjha123@gmail.com


Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 5d64ac92
Loading
Loading
Loading
Loading
+43 −11
Original line number Diff line number Diff line
@@ -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,16 +212,26 @@ 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;

	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)
@@ -235,6 +246,7 @@ static int vl6180_measure(struct vl6180_data *data, int addr)
			ret = -EIO;
			goto fail;
		}
	}

	/* Read result value from appropriate registers */
	ret = vl6180_chan_regs_table[addr].word ?
@@ -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);
}