* [PATCH v4 0/2] iio: amplifiers: add support for ADL8113 Low Noise Amplifier @ 2025-11-21 9:52 Antoniu Miclaus 2025-11-21 9:52 ` [PATCH v4 1/2] dt-bindings: iio: amplifiers: add adl8113 Antoniu Miclaus 2025-11-21 9:52 ` [PATCH v4 2/2] iio: amplifiers: adl8113: add driver support Antoniu Miclaus 0 siblings, 2 replies; 6+ messages in thread From: Antoniu Miclaus @ 2025-11-21 9:52 UTC (permalink / raw) To: jic23, robh, conor+dt, linux-iio, linux-kernel, devicetree Cc: Antoniu Miclaus This patch series adds support for the Analog Devices ADL8113, a 10MHz to 12GHz Low Noise Amplifier with integrated bypass switches. The ADL8113 provides four operation modes controlled by two GPIO pins: - Internal Amplifier (14dB gain) - Internal Bypass (0dB gain) - External Bypass A (0dB gain) - Signal routes from RFIN to OUT_A and from IN_A to RFOUT - External Bypass B (0dB gain) - Signal routes from RFIN to OUT_B and from IN_B to RFOUT Antoniu Miclaus (2): dt-bindings: iio: amplifiers: add adl8113 iio: amplifiers: adl8113: add driver support .../bindings/iio/amplifiers/adi,adl8113.yaml | 93 ++++++ drivers/iio/amplifiers/Kconfig | 12 + drivers/iio/amplifiers/Makefile | 1 + drivers/iio/amplifiers/adl8113.c | 277 ++++++++++++++++++ 4 files changed, 383 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/amplifiers/adi,adl8113.yaml create mode 100644 drivers/iio/amplifiers/adl8113.c -- 2.43.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 1/2] dt-bindings: iio: amplifiers: add adl8113 2025-11-21 9:52 [PATCH v4 0/2] iio: amplifiers: add support for ADL8113 Low Noise Amplifier Antoniu Miclaus @ 2025-11-21 9:52 ` Antoniu Miclaus 2025-11-22 16:17 ` David Lechner 2025-11-21 9:52 ` [PATCH v4 2/2] iio: amplifiers: adl8113: add driver support Antoniu Miclaus 1 sibling, 1 reply; 6+ messages in thread From: Antoniu Miclaus @ 2025-11-21 9:52 UTC (permalink / raw) To: jic23, robh, conor+dt, linux-iio, linux-kernel, devicetree Cc: Antoniu Miclaus Add devicetree bindings for adl8113. Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com> --- Changes in v4: - Add adi,external-bypass-a-gain-db and adi,external-bypass-b-gain-db properties - Add example with external amplifier configuration --- .../bindings/iio/amplifiers/adi,adl8113.yaml | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/amplifiers/adi,adl8113.yaml diff --git a/Documentation/devicetree/bindings/iio/amplifiers/adi,adl8113.yaml b/Documentation/devicetree/bindings/iio/amplifiers/adi,adl8113.yaml new file mode 100644 index 000000000000..3da5de01e31b --- /dev/null +++ b/Documentation/devicetree/bindings/iio/amplifiers/adi,adl8113.yaml @@ -0,0 +1,93 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/amplifiers/adi,adl8113.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices ADL8113 Low Noise Amplifier with integrated bypass switches + +maintainers: + - Antoniu Miclaus <antoniu.miclaus@analog.com> + +description: | + The ADL8113 is a 10MHz to 12GHz Low Noise Amplifier with integrated bypass + switches controlled by two GPIO pins (VA and VB). The device supports four + operation modes: + - Internal Amplifier: VA=0, VB=0 - Signal passes through the internal LNA + - Internal Bypass: VA=1, VB=1 - Signal bypasses through internal path + - External Bypass A: VA=0, VB=1 - Signal routes from RFIN to OUT_A and from IN_A to RFOUT + - External Bypass B: VA=1, VB=0 - Signal routes from RFIN to OUT_B and from IN_B to RFOUT + + https://www.analog.com/en/products/adl8113.html + +properties: + compatible: + const: adi,adl8113 + + vdd1-supply: true + + vdd2-supply: true + + vss2-supply: true + + va-gpios: + description: + GPIO connected to the VA control pin. Must be specified as GPIO_ACTIVE_HIGH. + maxItems: 1 + + vb-gpios: + description: + GPIO connected to the VB control pin. Must be specified as GPIO_ACTIVE_HIGH. + maxItems: 1 + + adi,external-bypass-a-gain-db: + description: + Gain in dB of external amplifier connected to bypass path A (OUT_A/IN_A). + When specified, this gain value becomes selectable via the hardwaregain + attribute and automatically routes through the external A path. + + adi,external-bypass-b-gain-db: + description: + Gain in dB of external amplifier connected to bypass path B (OUT_B/IN_B). + When specified, this gain value becomes selectable via the hardwaregain + attribute and automatically routes through the external B path. + +required: + - compatible + - va-gpios + - vb-gpios + - vdd1-supply + - vdd2-supply + - vss2-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + /* Basic configuration with only internal paths */ + amplifier { + compatible = "adi,adl8113"; + va-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; + vb-gpios = <&gpio 23 GPIO_ACTIVE_HIGH>; + vdd1-supply = <&vdd1_5v>; + vdd2-supply = <&vdd2_3v3>; + vss2-supply = <&vss2_neg>; + }; + + - | + #include <dt-bindings/gpio/gpio.h> + + /* Configuration with external bypass amplifiers */ + amplifier { + compatible = "adi,adl8113"; + va-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + vb-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; + vdd1-supply = <&vdd1_5v>; + vdd2-supply = <&vdd2_3v3>; + vss2-supply = <&vss2_neg>; + adi,external-bypass-a-gain-db = <20>; + adi,external-bypass-b-gain-db = <6>; + }; +... -- 2.43.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: iio: amplifiers: add adl8113 2025-11-21 9:52 ` [PATCH v4 1/2] dt-bindings: iio: amplifiers: add adl8113 Antoniu Miclaus @ 2025-11-22 16:17 ` David Lechner 0 siblings, 0 replies; 6+ messages in thread From: David Lechner @ 2025-11-22 16:17 UTC (permalink / raw) To: Antoniu Miclaus, jic23, robh, conor+dt, linux-iio, linux-kernel, devicetree On 11/21/25 3:52 AM, Antoniu Miclaus wrote: > Add devicetree bindings for adl8113. > > Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com> > --- > ... > + adi,external-bypass-a-gain-db: Hmm... are we sure we will never need a non-integer value? Maybe we should add "-microdb$" to dtschema? https://github.com/devicetree-org/dt-schema/blob/7033eb7cec1abe55f496309f0f6f271524f5d612/dtschema/schemas/property-units.yaml#L52 > + description: > + Gain in dB of external amplifier connected to bypass path A (OUT_A/IN_A). > + When specified, this gain value becomes selectable via the hardwaregain > + attribute and automatically routes through the external A path. The dt-bindings should not specify how the driver should operate. We can leave out the last sentence. We could say though that when omitted it means nothing is connected. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 2/2] iio: amplifiers: adl8113: add driver support 2025-11-21 9:52 [PATCH v4 0/2] iio: amplifiers: add support for ADL8113 Low Noise Amplifier Antoniu Miclaus 2025-11-21 9:52 ` [PATCH v4 1/2] dt-bindings: iio: amplifiers: add adl8113 Antoniu Miclaus @ 2025-11-21 9:52 ` Antoniu Miclaus 2025-11-22 16:52 ` David Lechner 2025-11-28 18:46 ` kernel test robot 1 sibling, 2 replies; 6+ messages in thread From: Antoniu Miclaus @ 2025-11-21 9:52 UTC (permalink / raw) To: jic23, robh, conor+dt, linux-iio, linux-kernel, devicetree Cc: Antoniu Miclaus Add support for adl8113 10MHz to 12GHz Low Noise Amplifier with 10MHz to 14GHz bypass switches. Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com> --- Changes in v4: - Replace signal_path sysfs attribute with hardwaregain-only control - Add support for external bypass amplifiers via DT properties - Introduce dynamic gain configuration system with adl8113_gain_config structure --- drivers/iio/amplifiers/Kconfig | 12 ++ drivers/iio/amplifiers/Makefile | 1 + drivers/iio/amplifiers/adl8113.c | 277 +++++++++++++++++++++++++++++++ 3 files changed, 290 insertions(+) create mode 100644 drivers/iio/amplifiers/adl8113.c diff --git a/drivers/iio/amplifiers/Kconfig b/drivers/iio/amplifiers/Kconfig index 55eb16b32f6c..a8a604863eed 100644 --- a/drivers/iio/amplifiers/Kconfig +++ b/drivers/iio/amplifiers/Kconfig @@ -36,6 +36,18 @@ config ADA4250 To compile this driver as a module, choose M here: the module will be called ada4250. +config ADL8113 + tristate "Analog Devices ADL8113 Low Noise Amplifier" + depends on GPIOLIB + help + Say yes here to build support for Analog Devices ADL8113 Low Noise + Amplifier with integrated bypass switches. The device supports four + operation modes controlled by GPIO pins: internal amplifier, + internal bypass, and two external bypass modes. + + To compile this driver as a module, choose M here: the + module will be called adl8113. + config HMC425 tristate "Analog Devices HMC425A and similar GPIO Gain Amplifiers" depends on GPIOLIB diff --git a/drivers/iio/amplifiers/Makefile b/drivers/iio/amplifiers/Makefile index 2126331129cf..0a76443be1aa 100644 --- a/drivers/iio/amplifiers/Makefile +++ b/drivers/iio/amplifiers/Makefile @@ -6,4 +6,5 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_AD8366) += ad8366.o obj-$(CONFIG_ADA4250) += ada4250.o +obj-$(CONFIG_ADL8113) += adl8113.o obj-$(CONFIG_HMC425) += hmc425a.o diff --git a/drivers/iio/amplifiers/adl8113.c b/drivers/iio/amplifiers/adl8113.c new file mode 100644 index 000000000000..118789aa2c19 --- /dev/null +++ b/drivers/iio/amplifiers/adl8113.c @@ -0,0 +1,277 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ADL8113 Low Noise Amplifier with integrated bypass switches + * + * Copyright 2025 Analog Devices Inc. + */ + +#include <linux/array_size.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/gpio/consumer.h> +#include <linux/iio/iio.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/property.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> +#include <linux/sysfs.h> + +enum adl8113_signal_path { + ADL8113_INTERNAL_AMP, + ADL8113_INTERNAL_BYPASS, + ADL8113_EXTERNAL_A, + ADL8113_EXTERNAL_B, +}; + +struct adl8113_gain_config { + enum adl8113_signal_path path; + int gain_db; + int va; + int vb; +}; + +struct adl8113_state { + struct gpio_desc *gpio_va; + struct gpio_desc *gpio_vb; + struct adl8113_gain_config *gain_configs; + int num_gain_configs; + enum adl8113_signal_path current_path; +}; + +static const char * const adl8113_supply_names[] = { + "vdd1", + "vdd2", + "vss2" +}; + +static int adl8113_set_path(struct adl8113_state *st, + enum adl8113_signal_path path) +{ + int va, vb; + + /* Determine GPIO values based on signal path */ + switch (path) { + case ADL8113_INTERNAL_AMP: + va = 0; vb = 0; /* Internal amplifier */ + break; + case ADL8113_INTERNAL_BYPASS: + va = 1; vb = 1; /* Internal bypass */ + break; + case ADL8113_EXTERNAL_A: + va = 0; vb = 1; /* External bypass A */ + break; + case ADL8113_EXTERNAL_B: + va = 1; vb = 0; /* External bypass B */ + break; + default: + return -EINVAL; + } + + gpiod_set_value(st->gpio_va, va); + gpiod_set_value(st->gpio_vb, vb); + st->current_path = path; + return 0; +} + +static int adl8113_find_gain_config(struct adl8113_state *st, int gain_db) +{ + int i; + + for (i = 0; i < st->num_gain_configs; i++) { + if (st->gain_configs[i].gain_db == gain_db) + return i; + } + return -EINVAL; +} + +static const struct iio_chan_spec adl8113_channels[] = { + { + .type = IIO_VOLTAGE, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_HARDWAREGAIN), + .indexed = 1, + .channel = 0, + }, +}; + +static int adl8113_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct adl8113_state *st = iio_priv(indio_dev); + int i; + + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + /* Find current gain configuration */ + for (i = 0; i < st->num_gain_configs; i++) { + if (st->gain_configs[i].path == st->current_path) { + *val = st->gain_configs[i].gain_db; + *val2 = 0; + return IIO_VAL_INT_PLUS_MICRO_DB; + } + } + return -EINVAL; + default: + return -EINVAL; + } +} + +static int adl8113_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct adl8113_state *st = iio_priv(indio_dev); + int config_idx; + + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + if (val2 != 0) + return -EINVAL; + + config_idx = adl8113_find_gain_config(st, val); + if (config_idx < 0) + return -EINVAL; + + return adl8113_set_path(st, st->gain_configs[config_idx].path); + default: + return -EINVAL; + } +} + +static const struct iio_info adl8113_info = { + .read_raw = adl8113_read_raw, + .write_raw = adl8113_write_raw, +}; + +static int adl8113_init_gain_configs(struct device *dev, struct adl8113_state *st) +{ + int external_a_gain, external_b_gain; + int num_configs = 2; /* Always have internal amp and internal bypass */ + int i = 0; + + /* Check for optional external bypass amplifier gains */ + if (!device_property_read_u32(dev, "adi,external-bypass-a-gain-db", + &external_a_gain)) + num_configs++; + + if (!device_property_read_u32(dev, "adi,external-bypass-b-gain-db", + &external_b_gain)) + num_configs++; + + st->gain_configs = devm_kcalloc(dev, num_configs, + sizeof(*st->gain_configs), GFP_KERNEL); + if (!st->gain_configs) + return -ENOMEM; + + /* Always include internal amplifier (14dB) */ + st->gain_configs[i].path = ADL8113_INTERNAL_AMP; + st->gain_configs[i].gain_db = 14; + i++; + + /* Always include internal bypass (0dB) */ + st->gain_configs[i].path = ADL8113_INTERNAL_BYPASS; + st->gain_configs[i].gain_db = 0; + i++; + + /* Add external bypass A if configured */ + if (!device_property_read_u32(dev, "adi,external-bypass-a-gain-db", + &external_a_gain)) { + st->gain_configs[i].path = ADL8113_EXTERNAL_A; + st->gain_configs[i].gain_db = external_a_gain; + i++; + } + + /* Add external bypass B if configured */ + if (!device_property_read_u32(dev, "adi,external-bypass-b-gain-db", + &external_b_gain)) { + st->gain_configs[i].path = ADL8113_EXTERNAL_B; + st->gain_configs[i].gain_db = external_b_gain; + i++; + } + + st->num_gain_configs = num_configs; + + /* Check for duplicate gain values */ + for (i = 0; i < num_configs - 1; i++) { + for (int j = i + 1; j < num_configs; j++) { + if (st->gain_configs[i].gain_db == st->gain_configs[j].gain_db) { + dev_err(dev, "Duplicate gain values not allowed: %d dB\n", + st->gain_configs[i].gain_db); + return -EINVAL; + } + } + } + + return 0; +} + +static int adl8113_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct adl8113_state *st; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->gpio_va = devm_gpiod_get(dev, "va", GPIOD_OUT_LOW); + if (IS_ERR(st->gpio_va)) + return dev_err_probe(dev, PTR_ERR(st->gpio_va), + "failed to get VA GPIO\n"); + + st->gpio_vb = devm_gpiod_get(dev, "vb", GPIOD_OUT_LOW); + if (IS_ERR(st->gpio_vb)) + return dev_err_probe(dev, PTR_ERR(st->gpio_vb), + "failed to get VB GPIO\n"); + + ret = devm_regulator_bulk_get_enable(dev, + ARRAY_SIZE(adl8113_supply_names), + adl8113_supply_names); + if (ret) + return dev_err_probe(dev, ret, + "failed to get and enable supplies\n"); + + /* Initialize gain configurations from devicetree */ + ret = adl8113_init_gain_configs(dev, st); + if (ret) + return ret; + + /* Initialize to internal amplifier path (14dB) */ + ret = adl8113_set_path(st, ADL8113_INTERNAL_AMP); + if (ret) + return ret; + + indio_dev->info = &adl8113_info; + indio_dev->name = "adl8113"; + indio_dev->channels = adl8113_channels; + indio_dev->num_channels = ARRAY_SIZE(adl8113_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id adl8113_of_match[] = { + { .compatible = "adi,adl8113" }, + { } +}; +MODULE_DEVICE_TABLE(of, adl8113_of_match); + +static struct platform_driver adl8113_driver = { + .driver = { + .name = "adl8113", + .of_match_table = adl8113_of_match, + }, + .probe = adl8113_probe, +}; + +module_platform_driver(adl8113_driver); + +MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>"); +MODULE_DESCRIPTION("Analog Devices ADL8113 Low Noise Amplifier"); +MODULE_LICENSE("GPL"); -- 2.43.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 2/2] iio: amplifiers: adl8113: add driver support 2025-11-21 9:52 ` [PATCH v4 2/2] iio: amplifiers: adl8113: add driver support Antoniu Miclaus @ 2025-11-22 16:52 ` David Lechner 2025-11-28 18:46 ` kernel test robot 1 sibling, 0 replies; 6+ messages in thread From: David Lechner @ 2025-11-22 16:52 UTC (permalink / raw) To: Antoniu Miclaus, jic23, robh, conor+dt, linux-iio, linux-kernel, devicetree On 11/21/25 3:52 AM, Antoniu Miclaus wrote: > Add support for adl8113 10MHz to 12GHz Low Noise Amplifier with > 10MHz to 14GHz bypass switches. > > Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com> > --- > > Changes in v4: > - Replace signal_path sysfs attribute with hardwaregain-only control > - Add support for external bypass amplifiers via DT properties > - Introduce dynamic gain configuration system with adl8113_gain_config structure > --- > drivers/iio/amplifiers/Kconfig | 12 ++ > drivers/iio/amplifiers/Makefile | 1 + > drivers/iio/amplifiers/adl8113.c | 277 +++++++++++++++++++++++++++++++ > 3 files changed, 290 insertions(+) > create mode 100644 drivers/iio/amplifiers/adl8113.c > > diff --git a/drivers/iio/amplifiers/Kconfig b/drivers/iio/amplifiers/Kconfig > index 55eb16b32f6c..a8a604863eed 100644 > --- a/drivers/iio/amplifiers/Kconfig > +++ b/drivers/iio/amplifiers/Kconfig > @@ -36,6 +36,18 @@ config ADA4250 > To compile this driver as a module, choose M here: the > module will be called ada4250. > > +config ADL8113 > + tristate "Analog Devices ADL8113 Low Noise Amplifier" > + depends on GPIOLIB > + help > + Say yes here to build support for Analog Devices ADL8113 Low Noise > + Amplifier with integrated bypass switches. The device supports four > + operation modes controlled by GPIO pins: internal amplifier, > + internal bypass, and two external bypass modes. > + > + To compile this driver as a module, choose M here: the > + module will be called adl8113. > + > config HMC425 > tristate "Analog Devices HMC425A and similar GPIO Gain Amplifiers" > depends on GPIOLIB > diff --git a/drivers/iio/amplifiers/Makefile b/drivers/iio/amplifiers/Makefile > index 2126331129cf..0a76443be1aa 100644 > --- a/drivers/iio/amplifiers/Makefile > +++ b/drivers/iio/amplifiers/Makefile > @@ -6,4 +6,5 @@ > # When adding new entries keep the list in alphabetical order > obj-$(CONFIG_AD8366) += ad8366.o > obj-$(CONFIG_ADA4250) += ada4250.o > +obj-$(CONFIG_ADL8113) += adl8113.o > obj-$(CONFIG_HMC425) += hmc425a.o > diff --git a/drivers/iio/amplifiers/adl8113.c b/drivers/iio/amplifiers/adl8113.c > new file mode 100644 > index 000000000000..118789aa2c19 > --- /dev/null > +++ b/drivers/iio/amplifiers/adl8113.c > @@ -0,0 +1,277 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * ADL8113 Low Noise Amplifier with integrated bypass switches > + * > + * Copyright 2025 Analog Devices Inc. > + */ > + > +#include <linux/array_size.h> > +#include <linux/device.h> > +#include <linux/err.h> > +#include <linux/gpio/consumer.h> > +#include <linux/iio/iio.h> > +#include <linux/mod_devicetable.h> > +#include <linux/module.h> > +#include <linux/platform_device.h> > +#include <linux/property.h> > +#include <linux/regulator/consumer.h> > +#include <linux/slab.h> > +#include <linux/sysfs.h> > + > +enum adl8113_signal_path { > + ADL8113_INTERNAL_AMP, > + ADL8113_INTERNAL_BYPASS, > + ADL8113_EXTERNAL_A, > + ADL8113_EXTERNAL_B, > +}; > + > +struct adl8113_gain_config { > + enum adl8113_signal_path path; > + int gain_db; > + int va; > + int vb; > +}; > + > +struct adl8113_state { > + struct gpio_desc *gpio_va; > + struct gpio_desc *gpio_vb; > + struct adl8113_gain_config *gain_configs; > + int num_gain_configs; > + enum adl8113_signal_path current_path; > +}; > + > +static const char * const adl8113_supply_names[] = { > + "vdd1", > + "vdd2", > + "vss2" > +}; Datasheet says recommended power on sequence is VDD_SW, VSS, VDD_PA. Don't know why they used different names for just that one section in the datasheet, but at least vss2 should go in the middle. Not sure which VSS is which though. > + > +static int adl8113_set_path(struct adl8113_state *st, > + enum adl8113_signal_path path) > +{ > + int va, vb; > + > + /* Determine GPIO values based on signal path */ > + switch (path) { > + case ADL8113_INTERNAL_AMP: > + va = 0; vb = 0; /* Internal amplifier */ > + break; > + case ADL8113_INTERNAL_BYPASS: > + va = 1; vb = 1; /* Internal bypass */ > + break; > + case ADL8113_EXTERNAL_A: > + va = 0; vb = 1; /* External bypass A */ > + break; > + case ADL8113_EXTERNAL_B: > + va = 1; vb = 0; /* External bypass B */ > + break; > + default: > + return -EINVAL; > + } This could be simplified by using a gpiod array. > + > + gpiod_set_value(st->gpio_va, va); > + gpiod_set_value(st->gpio_vb, vb); This doesn't need to be atomic, so we can use the _cansleep() versions of the gpio functions. > + st->current_path = path; > + return 0; > +} > + > +static int adl8113_find_gain_config(struct adl8113_state *st, int gain_db) > +{ > + int i; > + > + for (i = 0; i < st->num_gain_configs; i++) { > + if (st->gain_configs[i].gain_db == gain_db) > + return i; > + } > + return -EINVAL; > +} > + > +static const struct iio_chan_spec adl8113_channels[] = { > + { > + .type = IIO_VOLTAGE, > + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_HARDWAREGAIN), > + .indexed = 1, > + .channel = 0, .indexed and .channel have no effect for shared_by_type so can be omitted. > + }, > +}; > + > +static int adl8113_read_raw(struct iio_dev *indio_dev, > + struct iio_chan_spec const *chan, > + int *val, int *val2, long mask) > +{ > + struct adl8113_state *st = iio_priv(indio_dev); > + int i; > + > + switch (mask) { > + case IIO_CHAN_INFO_HARDWAREGAIN: > + /* Find current gain configuration */ > + for (i = 0; i < st->num_gain_configs; i++) { > + if (st->gain_configs[i].path == st->current_path) { > + *val = st->gain_configs[i].gain_db; > + *val2 = 0; > + return IIO_VAL_INT_PLUS_MICRO_DB; > + } > + } > + return -EINVAL; > + default: > + return -EINVAL; > + } > +} > + > +static int adl8113_write_raw(struct iio_dev *indio_dev, > + struct iio_chan_spec const *chan, > + int val, int val2, long mask) > +{ > + struct adl8113_state *st = iio_priv(indio_dev); > + int config_idx; > + > + switch (mask) { > + case IIO_CHAN_INFO_HARDWAREGAIN: > + if (val2 != 0) > + return -EINVAL; > + > + config_idx = adl8113_find_gain_config(st, val); > + if (config_idx < 0) > + return -EINVAL; return config_idx; would be more typical. > + > + return adl8113_set_path(st, st->gain_configs[config_idx].path); > + default: > + return -EINVAL; > + } > +} > + > +static const struct iio_info adl8113_info = { > + .read_raw = adl8113_read_raw, > + .write_raw = adl8113_write_raw, > +}; > + > +static int adl8113_init_gain_configs(struct device *dev, struct adl8113_state *st) > +{ > + int external_a_gain, external_b_gain; > + int num_configs = 2; /* Always have internal amp and internal bypass */ > + int i = 0; > + > + /* Check for optional external bypass amplifier gains */ > + if (!device_property_read_u32(dev, "adi,external-bypass-a-gain-db", > + &external_a_gain)) Looks like we could just use device_property_present() here. > + num_configs++; > + > + if (!device_property_read_u32(dev, "adi,external-bypass-b-gain-db", > + &external_b_gain)) > + num_configs++; > + > + st->gain_configs = devm_kcalloc(dev, num_configs, > + sizeof(*st->gain_configs), GFP_KERNEL); > + if (!st->gain_configs) > + return -ENOMEM; > + > + /* Always include internal amplifier (14dB) */ > + st->gain_configs[i].path = ADL8113_INTERNAL_AMP; > + st->gain_configs[i].gain_db = 14; > + i++; > + > + /* Always include internal bypass (0dB) */ > + st->gain_configs[i].path = ADL8113_INTERNAL_BYPASS; > + st->gain_configs[i].gain_db = 0; The datasheet says there is actually a loss here. In one place it says 2.2dB and in another 1.8db. So it would make sense for this to be -2. > + i++; > + > + /* Add external bypass A if configured */ > + if (!device_property_read_u32(dev, "adi,external-bypass-a-gain-db", > + &external_a_gain)) { > + st->gain_configs[i].path = ADL8113_EXTERNAL_A; > + st->gain_configs[i].gain_db = external_a_gain; > + i++; > + } > + > + /* Add external bypass B if configured */ > + if (!device_property_read_u32(dev, "adi,external-bypass-b-gain-db", > + &external_b_gain)) { > + st->gain_configs[i].path = ADL8113_EXTERNAL_B; > + st->gain_configs[i].gain_db = external_b_gain; > + i++; > + } > + > + st->num_gain_configs = num_configs; The datasheet mentioned switching to a bypass with nothing connected for testing, so it could make sense that if there is a free config, add one more with gain of INT_MIN (for near-infinite attenuation) to allow that if needed. > + > + /* Check for duplicate gain values */ > + for (i = 0; i < num_configs - 1; i++) { > + for (int j = i + 1; j < num_configs; j++) { This type of inline variable declaration is usually avoided in the kernel. > + if (st->gain_configs[i].gain_db == st->gain_configs[j].gain_db) { > + dev_err(dev, "Duplicate gain values not allowed: %d dB\n", > + st->gain_configs[i].gain_db); > + return -EINVAL; Should be OK to use dev_err_probe() here. > + } > + } > + } > + > + return 0; > +} > + > +static int adl8113_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct adl8113_state *st; > + struct iio_dev *indio_dev; > + int ret; > + > + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); > + if (!indio_dev) > + return -ENOMEM; > + > + st = iio_priv(indio_dev); > + > + st->gpio_va = devm_gpiod_get(dev, "va", GPIOD_OUT_LOW); > + if (IS_ERR(st->gpio_va)) > + return dev_err_probe(dev, PTR_ERR(st->gpio_va), > + "failed to get VA GPIO\n"); > + > + st->gpio_vb = devm_gpiod_get(dev, "vb", GPIOD_OUT_LOW); > + if (IS_ERR(st->gpio_vb)) > + return dev_err_probe(dev, PTR_ERR(st->gpio_vb), > + "failed to get VB GPIO\n"); > + > + ret = devm_regulator_bulk_get_enable(dev, > + ARRAY_SIZE(adl8113_supply_names), > + adl8113_supply_names); > + if (ret) > + return dev_err_probe(dev, ret, > + "failed to get and enable supplies\n"); > + > + /* Initialize gain configurations from devicetree */ > + ret = adl8113_init_gain_configs(dev, st); > + if (ret) > + return ret; > + > + /* Initialize to internal amplifier path (14dB) */ > + ret = adl8113_set_path(st, ADL8113_INTERNAL_AMP); > + if (ret) > + return ret; > + > + indio_dev->info = &adl8113_info; > + indio_dev->name = "adl8113"; > + indio_dev->channels = adl8113_channels; > + indio_dev->num_channels = ARRAY_SIZE(adl8113_channels); > + indio_dev->modes = INDIO_DIRECT_MODE; This doesn't do single conversions, so no INDIO_DIRECT_MODE (or any other mode). > + > + return devm_iio_device_register(dev, indio_dev); > +} > + > +static const struct of_device_id adl8113_of_match[] = { > + { .compatible = "adi,adl8113" }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, adl8113_of_match); > + > +static struct platform_driver adl8113_driver = { > + .driver = { > + .name = "adl8113", > + .of_match_table = adl8113_of_match, > + }, > + .probe = adl8113_probe, > +}; > + > +module_platform_driver(adl8113_driver); > + > +MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>"); > +MODULE_DESCRIPTION("Analog Devices ADL8113 Low Noise Amplifier"); > +MODULE_LICENSE("GPL"); ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 2/2] iio: amplifiers: adl8113: add driver support 2025-11-21 9:52 ` [PATCH v4 2/2] iio: amplifiers: adl8113: add driver support Antoniu Miclaus 2025-11-22 16:52 ` David Lechner @ 2025-11-28 18:46 ` kernel test robot 1 sibling, 0 replies; 6+ messages in thread From: kernel test robot @ 2025-11-28 18:46 UTC (permalink / raw) To: Antoniu Miclaus, jic23, robh, conor+dt, linux-iio, linux-kernel, devicetree Cc: oe-kbuild-all, Antoniu Miclaus Hi Antoniu, kernel test robot noticed the following build warnings: [auto build test WARNING on jic23-iio/togreg] [also build test WARNING on robh/for-next linus/master v6.18-rc7 next-20251128] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Antoniu-Miclaus/dt-bindings-iio-amplifiers-add-adl8113/20251121-180600 base: https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg patch link: https://lore.kernel.org/r/20251121095204.18574-3-antoniu.miclaus%40analog.com patch subject: [PATCH v4 2/2] iio: amplifiers: adl8113: add driver support config: x86_64-randconfig-r071-20251128 (https://download.01.org/0day-ci/archive/20251129/202511290251.tcqKd4O5-lkp@intel.com/config) compiler: gcc-14 (Debian 14.2.0-19) 14.2.0 If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202511290251.tcqKd4O5-lkp@intel.com/ smatch warnings: drivers/iio/amplifiers/adl8113.c:58 adl8113_set_path() warn: inconsistent indenting vim +58 drivers/iio/amplifiers/adl8113.c 48 49 static int adl8113_set_path(struct adl8113_state *st, 50 enum adl8113_signal_path path) 51 { 52 int va, vb; 53 54 /* Determine GPIO values based on signal path */ 55 switch (path) { 56 case ADL8113_INTERNAL_AMP: 57 va = 0; vb = 0; /* Internal amplifier */ > 58 break; 59 case ADL8113_INTERNAL_BYPASS: 60 va = 1; vb = 1; /* Internal bypass */ 61 break; 62 case ADL8113_EXTERNAL_A: 63 va = 0; vb = 1; /* External bypass A */ 64 break; 65 case ADL8113_EXTERNAL_B: 66 va = 1; vb = 0; /* External bypass B */ 67 break; 68 default: 69 return -EINVAL; 70 } 71 72 gpiod_set_value(st->gpio_va, va); 73 gpiod_set_value(st->gpio_vb, vb); 74 st->current_path = path; 75 return 0; 76 } 77 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-11-28 18:46 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-11-21 9:52 [PATCH v4 0/2] iio: amplifiers: add support for ADL8113 Low Noise Amplifier Antoniu Miclaus 2025-11-21 9:52 ` [PATCH v4 1/2] dt-bindings: iio: amplifiers: add adl8113 Antoniu Miclaus 2025-11-22 16:17 ` David Lechner 2025-11-21 9:52 ` [PATCH v4 2/2] iio: amplifiers: adl8113: add driver support Antoniu Miclaus 2025-11-22 16:52 ` David Lechner 2025-11-28 18:46 ` kernel test robot
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®