From: Andy Shevchenko <andriy.shevchenko@intel.com>
To: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Cc: "Jonathan Cameron" <jic23@kernel.org>,
"Lars-Peter Clausen" <lars@metafoo.de>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"David Lechner" <dlechner@baylibre.com>,
"Nuno Sá" <nuno.sa@analog.com>,
"Andy Shevchenko" <andy@kernel.org>,
linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v5 2/4] iio: light: add support for veml6031x00 ALS series
Date: Mon, 10 Aug 2026 16:38:53 +0300 [thread overview]
Message-ID: <annUbQQn2TzzuFNC@ashevche-desk.local> (raw)
In-Reply-To: <20260807-veml6031x00-v5-2-e60876fb3640@gmail.com>
On Fri, Aug 07, 2026 at 03:51:53PM +0200, Javier Carrasco wrote:
> These sensors provide two light channels (ALS and IR), I2C communication
> and a multiplexed interrupt line to signal data ready and configurable
> threshold alarms.
>
> This first implementation provides basic functionality (measurement
> configuration, raw reads and ID validation) and defines the different
> register regions in preparation for extended features in the subsequent
> patches of the series.
Since it's going to be a new version, my comments below.
...
+ array_size.h // ARRAY_SIZE()
> +#include <linux/bitfield.h>
Is this in use?
+ bits.h // BIT()
> +#include <linux/cleanup.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
Oh, the whole headers hell is loaded just due to dev_get_drvdata() it seems...
> +#include <linux/err.h>
> +#include <linux/i2c.h>
> +#include <linux/limits.h>
I missed probably it, but is it used?
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/mutex.h>
> +#include <linux/pm.h>
Not really required as pm_runtime.h takes care of.
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
+ types.h // bool, __le16, et cetera.
+ asm/byteorder.h // le16_to_cpu() et alia.
...
> +static void veml6031x00_als_shutdown_action(void *data)
> +{
> + struct veml6031x00_data *veml = data;
> + int ret;
> +
> + ret = veml6031x00_set_power_state(veml, false);
> + if (ret)
> + dev_err(regmap_get_device(veml->regmap),
> + "Failed to shut down device: %d\n", ret);
It's only a warning, as there is neither error returning, nor a fallback.
> +}
...
> +static int veml6031x00_regfield_init(struct veml6031x00_data *data)
> +{
struct device *dev = regmap_get_device(...);
> + struct regmap_field *rm_field;
> + struct veml6031x00_rf *rf = &data->rf;
> +
> + rm_field = devm_regmap_field_alloc(regmap_get_device(data->regmap),
> + data->regmap, veml6031x00_rf_gain);
rm_field = devm_regmap_field_alloc(dev, data->regmap, veml6031x00_rf_gain);
(yes, slightly longer than 80, but I think it's okay, even in the last case
below).
> + if (IS_ERR(rm_field))
> + return PTR_ERR(rm_field);
> + rf->gain = rm_field;
> +
> + rm_field = devm_regmap_field_alloc(regmap_get_device(data->regmap),
> + data->regmap, veml6031x00_rf_it);
> + if (IS_ERR(rm_field))
> + return PTR_ERR(rm_field);
> + rf->it = rm_field;
> +
> + rm_field = devm_regmap_field_alloc(regmap_get_device(data->regmap),
> + data->regmap, veml6031x00_rf_pd_div4);
> + if (IS_ERR(rm_field))
> + return PTR_ERR(rm_field);
> + rf->pd_div4 = rm_field;
> +
> + return 0;
> +}
...
> +static int veml6031x00_get_it(struct veml6031x00_data *data, int *val2)
> +{
> + scoped_guard(mutex, &data->scale_lock)
guard()() will suffice in this case. Yes, will need a blank line, but overall
it's a better choice I think.
> + return __veml6031x00_get_it(data, val2);
> +}
...
> +static int veml6031x00_set_it(struct iio_dev *iio, int val, int val2)
> +{
> + struct veml6031x00_data *data = iio_priv(iio);
> + int ret, gain_sel, new_gain, prev_gain, prev_it;
> + unsigned int gain_reg, it_idx, pd_div4;
> + bool in_range;
Can we name it differently? When grepping over the whole tree this will give
a lot of the common in_range() calls...
> +
> + if (val || !iio_gts_valid_time(&data->gts, val2))
> + return -EINVAL;
> +
> + guard(mutex)(&data->scale_lock);
> +
> + ret = regmap_field_read(data->rf.it, &it_idx);
> + if (ret)
> + return ret;
> +
> + ret = regmap_field_read(data->rf.gain, &gain_reg);
> + if (ret)
> + return ret;
> +
> + ret = regmap_field_read(data->rf.pd_div4, &pd_div4);
> + if (ret)
> + return ret;
> +
> + prev_it = iio_gts_find_int_time_by_sel(&data->gts, it_idx);
> + if (prev_it < 0)
> + return prev_it;
> +
> + if (prev_it == val2)
> + return 0;
> +
> + prev_gain = iio_gts_find_gain_by_sel(&data->gts, (pd_div4 << 2) | gain_reg);
> + if (prev_gain < 0)
> + return prev_gain;
> +
> + ret = iio_gts_find_new_gain_by_gain_time_min(&data->gts, prev_gain, prev_it,
> + val2, &new_gain, &in_range);
> + if (ret)
> + return ret;
> +
> + if (!in_range)
> + dev_dbg(regmap_get_device(data->regmap), "Optimal gain out of range\n");
> +
> + ret = iio_gts_find_sel_by_int_time(&data->gts, val2);
> + if (ret < 0)
> + return ret;
> +
> + ret = regmap_field_write(data->rf.it, ret);
> + if (ret)
> + return ret;
> +
> + gain_sel = iio_gts_find_sel_by_gain(&data->gts, new_gain);
> + if (gain_sel < 0)
> + return gain_sel;
> +
> + return veml6031x00_write_gain(data, gain_sel);
> +}
...
> +static int veml6031x00_get_scale(struct veml6031x00_data *data, int *val,
> + int *val2)
> +{
> + int gain, it, gain_reg, pd_div4, it_reg, ret, sel;
> +
> + scoped_guard(mutex, &data->scale_lock) {
> + ret = regmap_field_read(data->rf.gain, &gain_reg);
> + if (ret)
> + return ret;
> +
> + ret = regmap_field_read(data->rf.pd_div4, &pd_div4);
> + if (ret)
> + return ret;
> + sel = (pd_div4 << 2) | gain_reg;
This magic happens a few times, perhaps some macros to define?
#define DIV4_GAIN_TO_SEL(div4, gain)
#define DIV4_FROM_SEL(sel)
#define GAIN_FROM_SEL(sel)
?
> + gain = iio_gts_find_gain_by_sel(&data->gts, sel);
> + if (gain < 0)
> + return gain;
> +
> + ret = regmap_field_read(data->rf.it, &it_reg);
> + if (ret)
> + return ret;
> + }
> +
> + it = iio_gts_find_int_time_by_sel(&data->gts, it_reg);
> + if (it < 0)
> + return it;
> +
> + ret = iio_gts_get_scale(&data->gts, gain, it, val, val2);
> + if (ret)
> + return ret;
> +
> + return IIO_VAL_INT_PLUS_NANO;
> +}
> + int addr, it_usec, ret;
> + __le16 regval;
> +
> + switch (type) {
> + case IIO_LIGHT:
> + addr = VEML6031X00_REG_ALS_L;
> + break;
> + case IIO_INTENSITY:
> + addr = VEML6031X00_REG_IR_L;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + guard(mutex)(&data->scale_lock);
> +
> + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(regmap_get_device(data->regmap), pm);
> + ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> + if (ret)
> + return ret;
> +
> + ret = __veml6031x00_get_it(data, &it_usec);
> + if (ret < 0)
> + return ret;
> +
> + /* integration time + 10% to ensure completion */
> + fsleep(it_usec + (it_usec / 10));
> +
> + ret = regmap_bulk_read(data->regmap, addr, ®val, sizeof(regval));
> + if (ret)
> + return ret;
> +
> + *val = le16_to_cpu(regval);
> +
> + return IIO_VAL_INT;
> +}
...
> +static int veml6031x00_read_raw(struct iio_dev *iio,
> + struct iio_chan_spec const *chan, int *val,
> + int *val2, long mask)
Split logically
static int veml6031x00_read_raw(struct iio_dev *iio,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
...
> +static int veml6031x00_validate_part_id(struct veml6031x00_data *data)
> +{
struct device *dev = ...;
> + int part_id, ret;
> + __le16 regval;
> +
> + ret = regmap_bulk_read(data->regmap, VEML6031X00_REG_ID_L, ®val,
> + sizeof(regval));
> + if (ret)
> + return dev_err_probe(regmap_get_device(data->regmap), ret,
> + "Failed to read ID\n");
> +
> + part_id = le16_to_cpu(regval);
> + if (part_id != data->chip->part_id)
> + dev_info(regmap_get_device(data->regmap), "Unknown ID %04x\n", part_id);
> +
> + return 0;
> +}
...
> +static int veml6031x00_hw_init(struct iio_dev *iio)
> +{
As per above, and check the rest of the code for the same opportunity.
> + struct veml6031x00_data *data = iio_priv(iio);
> + int ret;
> +
> + /* Max resolution = 6.9632 lx/cnt for gain = 0.125 and IT = 3.125ms */
> + ret = devm_iio_init_iio_gts(regmap_get_device(data->regmap), 6, 963200000,
> + veml6031x00_gain_sel,
> + ARRAY_SIZE(veml6031x00_gain_sel),
> + veml6031x00_it_sel,
> + ARRAY_SIZE(veml6031x00_it_sel),
> + &data->gts);
> + if (ret)
> + return dev_err_probe(regmap_get_device(data->regmap), ret,
> + "failed to init IIO GTS\n");
> +
> + return 0;
> +}
...
> +static int veml6031x00_probe(struct i2c_client *i2c)
Ditto.
--
With Best Regards,
Andy Shevchenko
next prev parent reply other threads:[~2026-08-10 13:38 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 13:51 [PATCH v5 0/4] iio: light: add support for veml6031x00 ALS series Javier Carrasco
2026-08-07 13:51 ` [PATCH v5 1/4] dt-bindings: iio: light: veml6030: add " Javier Carrasco
2026-08-07 14:06 ` sashiko-bot
2026-08-07 14:34 ` Javier Carrasco
2026-08-07 15:33 ` Rob Herring (Arm)
2026-08-10 6:23 ` Krzysztof Kozlowski
2026-08-10 7:23 ` Javier Carrasco
2026-08-07 13:51 ` [PATCH v5 2/4] iio: light: add support for " Javier Carrasco
2026-08-07 14:19 ` sashiko-bot
2026-08-07 14:53 ` Javier Carrasco
2026-08-07 21:02 ` Uwe Kleine-König
2026-08-10 13:38 ` Andy Shevchenko [this message]
2026-08-10 23:06 ` Javier Carrasco
2026-08-11 5:40 ` Andy Shevchenko
2026-08-07 13:51 ` [PATCH v5 3/4] iio: light: veml6031x00: add support for triggered buffers Javier Carrasco
2026-08-07 14:49 ` sashiko-bot
2026-08-07 20:33 ` Javier Carrasco
2026-08-07 13:51 ` [PATCH v5 4/4] iio: light: veml6031x00: add support for events and trigger Javier Carrasco
2026-08-07 15:08 ` sashiko-bot
2026-08-08 6:35 ` Javier Carrasco
2026-08-10 15:32 ` Andy Shevchenko
2026-08-10 23:09 ` Javier Carrasco
2026-08-11 5:42 ` Andy Shevchenko
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=annUbQQn2TzzuFNC@ashevche-desk.local \
--to=andriy.shevchenko@intel.com \
--cc=andy@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dlechner@baylibre.com \
--cc=javier.carrasco.cruz@gmail.com \
--cc=jic23@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nuno.sa@analog.com \
--cc=robh@kernel.org \
/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.