From b2cc2a31073a9357e94330c40de5d9d5adb68fc6 Mon Sep 17 00:00:00 2001 From: Kim Seer Paller Date: Wed, 15 Nov 2023 09:50:13 +0800 Subject: [PATCH 1/3] dt-bindings: gpio: add adg1414 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the ADG1414 an 9.5 Ω RON ±15 V/+12 V/±5 V iCMOS Serially-Controlled Octal SPST Switches Signed-off-by: Kim Seer Paller --- .../bindings/gpio/adi,adg1414-gpio.yaml | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/adi,adg1414-gpio.yaml diff --git a/Documentation/devicetree/bindings/gpio/adi,adg1414-gpio.yaml b/Documentation/devicetree/bindings/gpio/adi,adg1414-gpio.yaml new file mode 100644 index 00000000000000..20c772b2061434 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/adi,adg1414-gpio.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/adi,adg1414-gpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ADG1414 Serially-Controlled Octal SPST Switches + +maintainers: + - Kim Seer Paller + +description: + The ADG1414 is a 9.5 Ω RON ±15 V/+12 V/±5 V iCMOS serially-controlled octal + SPST switches. + +properties: + compatible: + enum: + - adi,adg14140-gpio + + reg: + maxItems: 1 + + gpio-controller: true + + '#gpio-cells': + const: 2 + + spi-cpha: true + + reset-gpios: + description: RESET/Logic Power Supply Input (VL). When the RESET/VL pin is + low, all switches are off and the appropriate registers are cleared to 0. + maxItems: 1 + + '#daisy-chained-devices': + description: The number of daisy-chained devices. + $ref: /schemas/types.yaml#/definitions/uint32 + default: 1 + minimum: 1 + maximum: 4 + +required: + - compatible + - reg + - spi-cpha + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + spi { + #address-cells = <1>; + #size-cells = <0>; + + gpio@0 { + compatible = "adi,adg14140-gpio"; + reg = <0>; + spi-max-frequency = <1000000>; + spi-cpha; + reset-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>; + }; + }; +... From 6d3bbcff9e824a74cea80632b19d7dd839b6ce81 Mon Sep 17 00:00:00 2001 From: Kim Seer Paller Date: Wed, 15 Nov 2023 09:53:46 +0800 Subject: [PATCH 2/3] gpio: gpio-adg1414: add ADG1414 The ADG1414 is a set of octal, single-pole, single-throw (SPST) switches controlled via a 3-wire serial interface. On resistance is matched closely between switches and is very flat over the full signal range. Each switch conducts equally well in both directions and the input signal range extends to the supplies. Data is written to these devices in the form of eight bits; each bit corresponds to one channel. Signed-off-by: Kim Seer Paller --- drivers/gpio/Kconfig | 10 +++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-adg1414.c | 155 ++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 drivers/gpio/gpio-adg1414.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 3be1a8d9bc400f..da2ea39c0b4944 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1708,6 +1708,16 @@ config GPIO_74X164 shift registers. This driver can be used to provide access to more GPIO outputs. +config GPIO_ADG1414 + tristate "ADG1414 SPST Switch Driver" + depends on GPIOLIB && SPI + help + Say yes here to build support for Analog Devices ADG1414 SPST + Switch Driver + + To compile this driver as a module, choose M here: the + module will be called gpio-adg1414. + config GPIO_ADI_DAQ1 tristate "Analog Devices AD-FMCDAQ1-EBZ SPI-GPIO expander driver" help diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 2a5bf62087bbb9..3d53cfbe7ef2e8 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o +obj-$(CONFIG_GPIO_ADG1414) += gpio-adg1414.o obj-$(CONFIG_GPIO_ADI_DAQ1) += gpio-adi-daq1.o obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o diff --git a/drivers/gpio/gpio-adg1414.c b/drivers/gpio/gpio-adg1414.c new file mode 100644 index 00000000000000..678f7894599702 --- /dev/null +++ b/drivers/gpio/gpio-adg1414.c @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ADG1414 Serially-Controlled Octal SPST Switches Driver + * + * Copyright 2025 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include + +#define ADG1414_MAX_DEVICES 4 + +struct adg1414_state { + struct spi_device *spi; + struct gpio_chip chip; + /* lock to protect against multiple access to the device and shared data */ + struct mutex lock; + + u8 buffer[]; +}; + +static int adg1414_write_config(struct adg1414_state *st) +{ + return spi_write(st->spi, st->buffer, st->chip.ngpio / 8); +} + +static int adg1414_get_value(struct gpio_chip *chip, unsigned int offset) +{ + struct adg1414_state *st = gpiochip_get_data(chip); + u8 bank, pin; + + guard(mutex)(&st->lock); + bank = (chip->ngpio / 8) - 1 - offset / 8; + pin = offset % 8; + + return (st->buffer[bank] >> pin) & 0x1; +} + +static void adg1414_set_value(struct gpio_chip *chip, unsigned int offset, + int val) +{ + struct adg1414_state *st = gpiochip_get_data(chip); + u8 bank, pin; + + guard(mutex)(&st->lock); + bank = (chip->ngpio / 8) - 1 - offset / 8; + pin = offset % 8; + + if (val) + st->buffer[bank] |= BIT(pin); + else + st->buffer[bank] &= ~BIT(pin); + + adg1414_write_config(st); +} + +static void adg1414_set_multiple(struct gpio_chip *chip, unsigned long *mask, + unsigned long *bits) +{ + struct adg1414_state *st = gpiochip_get_data(chip); + unsigned long offset, bankmask, bitmask; + size_t bank; + + guard(mutex)(&st->lock); + for_each_set_clump8(offset, bankmask, mask, chip->ngpio) { + bank = (chip->ngpio / 8) - 1 - offset / 8; + bitmask = bitmap_get_value8(bits, offset) & bankmask; + + st->buffer[bank] &= ~bankmask; + st->buffer[bank] |= bitmask; + } + + adg1414_write_config(st); +} + +static int adg1414_direction_output(struct gpio_chip *chip, unsigned int offset, + int val) +{ + adg1414_set_value(chip, offset, val); + return 0; +} + +static int adg1414_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct adg1414_state *st; + struct gpio_desc *reset; + u32 num_devices; + int ret; + + num_devices = 1; + ret = device_property_read_u32(dev, "#daisy-chained-devices", + &num_devices); + if (!ret) { + if (!num_devices || num_devices > ADG1414_MAX_DEVICES) + return dev_err_probe(dev, ret, + "Failed to get daisy-chained-devices property\n"); + } + + st = devm_kzalloc(dev, sizeof(*st) + num_devices, GFP_KERNEL); + if (!st) + return -ENOMEM; + + st->spi = spi; + + /* Use reset pin to reset the device */ + reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(reset)) + return dev_err_probe(dev, PTR_ERR(reset), + "Failed to get reset gpio"); + + if (reset) { + fsleep(1); + gpiod_set_value_cansleep(reset, 0); + } + + st->chip.label = "adg1414"; + st->chip.parent = dev; + st->chip.direction_output = adg1414_direction_output; + st->chip.set = adg1414_set_value; + st->chip.get = adg1414_get_value; + st->chip.set_multiple = adg1414_set_multiple; + st->chip.base = -1; + st->chip.ngpio = num_devices * 8; + st->chip.can_sleep = true; + + ret = devm_mutex_init(dev, &st->lock); + if (ret) + return ret; + + return devm_gpiochip_add_data(dev, &st->chip, st); +} + +static const struct of_device_id adg1414_of_match[] = { + { .compatible = "adi,adg1414-gpio" }, + { } +}; +MODULE_DEVICE_TABLE(of, adg1414_of_match); + +static struct spi_driver adg1414_driver = { + .driver = { + .name = "adg1414-gpio", + .of_match_table = adg1414_of_match, + }, + .probe = adg1414_probe, +}; +module_spi_driver(adg1414_driver); + +MODULE_AUTHOR("Kim Seer Paller "); +MODULE_DESCRIPTION("ADG1414 Serially-Controlled Octal SPST Switches Driver"); +MODULE_LICENSE("GPL"); From 4d42ab1e1f4d3165367d45868e88859d73568bf1 Mon Sep 17 00:00:00 2001 From: Kim Seer Paller Date: Mon, 31 Mar 2025 15:55:04 +0800 Subject: [PATCH 3/3] Kconfig.adi: add ADG1414 Imply GPIO_ADG1414 GPIO driver. Signed-off-by: Kim Seer Paller --- Kconfig.adi | 1 + 1 file changed, 1 insertion(+) diff --git a/Kconfig.adi b/Kconfig.adi index 307c1bab7b03c7..fbf8e776eac8cc 100644 --- a/Kconfig.adi +++ b/Kconfig.adi @@ -96,6 +96,7 @@ config KERNEL_ALL_ADI_DRIVERS imply REGULATOR_MAX77857 imply REGULATOR_MAX77541 imply MFD_MAX77541 + imply GPIO_ADG1414 source "drivers/clk/Kconfig.adi" source "drivers/hwmon/Kconfig.adi"