iio: proximity: Add Vishay VCNL36829 driver
Subsystems (2)
cover iio: proximity: Add Vishay VCNL36829 driver
From: Liu Yufei <[email protected]>
This series adds support for the Vishay VCNL36829, an I2C proximity sensor with an integrated VCSEL emitter.
Patch 1 adds the devicetree binding.
Patch 2 adds the IIO driver, which exposes the proximity reading and a configurable integration time.
Tested on Orange Pi Zero 2W.
Liu Yufei (2):
dt-bindings: iio: proximity: Add Vishay VCNL36829
iio: proximity: Add driver for Vishay VCNL36829
.../iio/proximity/vishay,vcnl36829.yaml | 55 ++++ MAINTAINERS | 6 + drivers/iio/proximity/Kconfig | 11 + drivers/iio/proximity/Makefile | 1 + drivers/iio/proximity/vcnl36829.c | 278 ++++++++++++++++++ 5 files changed, 351 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/proximity/vishay,vcnl36829.yaml create mode 100644 drivers/iio/proximity/vcnl36829.c
base-commit: 52c36105f76e96b638152a42e735f2e7767ed946
Signature · 1 line
2.53.0
PATCH 1/2 dt-bindings: iio: proximity: Add Vishay VCNL36829
From: Liu Yufei <[email protected]>
Add devicetree binding for the Vishay VCNL36829 proximity sensor.
The VCNL36829 is a proximity sensor with an integrated VCSEL emitter in a small package. It is controlled over I2C and has an interrupt output. It is powered by two supplies, vdd and vddio.
--- .../iio/proximity/vishay,vcnl36829.yaml | 55 +++++++++++++++++++ MAINTAINERS | 5 ++ 2 files changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/proximity/vishay,vcnl36829.yaml
Documentation/devicetree/bindings/iio/proximity/vishay,vcnl36829.yaml new file +55 -0
@@ -0,0 +1,55 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/proximity/vishay,vcnl36829.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: VISHAY VCNL36829 Proximity Sensor + +maintainers: + - Liu Yufei <[email protected]> + +description: | + Proximity sensor with VCSEL in an ultra thin small package with I2C + interface. + Datasheet: https://www.vishay.com/docs/80580/vcnl36829um.pdf + +properties: + compatible: + const: vishay,vcnl36829 + + reg: + maxItems: 1 + + vdd-supply: true + + vddio-supply: true + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - vdd-supply + - vddio-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + + proximity@60 { + compatible = "vishay,vcnl36829"; + reg = <0x60>; + vdd-supply = <&vdd_reg>; + vddio-supply = <&vddio_reg>; + interrupt-parent = <&gpio>; + interrupts = <17 IRQ_TYPE_LEVEL_LOW>; + }; + }; +...
MAINTAINERS +5 -0
@@ -28754,6 +28754,11 @@ S: Maintained F: drivers/input/serio/userio.c F: include/uapi/linux/userio.h +VISHAY VCNL36829 PROXIMITY SENSOR DRIVER +M: Liu Yufei <[email protected]> +S: Maintained +F: Documentation/devicetree/bindings/iio/proximity/vishay,vcnl36829.yaml + VISHAY VEML3235 AMBIENT LIGHT SENSOR DRIVER M: Javier Carrasco <[email protected]> S: Maintained
Signature · 1 line
2.53.0
Re: [PATCH 1/2] dt-bindings: iio: proximity: Add Vishay VCNL36829
Quoted 8 lines · Liu Yufei
From: Liu Yufei <[email protected]>
Add devicetree binding for the Vishay VCNL36829 proximity sensor.
The VCNL36829 is a proximity sensor with an integrated VCSEL emitter in a small package. It is controlled over I2C and has an interrupt output. It is powered by two supplies, vdd and vddio.
Quoted 6 lines
Signed-off-by Liu Yufei <[email protected]>--- .../iio/proximity/vishay,vcnl36829.yaml | 55 +++++++++++++++++++ MAINTAINERS | 5 ++ 2 files changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/proximity/vishay,vcnl36829.yaml
Best regards,
Krzysztof
Jonathan Cameron
maintainerRe: [PATCH 1/2] dt-bindings: iio: proximity: Add Vishay VCNL36829
In reply to Liu YufeiQuoted 7 lines · On Sat, 3 Oct 2026 13:04:52 +0800 Liu Yufei <[email protected]> wrote:
From: Liu Yufei <[email protected]>
Add devicetree binding for the Vishay VCNL36829 proximity sensor.
The VCNL36829 is a proximity sensor with an integrated VCSEL emitter in a small package. It is controlled over I2C and has an interrupt output. It is powered by two supplies, vdd and vddio.
I wondered if we should just combine this with the vcml3020 binding which is fairly similar but with the integrated vcsel rather than an led, it would get just complicated enough that I guess for two such short bindings keeping them separate is easier.
Quoted 2 lines
Signed-off-by Liu Yufei <[email protected]>
What changed enough to justify not picking up Krzysztof's tag?
https://lore.kernel.org/all/20261004-outgoing-outrageous-fulmar-2ba7f4@quoll/
Looks like nothing. Please be careful around that in future. If everything else is fine I might just assume it is fine to put that tag back
Thanks,
Jonathan
Jonathan Cameron
maintainerRe: [PATCH 1/2] dt-bindings: iio: proximity: Add Vishay VCNL36829
Quoted 16 lines · On Sat, 17 Oct 2026 21:05:02 +0100 Jonathan Cameron <[email protected]> wrote:
Quoted 7 lines · On Sat, 3 Oct 2026 13:04:52 +0800 Liu Yufei <[email protected]> wrote:
From: Liu Yufei <[email protected]>
Add devicetree binding for the Vishay VCNL36829 proximity sensor.
The VCNL36829 is a proximity sensor with an integrated VCSEL emitter in a small package. It is controlled over I2C and has an interrupt output. It is powered by two supplies, vdd and vddio.
I wondered if we should just combine this with the vcml3020 binding which is fairly similar but with the integrated vcsel rather than an led, it would get just complicated enough that I guess for two such short bindings keeping them separate is easier.
Quoted 1 line
Quoted 6 lines
Quoted 1 line
Signed-off-by Liu Yufei <[email protected]>What changed enough to justify not picking up Krzysztof's tag?
https://lore.kernel.org/all/20261004-outgoing-outrageous-fulmar-2ba7f4@quoll/
Looks like nothing. Please be careful around that in future. If everything else is fine I might just assume it is fine to put that tag back
Oops. Illustrates my point about confused threads nicely :( I thought I was replying to v3! Ignore this gibberish.
J
Quoted 7 lines
Thanks,
Jonathan
PATCH 2/2 iio: proximity: Add driver for Vishay VCNL36829
In reply to Liu YufeiFrom: Liu Yufei <[email protected]>
Add an IIO driver for the Vishay VCNL36829 proximity sensor with integrated VCSEL, connected over I2C.
At probe the driver enables the vdd and vddio supplies, waits for the sensor to power up, checks the device ID, configures the VCSEL current and photodiodes, and turns the proximity engine on. The sensor is put back into shutdown when the device is removed.
The following attributes are exposed:
- in_proximity0_raw
- in_proximity_integration_time
- in_proximity_integration_time_available
The datasheet is available at:
https://www.vishay.com/docs/80580/vcnl36829um.pdf
--- MAINTAINERS | 1 + drivers/iio/proximity/Kconfig | 11 ++ drivers/iio/proximity/Makefile | 1 + drivers/iio/proximity/vcnl36829.c | 278 ++++++++++++++++++++++++++++++ 4 files changed, 291 insertions(+) create mode 100644 drivers/iio/proximity/vcnl36829.c
MAINTAINERS +1 -0
@@ -28758,6 +28758,7 @@ VISHAY VCNL36829 PROXIMITY SENSOR DRIVER M: Liu Yufei <[email protected]> S: Maintained F: Documentation/devicetree/bindings/iio/proximity/vishay,vcnl36829.yaml +F: drivers/iio/proximity/vcnl36829.c VISHAY VEML3235 AMBIENT LIGHT SENSOR DRIVER M: Javier Carrasco <[email protected]>
drivers/iio/proximity/Kconfig +11 -0
@@ -233,6 +233,17 @@ config VCNL3020 To compile this driver as a module, choose M here: the module will be called vcnl3020. +config VCNL36829 + tristate "Vishay VCNL36829 proximity sensor" + depends on I2C + select REGMAP_I2C + help + Say Y here if you want to build a driver for the Vishay VCNL36829 + proximity sensor with integrated VCSEL. + + To compile this driver as a module, choose M here: the + module will be called vcnl36829. + config VL53L0X_I2C tristate "STMicroelectronics VL53L0X ToF ranger sensor (I2C)" depends on I2C
drivers/iio/proximity/Makefile +1 -0
@@ -22,6 +22,7 @@ obj-$(CONFIG_SX9360) += sx9360.o obj-$(CONFIG_SX_COMMON) += sx_common.o obj-$(CONFIG_SX9500) += sx9500.o obj-$(CONFIG_VCNL3020) += vcnl3020.o +obj-$(CONFIG_VCNL36829) += vcnl36829.o obj-$(CONFIG_VL53L0X_I2C) += vl53l0x-i2c.o obj-$(CONFIG_VL53L1X_I2C) += vl53l1x-i2c.o obj-$(CONFIG_AW96103) += aw96103.o
drivers/iio/proximity/vcnl36829.c new file +278 -0
278 lines not on this page · raw message
Signature · 1 line
2.53.0
[email protected]
AI reviewRe: [PATCH 2/2] iio: proximity: Add driver for Vishay VCNL36829
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] iio: proximity: vcnl36829: unnecessary I2C_FUNC_I2C check breaks SMBus compatibility --
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] iio: proximity: vcnl36829: unnecessary I2C_FUNC_I2C check breaks SMBus compatibility --
commit 31b66b302335366e3d26270b9301e19d433bfdf7
Author: Liu Yufei <[email protected]>
iio: proximity: Add driver for Vishay VCNL36829
This commit adds an IIO driver for the Vishay VCNL36829 proximity sensor connected over I2C. At probe, the driver enables supplies, configures the sensor and VCSEL, and exposes proximity data attributes.
Quoted 5 lines
drivers/iio/proximity/vcnl36829.c new file +0
-0
[ ... ]
drivers/iio/proximity/vcnl36829.c line 174
Quoted 13 lines
drivers/iio/proximity/vcnl36829.c new file +13
-0+static int vcnl36829_probe (struct i2c_client *client) +{ +struct device *dev = &client->dev; +struct vcnl36829_data *data; +struct iio_dev *indio_dev; +struct regmap *regmap; + +int ret; +unsigned int reg; + +if (!i2c_check_functionality (client->adapter,I2C_FUNC_I2C )) +return dev_err_probe (dev, -EOPNOTSUPP , +"I2C adapter doesn't support plain I2C\n" );
[Severity: Medium]
Does this artificially restrict the driver from probing on SMBus-only controllers?
The devm_regmap_init_i2c() framework natively implements seamless SMBus fallback for 8-bit register / 16-bit little-endian value devices using I2C_FUNC_SMBUS_WORD_DATA. By manually enforcing I2C_FUNC_I2C up front, it looks like the driver defeats this regmap feature and prevents itself from operating on otherwise compatible SMBus hardware.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
Re: [PATCH 2/2] iio: proximity: Add driver for Vishay VCNL36829
In reply to Liu YufeiQuoted 8 lines · Liu Yufei
Add an IIO driver for the Vishay VCNL36829 proximity sensor with integrated VCSEL, connected over I2C.
At probe the driver enables the vdd and vddio supplies, waits for the sensor to power up, checks the device ID, configures the VCSEL current and photodiodes, and turns the proximity engine on. The sensor is put back into shutdown when the device is removed.
Quoted 7 lines
The following attributes are exposed:
-in_proximity0_raw
-in_proximity_integration_time
-in_proximity_integration_time_availableThe datasheet is available at:
https://www.vishay.com/docs/80580/vcnl36829um.pdf
Make it a Datasheet: tag.
Quoted 1 line
Assisted-by Claude:claude-opus-5-5 checkpatch dtschema
...
drivers/iio/proximity/vcnl36829.c line 8
Quoted 3 lines
drivers/iio/proximity/vcnl36829.c new file +2
-0+#include <linux/i2c.h> +#include <linux/mod_devicetable.h>
In the new code we rely on the bus header to provide the ID definitions.
drivers/iio/proximity/vcnl36829.c line 14
Quoted 6 lines
drivers/iio/proximity/vcnl36829.c new file +6
-0+#include <linux/iio/iio.h> +#include <linux/regmap.h> +#include <linux/bitfield.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> +#include <linux/delay.h>
Keep it sorted, also follow the IWYU principle.
...
drivers/iio/proximity/vcnl36829.c line 45
Quoted 3 lines
drivers/iio/proximity/vcnl36829.c new file +3
-0+struct vcnl36829_data { +struct i2c_client *client; +struct regmap *regmap;
One can be derived through the other, no need to keep client here.
drivers/iio/proximity/vcnl36829.c line 53
Quoted 8 lines
drivers/iio/proximity/vcnl36829.c new file +8
-0+}; + +static const struct regmap_config vcnl36829_regmap_config = { + .name ="vcnl36829_regmap" , + .reg_bits =8 , + .val_bits =16 , + .max_register =VCNL36829_DEV_ID , + .val_format_endian =REGMAP_ENDIAN_LITTLE ,
No cache?
Quoted 1 line
+};
...
Quoted 5 lines
drivers/iio/proximity/vcnl36829.c new file +5
-0+static int vcnl36829_write_raw (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan,int val, +int val2,long mask) +{ +struct vcnl36829_data *data =iio_priv (indio_dev);
drivers/iio/proximity/vcnl36829.c line 109
Quoted 10 lines
drivers/iio/proximity/vcnl36829.c new file +10
-0+ +switch (mask) { +case IIO_CHAN_INFO_INT_TIME : +if (val !=0 ) +return -EINVAL ; +if (val2 >=25 && val2 <=375 && val2 %25 ==0 ) +return regmap_update_bits (data->regmap, +VCNL36829_PS_CONF2 , +VCNL36829_PS_IT_MSK , +FIELD_PREP (VCNL36829_PS_IT_MSK , val2 /25 ));
Compiler might utilise some specific assembler instructions on some CPUs to do % and / at once. To make it happen we can hint compiler with locating these two operations next to each other. Also use standard pattern to check for an error first and correct indentation.
int ival = val2 / 25; int fval = val2 % 25; ... if (val != 0) return -EINVAL; if (ival < 1 && ival > 15) return -EINVAL; if (fval != 0) return -EINVAL; return regmap_update_bits(data->regmap, VCNL36829_PS_CONF2, VCNL36829_PS_IT_MSK, FIELD_PREP(VCNL36829_PS_IT_MSK, ival));
Quoted 5 lines
drivers/iio/proximity/vcnl36829.c new file +5
-0+return -EINVAL ; +default : +return -EINVAL ; + } +}
...
drivers/iio/proximity/vcnl36829.c line 170
Quoted 9 lines
drivers/iio/proximity/vcnl36829.c new file +9
-0+static int vcnl36829_probe (struct i2c_client *client) +{ +struct device *dev = &client->dev; +struct vcnl36829_data *data; +struct iio_dev *indio_dev; +struct regmap *regmap; + +int ret; +unsigned int reg;
No blank lines in the definition block, also keep it in reversed xmas tree order.
Quoted 6 lines
drivers/iio/proximity/vcnl36829.c new file +6
-0+if (!i2c_check_functionality (client->adapter,I2C_FUNC_I2C )) +return dev_err_probe (dev, -EOPNOTSUPP , +"I2C adapter doesn't support plain I2C\n" ); + + indio_dev =devm_iio_device_alloc (dev,sizeof (*data)); +if (!indio_dev)
drivers/iio/proximity/vcnl36829.c line 186
Quoted 10 lines
drivers/iio/proximity/vcnl36829.c new file +9
-0+return -ENOMEM ; + + regmap =devm_regmap_init_i2c (client, &vcnl36829_regmap_config); +if (IS_ERR (regmap)) +return dev_err_probe (dev,PTR_ERR (regmap), +"Regmap setup failed\n" ); + + data =iio_priv (indio_dev); +i2c_set_clientdata (client, indio_dev);
Is this being used?
Quoted 6 lines
drivers/iio/proximity/vcnl36829.c new file +6
-0+ data->client = client; + data->regmap = regmap; + + indio_dev->name ="vcnl36829" ; + indio_dev->info = &vcnl36829_info; + indio_dev->channels = vcnl36829_channels;
drivers/iio/proximity/vcnl36829.c line 202
Quoted 10 lines
drivers/iio/proximity/vcnl36829.c new file +10
-0+ indio_dev->num_channels =ARRAY_SIZE (vcnl36829_channels); + indio_dev->modes =INDIO_DIRECT_MODE ; + + ret =devm_regulator_get_enable (dev,"vdd" ); +if (ret) +return dev_err_probe (dev, ret,"failed to enable vdd\n" ); + + ret =devm_regulator_get_enable (dev,"vddio" ); +if (ret) +return dev_err_probe (dev, ret,"failed to enable vddio\n" );
The following sleep needs a comment with a reference to the specific section and/or table in the datasheet.
drivers/iio/proximity/vcnl36829.c line 204
Quoted 1 line
drivers/iio/proximity/vcnl36829.c new file +1
-0+fsleep (3000 );
3 * USEC_PER_MSEC
(will require time.h to be included)
drivers/iio/proximity/vcnl36829.c line 211
Quoted 7 lines
drivers/iio/proximity/vcnl36829.c new file +6
-0+ ret =regmap_read (regmap,VCNL36829_DEV_ID , ®); +if (ret) +return dev_err_probe (dev, ret,"Failed to read device ID\n" ); +if ((reg &0xFF ) !=VCNL36829_DEV_ID_VAL ) +return dev_err_probe (dev, -ENODEV , +"Unknown device ID 0x%x\n" , reg);
Don't we simply warn and continue in this case?
drivers/iio/proximity/vcnl36829.c line 218
Quoted 7 lines
drivers/iio/proximity/vcnl36829.c new file +6
-0+ ret =regmap_update_bits (regmap,VCNL36829_PS_CONF2 , +VCNL36829_PS_IT_MSK , +FIELD_PREP (VCNL36829_PS_IT_MSK ,VCNL36829_PS_INT_TIME_25 )); +if (ret) +return dev_err_probe (dev, ret, +"Could not configure PS_IT\n" );
It's perfectly a single line.
Quoted 34 lines
drivers/iio/proximity/vcnl36829.c new file +34
-0+ + ret =regmap_update_bits (regmap,VCNL36829_PS_CONF3 , +VCNL36829_PS_CURRENT_EN_MSK | +VCNL36829_PS_CURRENT_MSK | +VCNL36829_PD1_EN_MSK | +VCNL36829_PD2_EN_MSK | +VCNL36829_PD3_EN_MSK , +FIELD_PREP (VCNL36829_PS_CURRENT_EN_MSK ,1 ) | +FIELD_PREP (VCNL36829_PS_CURRENT_MSK ,VCNL36829_PS_CURRENT_18MA ) | +FIELD_PREP (VCNL36829_PD1_EN_MSK ,1 ) | +FIELD_PREP (VCNL36829_PD2_EN_MSK ,1 ) | +FIELD_PREP (VCNL36829_PD3_EN_MSK ,1 )); +if (ret) +return dev_err_probe (dev, ret, +"Could not configure VCSEL/PD\n" ); + + ret =regmap_write (regmap,VCNL36829_PS_CONF5 ,VCNL36829_PS_CONF5_INIT ); +if (ret) +return dev_err_probe (dev, ret,"Could not set PS_CONF5\n" ); + + ret =regmap_update_bits (regmap,VCNL36829_PS_CONF1 , +VCNL36829_PS_ON_MSK |VCNL36829_PS_SD_MSK , +FIELD_PREP (VCNL36829_PS_ON_MSK ,1 ) | +FIELD_PREP (VCNL36829_PS_SD_MSK ,0 )); +if (ret) +return dev_err_probe (dev, ret, +"Could not set initial config\n" ); + + ret =devm_add_action_or_reset (dev, vcnl36829_shutdown_action, data); +if (ret) +return ret; + +return devm_iio_device_register (dev, indio_dev); +}
Signature · 2 lines
With Best Regards, Andy Shevchenko