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 |
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); > } >
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>; > > +}
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>; > > > +}
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
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
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
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
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
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 --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); }
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(-)