From: Jonathan Cameron <jic23@kernel.org>
To: Tomas Novotny <tomas@novotny.cz>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>,
linux-iio@vger.kernel.org, Hartmut Knaack <knaack.h@gmx.de>,
Lars-Peter Clausen <lars@metafoo.de>
Subject: Re: [PATCH 1/2] iio: vcnl4000: make the driver extendable
Date: Sat, 10 Feb 2018 14:59:32 +0000 [thread overview]
Message-ID: <20180210145932.1de3f3e2@archlinux> (raw)
In-Reply-To: <20180206141740.5cd02807@tomas.local.tbs-biometrics.cz>
On Tue, 6 Feb 2018 14:17:40 +0100
Tomas Novotny <tomas@novotny.cz> wrote:
> Hi Peter,
>
> On Mon, 5 Feb 2018 21:00:48 +0100 (CET)
> Peter Meerwald-Stadler <pmeerw@pmeerw.net> wrote:
>
> > > There are similar chips in a vcnl4xxx family. The initialization and
> > > communication is a bit different for another members of the family, so
> > > this patch makes the driver extendable for different chips.
> >
> > > There is no functional change.
> >
> > looks good to me, suggestion below but not mandatory
> >
> > > Signed-off-by: Tomas Novotny <tomas@novotny.cz>
> > > ---
> > > drivers/iio/light/vcnl4000.c | 86 ++++++++++++++++++++++++++++++++++----------
> > > 1 file changed, 68 insertions(+), 18 deletions(-)
> > >
> > > diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
> > > index c599a90506ad..d7e43fd9333e 100644
> > > --- a/drivers/iio/light/vcnl4000.c
> > > +++ b/drivers/iio/light/vcnl4000.c
> > > @@ -26,8 +26,8 @@
> > > #include <linux/iio/sysfs.h>
> > >
> > > #define VCNL4000_DRV_NAME "vcnl4000"
> > > -#define VCNL4000_ID 0x01
> > > -#define VCNL4010_ID 0x02 /* for VCNL4020, VCNL4010 */
> > > +#define VCNL4000_PROD_ID 0x01
> > > +#define VCNL4010_PROD_ID 0x02 /* for VCNL4020, VCNL4010 */
> > >
> > > #define VCNL4000_COMMAND 0x80 /* Command register */
> > > #define VCNL4000_PROD_REV 0x81 /* Product ID and Revision ID */
> > > @@ -46,17 +46,52 @@
> > > #define VCNL4000_AL_OD BIT(4) /* start on-demand ALS measurement */
> > > #define VCNL4000_PS_OD BIT(3) /* start on-demand proximity measurement */
> > >
> > > +enum vcnl4000_device_ids {
> > > + VCNL4000,
> >
> > maybe add VCNL4010 here and in vcnl4000_chip_spec_cfg just for
> > completeness, so that all IDs are actually used?
>
> ok, I will do. Does it make sense to be strict and return -ENODEV (with
> appropriate message) when vcnl4000 i2c device is specified but
> VCNL4010_PROD_ID is found (and the same for VCNL4000_PROD_ID)? There is only
> a general check now, see below.
Probably better to just put a warning out. People have an irritating habit
of having a dt file for their board based on the wrong compatible.
Given the driver can detect this and 'fix' it I think it should.
Please do put a suitably worded warning in the logs though as better
to fix it properly!
>
> > > +};
> > > +
> > > struct vcnl4000_data {
> > > struct i2c_client *client;
> > > + enum vcnl4000_device_ids id;
> > > + const char *prod;
> > > + int rev;
> > > + int al_scale;
> > > + const struct vcnl4000_chip_spec *chip_spec;
> > > struct mutex lock;
> > > };
> > >
> > > +struct vcnl4000_chip_spec {
> > > + int (*init)(struct vcnl4000_data *data);
> > > + int (*measure_light)(struct vcnl4000_data *data, int *val);
> > > + int (*measure_proximity)(struct vcnl4000_data *data, int *val);
> > > +};
> > > +
> > > static const struct i2c_device_id vcnl4000_id[] = {
> > > - { "vcnl4000", 0 },
> > > + { "vcnl4000", VCNL4000 },
> > > { }
> > > };
> > > MODULE_DEVICE_TABLE(i2c, vcnl4000_id);
> > >
> > > +static int vcnl4000_init(struct vcnl4000_data *data)
> > > +{
> > > + int ret, prod_id;
> > > +
> > > + ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
> > > + if (ret < 0)
> > > + return ret;
> > > +
> > > + prod_id = ret >> 4;
> > > + if (prod_id != VCNL4010_PROD_ID && prod_id != VCNL4000_PROD_ID)
> > > + return -ENODEV;
>
As a general scalability thing, I would do that as a switch statement.
These sorts of if statements have a habit of growing every time a new
variant comes along and in the end get changed to a switch statement
which causes more noise than it would have done if we had allowed for
the future in the first place.
> here ^^^
>
> Thanks,
>
> Tomas
>
> > > + data->prod = prod_id == VCNL4010_PROD_ID ? "VCNL4010/4020" : "VCNL4000";
> > > + data->rev = ret & 0xf;
> > > +
> > > + data->al_scale = 250000;
> > > +
> > > + return 0;
> > > +};
> > > +
> > > static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
> > > u8 rdy_mask, u8 data_reg, int *val)
> > > {
> > > @@ -103,6 +138,28 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
> > > return ret;
> > > }
> > >
> > > +static int vcnl4000_measure_light(struct vcnl4000_data *data, int *val)
> > > +{
> > > + return vcnl4000_measure(data,
> > > + VCNL4000_AL_OD, VCNL4000_AL_RDY,
> > > + VCNL4000_AL_RESULT_HI, val);
> > > +}
> > > +
> > > +static int vcnl4000_measure_proximity(struct vcnl4000_data *data, int *val)
> > > +{
> > > + return vcnl4000_measure(data,
> > > + VCNL4000_PS_OD, VCNL4000_PS_RDY,
> > > + VCNL4000_PS_RESULT_HI, val);
> > > +}
> > > +
> > > +static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = {
> > > + [VCNL4000] = {
> > > + .init = vcnl4000_init,
> > > + .measure_light = vcnl4000_measure_light,
> > > + .measure_proximity = vcnl4000_measure_proximity,
> > > + },
> > > +};
> > > +
> > > static const struct iio_chan_spec vcnl4000_channels[] = {
> > > {
> > > .type = IIO_LIGHT,
> > > @@ -125,16 +182,12 @@ static int vcnl4000_read_raw(struct iio_dev *indio_dev,
> > > case IIO_CHAN_INFO_RAW:
> > > switch (chan->type) {
> > > case IIO_LIGHT:
> > > - ret = vcnl4000_measure(data,
> > > - VCNL4000_AL_OD, VCNL4000_AL_RDY,
> > > - VCNL4000_AL_RESULT_HI, val);
> > > + ret = data->chip_spec->measure_light(data, val);
> > > if (ret < 0)
> > > return ret;
> > > return IIO_VAL_INT;
> > > case IIO_PROXIMITY:
> > > - ret = vcnl4000_measure(data,
> > > - VCNL4000_PS_OD, VCNL4000_PS_RDY,
> > > - VCNL4000_PS_RESULT_HI, val);
> > > + ret = data->chip_spec->measure_proximity(data, val);
> > > if (ret < 0)
> > > return ret;
> > > return IIO_VAL_INT;
> > > @@ -146,7 +199,7 @@ static int vcnl4000_read_raw(struct iio_dev *indio_dev,
> > > return -EINVAL;
> > >
> > > *val = 0;
> > > - *val2 = 250000;
> > > + *val2 = data->al_scale;
> > > return IIO_VAL_INT_PLUS_MICRO;
> > > default:
> > > return -EINVAL;
> > > @@ -162,7 +215,7 @@ static int vcnl4000_probe(struct i2c_client *client,
> > > {
> > > struct vcnl4000_data *data;
> > > struct iio_dev *indio_dev;
> > > - int ret, prod_id;
> > > + int ret;
> > >
> > > indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> > > if (!indio_dev)
> > > @@ -171,19 +224,16 @@ static int vcnl4000_probe(struct i2c_client *client,
> > > data = iio_priv(indio_dev);
> > > i2c_set_clientdata(client, indio_dev);
> > > data->client = client;
> > > + data->id = id->driver_data;
> > > + data->chip_spec = &vcnl4000_chip_spec_cfg[data->id];
> > > mutex_init(&data->lock);
> > >
> > > - ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
> > > + ret = data->chip_spec->init(data);
> > > if (ret < 0)
> > > return ret;
> > >
> > > - prod_id = ret >> 4;
> > > - if (prod_id != VCNL4010_ID && prod_id != VCNL4000_ID)
> > > - return -ENODEV;
> > > -
> > > dev_dbg(&client->dev, "%s Ambient light/proximity sensor, Rev: %02x\n",
> > > - (prod_id == VCNL4010_ID) ? "VCNL4010/4020" : "VCNL4000",
> > > - ret & 0xf);
> > > + data->prod, data->rev);
> > >
> > > indio_dev->dev.parent = &client->dev;
> > > indio_dev->info = &vcnl4000_info;
> > >
> >
next prev parent reply other threads:[~2018-02-10 14:59 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-05 18:04 [PATCH 0/2] iio: vcnl4000: add support for vcnl4200 Tomas Novotny
2018-02-05 18:04 ` [PATCH 1/2] iio: vcnl4000: make the driver extendable Tomas Novotny
2018-02-05 20:00 ` Peter Meerwald-Stadler
2018-02-06 13:17 ` Tomas Novotny
2018-02-10 14:59 ` Jonathan Cameron [this message]
2018-02-13 18:19 ` Tomas Novotny
2018-02-05 18:04 ` [PATCH 2/2] iio: vcnl4000: add support for VCNL4200 Tomas Novotny
2018-02-05 19:55 ` Peter Meerwald-Stadler
2018-02-06 13:46 ` Tomas Novotny
2018-02-10 15:16 ` Jonathan Cameron
2018-02-13 18:13 ` Tomas Novotny
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180210145932.1de3f3e2@archlinux \
--to=jic23@kernel.org \
--cc=knaack.h@gmx.de \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=pmeerw@pmeerw.net \
--cc=tomas@novotny.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.