// SPDX-License-Identifier: GPL-2.0 /* * Analog Devices AD7768 GPIO auxiliary driver * * Copyright 2026 Analog Devices Inc. */ #include #include #include #include #include #include #include #include #include #include #define AD7768_REG_GPIO_CONTROL 0x0E #define AD7768_GPIO_UGPIO_ENABLE BIT(7) #define AD7768_REG_GPIO_WRITE 0x0F #define AD7768_REG_GPIO_READ 0x10 #define AD7768_NUM_GPIOS 5 #define AD7768_FILTER_GPIO 4 static int ad7768_gpio_init_valid_mask(struct gpio_chip *gc, unsigned long *valid_mask, unsigned int ngpios) { if (ngpios > AD7768_FILTER_GPIO && fwnode_property_match_string(gc->fwnode, "clock-names", "mclk") < 0) __clear_bit(AD7768_FILTER_GPIO, valid_mask); return 0; } static int ad7768_gpio_reg_mask_xlate(struct gpio_regmap *gpio, enum gpio_regmap_operation op, unsigned int base, unsigned int offset, unsigned int *reg, unsigned int *mask) { struct regmap *regmap = gpio_regmap_get_drvdata(gpio); int ret; *reg = base; *mask = BIT(offset); if (op != GPIO_REGMAP_GET_OP) return 0; /* * AD7768 has separate input-state and output-latch registers. For an * output line, report the programmed value from the output latch; * input lines continue to use the input-state register. */ ret = regmap_test_bits(regmap, AD7768_REG_GPIO_CONTROL, *mask); if (ret < 0) return ret; if (ret) *reg = AD7768_REG_GPIO_WRITE; return 0; } static int ad7768_gpio_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id) { struct gpio_regmap_config config; struct device *dev = &adev->dev; struct device *parent = dev->parent; struct regmap *map; int ret; map = dev_get_regmap(parent, NULL); if (!map) return -ENODEV; PM_RUNTIME_ACQUIRE_AUTOSUSPEND(parent, pm); ret = PM_RUNTIME_ACQUIRE_ERR(&pm); if (ret) return ret; ret = regmap_set_bits(map, AD7768_REG_GPIO_CONTROL, AD7768_GPIO_UGPIO_ENABLE); if (ret) return ret; config = (struct gpio_regmap_config) { .parent = dev, .regmap = map, .label = dev_name(parent), .ngpio = AD7768_NUM_GPIOS, .reg_dat_base = AD7768_REG_GPIO_READ, .reg_set_base = AD7768_REG_GPIO_WRITE, .reg_dir_out_base = AD7768_REG_GPIO_CONTROL, .pm_dev = parent, .fwnode = dev_fwnode(parent), .reg_mask_xlate = ad7768_gpio_reg_mask_xlate, .init_valid_mask = ad7768_gpio_init_valid_mask, .drvdata = map, }; return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &config)); } static const struct auxiliary_device_id ad7768_gpio_ids[] = { { .name = "ad7768.gpio" }, { } }; MODULE_DEVICE_TABLE(auxiliary, ad7768_gpio_ids); static struct auxiliary_driver ad7768_gpio_driver = { .probe = ad7768_gpio_probe, .id_table = ad7768_gpio_ids, }; module_auxiliary_driver(ad7768_gpio_driver); MODULE_AUTHOR("Janani Sunil "); MODULE_DESCRIPTION("Analog Devices AD7768 GPIO auxiliary driver"); MODULE_LICENSE("GPL");