Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio: ds4520: Add ADI DS4520 GPIO Expander Support

The DS4520 is a 9-bit nonvolatile (NV) I/O expander.
It offers users a digitally programmable alternative
to hardware jumpers and mechanical switches that are
being used to control digital logic node.

Signed-off-by: Okan Sahin <okan.sahin@analog.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

authored by

Okan Sahin and committed by
Bartosz Golaszewski
659ad5f7 451c923d

+92
+11
drivers/gpio/Kconfig
··· 1029 1029 To compile this driver as a module, choose M here: the module will 1030 1030 be called gpio-fxl6408. 1031 1031 1032 + config GPIO_DS4520 1033 + tristate "DS4520 I2C GPIO expander" 1034 + select REGMAP_I2C 1035 + select GPIO_REGMAP 1036 + help 1037 + GPIO driver for ADI DS4520 I2C-based GPIO expander. 1038 + Say yes here to enable the GPIO driver for the ADI DS4520 chip. 1039 + 1040 + To compile this driver as a module, choose M here: the module will 1041 + be called gpio-ds4520. 1042 + 1032 1043 config GPIO_GW_PLD 1033 1044 tristate "Gateworks PLD GPIO Expander" 1034 1045 depends on OF_GPIO
+1
drivers/gpio/Makefile
··· 52 52 obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o 53 53 obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o 54 54 obj-$(CONFIG_GPIO_DLN2) += gpio-dln2.o 55 + obj-$(CONFIG_GPIO_DS4520) += gpio-ds4520.o 55 56 obj-$(CONFIG_GPIO_DWAPB) += gpio-dwapb.o 56 57 obj-$(CONFIG_GPIO_EIC_SPRD) += gpio-eic-sprd.o 57 58 obj-$(CONFIG_GPIO_ELKHARTLAKE) += gpio-elkhartlake.o
+80
drivers/gpio/gpio-ds4520.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (c) 2023 Analog Devices, Inc. 4 + * Driver for the DS4520 I/O Expander 5 + */ 6 + 7 + #include <linux/device.h> 8 + #include <linux/gpio/driver.h> 9 + #include <linux/gpio/regmap.h> 10 + #include <linux/i2c.h> 11 + #include <linux/property.h> 12 + #include <linux/regmap.h> 13 + 14 + #define DS4520_PULLUP0 0xF0 15 + #define DS4520_IO_CONTROL0 0xF2 16 + #define DS4520_IO_STATUS0 0xF8 17 + 18 + static const struct regmap_config ds4520_regmap_config = { 19 + .reg_bits = 8, 20 + .val_bits = 8, 21 + }; 22 + 23 + static int ds4520_gpio_probe(struct i2c_client *client) 24 + { 25 + struct gpio_regmap_config config = { }; 26 + struct device *dev = &client->dev; 27 + struct regmap *regmap; 28 + u32 ngpio; 29 + u32 base; 30 + int ret; 31 + 32 + ret = device_property_read_u32(dev, "reg", &base); 33 + if (ret) 34 + return dev_err_probe(dev, ret, "Missing 'reg' property.\n"); 35 + 36 + ret = device_property_read_u32(dev, "ngpios", &ngpio); 37 + if (ret) 38 + return dev_err_probe(dev, ret, "Missing 'ngpios' property.\n"); 39 + 40 + regmap = devm_regmap_init_i2c(client, &ds4520_regmap_config); 41 + if (IS_ERR(regmap)) 42 + return dev_err_probe(dev, PTR_ERR(regmap), 43 + "Failed to allocate register map\n"); 44 + 45 + config.regmap = regmap; 46 + config.parent = dev; 47 + config.ngpio = ngpio; 48 + 49 + config.reg_dat_base = base + DS4520_IO_STATUS0; 50 + config.reg_set_base = base + DS4520_PULLUP0; 51 + config.reg_dir_out_base = base + DS4520_IO_CONTROL0; 52 + 53 + return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &config)); 54 + } 55 + 56 + static const struct of_device_id ds4520_gpio_of_match_table[] = { 57 + { .compatible = "adi,ds4520-gpio" }, 58 + { } 59 + }; 60 + MODULE_DEVICE_TABLE(of, ds4520_gpio_of_match_table); 61 + 62 + static const struct i2c_device_id ds4520_gpio_id_table[] = { 63 + { "ds4520-gpio" }, 64 + { } 65 + }; 66 + MODULE_DEVICE_TABLE(i2c, ds4520_gpio_id_table); 67 + 68 + static struct i2c_driver ds4520_gpio_driver = { 69 + .driver = { 70 + .name = "ds4520-gpio", 71 + .of_match_table = ds4520_gpio_of_match_table, 72 + }, 73 + .probe = ds4520_gpio_probe, 74 + .id_table = ds4520_gpio_id_table, 75 + }; 76 + module_i2c_driver(ds4520_gpio_driver); 77 + 78 + MODULE_DESCRIPTION("DS4520 I/O Expander"); 79 + MODULE_AUTHOR("Okan Sahin <okan.sahin@analog.com>"); 80 + MODULE_LICENSE("GPL");