From 673d3358b0b9ba9e75de4d4775cbfd33b9d93552 Mon Sep 17 00:00:00 2001 From: Wyon Bi Date: Mon, 2 May 2022 02:13:26 +0000 Subject: [PATCH] gpio: Add support for Maxim MAX96752F GPIO controller Signed-off-by: Wyon Bi Change-Id: Ib94de1c8ac1af44f0f3b61aa5eccff8dda741450 --- drivers/gpio/Kconfig | 7 +++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-max96752f.c | 104 ++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 drivers/gpio/gpio-max96752f.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 9a4110ad1c20..d82126d6135d 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1235,6 +1235,13 @@ config GPIO_MAX77650 GPIO driver for MAX77650/77651 PMIC from Maxim Semiconductor. These chips have a single pin that can be configured as GPIO. +config GPIO_MAX96752F + tristate "MAX96752F GPIO" + depends on MFD_MAX96752F + help + Select this option to enable GPIO driver for the MAX96752F + chip. + config GPIO_MSIC bool "Intel MSIC mixed signal gpio support" depends on (X86 || COMPILE_TEST) && MFD_INTEL_MSIC diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index ce6cafb6d3de..7b42304be907 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -88,6 +88,7 @@ obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o obj-$(CONFIG_GPIO_MAX77620) += gpio-max77620.o obj-$(CONFIG_GPIO_MAX77650) += gpio-max77650.o +obj-$(CONFIG_GPIO_MAX96752F) += gpio-max96752f.o obj-$(CONFIG_GPIO_MB86S7X) += gpio-mb86s7x.o obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o diff --git a/drivers/gpio/gpio-max96752f.c b/drivers/gpio/gpio-max96752f.c new file mode 100644 index 000000000000..1c3816737c55 --- /dev/null +++ b/drivers/gpio/gpio-max96752f.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Maxim MAX96752F GPIO driver + * + * Copyright (C) 2022 Rockchip Electronics Co. Ltd. + */ + +#include +#include +#include +#include +#include + +struct max96752f_gpio { + struct device *dev; + struct regmap *regmap; + struct gpio_chip gpio_chip; +}; + +static int max96752f_gpio_direction_output(struct gpio_chip *gc, + unsigned int offset, int value) +{ + struct max96752f_gpio *gpio = gpiochip_get_data(gc); + + regmap_update_bits(gpio->regmap, GPIO_A_REG(offset), + GPIO_OUT_DIS | GPIO_OUT, + FIELD_PREP(GPIO_OUT_DIS, 0) | + FIELD_PREP(GPIO_OUT, value)); + + return 0; +} + +static void max96752f_gpio_set(struct gpio_chip *gc, unsigned int offset, + int value) +{ + struct max96752f_gpio *gpio = gpiochip_get_data(gc); + + regmap_update_bits(gpio->regmap, GPIO_A_REG(offset), GPIO_OUT, + FIELD_PREP(GPIO_OUT, value)); +} + +static int max96752f_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct max96752f_gpio *gpio = gpiochip_get_data(gc); + unsigned int value; + + regmap_read(gpio->regmap, GPIO_A_REG(offset), &value); + + return !!FIELD_GET(GPIO_OUT, value); +} + +static int max96752f_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct max96752f_gpio *gpio; + int ret; + + gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) + return -ENOMEM; + + gpio->dev = dev; + platform_set_drvdata(pdev, gpio); + + gpio->regmap = dev_get_regmap(dev->parent, NULL); + if (!gpio->regmap) + return dev_err_probe(dev, -ENODEV, "failed to get regmap\n"); + + gpio->gpio_chip.of_node = dev->of_node; + gpio->gpio_chip.label = dev_name(dev); + gpio->gpio_chip.parent = dev->parent; + gpio->gpio_chip.direction_output = max96752f_gpio_direction_output; + gpio->gpio_chip.set = max96752f_gpio_set; + gpio->gpio_chip.get = max96752f_gpio_get; + gpio->gpio_chip.ngpio = 16; + gpio->gpio_chip.can_sleep = true; + gpio->gpio_chip.base = -1; + + ret = devm_gpiochip_add_data(dev, &gpio->gpio_chip, gpio); + if (ret) + return dev_err_probe(dev, ret, "failed to add gpio chip\n"); + + return 0; +} + +static const struct of_device_id max96752f_gpio_of_match[] = { + { .name = "maxim,max96752f-gpio", }, + {} +}; +MODULE_DEVICE_TABLE(of, max96752f_gpio_of_match); + +static struct platform_driver max96752f_gpio_driver = { + .driver = { + .name = "max96752f-gpio", + .of_match_table = max96752f_gpio_of_match, + }, + .probe = max96752f_gpio_probe, +}; + +module_platform_driver(max96752f_gpio_driver); + +MODULE_AUTHOR("Wyon Bi "); +MODULE_DESCRIPTION("Maxim MAX96752F GPIO driver"); +MODULE_LICENSE("GPL");