* [PATCH 0/4] iio: light: gp2ap020a00f: Add supplies and GP2AP030A00F support
@ 2026-11-07 23:31 Linus Walleij
2026-11-07 23:31 ` [PATCH 1/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add supplies Linus Walleij
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Linus Walleij @ 2026-11-07 23:31 UTC (permalink / raw)
To: linux-iio, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Kyungmin Park
Cc: devicetree, Linus Walleij
Describe and enable optional core and I2C/interrupt pull-up supplies for
the GP2AP020A00F. Preserve compatibility with existing device trees that
only describe the LED supply.
Extend the existing binding and driver to support the GP2AP030A00F. It
shares the register layout, but has different proximity resolution
encodings and no automatic lux calculation. Select model-specific
initialization, keep reserved bits clear and expose fixed-range raw
clear and infrared counts. Keep generic supply handling in separate
patches from the model-specific binding and driver additions.
Assisted by LLM.
Signed-off-by: Linus Walleij <linusw@kernel.org>
---
Linus Walleij (4):
dt-bindings: iio: light: sharp,gp2ap020a00f: Add supplies
dt-bindings: iio: light: sharp,gp2ap020a00f: Add GP2AP030A00F
iio: light: gp2ap020a00f: Enable the core and I/O supplies
iio: light: gp2ap020a00f: Add GP2AP030A00F support
.../bindings/iio/light/sharp,gp2ap020a00f.yaml | 20 ++++-
drivers/iio/light/Kconfig | 6 +-
drivers/iio/light/gp2ap020a00f.c | 88 ++++++++++++++++++++--
3 files changed, 100 insertions(+), 14 deletions(-)
---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20261107-gp2ap030-99504c2dc038
Best regards,
--
Linus Walleij <linusw@kernel.org>
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH 1/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add supplies 2026-11-07 23:31 [PATCH 0/4] iio: light: gp2ap020a00f: Add supplies and GP2AP030A00F support Linus Walleij @ 2026-11-07 23:31 ` Linus Walleij 2026-11-07 23:58 ` Jonathan Cameron 2026-11-07 23:31 ` [PATCH 2/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add GP2AP030A00F Linus Walleij ` (2 subsequent siblings) 3 siblings, 1 reply; 11+ messages in thread From: Linus Walleij @ 2026-11-07 23:31 UTC (permalink / raw) To: linux-iio, Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Kyungmin Park Cc: devicetree, Linus Walleij The GP2AP020A00F needs a core supply as well as power for its infrared LED. Its I2C and interrupt pull-up resistors may also be supplied from a separately controlled rail. Describe the core supply as vdd-supply and the pull-up supply as vio-supply. Keep both properties optional to preserve compatibility with existing device trees that only describe vled-supply. Link: https://global.sharp/corporate/news/110721.html Signed-off-by: Linus Walleij <linusw@kernel.org> --- Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml b/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml index 3fabf1f576cf..d4bcca0f2d0a 100644 --- a/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml +++ b/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml @@ -22,6 +22,12 @@ properties: interrupts: maxItems: 1 + vdd-supply: + description: Sensor core power supply (VCC). + + vio-supply: + description: Supply for the I2C and interrupt pull-up resistors. + vled-supply: true additionalProperties: false -- 2.56.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add supplies 2026-11-07 23:31 ` [PATCH 1/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add supplies Linus Walleij @ 2026-11-07 23:58 ` Jonathan Cameron 2026-11-08 16:08 ` Linus Walleij 0 siblings, 1 reply; 11+ messages in thread From: Jonathan Cameron @ 2026-11-07 23:58 UTC (permalink / raw) To: Linus Walleij Cc: linux-iio, David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Kyungmin Park, devicetree On Sun, 08 Nov 2026 00:31:33 +0100 Linus Walleij <linusw@kernel.org> wrote: > The GP2AP020A00F needs a core supply as well as power for its infrared > LED. Its I2C and interrupt pull-up resistors may also be supplied from > a separately controlled rail. Hi Linus, The infrared led mention made me think there was a separate supply for that. If not, does it warrant mentioning? > > Describe the core supply as vdd-supply and the pull-up supply as > vio-supply. Keep both properties optional to preserve compatibility > with existing device trees that only describe vled-supply. Is vio supply wired to the device? It would be unusual to describe a supply that is a pull up only one given that would often be a characteristic of the interrupt chip at the other end of the wire. Definitely after input from one of the DT binding reviewers on that aspect. If there is precedence for this good to call that out. > > Link: https://global.sharp/corporate/news/110721.html What is the link for? It is not referenced from rest of patch description so seems a bit odd. > Signed-off-by: Linus Walleij <linusw@kernel.org> > --- > Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml b/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml > index 3fabf1f576cf..d4bcca0f2d0a 100644 > --- a/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml > +++ b/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml > @@ -22,6 +22,12 @@ properties: > interrupts: > maxItems: 1 > > + vdd-supply: > + description: Sensor core power supply (VCC). > + > + vio-supply: > + description: Supply for the I2C and interrupt pull-up resistors. > + > vled-supply: true > > additionalProperties: false > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add supplies 2026-11-07 23:58 ` Jonathan Cameron @ 2026-11-08 16:08 ` Linus Walleij 0 siblings, 0 replies; 11+ messages in thread From: Linus Walleij @ 2026-11-08 16:08 UTC (permalink / raw) To: Jonathan Cameron Cc: linux-iio, David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Kyungmin Park, devicetree On Sun, Nov 8, 2026 at 12:58 AM Jonathan Cameron <jic23@kernel.org> wrote: > On Sun, 08 Nov 2026 00:31:33 +0100 > Linus Walleij <linusw@kernel.org> wrote: > > > The GP2AP020A00F needs a core supply as well as power for its infrared > > LED. Its I2C and interrupt pull-up resistors may also be supplied from > > a separately controlled rail. > > Hi Linus, > > The infrared led mention made me think there was a separate supply for that. > If not, does it warrant mentioning? It is already in the binding, incorrectly named vled-supply. A later patch clarifies that this is the leda-supply. (I saw that you saw this too ;) > > Describe the core supply as vdd-supply and the pull-up supply as > > vio-supply. Keep both properties optional to preserve compatibility > > with existing device trees that only describe vled-supply. > > Is vio supply wired to the device? It would be unusual to describe > a supply that is a pull up only one given that would often be a characteristic > of the interrupt chip at the other end of the wire. I guess I managed to look at the datasheet for the suspiciously similarly named GP2AP002* which as separate VDD and VIO... I think both of these should have VCC only. I'll fix! > Definitely after input from one of the DT binding reviewers on that aspect. > If there is precedence for this good to call that out. > > > > > > Link: https://global.sharp/corporate/news/110721.html > > What is the link for? It is not referenced from rest of patch description > so seems a bit odd. It's the only thing even close to a datasheet that Sharp has published for GP2AP020*. It doesn't deserve the title of Datasheet: tags. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add GP2AP030A00F 2026-11-07 23:31 [PATCH 0/4] iio: light: gp2ap020a00f: Add supplies and GP2AP030A00F support Linus Walleij 2026-11-07 23:31 ` [PATCH 1/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add supplies Linus Walleij @ 2026-11-07 23:31 ` Linus Walleij 2026-11-08 0:02 ` Jonathan Cameron 2026-11-07 23:31 ` [PATCH 3/4] iio: light: gp2ap020a00f: Enable the core and I/O supplies Linus Walleij 2026-11-07 23:31 ` [PATCH 4/4] iio: light: gp2ap020a00f: Add GP2AP030A00F support Linus Walleij 3 siblings, 1 reply; 11+ messages in thread From: Linus Walleij @ 2026-11-07 23:31 UTC (permalink / raw) To: linux-iio, Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Kyungmin Park Cc: devicetree, Linus Walleij The GP2AP030A00F uses the same register address layout and interrupt interface as the GP2AP020A00F, but returns raw clear and infrared counts instead of providing automatic illuminance calculation. Describe it in the existing binding with its own compatible. Keep the core and I/O pull-up supplies optional so boards with hardwired power do not have to describe them. Datasheet: https://global.sharp/products/device/lineup/data/pdf/datasheet/gp2ap030a00f_e.pdf Datasheet: https://jp.sharp/products/device/doc/opto/gp2ap030a00f_appl_e.pdf Signed-off-by: Linus Walleij <linusw@kernel.org> --- .../devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml b/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml index d4bcca0f2d0a..45f1b53d6d7b 100644 --- a/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml +++ b/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml @@ -4,17 +4,22 @@ $id: http://devicetree.org/schemas/iio/light/sharp,gp2ap020a00f.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Sharp GP2AP020A00F I2C Proximity/ALS sensor +title: Sharp GP2AP020A00F and GP2AP030A00F proximity and ambient light sensors maintainers: - Kyungmin Park <kyungmin.park@samsung.com> description: | - The proximity detector sensor requires power supply for its built-in led. + The sensors provide digital clear, infrared and proximity measurements. + The GP2AP020A00F can also calculate illuminance internally, while the + GP2AP030A00F exposes raw clear and infrared photodiode counts. + The proximity detector requires a power supply for its built-in LED. properties: compatible: - const: sharp,gp2ap020a00f + enum: + - sharp,gp2ap020a00f + - sharp,gp2ap030a00f reg: maxItems: 1 @@ -28,7 +33,8 @@ properties: vio-supply: description: Supply for the I2C and interrupt pull-up resistors. - vled-supply: true + vled-supply: + description: Infrared LED anode power supply (LEDA). additionalProperties: false -- 2.56.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 2/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add GP2AP030A00F 2026-11-07 23:31 ` [PATCH 2/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add GP2AP030A00F Linus Walleij @ 2026-11-08 0:02 ` Jonathan Cameron 0 siblings, 0 replies; 11+ messages in thread From: Jonathan Cameron @ 2026-11-08 0:02 UTC (permalink / raw) To: Linus Walleij Cc: linux-iio, David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Kyungmin Park, devicetree On Sun, 08 Nov 2026 00:31:34 +0100 Linus Walleij <linusw@kernel.org> wrote: > The GP2AP030A00F uses the same register address layout and interrupt > interface as the GP2AP020A00F, but returns raw clear and infrared counts > instead of providing automatic illuminance calculation. Describe it in > the existing binding with its own compatible. > > Keep the core and I/O pull-up supplies optional so boards with hardwired > power do not have to describe them. If they are needed for the chip to function we tend to require them anyway. That's not to say the driver enforces it, but just that the binding indicates they should be there. DT files can just spin up a fixed regulator if it is always on. The extra bit of led power description perhaps would be better in the previous patch given it isn't related to the new part introduction in a direct way. > > Datasheet: https://global.sharp/products/device/lineup/data/pdf/datasheet/gp2ap030a00f_e.pdf > Datasheet: https://jp.sharp/products/device/doc/opto/gp2ap030a00f_appl_e.pdf > Signed-off-by: Linus Walleij <linusw@kernel.org> > --- > .../devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml b/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml > index d4bcca0f2d0a..45f1b53d6d7b 100644 > --- a/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml > +++ b/Documentation/devicetree/bindings/iio/light/sharp,gp2ap020a00f.yaml > @@ -4,17 +4,22 @@ > $id: http://devicetree.org/schemas/iio/light/sharp,gp2ap020a00f.yaml# > $schema: http://devicetree.org/meta-schemas/core.yaml# > > -title: Sharp GP2AP020A00F I2C Proximity/ALS sensor > +title: Sharp GP2AP020A00F and GP2AP030A00F proximity and ambient light sensors > > maintainers: > - Kyungmin Park <kyungmin.park@samsung.com> > > description: | > - The proximity detector sensor requires power supply for its built-in led. > + The sensors provide digital clear, infrared and proximity measurements. > + The GP2AP020A00F can also calculate illuminance internally, while the > + GP2AP030A00F exposes raw clear and infrared photodiode counts. > + The proximity detector requires a power supply for its built-in LED. > > properties: > compatible: > - const: sharp,gp2ap020a00f > + enum: > + - sharp,gp2ap020a00f > + - sharp,gp2ap030a00f > > reg: > maxItems: 1 > @@ -28,7 +33,8 @@ properties: > vio-supply: > description: Supply for the I2C and interrupt pull-up resistors. > > - vled-supply: true > + vled-supply: > + description: Infrared LED anode power supply (LEDA). Not related to rest of the patch. Does explain the mention of the vled in the previous description though! Now I understand you were referring to what was already supported rather than what the patch did. > > additionalProperties: false > > ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/4] iio: light: gp2ap020a00f: Enable the core and I/O supplies 2026-11-07 23:31 [PATCH 0/4] iio: light: gp2ap020a00f: Add supplies and GP2AP030A00F support Linus Walleij 2026-11-07 23:31 ` [PATCH 1/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add supplies Linus Walleij 2026-11-07 23:31 ` [PATCH 2/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add GP2AP030A00F Linus Walleij @ 2026-11-07 23:31 ` Linus Walleij 2026-11-08 0:03 ` Jonathan Cameron 2026-11-07 23:31 ` [PATCH 4/4] iio: light: gp2ap020a00f: Add GP2AP030A00F support Linus Walleij 3 siblings, 1 reply; 11+ messages in thread From: Linus Walleij @ 2026-11-07 23:31 UTC (permalink / raw) To: linux-iio, Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Kyungmin Park Cc: devicetree, Linus Walleij Enable the optional vdd and vio supplies before accessing the device. Use managed helpers so both supplies are disabled on probe failure and removal. Continue probing when an optional supply is absent, while propagating other errors, including deferred probe. Signed-off-by: Linus Walleij <linusw@kernel.org> --- drivers/iio/light/gp2ap020a00f.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index b435dc5e8706..62c4beb20cce 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c @@ -1414,6 +1414,14 @@ static int gp2ap020a00f_probe(struct i2c_client *client) data = iio_priv(indio_dev); + err = devm_regulator_get_enable_optional(dev, "vdd"); + if (err && err != -ENODEV) + return dev_err_probe(dev, err, "Failed to enable core supply\n"); + + err = devm_regulator_get_enable_optional(dev, "vio"); + if (err && err != -ENODEV) + return dev_err_probe(dev, err, "Failed to enable I/O supply\n"); + data->vled_reg = devm_regulator_get(dev, "vled"); if (IS_ERR(data->vled_reg)) return PTR_ERR(data->vled_reg); -- 2.56.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 3/4] iio: light: gp2ap020a00f: Enable the core and I/O supplies 2026-11-07 23:31 ` [PATCH 3/4] iio: light: gp2ap020a00f: Enable the core and I/O supplies Linus Walleij @ 2026-11-08 0:03 ` Jonathan Cameron 0 siblings, 0 replies; 11+ messages in thread From: Jonathan Cameron @ 2026-11-08 0:03 UTC (permalink / raw) To: Linus Walleij Cc: linux-iio, David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Kyungmin Park, devicetree On Sun, 08 Nov 2026 00:31:35 +0100 Linus Walleij <linusw@kernel.org> wrote: > Enable the optional vdd and vio supplies before accessing the device. > Use managed helpers so both supplies are disabled on probe failure and > removal. Continue probing when an optional supply is absent, while > propagating other errors, including deferred probe. > > Signed-off-by: Linus Walleij <linusw@kernel.org> > --- > drivers/iio/light/gp2ap020a00f.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c > index b435dc5e8706..62c4beb20cce 100644 > --- a/drivers/iio/light/gp2ap020a00f.c > +++ b/drivers/iio/light/gp2ap020a00f.c > @@ -1414,6 +1414,14 @@ static int gp2ap020a00f_probe(struct i2c_client *client) > > data = iio_priv(indio_dev); > > + err = devm_regulator_get_enable_optional(dev, "vdd"); > + if (err && err != -ENODEV) > + return dev_err_probe(dev, err, "Failed to enable core supply\n"); > + > + err = devm_regulator_get_enable_optional(dev, "vio"); > + if (err && err != -ENODEV) > + return dev_err_probe(dev, err, "Failed to enable I/O supply\n"); Just use devm_regulator_get_enable() and the regulator framework should supply stub regulators if they aren't specified. The optional bit here is for when we do something different if they aren't wired (usually for IIO that means using an internal reference rather than an external one). Jonathan > + > data->vled_reg = devm_regulator_get(dev, "vled"); > if (IS_ERR(data->vled_reg)) > return PTR_ERR(data->vled_reg); > ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 4/4] iio: light: gp2ap020a00f: Add GP2AP030A00F support 2026-11-07 23:31 [PATCH 0/4] iio: light: gp2ap020a00f: Add supplies and GP2AP030A00F support Linus Walleij ` (2 preceding siblings ...) 2026-11-07 23:31 ` [PATCH 3/4] iio: light: gp2ap020a00f: Enable the core and I/O supplies Linus Walleij @ 2026-11-07 23:31 ` Linus Walleij 2026-11-08 0:21 ` Jonathan Cameron 3 siblings, 1 reply; 11+ messages in thread From: Linus Walleij @ 2026-11-07 23:31 UTC (permalink / raw) To: linux-iio, Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Kyungmin Park Cc: devicetree, Linus Walleij The GP2AP030A00F has the same register addresses and interrupt modes as the GP2AP020A00F, but does not implement its automatic illuminance calculation or selectable ambient-light cancellation. Datasheet: https://jp.sharp/products/device/doc/opto/gp2ap030a00f_appl_e.pdf Signed-off-by: Linus Walleij <linusw@kernel.org> --- drivers/iio/light/Kconfig | 6 +-- drivers/iio/light/gp2ap020a00f.c | 80 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 10 deletions(-) diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index 462fff1ddef2..549f644994df 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -259,15 +259,15 @@ config GP2AP002 module will be called gp2ap002. config GP2AP020A00F - tristate "Sharp GP2AP020A00F Proximity/ALS sensor" + tristate "Sharp GP2AP020A00F/GP2AP030A00F Proximity/ALS sensors" depends on I2C select REGMAP_I2C select IIO_BUFFER select IIO_TRIGGERED_BUFFER select IRQ_WORK help - Say Y here if you have a Sharp GP2AP020A00F proximity/ALS combo-chip - hooked to an I2C bus. + Say Y here if you have a Sharp GP2AP020A00F or GP2AP030A00F + proximity/ALS combo-chip hooked to an I2C bus. To compile this driver as a module, choose M here: the module will be called gp2ap020a00f. diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index 62c4beb20cce..3ea1ec273e7f 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c @@ -54,6 +54,11 @@ #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> +/* + * The GP2AP030A00F shares the register layout, but has no TYPE or ALC bit. + * Its D0 and D1 registers always contain raw clear and infrared counts. + */ + /* Registers */ #define GP2AP020A00F_OP_REG 0x00 /* Basic operations */ #define GP2AP020A00F_ALS_REG 0x01 /* ALS related settings */ @@ -137,6 +142,7 @@ #define GP2AP020A00F_RES_P_6_25ms_x2 0x28 #define GP2AP020A00F_RES_P_1_56ms_x2 0x30 #define GP2AP020A00F_RES_P_0_39ms_x2 0x38 +#define GP2AP030A00F_RES_P_1_56ms_x2 0x18 #define GP2AP020A00F_RANGE_P_MASK 0x07 /* PS: Max measurable range */ #define GP2AP020A00F_RANGE_P_x1 0x00 #define GP2AP020A00F_RANGE_P_x2 0x01 @@ -158,6 +164,7 @@ #define GP2AP020A00F_IS_27_5mA 0x10 #define GP2AP020A00F_IS_55mA 0x20 #define GP2AP020A00F_IS_110mA 0x30 +#define GP2AP030A00F_IS_130mA 0x30 #define GP2AP020A00F_PIN_MASK 0x0c /* INT terminal setting */ #define GP2AP020A00F_PIN_ALS_OR_PS 0x00 #define GP2AP020A00F_PIN_ALS 0x04 @@ -234,7 +241,14 @@ enum gp2ap020a00f_thresh_val_id { GP2AP020A00F_THRESH_PH, }; +struct gp2ap020a00f_chip_info { + const char *name; + const u8 *reg_init_tab; + bool has_als_auto; +}; + struct gp2ap020a00f_data { + const struct gp2ap020a00f_chip_info *chip_info; struct i2c_client *client; struct mutex lock; char *buffer; @@ -268,6 +282,28 @@ static const u8 gp2ap020a00f_reg_init_tab[] = { [GP2AP020A00F_PH_H_REG] = 0, }; +static const u8 gp2ap030a00f_reg_init_tab[ARRAY_SIZE(gp2ap020a00f_reg_init_tab)] = { + [GP2AP020A00F_OP_REG] = GP2AP020A00F_OP3_SHUTDOWN, + [GP2AP020A00F_ALS_REG] = GP2AP020A00F_RES_A_100ms | + GP2AP020A00F_RANGE_A_x8, + [GP2AP020A00F_PS_REG] = GP2AP030A00F_RES_P_1_56ms_x2 | + GP2AP020A00F_RANGE_P_x4, + [GP2AP020A00F_LED_REG] = GP2AP020A00F_INTVAL_0 | + GP2AP030A00F_IS_130mA | + GP2AP020A00F_FREQ_327_5kHz, +}; + +static const struct gp2ap020a00f_chip_info gp2ap020a00f_chip_info = { + .name = "gp2ap020a00f", + .reg_init_tab = gp2ap020a00f_reg_init_tab, + .has_als_auto = true, +}; + +static const struct gp2ap020a00f_chip_info gp2ap030a00f_chip_info = { + .name = "gp2ap030a00f", + .reg_init_tab = gp2ap030a00f_reg_init_tab, +}; + static bool gp2ap020a00f_is_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -364,6 +400,7 @@ static int gp2ap020a00f_set_operation_mode(struct gp2ap020a00f_data *data, enum gp2ap020a00f_opmode op) { unsigned int op_reg_val; + u8 op_reg = opmode_regs_settings[op].op_reg; int err; if (op != GP2AP020A00F_OPMODE_SHUTDOWN) { @@ -401,12 +438,16 @@ static int gp2ap020a00f_set_operation_mode(struct gp2ap020a00f_data *data, return err; } + /* Bit 0 is reserved on the GP2AP030A00F. */ + if (!data->chip_info->has_als_auto) + op_reg &= ~GP2AP020A00F_TYPE_MASK; + /* Set OP_REG and apply operation mode (power on / off) */ err = regmap_update_bits(data->regmap, GP2AP020A00F_OP_REG, GP2AP020A00F_OP_MASK | GP2AP020A00F_OP2_MASK | GP2AP020A00F_OP3_MASK | GP2AP020A00F_TYPE_MASK, - opmode_regs_settings[op].op_reg); + op_reg); if (err < 0) return err; @@ -438,6 +479,8 @@ static int gp2ap020a00f_write_event_threshold(struct gp2ap020a00f_data *data, if (!enable) thresh_reg_val = 0; + else if (!data->chip_info->has_als_auto) + thresh_reg_val = min(data->thresh_val[th_val_id], 65535U); else if (test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags) && th_val_id != GP2AP020A00F_THRESH_PL && th_val_id != GP2AP020A00F_THRESH_PH) @@ -701,6 +744,10 @@ static bool gp2ap020a00f_adjust_lux_mode(struct gp2ap020a00f_data *data, u8 new_range = 0xff; int err; + /* GP2AP030A00F thresholds and samples are raw counts at a fixed range. */ + if (!data->chip_info->has_als_auto) + return false; + if (!test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags)) { if (output_val > 16000) { set_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags); @@ -1401,7 +1448,7 @@ static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = { static int gp2ap020a00f_probe(struct i2c_client *client) { - const struct i2c_device_id *id = i2c_client_get_device_id(client); + struct iio_chan_spec *channels; struct device *dev = &client->dev; struct gp2ap020a00f_data *data; struct iio_dev *indio_dev; @@ -1413,6 +1460,7 @@ static int gp2ap020a00f_probe(struct i2c_client *client) return -ENOMEM; data = iio_priv(indio_dev); + data->chip_info = i2c_get_match_data(client); err = devm_regulator_get_enable_optional(dev, "vdd"); if (err && err != -ENODEV) @@ -1437,9 +1485,12 @@ static int gp2ap020a00f_probe(struct i2c_client *client) goto error_regulator_disable; } + if (!data->chip_info->has_als_auto) + usleep_range(1000, 2000); + /* Initialize device registers */ err = regmap_bulk_write(regmap, GP2AP020A00F_OP_REG, - gp2ap020a00f_reg_init_tab, + data->chip_info->reg_init_tab, ARRAY_SIZE(gp2ap020a00f_reg_init_tab)); if (err < 0) { @@ -1456,9 +1507,20 @@ static int gp2ap020a00f_probe(struct i2c_client *client) mutex_init(&data->lock); indio_dev->channels = gp2ap020a00f_channels; + if (!data->chip_info->has_als_auto) { + channels = devm_kmemdup(dev, gp2ap020a00f_channels, + sizeof(gp2ap020a00f_channels), GFP_KERNEL); + if (!channels) { + err = -ENOMEM; + goto error_regulator_disable; + } + channels[GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR].scan_type.realbits = 16; + channels[GP2AP020A00F_SCAN_MODE_LIGHT_IR].scan_type.realbits = 16; + indio_dev->channels = channels; + } indio_dev->num_channels = ARRAY_SIZE(gp2ap020a00f_channels); indio_dev->info = &gp2ap020a00f_info; - indio_dev->name = id->name; + indio_dev->name = data->chip_info->name; indio_dev->modes = INDIO_DIRECT_MODE; /* Allocate buffer */ @@ -1534,13 +1596,17 @@ static void gp2ap020a00f_remove(struct i2c_client *client) } static const struct i2c_device_id gp2ap020a00f_id[] = { - { .name = "gp2ap020a00f" }, + { .name = "gp2ap020a00f", + .driver_data = (kernel_ulong_t)&gp2ap020a00f_chip_info }, + { .name = "gp2ap030a00f", + .driver_data = (kernel_ulong_t)&gp2ap030a00f_chip_info }, { } }; MODULE_DEVICE_TABLE(i2c, gp2ap020a00f_id); static const struct of_device_id gp2ap020a00f_of_match[] = { - { .compatible = "sharp,gp2ap020a00f" }, + { .compatible = "sharp,gp2ap020a00f", .data = &gp2ap020a00f_chip_info }, + { .compatible = "sharp,gp2ap030a00f", .data = &gp2ap030a00f_chip_info }, { } }; MODULE_DEVICE_TABLE(of, gp2ap020a00f_of_match); @@ -1557,5 +1623,5 @@ static struct i2c_driver gp2ap020a00f_driver = { module_i2c_driver(gp2ap020a00f_driver); MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>"); -MODULE_DESCRIPTION("Sharp GP2AP020A00F Proximity/ALS sensor driver"); +MODULE_DESCRIPTION("Sharp GP2AP020A00F/GP2AP030A00F proximity/ALS sensor driver"); MODULE_LICENSE("GPL v2"); -- 2.56.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 4/4] iio: light: gp2ap020a00f: Add GP2AP030A00F support 2026-11-07 23:31 ` [PATCH 4/4] iio: light: gp2ap020a00f: Add GP2AP030A00F support Linus Walleij @ 2026-11-08 0:21 ` Jonathan Cameron 2026-11-08 21:13 ` Linus Walleij 0 siblings, 1 reply; 11+ messages in thread From: Jonathan Cameron @ 2026-11-08 0:21 UTC (permalink / raw) To: Linus Walleij Cc: linux-iio, David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Kyungmin Park, devicetree On Sun, 08 Nov 2026 00:31:36 +0100 Linus Walleij <linusw@kernel.org> wrote: > The GP2AP030A00F has the same register addresses and interrupt modes > as the GP2AP020A00F, but does not implement its automatic > illuminance calculation or selectable ambient-light cancellation. Hmm. Raw clear and IR signals are normally intensity channels, not light ones (because there is no standard match to illuminance). Seems the original driver is not doing this right and we are stuck with that though. > > Datasheet: https://jp.sharp/products/device/doc/opto/gp2ap030a00f_appl_e.pdf > Signed-off-by: Linus Walleij <linusw@kernel.org> > --- > drivers/iio/light/Kconfig | 6 +-- > drivers/iio/light/gp2ap020a00f.c | 80 ++++++++++++++++++++++++++++++++++++---- Hmm. Fairly small. Normally I'd ask for this in two patches 1) Introduce the infrastructure to support chip variants, but no functional changes. 2) Introduce the stuff for the part being added. If it is simple enough I'll sometimes be more relaxed about that. This is slightly too complex for me to be completely happy. > 2 files changed, 76 insertions(+), 10 deletions(-) > > diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig > index 462fff1ddef2..549f644994df 100644 > --- a/drivers/iio/light/Kconfig > +++ b/drivers/iio/light/Kconfig > @@ -259,15 +259,15 @@ config GP2AP002 > module will be called gp2ap002. > > config GP2AP020A00F > - tristate "Sharp GP2AP020A00F Proximity/ALS sensor" > + tristate "Sharp GP2AP020A00F/GP2AP030A00F Proximity/ALS sensors" As for the description below, I'd just use 'and similar' as this will become too long on the next part addition. So might as well avoid the problem now. > depends on I2C > select REGMAP_I2C > select IIO_BUFFER > select IIO_TRIGGERED_BUFFER > select IRQ_WORK > help > - Say Y here if you have a Sharp GP2AP020A00F proximity/ALS combo-chip > - hooked to an I2C bus. > + Say Y here if you have a Sharp GP2AP020A00F or GP2AP030A00F > + proximity/ALS combo-chip hooked to an I2C bus. Similar on making extension to more parts easy. Change to a bulleted list of parts now as it will avoid churn when the next one turns up. Lots of recent examples of this in tree. > > To compile this driver as a module, choose M here: the > module will be called gp2ap020a00f. > + > static bool gp2ap020a00f_is_volatile_reg(struct device *dev, unsigned int reg) > { > switch (reg) { > @@ -364,6 +400,7 @@ static int gp2ap020a00f_set_operation_mode(struct gp2ap020a00f_data *data, > enum gp2ap020a00f_opmode op) > { > unsigned int op_reg_val; > + u8 op_reg = opmode_regs_settings[op].op_reg; If nothing else effects things, prefer reverse xmas tree. So I'd move this up one line. > int err; > > if (op != GP2AP020A00F_OPMODE_SHUTDOWN) { > @@ -401,12 +438,16 @@ static int gp2ap020a00f_set_operation_mode(struct gp2ap020a00f_data *data, > return err; > } > > + /* Bit 0 is reserved on the GP2AP030A00F. */ > + if (!data->chip_info->has_als_auto) > + op_reg &= ~GP2AP020A00F_TYPE_MASK; Perhaps set it explicitly to MANUAL_CALC given I guess that is direct equivalent of this? Effectively chip doesn't support AUTO_CALC. That should be self explanatory given the has_als_auto check so you can probably drop the comment after doing that. > + > /* Set OP_REG and apply operation mode (power on / off) */ > err = regmap_update_bits(data->regmap, > GP2AP020A00F_OP_REG, > GP2AP020A00F_OP_MASK | GP2AP020A00F_OP2_MASK | > GP2AP020A00F_OP3_MASK | GP2AP020A00F_TYPE_MASK, > - opmode_regs_settings[op].op_reg); > + op_reg); > if (err < 0) > return err; ... > @@ -1401,7 +1448,7 @@ static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = { > > static int gp2ap020a00f_probe(struct i2c_client *client) > { > - const struct i2c_device_id *id = i2c_client_get_device_id(client); > + struct iio_chan_spec *channels; > struct device *dev = &client->dev; > struct gp2ap020a00f_data *data; > struct iio_dev *indio_dev; > @@ -1413,6 +1460,7 @@ static int gp2ap020a00f_probe(struct i2c_client *client) > return -ENOMEM; > > data = iio_priv(indio_dev); > + data->chip_info = i2c_get_match_data(client); Check for NULL. Sadly can happen via various weird probe paths. > > err = devm_regulator_get_enable_optional(dev, "vdd"); > if (err && err != -ENODEV) > @@ -1437,9 +1485,12 @@ static int gp2ap020a00f_probe(struct i2c_client *client) > goto error_regulator_disable; > } > > + if (!data->chip_info->has_als_auto) > + usleep_range(1000, 2000); fsleep() so no need to think if allow that slack makes sense or not. > + > /* Initialize device registers */ > err = regmap_bulk_write(regmap, GP2AP020A00F_OP_REG, > - gp2ap020a00f_reg_init_tab, > + data->chip_info->reg_init_tab, > ARRAY_SIZE(gp2ap020a00f_reg_init_tab)); > > if (err < 0) { > @@ -1456,9 +1507,20 @@ static int gp2ap020a00f_probe(struct i2c_client *client) > > mutex_init(&data->lock); > indio_dev->channels = gp2ap020a00f_channels; > + if (!data->chip_info->has_als_auto) { > + channels = devm_kmemdup(dev, gp2ap020a00f_channels, > + sizeof(gp2ap020a00f_channels), GFP_KERNEL); > + if (!channels) { > + err = -ENOMEM; > + goto error_regulator_disable; > + } > + channels[GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR].scan_type.realbits = 16; > + channels[GP2AP020A00F_SCAN_MODE_LIGHT_IR].scan_type.realbits = 16; > + indio_dev->channels = channels; For this just pick between two static arrays. Whilst that may make things a bit bigger module size wise, it is easier to read ad puts all this in one place. Put a pointer to the channel array + count of it's size in the chip_info structure. > + } > indio_dev->num_channels = ARRAY_SIZE(gp2ap020a00f_channels); > indio_dev->info = &gp2ap020a00f_info; > - indio_dev->name = id->name; > + indio_dev->name = data->chip_info->name; > indio_dev->modes = INDIO_DIRECT_MODE; > > /* Allocate buffer */ > @@ -1534,13 +1596,17 @@ static void gp2ap020a00f_remove(struct i2c_client *client) > } > @@ -1557,5 +1623,5 @@ static struct i2c_driver gp2ap020a00f_driver = { > module_i2c_driver(gp2ap020a00f_driver); > > MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>"); > -MODULE_DESCRIPTION("Sharp GP2AP020A00F Proximity/ALS sensor driver"); > +MODULE_DESCRIPTION("Sharp GP2AP020A00F/GP2AP030A00F proximity/ALS sensor driver"); These get long fast. Maybe just jump directly to where we end up which is the weasel words option of adding 'and similar' > MODULE_LICENSE("GPL v2"); > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/4] iio: light: gp2ap020a00f: Add GP2AP030A00F support 2026-11-08 0:21 ` Jonathan Cameron @ 2026-11-08 21:13 ` Linus Walleij 0 siblings, 0 replies; 11+ messages in thread From: Linus Walleij @ 2026-11-08 21:13 UTC (permalink / raw) To: Jonathan Cameron Cc: linux-iio, David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Kyungmin Park, devicetree On Sun, Nov 8, 2026 at 1:22 AM Jonathan Cameron <jic23@kernel.org> wrote: > > + /* Bit 0 is reserved on the GP2AP030A00F. */ > > + if (!data->chip_info->has_als_auto) > > + op_reg &= ~GP2AP020A00F_TYPE_MASK; > > Perhaps set it explicitly to MANUAL_CALC Jesus the name of that flag. I just shudder whenever I see code referring to "manual" in a computer program, as if there is a man in there, or we throw a prompt at the user to fix the issue as if there is a manual gearshift. What it actually means is "imperative", as performed by a machine. I will grudgingly swallow my pride and go with this because I suppose it is the name in the register description in the manual. Fixing up the rest of the comments! Yours, Linus Walleij ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-11-08 21:13 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-11-07 23:31 [PATCH 0/4] iio: light: gp2ap020a00f: Add supplies and GP2AP030A00F support Linus Walleij 2026-11-07 23:31 ` [PATCH 1/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add supplies Linus Walleij 2026-11-07 23:58 ` Jonathan Cameron 2026-11-08 16:08 ` Linus Walleij 2026-11-07 23:31 ` [PATCH 2/4] dt-bindings: iio: light: sharp,gp2ap020a00f: Add GP2AP030A00F Linus Walleij 2026-11-08 0:02 ` Jonathan Cameron 2026-11-07 23:31 ` [PATCH 3/4] iio: light: gp2ap020a00f: Enable the core and I/O supplies Linus Walleij 2026-11-08 0:03 ` Jonathan Cameron 2026-11-07 23:31 ` [PATCH 4/4] iio: light: gp2ap020a00f: Add GP2AP030A00F support Linus Walleij 2026-11-08 0:21 ` Jonathan Cameron 2026-11-08 21:13 ` Linus Walleij
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox