diff mbox series

[v6,2/2] iio: proximity: vl53l0x: add interrupt support

Message ID 20180918082422.13050-2-songqiang1304521@gmail.com (mailing list archive)
State New, archived
Headers show
Series [v6,1/2] iio: proximity: Add driver support for ST's VL53L0X ToF ranging sensor. | expand

Commit Message

Song Qiang Sept. 18, 2018, 8:24 a.m. UTC
The first version of this driver issues a measuring request and polling
for a status register in the device for measuring completes.
vl53l0x support configuring GPIO1 on it to generate interrupt to
indicate that new measurement is ready. This patch adds support for
using this mechanisim to reduce cpu cost.

Signed-off-by: Song Qiang <songqiang1304521@gmail.com>
---
 .../bindings/iio/proximity/vl53l0x.txt        |  14 +-
 drivers/iio/proximity/vl53l0x-i2c.c           | 135 +++++++++++++++---
 2 files changed, 129 insertions(+), 20 deletions(-)

Comments

Jonathan Cameron Sept. 22, 2018, 3:05 p.m. UTC | #1
On Tue, 18 Sep 2018 16:24:22 +0800
Song Qiang <songqiang1304521@gmail.com> wrote:

> The first version of this driver issues a measuring request and polling
> for a status register in the device for measuring completes.
> vl53l0x support configuring GPIO1 on it to generate interrupt to
> indicate that new measurement is ready. This patch adds support for
> using this mechanisim to reduce cpu cost.
> 
> Signed-off-by: Song Qiang <songqiang1304521@gmail.com>
Hi Song.

Looks correct in principal but a few things to tidy up before
this is ready to apply.

Also we have an unrelated change in here to check the devices ID.
That should be in it's own patch.

Thanks,

Jonathan
> ---
>  .../bindings/iio/proximity/vl53l0x.txt        |  14 +-
>  drivers/iio/proximity/vl53l0x-i2c.c           | 135 +++++++++++++++---
>  2 files changed, 129 insertions(+), 20 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> index ab9a9539fec4..40290f8dd70f 100644
> --- a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> +++ b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> @@ -4,9 +4,21 @@ Required properties:
>  	- compatible: must be "st,vl53l0x-i2c"
>  	- reg: i2c address where to find the device
>  
> +Optional properties:
> +	- interrupts : Interrupt line receiving GPIO1's measuring complete
> +	  output, supports IRQ_TYPE_EDGE_FALLING only.
> +
> +	Refer to interrupt-controller/interrupts.txt for generic
> +	interrupt client node bindings.
> +
>  Example:
>  
>  vl53l0x@29 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&vl53l0x_pins>;
> +
Please drop this from the example.  This is board specific rather than
being generally required.

>  	compatible = "st,vl53l0x-i2c";
>  	reg = <0x29>;
> -};
> +	interrupt-parent = <&gpio3>;
> +	interrupts = <17 IRQ_TYPE_EDGE_FALLING>;
> +}
> diff --git a/drivers/iio/proximity/vl53l0x-i2c.c b/drivers/iio/proximity/vl53l0x-i2c.c
> index 1aad45df8d95..a5cff11f41de 100644
> --- a/drivers/iio/proximity/vl53l0x-i2c.c
> +++ b/drivers/iio/proximity/vl53l0x-i2c.c
> @@ -10,18 +10,21 @@
>   *
>   * Default 7-bit i2c slave address 0x29.
>   *
> - * TODO: FIFO buffer, continuous mode, interrupts, range selection,
> - * sensor ID check.
> + * TODO: FIFO buffer, continuous mode, range selection.
>   */
>  
>  #include <linux/module.h>
>  #include <linux/i2c.h>
>  #include <linux/delay.h>
> +#include <linux/interrupt.h>
>  
>  #include <linux/iio/iio.h>
>  
> +#include <stdbool.h>
> +
>  #define VL_REG_SYSRANGE_START				0x00
>  
> +/* Mode configuration registers. */
>  #define VL_REG_SYSRANGE_MODE_MASK			GENMASK(3, 0)
>  #define VL_REG_SYSRANGE_MODE_SINGLESHOT			0x00
>  #define VL_REG_SYSRANGE_MODE_START_STOP			BIT(0)
> @@ -29,14 +32,61 @@
>  #define VL_REG_SYSRANGE_MODE_TIMED			BIT(2)
>  #define VL_REG_SYSRANGE_MODE_HISTOGRAM			BIT(3)
>  
> +/* Result registers. */
>  #define VL_REG_RESULT_INT_STATUS			0x13
>  #define VL_REG_RESULT_RANGE_STATUS			0x14
>  #define VL_REG_RESULT_RANGE_STATUS_COMPLETE		BIT(0)
>  
> +/* GPIO function configuration registers. */
> +#define VL_REG_GPIO_HV_MUX_ACTIVE_GIGH			0x84
> +#define VL_REG_SYS_INT_CFG_GPIO				0x0A
> +#define VL_GPIOFUNC_NEW_MEASURE_RDY			BIT(2)
> +
> +/* Interrupt configuration registers. */
> +#define VL_REG_SYS_INT_CLEAR				0x0B
> +#define VL_REG_RESULT_INT_STATUS			0x13
> +#define VL_INT_POLARITY_LOW				0x00
> +#define VL_INT_POLARITY_HIGH				BIT(0)
> +
> +/* Should be 0xEE if connection is fine. */
> +#define VL_REG_MODEL_ID					0xC0
> +
>  struct vl53l0x_data {
>  	struct i2c_client *client;
> +	struct completion measuring_done;
> +	bool use_interrupt;
>  };
>  
> +static int vl53l0x_clear_interrupt(struct vl53l0x_data *data)
> +{
> +	int ret;
> +	u8 cnt = 0;
> +
> +	do {
> +		/* bit 0 for measuring interrupt, bit 1 for error interrupt.  */
> +		i2c_smbus_write_byte_data(data->client,
> +			VL_REG_SYS_INT_CLEAR, 1);

All these i2c comms need checking for errors.  I2c buses aren't always the most
reliable things.

> +		i2c_smbus_write_byte_data(data->client,
> +			VL_REG_SYS_INT_CLEAR, 0);
> +		ret = i2c_smbus_read_byte_data(data->client,
> +			VL_REG_RESULT_INT_STATUS);
> +		cnt++;
> +	} while ((ret & 0x07) && (cnt < 3));
> +	if (cnt > 2)
> +		return -ETIMEDOUT;
> +	else
> +		return 0;
> +}
> +
> +static irqreturn_t vl53l0x_irq_handler(int irq, void *d)
> +{
> +	struct vl53l0x_data *data = d;
> +
> +	complete(&data->measuring_done);
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static int vl53l0x_read_proximity(struct vl53l0x_data *data,
>  				  const struct iio_chan_spec *chan,
>  				  int *val)
> @@ -46,23 +96,31 @@ static int vl53l0x_read_proximity(struct vl53l0x_data *data,
>  	u8 buffer[12];
>  	int ret;
>  
> -	ret = i2c_smbus_write_byte_data(client, VL_REG_SYSRANGE_START, 1);
> -	if (ret < 0)
> -		return ret;
> -
> -	do {
> -		ret = i2c_smbus_read_byte_data(client,
> -			VL_REG_RESULT_RANGE_STATUS);
> -		if (ret < 0)
> -			return ret;
> -
> -		if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE)
> -			break;
> -
> -		usleep_range(1000, 5000);
> -	} while (--tries);
> -	if (!tries)
> -		return -ETIMEDOUT;
> +	if (data->use_interrupt)
> +		reinit_completion(&data->measuring_done);

This seems a little strange. Should be initialized already on first
pass for example.  I don't suppose it matters, but feels a bit odd.
You may need to protect against multiple concurrent readers however...

> +
> +	i2c_smbus_write_byte_data(client, VL_REG_SYSRANGE_START, 1);
> +
> +	/* In usual case the longest valid conversion time is less than 70ms. */
> +	if (data->use_interrupt) {
> +		ret = wait_for_completion_timeout(&data->measuring_done,
> +			msecs_to_jiffies(100));
> +		if (!ret)
> +			return -ETIMEDOUT;
> +		vl53l0x_clear_interrupt(data);
> +	} else {
> +		do {
> +			ret = i2c_smbus_read_byte_data(client,
> +				VL_REG_RESULT_RANGE_STATUS);
> +
> +			if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE)
> +				break;
> +
> +			usleep_range(1000, 5000);
> +		} while (--tries);
> +		if (!tries)
> +			return -ETIMEDOUT;
> +	}
>  
>  	ret = i2c_smbus_read_i2c_block_data(client, VL_REG_RESULT_RANGE_STATUS,
>  		12, buffer);
> @@ -110,10 +168,21 @@ static const struct iio_info vl53l0x_info = {
>  	.read_raw = vl53l0x_read_raw,
>  };
>  
> +/* Congigure the GPIO1 pin to generate interrupt for measurement ready,
Comment syntax + spell check. Configure   For a description like this
nicer to have it in kernel-doc style as well rather than a freeform comment.

> + * default polarity is level low.
> + */
> +static int vl53l0x_config_irq(struct vl53l0x_data *data)
> +{
> +	i2c_smbus_write_byte_data(data->client, VL_REG_SYS_INT_CFG_GPIO,
> +		VL_GPIOFUNC_NEW_MEASURE_RDY);

Error checking on that write_byte?

> +	return vl53l0x_clear_interrupt(data);
> +}
> +
>  static int vl53l0x_probe(struct i2c_client *client)
>  {
>  	struct vl53l0x_data *data;
>  	struct iio_dev *indio_dev;
> +	int ret;
>  
>  	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
>  	if (!indio_dev)
> @@ -134,6 +203,34 @@ static int vl53l0x_probe(struct i2c_client *client)
>  	indio_dev->num_channels = ARRAY_SIZE(vl53l0x_channels);
>  	indio_dev->modes = INDIO_DIRECT_MODE;
>  
> +	if (!client->irq)
> +		data->use_interrupt = false;
> +	else {
> +		data->use_interrupt = true;
> +		ret = devm_request_irq(&client->dev,
> +			client->irq,
> +			vl53l0x_irq_handler,
> +			IRQF_TRIGGER_FALLING,
> +			indio_dev->name,
> +			data);
> +		if (ret < 0) {
> +			dev_err(&client->dev,

Lots of odd alignment in here.  Please tidy up.

> +			"request irq line failed.");
> +			return -EINVAL;
> +		}
> +		vl53l0x_config_irq(data);
> +		init_completion(&data->measuring_done);
> +	}
> +
> +	/* After checking this, assuming write and read byte operations should
/*
 * After..
 */
> +	 *  never fails.
> +	 */
> +	ret = i2c_smbus_read_byte_data(client, VL_REG_MODEL_ID);
> +	if (ret != 0xEE) {
> +		dev_err(&client->dev, "device not found. ");
No space after . and \n is normal for a dev_err message.

What does this have to do with interrupt support?

Please break it out as a separate patch.

> +		return -EREMOTEIO;
> +	}
> +
>  	return devm_iio_device_register(&client->dev, indio_dev);
>  }
>
Rob Herring (Arm) Sept. 26, 2018, 10:46 p.m. UTC | #2
On Sat, Sep 22, 2018 at 04:05:23PM +0100, Jonathan Cameron wrote:
> On Tue, 18 Sep 2018 16:24:22 +0800
> Song Qiang <songqiang1304521@gmail.com> wrote:
> 
> > The first version of this driver issues a measuring request and polling
> > for a status register in the device for measuring completes.
> > vl53l0x support configuring GPIO1 on it to generate interrupt to
> > indicate that new measurement is ready. This patch adds support for
> > using this mechanisim to reduce cpu cost.
> > 
> > Signed-off-by: Song Qiang <songqiang1304521@gmail.com>
> Hi Song.
> 
> Looks correct in principal but a few things to tidy up before
> this is ready to apply.
> 
> Also we have an unrelated change in here to check the devices ID.
> That should be in it's own patch.
> 
> Thanks,
> 
> Jonathan
> > ---
> >  .../bindings/iio/proximity/vl53l0x.txt        |  14 +-

This should have been split with the complete binding in one patch 
rather than piecemeal driver feature by feature.

> >  drivers/iio/proximity/vl53l0x-i2c.c           | 135 +++++++++++++++---
> >  2 files changed, 129 insertions(+), 20 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > index ab9a9539fec4..40290f8dd70f 100644
> > --- a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > +++ b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > @@ -4,9 +4,21 @@ Required properties:
> >  	- compatible: must be "st,vl53l0x-i2c"

Is there more than one interface on this device, such as SPI? If not, 
then '-i2c' should be dropped.

> >  	- reg: i2c address where to find the device
> >  
> > +Optional properties:
> > +	- interrupts : Interrupt line receiving GPIO1's measuring complete
> > +	  output, supports IRQ_TYPE_EDGE_FALLING only.
> > +
> > +	Refer to interrupt-controller/interrupts.txt for generic
> > +	interrupt client node bindings.
> > +
> >  Example:
> >  
> >  vl53l0x@29 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&vl53l0x_pins>;
> > +
> Please drop this from the example.  This is board specific rather than
> being generally required.
> 
> >  	compatible = "st,vl53l0x-i2c";
> >  	reg = <0x29>;
> > -};
> > +	interrupt-parent = <&gpio3>;
> > +	interrupts = <17 IRQ_TYPE_EDGE_FALLING>;
> > +}
Song Qiang Sept. 28, 2018, 9:36 a.m. UTC | #3
On Wed, Sep 26, 2018 at 05:46:18PM -0500, Rob Herring wrote:
> On Sat, Sep 22, 2018 at 04:05:23PM +0100, Jonathan Cameron wrote:
> > On Tue, 18 Sep 2018 16:24:22 +0800
> > Song Qiang <songqiang1304521@gmail.com> wrote:
> > 
> > > The first version of this driver issues a measuring request and polling
> > > for a status register in the device for measuring completes.
> > > vl53l0x support configuring GPIO1 on it to generate interrupt to
> > > indicate that new measurement is ready. This patch adds support for
> > > using this mechanisim to reduce cpu cost.
> > > 
> > > Signed-off-by: Song Qiang <songqiang1304521@gmail.com>
> > Hi Song.
> > 
> > Looks correct in principal but a few things to tidy up before
> > this is ready to apply.
> > 
> > Also we have an unrelated change in here to check the devices ID.
> > That should be in it's own patch.
> > 
> > Thanks,
> > 
> > Jonathan
> > > ---
> > >  .../bindings/iio/proximity/vl53l0x.txt        |  14 +-
> 
> This should have been split with the complete binding in one patch 
> rather than piecemeal driver feature by feature.
> 

Hi Rob,

A few days ago when I was submitting this driver, I didn't do it very
well, the function of this driver is limited. I added interrupt support 
the next day after you acked my first patch. I thought it's not polite 
to add something after someone acked that patch, so I send the interrupt
support as a second patch. The first patch is merged to togreg now, but
this doesn't. I don't know when can I add new functions to the code that
just merged to togreg branch, could you offer some suggestions?

> > >  drivers/iio/proximity/vl53l0x-i2c.c           | 135 +++++++++++++++---
> > >  2 files changed, 129 insertions(+), 20 deletions(-)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > index ab9a9539fec4..40290f8dd70f 100644
> > > --- a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > +++ b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > @@ -4,9 +4,21 @@ Required properties:
> > >  	- compatible: must be "st,vl53l0x-i2c"
> 
> Is there more than one interface on this device, such as SPI? If not, 
> then '-i2c' should be dropped.
> 

Yes, there is a CCI(Camera Control Interface) for communication.

> > >  	- reg: i2c address where to find the device
> > >  
> > > +Optional properties:
> > > +	- interrupts : Interrupt line receiving GPIO1's measuring complete
> > > +	  output, supports IRQ_TYPE_EDGE_FALLING only.
> > > +
> > > +	Refer to interrupt-controller/interrupts.txt for generic
> > > +	interrupt client node bindings.
> > > +
> > >  Example:
> > >  
> > >  vl53l0x@29 {
> > > +	pinctrl-names = "default";
> > > +	pinctrl-0 = <&vl53l0x_pins>;
> > > +
> > Please drop this from the example.  This is board specific rather than
> > being generally required.
> > 

Sure.

yours,
Song Qiang
> > >  	compatible = "st,vl53l0x-i2c";
> > >  	reg = <0x29>;
> > > -};
> > > +	interrupt-parent = <&gpio3>;
> > > +	interrupts = <17 IRQ_TYPE_EDGE_FALLING>;
> > > +}
Rob Herring (Arm) Sept. 28, 2018, 11:52 p.m. UTC | #4
On Fri, Sep 28, 2018 at 4:36 AM Song Qiang <songqiang1304521@gmail.com> wrote:
>
> On Wed, Sep 26, 2018 at 05:46:18PM -0500, Rob Herring wrote:
> > On Sat, Sep 22, 2018 at 04:05:23PM +0100, Jonathan Cameron wrote:
> > > On Tue, 18 Sep 2018 16:24:22 +0800
> > > Song Qiang <songqiang1304521@gmail.com> wrote:
> > >
> > > > The first version of this driver issues a measuring request and polling
> > > > for a status register in the device for measuring completes.
> > > > vl53l0x support configuring GPIO1 on it to generate interrupt to
> > > > indicate that new measurement is ready. This patch adds support for
> > > > using this mechanisim to reduce cpu cost.
> > > >
> > > > Signed-off-by: Song Qiang <songqiang1304521@gmail.com>
> > > Hi Song.
> > >
> > > Looks correct in principal but a few things to tidy up before
> > > this is ready to apply.
> > >
> > > Also we have an unrelated change in here to check the devices ID.
> > > That should be in it's own patch.
> > >
> > > Thanks,
> > >
> > > Jonathan
> > > > ---
> > > >  .../bindings/iio/proximity/vl53l0x.txt        |  14 +-
> >
> > This should have been split with the complete binding in one patch
> > rather than piecemeal driver feature by feature.
> >
>
> Hi Rob,
>
> A few days ago when I was submitting this driver, I didn't do it very
> well, the function of this driver is limited. I added interrupt support
> the next day after you acked my first patch. I thought it's not polite
> to add something after someone acked that patch, so I send the interrupt
> support as a second patch. The first patch is merged to togreg now, but
> this doesn't. I don't know when can I add new functions to the code that
> just merged to togreg branch, could you offer some suggestions?

You just needed to state why you didn't add a ack. But really, just
don't send things except as RFC until they are "done".

What to do next depends on Jonathan and whether he wants a follow-up
patch or he will drop the first one.

> > > >  drivers/iio/proximity/vl53l0x-i2c.c           | 135 +++++++++++++++---
> > > >  2 files changed, 129 insertions(+), 20 deletions(-)
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > index ab9a9539fec4..40290f8dd70f 100644
> > > > --- a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > +++ b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > @@ -4,9 +4,21 @@ Required properties:
> > > >   - compatible: must be "st,vl53l0x-i2c"
> >
> > Is there more than one interface on this device, such as SPI? If not,
> > then '-i2c' should be dropped.
> >
>
> Yes, there is a CCI(Camera Control Interface) for communication.

Isn't CCI just a subset of I2C? I should clarify my question is
whether there's more than 1 mutually exclusive control interface (as
many devices have control and data interfaces) where you could have 2
different drivers. A common example are devices with I2C and SPI
interfaces.

Rob
Jonathan Cameron Sept. 29, 2018, 11:10 a.m. UTC | #5
On Fri, 28 Sep 2018 18:52:13 -0500
Rob Herring <robh@kernel.org> wrote:

> On Fri, Sep 28, 2018 at 4:36 AM Song Qiang <songqiang1304521@gmail.com> wrote:
> >
> > On Wed, Sep 26, 2018 at 05:46:18PM -0500, Rob Herring wrote:  
> > > On Sat, Sep 22, 2018 at 04:05:23PM +0100, Jonathan Cameron wrote:  
> > > > On Tue, 18 Sep 2018 16:24:22 +0800
> > > > Song Qiang <songqiang1304521@gmail.com> wrote:
> > > >  
> > > > > The first version of this driver issues a measuring request and polling
> > > > > for a status register in the device for measuring completes.
> > > > > vl53l0x support configuring GPIO1 on it to generate interrupt to
> > > > > indicate that new measurement is ready. This patch adds support for
> > > > > using this mechanisim to reduce cpu cost.
> > > > >
> > > > > Signed-off-by: Song Qiang <songqiang1304521@gmail.com>  
> > > > Hi Song.
> > > >
> > > > Looks correct in principal but a few things to tidy up before
> > > > this is ready to apply.
> > > >
> > > > Also we have an unrelated change in here to check the devices ID.
> > > > That should be in it's own patch.
> > > >
> > > > Thanks,
> > > >
> > > > Jonathan  
> > > > > ---
> > > > >  .../bindings/iio/proximity/vl53l0x.txt        |  14 +-  
> > >
> > > This should have been split with the complete binding in one patch
> > > rather than piecemeal driver feature by feature.
> > >  
> >
> > Hi Rob,

Hi Rob, Song,

> >
> > A few days ago when I was submitting this driver, I didn't do it very
> > well, the function of this driver is limited. I added interrupt support
> > the next day after you acked my first patch. I thought it's not polite
> > to add something after someone acked that patch, so I send the interrupt
> > support as a second patch. The first patch is merged to togreg now, but
> > this doesn't. I don't know when can I add new functions to the code that
> > just merged to togreg branch, could you offer some suggestions?  
> 
> You just needed to state why you didn't add a ack. But really, just
> don't send things except as RFC until they are "done".

The RFC bit actually disagree on.  This driver could be considered 'done'
with just patch 1.  The driver worked, it was useful. When the early
versions of that patch came out Song had no idea how much work it would
be to add interrupt support.  As it turns out it was simple - it often isn't :(

> 
> What to do next depends on Jonathan and whether he wants a follow-up
> patch or he will drop the first one.

Yeah. I should have picked up on the binding in the second patch and merged
it.  I'd seen the first patch a few times before so was happy with it and
applied before actually looking at the second.

If they had come in separate series in my view the partial binding then
extend with 'optional' elements is fine.  The number of times I've discovered
issues with documentation of hardware that would have made any binding written
from the docs wrong is non trivial. So in my view it is always a gamble to
write bindings until you have tested they work.  I have not problem with
people who are confident and want to add them from the start though.

Obviously this only works for optional elements.

So follow up patch for 'optional' stuff is fine by me.  The only real
issue to my mind here is that they were in the same series, so we should
have seen a separate precursor patch giving the binding for all of it.

> 
> > > > >  drivers/iio/proximity/vl53l0x-i2c.c           | 135 +++++++++++++++---
> > > > >  2 files changed, 129 insertions(+), 20 deletions(-)
> > > > >
> > > > > diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > > index ab9a9539fec4..40290f8dd70f 100644
> > > > > --- a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > > +++ b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > > @@ -4,9 +4,21 @@ Required properties:
> > > > >   - compatible: must be "st,vl53l0x-i2c"  
> > >
> > > Is there more than one interface on this device, such as SPI? If not,
> > > then '-i2c' should be dropped.
> > >  
> >
> > Yes, there is a CCI(Camera Control Interface) for communication.  
> 
> Isn't CCI just a subset of I2C? I should clarify my question is
> whether there's more than 1 mutually exclusive control interface (as
> many devices have control and data interfaces) where you could have 2
> different drivers. A common example are devices with I2C and SPI
> interfaces.

Already fixed up when I applied the first patch.  I did more rework on
patch 1 than I'd normally do as I'd sent Song down a dead end with an
incorrect requested change so didn't want to waste more of his time
with a v7 of that patch.  This patch 2 was pretty much new so different
matter!

Thanks,

Jonathan

> 
> Rob
Rob Herring (Arm) Sept. 29, 2018, 11:49 p.m. UTC | #6
On Sat, Sep 29, 2018 at 6:10 AM Jonathan Cameron <jic23@kernel.org> wrote:
>
> On Fri, 28 Sep 2018 18:52:13 -0500
> Rob Herring <robh@kernel.org> wrote:
>
> > On Fri, Sep 28, 2018 at 4:36 AM Song Qiang <songqiang1304521@gmail.com> wrote:
> > >
> > > On Wed, Sep 26, 2018 at 05:46:18PM -0500, Rob Herring wrote:
> > > > On Sat, Sep 22, 2018 at 04:05:23PM +0100, Jonathan Cameron wrote:
> > > > > On Tue, 18 Sep 2018 16:24:22 +0800
> > > > > Song Qiang <songqiang1304521@gmail.com> wrote:
> > > > >
> > > > > > The first version of this driver issues a measuring request and polling
> > > > > > for a status register in the device for measuring completes.
> > > > > > vl53l0x support configuring GPIO1 on it to generate interrupt to
> > > > > > indicate that new measurement is ready. This patch adds support for
> > > > > > using this mechanisim to reduce cpu cost.
> > > > > >
> > > > > > Signed-off-by: Song Qiang <songqiang1304521@gmail.com>
> > > > > Hi Song.
> > > > >
> > > > > Looks correct in principal but a few things to tidy up before
> > > > > this is ready to apply.
> > > > >
> > > > > Also we have an unrelated change in here to check the devices ID.
> > > > > That should be in it's own patch.
> > > > >
> > > > > Thanks,
> > > > >
> > > > > Jonathan
> > > > > > ---
> > > > > >  .../bindings/iio/proximity/vl53l0x.txt        |  14 +-
> > > >
> > > > This should have been split with the complete binding in one patch
> > > > rather than piecemeal driver feature by feature.
> > > >
> > >
> > > Hi Rob,
>
> Hi Rob, Song,
>
> > >
> > > A few days ago when I was submitting this driver, I didn't do it very
> > > well, the function of this driver is limited. I added interrupt support
> > > the next day after you acked my first patch. I thought it's not polite
> > > to add something after someone acked that patch, so I send the interrupt
> > > support as a second patch. The first patch is merged to togreg now, but
> > > this doesn't. I don't know when can I add new functions to the code that
> > > just merged to togreg branch, could you offer some suggestions?
> >
> > You just needed to state why you didn't add a ack. But really, just
> > don't send things except as RFC until they are "done".
>
> The RFC bit actually disagree on.  This driver could be considered 'done'
> with just patch 1.  The driver worked, it was useful. When the early
> versions of that patch came out Song had no idea how much work it would
> be to add interrupt support.  As it turns out it was simple - it often isn't :(

I meant specifically in the context of this getting revised within a
number of days. I agree that drivers don't have to be complete, but
bindings should be as complete as possible. You can't foresee
everything, but I don't think that applies in this case.

> > What to do next depends on Jonathan and whether he wants a follow-up
> > patch or he will drop the first one.
>
> Yeah. I should have picked up on the binding in the second patch and merged
> it.  I'd seen the first patch a few times before so was happy with it and
> applied before actually looking at the second.
>
> If they had come in separate series in my view the partial binding then
> extend with 'optional' elements is fine.  The number of times I've discovered
> issues with documentation of hardware that would have made any binding written
> from the docs wrong is non trivial. So in my view it is always a gamble to
> write bindings until you have tested they work.  I have not problem with
> people who are confident and want to add them from the start though.

Well, if they were broken is some way, I don't think backwards
compatibility matters and we can still fix things. I'm not talking
about complex cases here. It is pretty trivial to determine whether a
device has an interrupt or not.

>
> Obviously this only works for optional elements.
>
> So follow up patch for 'optional' stuff is fine by me.  The only real
> issue to my mind here is that they were in the same series, so we should
> have seen a separate precursor patch giving the binding for all of it.

Certainly, that can't be avoided sometimes and is fine. It's really
the time frame for this particular case and reviewer bandwidth.

Rob
Jonathan Cameron Sept. 30, 2018, 3:20 p.m. UTC | #7
On 30 September 2018 00:49:43 BST, Rob Herring <robh@kernel.org> wrote:
>On Sat, Sep 29, 2018 at 6:10 AM Jonathan Cameron <jic23@kernel.org>
>wrote:
>>
>> On Fri, 28 Sep 2018 18:52:13 -0500
>> Rob Herring <robh@kernel.org> wrote:
>>
>> > On Fri, Sep 28, 2018 at 4:36 AM Song Qiang
><songqiang1304521@gmail.com> wrote:
>> > >
>> > > On Wed, Sep 26, 2018 at 05:46:18PM -0500, Rob Herring wrote:
>> > > > On Sat, Sep 22, 2018 at 04:05:23PM +0100, Jonathan Cameron
>wrote:
>> > > > > On Tue, 18 Sep 2018 16:24:22 +0800
>> > > > > Song Qiang <songqiang1304521@gmail.com> wrote:
>> > > > >
>> > > > > > The first version of this driver issues a measuring request
>and polling
>> > > > > > for a status register in the device for measuring
>completes.
>> > > > > > vl53l0x support configuring GPIO1 on it to generate
>interrupt to
>> > > > > > indicate that new measurement is ready. This patch adds
>support for
>> > > > > > using this mechanisim to reduce cpu cost.
>> > > > > >
>> > > > > > Signed-off-by: Song Qiang <songqiang1304521@gmail.com>
>> > > > > Hi Song.
>> > > > >
>> > > > > Looks correct in principal but a few things to tidy up before
>> > > > > this is ready to apply.
>> > > > >
>> > > > > Also we have an unrelated change in here to check the devices
>ID.
>> > > > > That should be in it's own patch.
>> > > > >
>> > > > > Thanks,
>> > > > >
>> > > > > Jonathan
>> > > > > > ---
>> > > > > >  .../bindings/iio/proximity/vl53l0x.txt        |  14 +-
>> > > >
>> > > > This should have been split with the complete binding in one
>patch
>> > > > rather than piecemeal driver feature by feature.
>> > > >
>> > >
>> > > Hi Rob,
>>
>> Hi Rob, Song,
>>
>> > >
>> > > A few days ago when I was submitting this driver, I didn't do it
>very
>> > > well, the function of this driver is limited. I added interrupt
>support
>> > > the next day after you acked my first patch. I thought it's not
>polite
>> > > to add something after someone acked that patch, so I send the
>interrupt
>> > > support as a second patch. The first patch is merged to togreg
>now, but
>> > > this doesn't. I don't know when can I add new functions to the
>code that
>> > > just merged to togreg branch, could you offer some suggestions?
>> >
>> > You just needed to state why you didn't add a ack. But really, just
>> > don't send things except as RFC until they are "done".
>>
>> The RFC bit actually disagree on.  This driver could be considered
>'done'
>> with just patch 1.  The driver worked, it was useful. When the early
>> versions of that patch came out Song had no idea how much work it
>would
>> be to add interrupt support.  As it turns out it was simple - it
>often isn't :(
>
>I meant specifically in the context of this getting revised within a
>number of days. I agree that drivers don't have to be complete, but
>bindings should be as complete as possible. You can't foresee
>everything, but I don't think that applies in this case.
>
>> > What to do next depends on Jonathan and whether he wants a
>follow-up
>> > patch or he will drop the first one.
>>
>> Yeah. I should have picked up on the binding in the second patch and
>merged
>> it.  I'd seen the first patch a few times before so was happy with it
>and
>> applied before actually looking at the second.
>>
>> If they had come in separate series in my view the partial binding
>then
>> extend with 'optional' elements is fine.  The number of times I've
>discovered
>> issues with documentation of hardware that would have made any
>binding written
>> from the docs wrong is non trivial. So in my view it is always a
>gamble to
>> write bindings until you have tested they work.  I have not problem
>with
>> people who are confident and want to add them from the start though.
>
>Well, if they were broken is some way, I don't think backwards
>compatibility matters and we can still fix things. I'm not talking
>about complex cases here. It is pretty trivial to determine whether a
>device has an interrupt or not.
>
>>
>> Obviously this only works for optional elements.
>>
>> So follow up patch for 'optional' stuff is fine by me.  The only real
>> issue to my mind here is that they were in the same series, so we
>should
>> have seen a separate precursor patch giving the binding for all of
>it.
>
>Certainly, that can't be avoided sometimes and is fine. It's really
>the time frame for this particular case and reviewer bandwidth.

Agreed. The timing wasn't ideal (in this limited sense)  Song got this done much faster than I normally expect
when someone says, I'll do this later! 

Thanks for clarifying.

Jonathan
>
>Rob
Song Qiang Oct. 1, 2018, 3:58 a.m. UTC | #8
On Fri, Sep 28, 2018 at 06:52:13PM -0500, Rob Herring wrote:
> On Fri, Sep 28, 2018 at 4:36 AM Song Qiang <songqiang1304521@gmail.com> wrote:
> >
> > On Wed, Sep 26, 2018 at 05:46:18PM -0500, Rob Herring wrote:
> > > On Sat, Sep 22, 2018 at 04:05:23PM +0100, Jonathan Cameron wrote:
> > > > On Tue, 18 Sep 2018 16:24:22 +0800
> > > > Song Qiang <songqiang1304521@gmail.com> wrote:
> > > >
> > > > > The first version of this driver issues a measuring request and polling
> > > > > for a status register in the device for measuring completes.
> > > > > vl53l0x support configuring GPIO1 on it to generate interrupt to
> > > > > indicate that new measurement is ready. This patch adds support for
> > > > > using this mechanisim to reduce cpu cost.
> > > > >
> > > > > Signed-off-by: Song Qiang <songqiang1304521@gmail.com>
> > > > Hi Song.
> > > >
> > > > Looks correct in principal but a few things to tidy up before
> > > > this is ready to apply.
> > > >
> > > > Also we have an unrelated change in here to check the devices ID.
> > > > That should be in it's own patch.
> > > >
> > > > Thanks,
> > > >
> > > > Jonathan
> > > > > ---
> > > > >  .../bindings/iio/proximity/vl53l0x.txt        |  14 +-
> > >
> > > This should have been split with the complete binding in one patch
> > > rather than piecemeal driver feature by feature.
> > >
> >
> > Hi Rob,
> >
> > A few days ago when I was submitting this driver, I didn't do it very
> > well, the function of this driver is limited. I added interrupt support
> > the next day after you acked my first patch. I thought it's not polite
> > to add something after someone acked that patch, so I send the interrupt
> > support as a second patch. The first patch is merged to togreg now, but
> > this doesn't. I don't know when can I add new functions to the code that
> > just merged to togreg branch, could you offer some suggestions?
> 
> You just needed to state why you didn't add a ack. But really, just
> don't send things except as RFC until they are "done".
> 
> What to do next depends on Jonathan and whether he wants a follow-up
> patch or he will drop the first one.
> 
> > > > >  drivers/iio/proximity/vl53l0x-i2c.c           | 135 +++++++++++++++---
> > > > >  2 files changed, 129 insertions(+), 20 deletions(-)
> > > > >
> > > > > diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > > index ab9a9539fec4..40290f8dd70f 100644
> > > > > --- a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > > +++ b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > > @@ -4,9 +4,21 @@ Required properties:
> > > > >   - compatible: must be "st,vl53l0x-i2c"
> > >
> > > Is there more than one interface on this device, such as SPI? If not,
> > > then '-i2c' should be dropped.
> > >
> >
> > Yes, there is a CCI(Camera Control Interface) for communication.
> 
> Isn't CCI just a subset of I2C? I should clarify my question is
> whether there's more than 1 mutually exclusive control interface (as
> many devices have control and data interfaces) where you could have 2
> different drivers. A common example are devices with I2C and SPI
> interfaces.
> 
> Rob

Hi Rob, Jonathan,

I don't know things about CCI very well, and google also tells me little
about it. Actually, I found it difficult to find a standard definition
about it. Then I dug into vl53l0x's API source code, and what I can
tell is when we use these two interfaces, the whole programming
framework is different, even though the pysical bus of them are likely
to be the same. 
Source code of CCI uses a 'msm_camera_i2c_fn_t' struct and a
'v4l2_file_operations' as hardware interfaces for controlling device,
while the i2c one just uses generic i2c bus interfaces.

This explanation is for why the file name still contains '-i2c'.

yours,
Song Qiang
Jonathan Cameron Oct. 1, 2018, 6:44 p.m. UTC | #9
On Mon, 1 Oct 2018 11:58:14 +0800
Song Qiang <songqiang1304521@gmail.com> wrote:

> On Fri, Sep 28, 2018 at 06:52:13PM -0500, Rob Herring wrote:
> > On Fri, Sep 28, 2018 at 4:36 AM Song Qiang <songqiang1304521@gmail.com> wrote:  
> > >
> > > On Wed, Sep 26, 2018 at 05:46:18PM -0500, Rob Herring wrote:  
> > > > On Sat, Sep 22, 2018 at 04:05:23PM +0100, Jonathan Cameron wrote:  
> > > > > On Tue, 18 Sep 2018 16:24:22 +0800
> > > > > Song Qiang <songqiang1304521@gmail.com> wrote:
> > > > >  
> > > > > > The first version of this driver issues a measuring request and polling
> > > > > > for a status register in the device for measuring completes.
> > > > > > vl53l0x support configuring GPIO1 on it to generate interrupt to
> > > > > > indicate that new measurement is ready. This patch adds support for
> > > > > > using this mechanisim to reduce cpu cost.
> > > > > >
> > > > > > Signed-off-by: Song Qiang <songqiang1304521@gmail.com>  
> > > > > Hi Song.
> > > > >
> > > > > Looks correct in principal but a few things to tidy up before
> > > > > this is ready to apply.
> > > > >
> > > > > Also we have an unrelated change in here to check the devices ID.
> > > > > That should be in it's own patch.
> > > > >
> > > > > Thanks,
> > > > >
> > > > > Jonathan  
> > > > > > ---
> > > > > >  .../bindings/iio/proximity/vl53l0x.txt        |  14 +-  
> > > >
> > > > This should have been split with the complete binding in one patch
> > > > rather than piecemeal driver feature by feature.
> > > >  
> > >
> > > Hi Rob,
> > >
> > > A few days ago when I was submitting this driver, I didn't do it very
> > > well, the function of this driver is limited. I added interrupt support
> > > the next day after you acked my first patch. I thought it's not polite
> > > to add something after someone acked that patch, so I send the interrupt
> > > support as a second patch. The first patch is merged to togreg now, but
> > > this doesn't. I don't know when can I add new functions to the code that
> > > just merged to togreg branch, could you offer some suggestions?  
> > 
> > You just needed to state why you didn't add a ack. But really, just
> > don't send things except as RFC until they are "done".
> > 
> > What to do next depends on Jonathan and whether he wants a follow-up
> > patch or he will drop the first one.
> >   
> > > > > >  drivers/iio/proximity/vl53l0x-i2c.c           | 135 +++++++++++++++---
> > > > > >  2 files changed, 129 insertions(+), 20 deletions(-)
> > > > > >
> > > > > > diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > > > index ab9a9539fec4..40290f8dd70f 100644
> > > > > > --- a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > > > +++ b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
> > > > > > @@ -4,9 +4,21 @@ Required properties:
> > > > > >   - compatible: must be "st,vl53l0x-i2c"  
> > > >
> > > > Is there more than one interface on this device, such as SPI? If not,
> > > > then '-i2c' should be dropped.
> > > >  
> > >
> > > Yes, there is a CCI(Camera Control Interface) for communication.  
> > 
> > Isn't CCI just a subset of I2C? I should clarify my question is
> > whether there's more than 1 mutually exclusive control interface (as
> > many devices have control and data interfaces) where you could have 2
> > different drivers. A common example are devices with I2C and SPI
> > interfaces.
> > 
> > Rob  
> 
> Hi Rob, Jonathan,
> 
> I don't know things about CCI very well, and google also tells me little
> about it. Actually, I found it difficult to find a standard definition
> about it. Then I dug into vl53l0x's API source code, and what I can
> tell is when we use these two interfaces, the whole programming
> framework is different, even though the pysical bus of them are likely
> to be the same. 
> Source code of CCI uses a 'msm_camera_i2c_fn_t' struct and a
> 'v4l2_file_operations' as hardware interfaces for controlling device,
> while the i2c one just uses generic i2c bus interfaces.
> 
> This explanation is for why the file name still contains '-i2c'.
> 
File names are easy to change in future compared to device tree bindings
(which may be fixed for ever in an embedded platform).

So this isn't a problem at all.

Thanks,

Jonathan

> yours,
> Song Qiang
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
index ab9a9539fec4..40290f8dd70f 100644
--- a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
+++ b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
@@ -4,9 +4,21 @@  Required properties:
 	- compatible: must be "st,vl53l0x-i2c"
 	- reg: i2c address where to find the device
 
+Optional properties:
+	- interrupts : Interrupt line receiving GPIO1's measuring complete
+	  output, supports IRQ_TYPE_EDGE_FALLING only.
+
+	Refer to interrupt-controller/interrupts.txt for generic
+	interrupt client node bindings.
+
 Example:
 
 vl53l0x@29 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&vl53l0x_pins>;
+
 	compatible = "st,vl53l0x-i2c";
 	reg = <0x29>;
-};
+	interrupt-parent = <&gpio3>;
+	interrupts = <17 IRQ_TYPE_EDGE_FALLING>;
+}
diff --git a/drivers/iio/proximity/vl53l0x-i2c.c b/drivers/iio/proximity/vl53l0x-i2c.c
index 1aad45df8d95..a5cff11f41de 100644
--- a/drivers/iio/proximity/vl53l0x-i2c.c
+++ b/drivers/iio/proximity/vl53l0x-i2c.c
@@ -10,18 +10,21 @@ 
  *
  * Default 7-bit i2c slave address 0x29.
  *
- * TODO: FIFO buffer, continuous mode, interrupts, range selection,
- * sensor ID check.
+ * TODO: FIFO buffer, continuous mode, range selection.
  */
 
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/interrupt.h>
 
 #include <linux/iio/iio.h>
 
+#include <stdbool.h>
+
 #define VL_REG_SYSRANGE_START				0x00
 
+/* Mode configuration registers. */
 #define VL_REG_SYSRANGE_MODE_MASK			GENMASK(3, 0)
 #define VL_REG_SYSRANGE_MODE_SINGLESHOT			0x00
 #define VL_REG_SYSRANGE_MODE_START_STOP			BIT(0)
@@ -29,14 +32,61 @@ 
 #define VL_REG_SYSRANGE_MODE_TIMED			BIT(2)
 #define VL_REG_SYSRANGE_MODE_HISTOGRAM			BIT(3)
 
+/* Result registers. */
 #define VL_REG_RESULT_INT_STATUS			0x13
 #define VL_REG_RESULT_RANGE_STATUS			0x14
 #define VL_REG_RESULT_RANGE_STATUS_COMPLETE		BIT(0)
 
+/* GPIO function configuration registers. */
+#define VL_REG_GPIO_HV_MUX_ACTIVE_GIGH			0x84
+#define VL_REG_SYS_INT_CFG_GPIO				0x0A
+#define VL_GPIOFUNC_NEW_MEASURE_RDY			BIT(2)
+
+/* Interrupt configuration registers. */
+#define VL_REG_SYS_INT_CLEAR				0x0B
+#define VL_REG_RESULT_INT_STATUS			0x13
+#define VL_INT_POLARITY_LOW				0x00
+#define VL_INT_POLARITY_HIGH				BIT(0)
+
+/* Should be 0xEE if connection is fine. */
+#define VL_REG_MODEL_ID					0xC0
+
 struct vl53l0x_data {
 	struct i2c_client *client;
+	struct completion measuring_done;
+	bool use_interrupt;
 };
 
+static int vl53l0x_clear_interrupt(struct vl53l0x_data *data)
+{
+	int ret;
+	u8 cnt = 0;
+
+	do {
+		/* bit 0 for measuring interrupt, bit 1 for error interrupt.  */
+		i2c_smbus_write_byte_data(data->client,
+			VL_REG_SYS_INT_CLEAR, 1);
+		i2c_smbus_write_byte_data(data->client,
+			VL_REG_SYS_INT_CLEAR, 0);
+		ret = i2c_smbus_read_byte_data(data->client,
+			VL_REG_RESULT_INT_STATUS);
+		cnt++;
+	} while ((ret & 0x07) && (cnt < 3));
+	if (cnt > 2)
+		return -ETIMEDOUT;
+	else
+		return 0;
+}
+
+static irqreturn_t vl53l0x_irq_handler(int irq, void *d)
+{
+	struct vl53l0x_data *data = d;
+
+	complete(&data->measuring_done);
+
+	return IRQ_HANDLED;
+}
+
 static int vl53l0x_read_proximity(struct vl53l0x_data *data,
 				  const struct iio_chan_spec *chan,
 				  int *val)
@@ -46,23 +96,31 @@  static int vl53l0x_read_proximity(struct vl53l0x_data *data,
 	u8 buffer[12];
 	int ret;
 
-	ret = i2c_smbus_write_byte_data(client, VL_REG_SYSRANGE_START, 1);
-	if (ret < 0)
-		return ret;
-
-	do {
-		ret = i2c_smbus_read_byte_data(client,
-			VL_REG_RESULT_RANGE_STATUS);
-		if (ret < 0)
-			return ret;
-
-		if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE)
-			break;
-
-		usleep_range(1000, 5000);
-	} while (--tries);
-	if (!tries)
-		return -ETIMEDOUT;
+	if (data->use_interrupt)
+		reinit_completion(&data->measuring_done);
+
+	i2c_smbus_write_byte_data(client, VL_REG_SYSRANGE_START, 1);
+
+	/* In usual case the longest valid conversion time is less than 70ms. */
+	if (data->use_interrupt) {
+		ret = wait_for_completion_timeout(&data->measuring_done,
+			msecs_to_jiffies(100));
+		if (!ret)
+			return -ETIMEDOUT;
+		vl53l0x_clear_interrupt(data);
+	} else {
+		do {
+			ret = i2c_smbus_read_byte_data(client,
+				VL_REG_RESULT_RANGE_STATUS);
+
+			if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE)
+				break;
+
+			usleep_range(1000, 5000);
+		} while (--tries);
+		if (!tries)
+			return -ETIMEDOUT;
+	}
 
 	ret = i2c_smbus_read_i2c_block_data(client, VL_REG_RESULT_RANGE_STATUS,
 		12, buffer);
@@ -110,10 +168,21 @@  static const struct iio_info vl53l0x_info = {
 	.read_raw = vl53l0x_read_raw,
 };
 
+/* Congigure the GPIO1 pin to generate interrupt for measurement ready,
+ * default polarity is level low.
+ */
+static int vl53l0x_config_irq(struct vl53l0x_data *data)
+{
+	i2c_smbus_write_byte_data(data->client, VL_REG_SYS_INT_CFG_GPIO,
+		VL_GPIOFUNC_NEW_MEASURE_RDY);
+	return vl53l0x_clear_interrupt(data);
+}
+
 static int vl53l0x_probe(struct i2c_client *client)
 {
 	struct vl53l0x_data *data;
 	struct iio_dev *indio_dev;
+	int ret;
 
 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 	if (!indio_dev)
@@ -134,6 +203,34 @@  static int vl53l0x_probe(struct i2c_client *client)
 	indio_dev->num_channels = ARRAY_SIZE(vl53l0x_channels);
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
+	if (!client->irq)
+		data->use_interrupt = false;
+	else {
+		data->use_interrupt = true;
+		ret = devm_request_irq(&client->dev,
+			client->irq,
+			vl53l0x_irq_handler,
+			IRQF_TRIGGER_FALLING,
+			indio_dev->name,
+			data);
+		if (ret < 0) {
+			dev_err(&client->dev,
+			"request irq line failed.");
+			return -EINVAL;
+		}
+		vl53l0x_config_irq(data);
+		init_completion(&data->measuring_done);
+	}
+
+	/* After checking this, assuming write and read byte operations should
+	 *  never fails.
+	 */
+	ret = i2c_smbus_read_byte_data(client, VL_REG_MODEL_ID);
+	if (ret != 0xEE) {
+		dev_err(&client->dev, "device not found. ");
+		return -EREMOTEIO;
+	}
+
 	return devm_iio_device_register(&client->dev, indio_dev);
 }