Skip to contentSkip to conversation

iio: proximity: Add Vishay VCNL36829 driver

PATCH Superseded Liu Yufei 5 participants 8 messages Oct 3 – Oct 17

Subsystems (2)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Liu Yufei

author
#0 lore raw

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
author
#1 lore raw

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
new file mode 100644
index 000000000..6f20537ad
@@ -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
index 8014b9f82..e6ef84b49 100644
@@ -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
Reviewed-by on v1 1/2
#2 lore raw

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
---
 .../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

maintainer
#3 lore raw

Re: [PATCH 1/2] dt-bindings: iio: proximity: Add Vishay VCNL36829

In reply to Liu Yufei
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 2 lines

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

maintainer
#4 lore raw

Re: [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

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

author
#5 lore raw

PATCH 2/2 iio: proximity: Add driver for Vishay VCNL36829

In reply to Liu Yufei

From: 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

Assisted-by Claude:claude-opus-5-5 checkpatch dtschema
---
 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
index e6ef84b49..5612b9371 100644
@@ -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
index bb77fad2a..f3cec799d 100644
@@ -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
index 4352833dd..8a65e42fb 100644
@@ -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
#6 lore raw

Re: [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
new file mode 100644
index 0000000000000..c9958a594abe2

[ ... ]

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
#7 lore raw

Re: [PATCH 2/2] iio: proximity: Add driver for Vishay VCNL36829

In reply to Liu Yufei
Quoted 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_available

The 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
Assisted-by LLM

...

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, &reg);
+	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