drivers/iio/light/veml6040.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
The VEML6040 RGBW light sensor stays in auto-measurement mode at all
times once probed, drawing its full active current (~200 uA per
Vishay VEML6040 datasheet, Doc# 84276 Rev. 1.7). On system suspend
there is no need to keep the sensor running.
Add system sleep PM callbacks that toggle the SD (shutdown) bit in
CONF register 00H to put the chip into shutdown on suspend and back
into normal operation on resume. The bit semantics are documented in
the datasheet Tables 2-1 and 2-2.
The existing veml6040_shutdown_action() is unchanged; it still runs
on module unload to leave the chip shut down.
Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com>
---
drivers/iio/light/veml6040.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/iio/light/veml6040.c b/drivers/iio/light/veml6040.c
index f563f9f0e..ffd0a2a70 100644
--- a/drivers/iio/light/veml6040.c
+++ b/drivers/iio/light/veml6040.c
@@ -13,6 +13,7 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/module.h>
+#include <linux/pm.h>
#include <linux/regmap.h>
/* VEML6040 Configuration Registers
@@ -201,6 +202,32 @@ static void veml6040_shutdown_action(void *data)
VEML6040_CONF_SD_MSK, VEML6040_CONF_SD_MSK);
}
+/*
+ * Per Vishay VEML6040 datasheet (Doc# 84276 Rev. 1.7), Table 2-1 and
+ * Table 2-2, the SD bit in CONF register 00H controls chip shutdown:
+ * SD = 1 disables the color sensor, SD = 0 re-enables it.
+ */
+static int veml6040_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct veml6040_data *data = iio_priv(indio_dev);
+
+ return regmap_update_bits(data->regmap, VEML6040_CONF_REG,
+ VEML6040_CONF_SD_MSK, VEML6040_CONF_SD_MSK);
+}
+
+static int veml6040_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct veml6040_data *data = iio_priv(indio_dev);
+
+ return regmap_update_bits(data->regmap, VEML6040_CONF_REG,
+ VEML6040_CONF_SD_MSK, 0);
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(veml6040_pm_ops, veml6040_suspend,
+ veml6040_resume);
+
static int veml6040_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
@@ -271,6 +298,7 @@ static struct i2c_driver veml6040_driver = {
.driver = {
.name = "veml6040",
.of_match_table = veml6040_of_match,
+ .pm = pm_sleep_ptr(&veml6040_pm_ops),
},
};
module_i2c_driver(veml6040_driver);
--
2.43.0
On Wed, May 13, 2026 at 19:15, Jonathan Cameron wrote: > Suspend / resume tend to be a little non trivial to add and datasheets > are sometimes less than perfect in describing powerdown modes, so can > I confirm: Do you have one of these that you are testing this with? Honest disclosure: no, I do not have a VEML6040 board to test with. The patch was prepared from datasheet inspection only (Vishay Doc# 84276 Rev. 1.7, Tables 2-1 and 2-2) plus the existing in-tree usage of the same SD bit in veml6040_shutdown_action(). If lack of hardware testing is a blocker for a PM addition, please drop the patch; I am OK with that. > dev_get_drvdata() rather than going in circles. It's get of > 'implicit' knowledge that works for i2c sequences like this Noted -- if this stays in scope I will switch to dev_get_drvdata(dev) in the suspend/resume callbacks. > Andy pointed out regmap_clear_bits() is handy here and set_bits above. Yes -- Andy made the same suggestion on v1 and I have a local v2 that uses regmap_set_bits()/regmap_clear_bits() (and applies the same simplification to the existing veml6040_shutdown_action() for consistency). I was going to send it after the 24h wait, but happy to hold it until the hardware-testing question is settled. Stepan
On Wed, 13 May 2026 19:26:32 +0500 Stepan Ionichev <sozdayvek@gmail.com> wrote: > On Wed, May 13, 2026 at 19:15, Jonathan Cameron wrote: > > Suspend / resume tend to be a little non trivial to add and datasheets > > are sometimes less than perfect in describing powerdown modes, so can > > I confirm: Do you have one of these that you are testing this with? > > Honest disclosure: no, I do not have a VEML6040 board to test with. > The patch was prepared from datasheet inspection only (Vishay Doc# > 84276 Rev. 1.7, Tables 2-1 and 2-2) plus the existing in-tree usage > of the same SD bit in veml6040_shutdown_action(). If lack of hardware > testing is a blocker for a PM addition, please drop the patch; I am > OK with that. > > > dev_get_drvdata() rather than going in circles. It's get of > > 'implicit' knowledge that works for i2c sequences like this > > Noted -- if this stays in scope I will switch to dev_get_drvdata(dev) > in the suspend/resume callbacks. > > > Andy pointed out regmap_clear_bits() is handy here and set_bits above. > > Yes -- Andy made the same suggestion on v1 and I have a local v2 that > uses regmap_set_bits()/regmap_clear_bits() (and applies the same > simplification to the existing veml6040_shutdown_action() for > consistency). I was going to send it after the 24h wait, but happy > to hold it until the hardware-testing question is settled. > > Stepan Hi Stepan, Given you are becoming a frequent contributor (which is great!) can you look into why your emails have the in response to set to your last email not the one you are replying to. It's making for hard to track threads in claws-mail! As to the hardware thing - let us wait and see if anyone surfaces with an offer to test. Thanks, Jonathan
On Wed, 13 May 2026 14:45:36 +0500
Stepan Ionichev <sozdayvek@gmail.com> wrote:
> The VEML6040 RGBW light sensor stays in auto-measurement mode at all
> times once probed, drawing its full active current (~200 uA per
> Vishay VEML6040 datasheet, Doc# 84276 Rev. 1.7). On system suspend
> there is no need to keep the sensor running.
>
> Add system sleep PM callbacks that toggle the SD (shutdown) bit in
> CONF register 00H to put the chip into shutdown on suspend and back
> into normal operation on resume. The bit semantics are documented in
> the datasheet Tables 2-1 and 2-2.
>
> The existing veml6040_shutdown_action() is unchanged; it still runs
> on module unload to leave the chip shut down.
>
> Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com>
Hi Stepan
Suspend / resume tend to be a little non trivial to add and datasheets
are sometimes less than perfect in describing powerdown modes, so can
I confirm: Do you have one of these that you are testing this with?
Thanks,
Jonathan
> ---
> drivers/iio/light/veml6040.c | 28 ++++++++++++++++++++++++++++
> 1 file changed, 28 insertions(+)
>
> diff --git a/drivers/iio/light/veml6040.c b/drivers/iio/light/veml6040.c
> index f563f9f0e..ffd0a2a70 100644
> --- a/drivers/iio/light/veml6040.c
> +++ b/drivers/iio/light/veml6040.c
> @@ -13,6 +13,7 @@
> #include <linux/iio/iio.h>
> #include <linux/iio/sysfs.h>
> #include <linux/module.h>
> +#include <linux/pm.h>
> #include <linux/regmap.h>
>
> /* VEML6040 Configuration Registers
> @@ -201,6 +202,32 @@ static void veml6040_shutdown_action(void *data)
> VEML6040_CONF_SD_MSK, VEML6040_CONF_SD_MSK);
> }
>
> +/*
> + * Per Vishay VEML6040 datasheet (Doc# 84276 Rev. 1.7), Table 2-1 and
> + * Table 2-2, the SD bit in CONF register 00H controls chip shutdown:
> + * SD = 1 disables the color sensor, SD = 0 re-enables it.
> + */
> +static int veml6040_suspend(struct device *dev)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct veml6040_data *data = iio_priv(indio_dev);
> +
> + return regmap_update_bits(data->regmap, VEML6040_CONF_REG,
> + VEML6040_CONF_SD_MSK, VEML6040_CONF_SD_MSK);
> +}
> +
> +static int veml6040_resume(struct device *dev)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
dev_get_drvdata() rather than going in circles. It's get of 'implicit'
knowledge that works for i2c sequences like this so most instances of what
you have here got ripped out years ago. I've never really like the missbalance
and would love to get rid of i2c_set_clientdata() but such is life!
> + struct veml6040_data *data = iio_priv(indio_dev);
> +
> + return regmap_update_bits(data->regmap, VEML6040_CONF_REG,
> + VEML6040_CONF_SD_MSK, 0);
Andy pointed out regmap_clear_bits() is handy here and set_bits above.
> +}
> +
> +static DEFINE_SIMPLE_DEV_PM_OPS(veml6040_pm_ops, veml6040_suspend,
> + veml6040_resume);
> +
> static int veml6040_probe(struct i2c_client *client)
> {
> struct device *dev = &client->dev;
> @@ -271,6 +298,7 @@ static struct i2c_driver veml6040_driver = {
> .driver = {
> .name = "veml6040",
> .of_match_table = veml6040_of_match,
> + .pm = pm_sleep_ptr(&veml6040_pm_ops),
> },
> };
> module_i2c_driver(veml6040_driver);
On Wed, May 13, 2026 at 12:46 PM Stepan Ionichev <sozdayvek@gmail.com> wrote: > > The VEML6040 RGBW light sensor stays in auto-measurement mode at all > times once probed, drawing its full active current (~200 uA per > Vishay VEML6040 datasheet, Doc# 84276 Rev. 1.7). On system suspend > there is no need to keep the sensor running. > > Add system sleep PM callbacks that toggle the SD (shutdown) bit in > CONF register 00H to put the chip into shutdown on suspend and back > into normal operation on resume. The bit semantics are documented in > the datasheet Tables 2-1 and 2-2. > > The existing veml6040_shutdown_action() is unchanged; it still runs > on module unload to leave the chip shut down. We also have regmap_set_bits() and regmap_clear_bits(). This will make your code shorter and easier to understand. -- With Best Regards, Andy Shevchenko
© 2016 - 2026 Red Hat, Inc.