18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * ams AS3722 pin control and GPIO driver.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (c) 2013, NVIDIA Corporation.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Author: Laxman Dewangan <ldewangan@nvidia.com>
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or
98c2ecf20Sopenharmony_ci * modify it under the terms of the GNU General Public License as
108c2ecf20Sopenharmony_ci * published by the Free Software Foundation version 2.
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
138c2ecf20Sopenharmony_ci * whether express or implied; without even the implied warranty of
148c2ecf20Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
158c2ecf20Sopenharmony_ci * General Public License for more details.
168c2ecf20Sopenharmony_ci *
178c2ecf20Sopenharmony_ci * You should have received a copy of the GNU General Public License
188c2ecf20Sopenharmony_ci * along with this program; if not, write to the Free Software
198c2ecf20Sopenharmony_ci * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
208c2ecf20Sopenharmony_ci * 02111-1307, USA
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#include <linux/delay.h>
248c2ecf20Sopenharmony_ci#include <linux/gpio/driver.h>
258c2ecf20Sopenharmony_ci#include <linux/kernel.h>
268c2ecf20Sopenharmony_ci#include <linux/module.h>
278c2ecf20Sopenharmony_ci#include <linux/mfd/as3722.h>
288c2ecf20Sopenharmony_ci#include <linux/of.h>
298c2ecf20Sopenharmony_ci#include <linux/of_device.h>
308c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
318c2ecf20Sopenharmony_ci#include <linux/pinctrl/consumer.h>
328c2ecf20Sopenharmony_ci#include <linux/pinctrl/machine.h>
338c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinctrl.h>
348c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinconf-generic.h>
358c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinconf.h>
368c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinmux.h>
378c2ecf20Sopenharmony_ci#include <linux/pm.h>
388c2ecf20Sopenharmony_ci#include <linux/slab.h>
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci#include "core.h"
418c2ecf20Sopenharmony_ci#include "pinconf.h"
428c2ecf20Sopenharmony_ci#include "pinctrl-utils.h"
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#define AS3722_PIN_GPIO0		0
458c2ecf20Sopenharmony_ci#define AS3722_PIN_GPIO1		1
468c2ecf20Sopenharmony_ci#define AS3722_PIN_GPIO2		2
478c2ecf20Sopenharmony_ci#define AS3722_PIN_GPIO3		3
488c2ecf20Sopenharmony_ci#define AS3722_PIN_GPIO4		4
498c2ecf20Sopenharmony_ci#define AS3722_PIN_GPIO5		5
508c2ecf20Sopenharmony_ci#define AS3722_PIN_GPIO6		6
518c2ecf20Sopenharmony_ci#define AS3722_PIN_GPIO7		7
528c2ecf20Sopenharmony_ci#define AS3722_PIN_NUM			(AS3722_PIN_GPIO7 + 1)
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci#define AS3722_GPIO_MODE_PULL_UP           BIT(PIN_CONFIG_BIAS_PULL_UP)
558c2ecf20Sopenharmony_ci#define AS3722_GPIO_MODE_PULL_DOWN         BIT(PIN_CONFIG_BIAS_PULL_DOWN)
568c2ecf20Sopenharmony_ci#define AS3722_GPIO_MODE_HIGH_IMPED        BIT(PIN_CONFIG_BIAS_HIGH_IMPEDANCE)
578c2ecf20Sopenharmony_ci#define AS3722_GPIO_MODE_OPEN_DRAIN        BIT(PIN_CONFIG_DRIVE_OPEN_DRAIN)
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistruct as3722_pin_function {
608c2ecf20Sopenharmony_ci	const char *name;
618c2ecf20Sopenharmony_ci	const char * const *groups;
628c2ecf20Sopenharmony_ci	unsigned ngroups;
638c2ecf20Sopenharmony_ci	int mux_option;
648c2ecf20Sopenharmony_ci};
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistruct as3722_gpio_pin_control {
678c2ecf20Sopenharmony_ci	unsigned mode_prop;
688c2ecf20Sopenharmony_ci	int io_function;
698c2ecf20Sopenharmony_ci};
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistruct as3722_pingroup {
728c2ecf20Sopenharmony_ci	const char *name;
738c2ecf20Sopenharmony_ci	const unsigned pins[1];
748c2ecf20Sopenharmony_ci	unsigned npins;
758c2ecf20Sopenharmony_ci};
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_cistruct as3722_pctrl_info {
788c2ecf20Sopenharmony_ci	struct device *dev;
798c2ecf20Sopenharmony_ci	struct pinctrl_dev *pctl;
808c2ecf20Sopenharmony_ci	struct as3722 *as3722;
818c2ecf20Sopenharmony_ci	struct gpio_chip gpio_chip;
828c2ecf20Sopenharmony_ci	int pins_current_opt[AS3722_PIN_NUM];
838c2ecf20Sopenharmony_ci	const struct as3722_pin_function *functions;
848c2ecf20Sopenharmony_ci	unsigned num_functions;
858c2ecf20Sopenharmony_ci	const struct as3722_pingroup *pin_groups;
868c2ecf20Sopenharmony_ci	int num_pin_groups;
878c2ecf20Sopenharmony_ci	const struct pinctrl_pin_desc *pins;
888c2ecf20Sopenharmony_ci	unsigned num_pins;
898c2ecf20Sopenharmony_ci	struct as3722_gpio_pin_control gpio_control[AS3722_PIN_NUM];
908c2ecf20Sopenharmony_ci};
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_cistatic const struct pinctrl_pin_desc as3722_pins_desc[] = {
938c2ecf20Sopenharmony_ci	PINCTRL_PIN(AS3722_PIN_GPIO0, "gpio0"),
948c2ecf20Sopenharmony_ci	PINCTRL_PIN(AS3722_PIN_GPIO1, "gpio1"),
958c2ecf20Sopenharmony_ci	PINCTRL_PIN(AS3722_PIN_GPIO2, "gpio2"),
968c2ecf20Sopenharmony_ci	PINCTRL_PIN(AS3722_PIN_GPIO3, "gpio3"),
978c2ecf20Sopenharmony_ci	PINCTRL_PIN(AS3722_PIN_GPIO4, "gpio4"),
988c2ecf20Sopenharmony_ci	PINCTRL_PIN(AS3722_PIN_GPIO5, "gpio5"),
998c2ecf20Sopenharmony_ci	PINCTRL_PIN(AS3722_PIN_GPIO6, "gpio6"),
1008c2ecf20Sopenharmony_ci	PINCTRL_PIN(AS3722_PIN_GPIO7, "gpio7"),
1018c2ecf20Sopenharmony_ci};
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_cistatic const char * const gpio_groups[] = {
1048c2ecf20Sopenharmony_ci	"gpio0",
1058c2ecf20Sopenharmony_ci	"gpio1",
1068c2ecf20Sopenharmony_ci	"gpio2",
1078c2ecf20Sopenharmony_ci	"gpio3",
1088c2ecf20Sopenharmony_ci	"gpio4",
1098c2ecf20Sopenharmony_ci	"gpio5",
1108c2ecf20Sopenharmony_ci	"gpio6",
1118c2ecf20Sopenharmony_ci	"gpio7",
1128c2ecf20Sopenharmony_ci};
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_cienum as3722_pinmux_option {
1158c2ecf20Sopenharmony_ci	AS3722_PINMUX_GPIO			= 0,
1168c2ecf20Sopenharmony_ci	AS3722_PINMUX_INTERRUPT_OUT		= 1,
1178c2ecf20Sopenharmony_ci	AS3722_PINMUX_VSUB_VBAT_UNDEB_LOW_OUT	= 2,
1188c2ecf20Sopenharmony_ci	AS3722_PINMUX_GPIO_INTERRUPT		= 3,
1198c2ecf20Sopenharmony_ci	AS3722_PINMUX_PWM_INPUT			= 4,
1208c2ecf20Sopenharmony_ci	AS3722_PINMUX_VOLTAGE_IN_STBY		= 5,
1218c2ecf20Sopenharmony_ci	AS3722_PINMUX_OC_PG_SD0			= 6,
1228c2ecf20Sopenharmony_ci	AS3722_PINMUX_PG_OUT			= 7,
1238c2ecf20Sopenharmony_ci	AS3722_PINMUX_CLK32K_OUT		= 8,
1248c2ecf20Sopenharmony_ci	AS3722_PINMUX_WATCHDOG_INPUT		= 9,
1258c2ecf20Sopenharmony_ci	AS3722_PINMUX_SOFT_RESET_IN		= 11,
1268c2ecf20Sopenharmony_ci	AS3722_PINMUX_PWM_OUTPUT		= 12,
1278c2ecf20Sopenharmony_ci	AS3722_PINMUX_VSUB_VBAT_LOW_DEB_OUT	= 13,
1288c2ecf20Sopenharmony_ci	AS3722_PINMUX_OC_PG_SD6			= 14,
1298c2ecf20Sopenharmony_ci};
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci#define FUNCTION_GROUP(fname, mux)			\
1328c2ecf20Sopenharmony_ci	{						\
1338c2ecf20Sopenharmony_ci		.name = #fname,				\
1348c2ecf20Sopenharmony_ci		.groups = gpio_groups,			\
1358c2ecf20Sopenharmony_ci		.ngroups = ARRAY_SIZE(gpio_groups),	\
1368c2ecf20Sopenharmony_ci		.mux_option = AS3722_PINMUX_##mux,	\
1378c2ecf20Sopenharmony_ci	}
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_cistatic const struct as3722_pin_function as3722_pin_function[] = {
1408c2ecf20Sopenharmony_ci	FUNCTION_GROUP(gpio, GPIO),
1418c2ecf20Sopenharmony_ci	FUNCTION_GROUP(interrupt-out, INTERRUPT_OUT),
1428c2ecf20Sopenharmony_ci	FUNCTION_GROUP(gpio-in-interrupt, GPIO_INTERRUPT),
1438c2ecf20Sopenharmony_ci	FUNCTION_GROUP(vsup-vbat-low-undebounce-out, VSUB_VBAT_UNDEB_LOW_OUT),
1448c2ecf20Sopenharmony_ci	FUNCTION_GROUP(vsup-vbat-low-debounce-out, VSUB_VBAT_LOW_DEB_OUT),
1458c2ecf20Sopenharmony_ci	FUNCTION_GROUP(voltage-in-standby, VOLTAGE_IN_STBY),
1468c2ecf20Sopenharmony_ci	FUNCTION_GROUP(oc-pg-sd0, OC_PG_SD0),
1478c2ecf20Sopenharmony_ci	FUNCTION_GROUP(oc-pg-sd6, OC_PG_SD6),
1488c2ecf20Sopenharmony_ci	FUNCTION_GROUP(powergood-out, PG_OUT),
1498c2ecf20Sopenharmony_ci	FUNCTION_GROUP(pwm-in, PWM_INPUT),
1508c2ecf20Sopenharmony_ci	FUNCTION_GROUP(pwm-out, PWM_OUTPUT),
1518c2ecf20Sopenharmony_ci	FUNCTION_GROUP(clk32k-out, CLK32K_OUT),
1528c2ecf20Sopenharmony_ci	FUNCTION_GROUP(watchdog-in, WATCHDOG_INPUT),
1538c2ecf20Sopenharmony_ci	FUNCTION_GROUP(soft-reset-in, SOFT_RESET_IN),
1548c2ecf20Sopenharmony_ci};
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci#define AS3722_PINGROUP(pg_name, pin_id) \
1578c2ecf20Sopenharmony_ci	{								\
1588c2ecf20Sopenharmony_ci		.name = #pg_name,					\
1598c2ecf20Sopenharmony_ci		.pins = {AS3722_PIN_##pin_id},				\
1608c2ecf20Sopenharmony_ci		.npins = 1,						\
1618c2ecf20Sopenharmony_ci	}
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistatic const struct as3722_pingroup as3722_pingroups[] = {
1648c2ecf20Sopenharmony_ci	AS3722_PINGROUP(gpio0,	GPIO0),
1658c2ecf20Sopenharmony_ci	AS3722_PINGROUP(gpio1,	GPIO1),
1668c2ecf20Sopenharmony_ci	AS3722_PINGROUP(gpio2,	GPIO2),
1678c2ecf20Sopenharmony_ci	AS3722_PINGROUP(gpio3,	GPIO3),
1688c2ecf20Sopenharmony_ci	AS3722_PINGROUP(gpio4,	GPIO4),
1698c2ecf20Sopenharmony_ci	AS3722_PINGROUP(gpio5,	GPIO5),
1708c2ecf20Sopenharmony_ci	AS3722_PINGROUP(gpio6,	GPIO6),
1718c2ecf20Sopenharmony_ci	AS3722_PINGROUP(gpio7,	GPIO7),
1728c2ecf20Sopenharmony_ci};
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_cistatic int as3722_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
1758c2ecf20Sopenharmony_ci{
1768c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	return as_pci->num_pin_groups;
1798c2ecf20Sopenharmony_ci}
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_cistatic const char *as3722_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
1828c2ecf20Sopenharmony_ci		unsigned group)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	return as_pci->pin_groups[group].name;
1878c2ecf20Sopenharmony_ci}
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_cistatic int as3722_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
1908c2ecf20Sopenharmony_ci		unsigned group, const unsigned **pins, unsigned *num_pins)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci	*pins = as_pci->pin_groups[group].pins;
1958c2ecf20Sopenharmony_ci	*num_pins = as_pci->pin_groups[group].npins;
1968c2ecf20Sopenharmony_ci	return 0;
1978c2ecf20Sopenharmony_ci}
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_cistatic const struct pinctrl_ops as3722_pinctrl_ops = {
2008c2ecf20Sopenharmony_ci	.get_groups_count = as3722_pinctrl_get_groups_count,
2018c2ecf20Sopenharmony_ci	.get_group_name = as3722_pinctrl_get_group_name,
2028c2ecf20Sopenharmony_ci	.get_group_pins = as3722_pinctrl_get_group_pins,
2038c2ecf20Sopenharmony_ci	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
2048c2ecf20Sopenharmony_ci	.dt_free_map = pinctrl_utils_free_map,
2058c2ecf20Sopenharmony_ci};
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_cistatic int as3722_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
2088c2ecf20Sopenharmony_ci{
2098c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	return as_pci->num_functions;
2128c2ecf20Sopenharmony_ci}
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_cistatic const char *as3722_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
2158c2ecf20Sopenharmony_ci			unsigned function)
2168c2ecf20Sopenharmony_ci{
2178c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci	return as_pci->functions[function].name;
2208c2ecf20Sopenharmony_ci}
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_cistatic int as3722_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
2238c2ecf20Sopenharmony_ci		unsigned function, const char * const **groups,
2248c2ecf20Sopenharmony_ci		unsigned * const num_groups)
2258c2ecf20Sopenharmony_ci{
2268c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci	*groups = as_pci->functions[function].groups;
2298c2ecf20Sopenharmony_ci	*num_groups = as_pci->functions[function].ngroups;
2308c2ecf20Sopenharmony_ci	return 0;
2318c2ecf20Sopenharmony_ci}
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_cistatic int as3722_pinctrl_set(struct pinctrl_dev *pctldev, unsigned function,
2348c2ecf20Sopenharmony_ci		unsigned group)
2358c2ecf20Sopenharmony_ci{
2368c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
2378c2ecf20Sopenharmony_ci	int gpio_cntr_reg = AS3722_GPIOn_CONTROL_REG(group);
2388c2ecf20Sopenharmony_ci	u8 val = AS3722_GPIO_IOSF_VAL(as_pci->functions[function].mux_option);
2398c2ecf20Sopenharmony_ci	int ret;
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci	dev_dbg(as_pci->dev, "%s(): GPIO %u pin to function %u and val %u\n",
2428c2ecf20Sopenharmony_ci		__func__, group, function, val);
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	ret = as3722_update_bits(as_pci->as3722, gpio_cntr_reg,
2458c2ecf20Sopenharmony_ci			AS3722_GPIO_IOSF_MASK, val);
2468c2ecf20Sopenharmony_ci	if (ret < 0) {
2478c2ecf20Sopenharmony_ci		dev_err(as_pci->dev, "GPIO%d_CTRL_REG update failed %d\n",
2488c2ecf20Sopenharmony_ci			group, ret);
2498c2ecf20Sopenharmony_ci		return ret;
2508c2ecf20Sopenharmony_ci	}
2518c2ecf20Sopenharmony_ci	as_pci->gpio_control[group].io_function = function;
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci	switch (val) {
2548c2ecf20Sopenharmony_ci	case AS3722_GPIO_IOSF_SD0_OUT:
2558c2ecf20Sopenharmony_ci	case AS3722_GPIO_IOSF_PWR_GOOD_OUT:
2568c2ecf20Sopenharmony_ci	case AS3722_GPIO_IOSF_Q32K_OUT:
2578c2ecf20Sopenharmony_ci	case AS3722_GPIO_IOSF_PWM_OUT:
2588c2ecf20Sopenharmony_ci	case AS3722_GPIO_IOSF_SD6_LOW_VOLT_LOW:
2598c2ecf20Sopenharmony_ci		ret = as3722_update_bits(as_pci->as3722, gpio_cntr_reg,
2608c2ecf20Sopenharmony_ci			AS3722_GPIO_MODE_MASK, AS3722_GPIO_MODE_OUTPUT_VDDH);
2618c2ecf20Sopenharmony_ci		if (ret < 0) {
2628c2ecf20Sopenharmony_ci			dev_err(as_pci->dev, "GPIO%d_CTRL update failed %d\n",
2638c2ecf20Sopenharmony_ci				group, ret);
2648c2ecf20Sopenharmony_ci			return ret;
2658c2ecf20Sopenharmony_ci		}
2668c2ecf20Sopenharmony_ci		as_pci->gpio_control[group].mode_prop =
2678c2ecf20Sopenharmony_ci				AS3722_GPIO_MODE_OUTPUT_VDDH;
2688c2ecf20Sopenharmony_ci		break;
2698c2ecf20Sopenharmony_ci	default:
2708c2ecf20Sopenharmony_ci		break;
2718c2ecf20Sopenharmony_ci	}
2728c2ecf20Sopenharmony_ci	return ret;
2738c2ecf20Sopenharmony_ci}
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_cistatic int as3722_pinctrl_gpio_get_mode(unsigned gpio_mode_prop, bool input)
2768c2ecf20Sopenharmony_ci{
2778c2ecf20Sopenharmony_ci	if (gpio_mode_prop & AS3722_GPIO_MODE_HIGH_IMPED)
2788c2ecf20Sopenharmony_ci		return -EINVAL;
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci	if (gpio_mode_prop & AS3722_GPIO_MODE_OPEN_DRAIN) {
2818c2ecf20Sopenharmony_ci		if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_UP)
2828c2ecf20Sopenharmony_ci			return AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP;
2838c2ecf20Sopenharmony_ci		return AS3722_GPIO_MODE_IO_OPEN_DRAIN;
2848c2ecf20Sopenharmony_ci	}
2858c2ecf20Sopenharmony_ci	if (input) {
2868c2ecf20Sopenharmony_ci		if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_UP)
2878c2ecf20Sopenharmony_ci			return AS3722_GPIO_MODE_INPUT_PULL_UP;
2888c2ecf20Sopenharmony_ci		else if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_DOWN)
2898c2ecf20Sopenharmony_ci			return AS3722_GPIO_MODE_INPUT_PULL_DOWN;
2908c2ecf20Sopenharmony_ci		return AS3722_GPIO_MODE_INPUT;
2918c2ecf20Sopenharmony_ci	}
2928c2ecf20Sopenharmony_ci	if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_DOWN)
2938c2ecf20Sopenharmony_ci		return AS3722_GPIO_MODE_OUTPUT_VDDL;
2948c2ecf20Sopenharmony_ci	return AS3722_GPIO_MODE_OUTPUT_VDDH;
2958c2ecf20Sopenharmony_ci}
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_cistatic int as3722_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
2988c2ecf20Sopenharmony_ci		struct pinctrl_gpio_range *range, unsigned offset)
2998c2ecf20Sopenharmony_ci{
3008c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_ci	if (as_pci->gpio_control[offset].io_function)
3038c2ecf20Sopenharmony_ci		return -EBUSY;
3048c2ecf20Sopenharmony_ci	return 0;
3058c2ecf20Sopenharmony_ci}
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_cistatic int as3722_pinctrl_gpio_set_direction(struct pinctrl_dev *pctldev,
3088c2ecf20Sopenharmony_ci		struct pinctrl_gpio_range *range, unsigned offset, bool input)
3098c2ecf20Sopenharmony_ci{
3108c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
3118c2ecf20Sopenharmony_ci	struct as3722 *as3722 = as_pci->as3722;
3128c2ecf20Sopenharmony_ci	int mode;
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci	mode = as3722_pinctrl_gpio_get_mode(
3158c2ecf20Sopenharmony_ci			as_pci->gpio_control[offset].mode_prop, input);
3168c2ecf20Sopenharmony_ci	if (mode < 0) {
3178c2ecf20Sopenharmony_ci		dev_err(as_pci->dev, "%s direction for GPIO %d not supported\n",
3188c2ecf20Sopenharmony_ci			(input) ? "Input" : "Output", offset);
3198c2ecf20Sopenharmony_ci		return mode;
3208c2ecf20Sopenharmony_ci	}
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci	return as3722_update_bits(as3722, AS3722_GPIOn_CONTROL_REG(offset),
3238c2ecf20Sopenharmony_ci				AS3722_GPIO_MODE_MASK, mode);
3248c2ecf20Sopenharmony_ci}
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_cistatic const struct pinmux_ops as3722_pinmux_ops = {
3278c2ecf20Sopenharmony_ci	.get_functions_count	= as3722_pinctrl_get_funcs_count,
3288c2ecf20Sopenharmony_ci	.get_function_name	= as3722_pinctrl_get_func_name,
3298c2ecf20Sopenharmony_ci	.get_function_groups	= as3722_pinctrl_get_func_groups,
3308c2ecf20Sopenharmony_ci	.set_mux		= as3722_pinctrl_set,
3318c2ecf20Sopenharmony_ci	.gpio_request_enable	= as3722_pinctrl_gpio_request_enable,
3328c2ecf20Sopenharmony_ci	.gpio_set_direction	= as3722_pinctrl_gpio_set_direction,
3338c2ecf20Sopenharmony_ci};
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_cistatic int as3722_pinconf_get(struct pinctrl_dev *pctldev,
3368c2ecf20Sopenharmony_ci			unsigned pin, unsigned long *config)
3378c2ecf20Sopenharmony_ci{
3388c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
3398c2ecf20Sopenharmony_ci	enum pin_config_param param = pinconf_to_config_param(*config);
3408c2ecf20Sopenharmony_ci	int arg = 0;
3418c2ecf20Sopenharmony_ci	u16 prop;
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ci	switch (param) {
3448c2ecf20Sopenharmony_ci	case PIN_CONFIG_BIAS_DISABLE:
3458c2ecf20Sopenharmony_ci		prop = AS3722_GPIO_MODE_PULL_UP |
3468c2ecf20Sopenharmony_ci				AS3722_GPIO_MODE_PULL_DOWN;
3478c2ecf20Sopenharmony_ci		if (!(as_pci->gpio_control[pin].mode_prop & prop))
3488c2ecf20Sopenharmony_ci			arg = 1;
3498c2ecf20Sopenharmony_ci		prop = 0;
3508c2ecf20Sopenharmony_ci		break;
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci	case PIN_CONFIG_BIAS_PULL_UP:
3538c2ecf20Sopenharmony_ci		prop = AS3722_GPIO_MODE_PULL_UP;
3548c2ecf20Sopenharmony_ci		break;
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci	case PIN_CONFIG_BIAS_PULL_DOWN:
3578c2ecf20Sopenharmony_ci		prop = AS3722_GPIO_MODE_PULL_DOWN;
3588c2ecf20Sopenharmony_ci		break;
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
3618c2ecf20Sopenharmony_ci		prop = AS3722_GPIO_MODE_OPEN_DRAIN;
3628c2ecf20Sopenharmony_ci		break;
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ci	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
3658c2ecf20Sopenharmony_ci		prop = AS3722_GPIO_MODE_HIGH_IMPED;
3668c2ecf20Sopenharmony_ci		break;
3678c2ecf20Sopenharmony_ci
3688c2ecf20Sopenharmony_ci	default:
3698c2ecf20Sopenharmony_ci		dev_err(as_pci->dev, "Properties not supported\n");
3708c2ecf20Sopenharmony_ci		return -ENOTSUPP;
3718c2ecf20Sopenharmony_ci	}
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci	if (as_pci->gpio_control[pin].mode_prop & prop)
3748c2ecf20Sopenharmony_ci		arg = 1;
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci	*config = pinconf_to_config_packed(param, (u16)arg);
3778c2ecf20Sopenharmony_ci	return 0;
3788c2ecf20Sopenharmony_ci}
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_cistatic int as3722_pinconf_set(struct pinctrl_dev *pctldev,
3818c2ecf20Sopenharmony_ci			unsigned pin, unsigned long *configs,
3828c2ecf20Sopenharmony_ci			unsigned num_configs)
3838c2ecf20Sopenharmony_ci{
3848c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
3858c2ecf20Sopenharmony_ci	enum pin_config_param param;
3868c2ecf20Sopenharmony_ci	int mode_prop;
3878c2ecf20Sopenharmony_ci	int i;
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci	for (i = 0; i < num_configs; i++) {
3908c2ecf20Sopenharmony_ci		param = pinconf_to_config_param(configs[i]);
3918c2ecf20Sopenharmony_ci		mode_prop = as_pci->gpio_control[pin].mode_prop;
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_ci		switch (param) {
3948c2ecf20Sopenharmony_ci		case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
3958c2ecf20Sopenharmony_ci			break;
3968c2ecf20Sopenharmony_ci
3978c2ecf20Sopenharmony_ci		case PIN_CONFIG_BIAS_DISABLE:
3988c2ecf20Sopenharmony_ci			mode_prop &= ~(AS3722_GPIO_MODE_PULL_UP |
3998c2ecf20Sopenharmony_ci					AS3722_GPIO_MODE_PULL_DOWN);
4008c2ecf20Sopenharmony_ci			break;
4018c2ecf20Sopenharmony_ci		case PIN_CONFIG_BIAS_PULL_UP:
4028c2ecf20Sopenharmony_ci			mode_prop |= AS3722_GPIO_MODE_PULL_UP;
4038c2ecf20Sopenharmony_ci			break;
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci		case PIN_CONFIG_BIAS_PULL_DOWN:
4068c2ecf20Sopenharmony_ci			mode_prop |= AS3722_GPIO_MODE_PULL_DOWN;
4078c2ecf20Sopenharmony_ci			break;
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_ci		case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
4108c2ecf20Sopenharmony_ci			mode_prop |= AS3722_GPIO_MODE_HIGH_IMPED;
4118c2ecf20Sopenharmony_ci			break;
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ci		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
4148c2ecf20Sopenharmony_ci			mode_prop |= AS3722_GPIO_MODE_OPEN_DRAIN;
4158c2ecf20Sopenharmony_ci			break;
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_ci		default:
4188c2ecf20Sopenharmony_ci			dev_err(as_pci->dev, "Properties not supported\n");
4198c2ecf20Sopenharmony_ci			return -ENOTSUPP;
4208c2ecf20Sopenharmony_ci		}
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_ci		as_pci->gpio_control[pin].mode_prop = mode_prop;
4238c2ecf20Sopenharmony_ci	}
4248c2ecf20Sopenharmony_ci	return 0;
4258c2ecf20Sopenharmony_ci}
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_cistatic const struct pinconf_ops as3722_pinconf_ops = {
4288c2ecf20Sopenharmony_ci	.pin_config_get = as3722_pinconf_get,
4298c2ecf20Sopenharmony_ci	.pin_config_set = as3722_pinconf_set,
4308c2ecf20Sopenharmony_ci};
4318c2ecf20Sopenharmony_ci
4328c2ecf20Sopenharmony_cistatic struct pinctrl_desc as3722_pinctrl_desc = {
4338c2ecf20Sopenharmony_ci	.pctlops = &as3722_pinctrl_ops,
4348c2ecf20Sopenharmony_ci	.pmxops = &as3722_pinmux_ops,
4358c2ecf20Sopenharmony_ci	.confops = &as3722_pinconf_ops,
4368c2ecf20Sopenharmony_ci	.owner = THIS_MODULE,
4378c2ecf20Sopenharmony_ci};
4388c2ecf20Sopenharmony_ci
4398c2ecf20Sopenharmony_cistatic int as3722_gpio_get(struct gpio_chip *chip, unsigned offset)
4408c2ecf20Sopenharmony_ci{
4418c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = gpiochip_get_data(chip);
4428c2ecf20Sopenharmony_ci	struct as3722 *as3722 = as_pci->as3722;
4438c2ecf20Sopenharmony_ci	int ret;
4448c2ecf20Sopenharmony_ci	u32 reg;
4458c2ecf20Sopenharmony_ci	u32 control;
4468c2ecf20Sopenharmony_ci	u32 val;
4478c2ecf20Sopenharmony_ci	int mode;
4488c2ecf20Sopenharmony_ci	int invert_enable;
4498c2ecf20Sopenharmony_ci
4508c2ecf20Sopenharmony_ci	ret = as3722_read(as3722, AS3722_GPIOn_CONTROL_REG(offset), &control);
4518c2ecf20Sopenharmony_ci	if (ret < 0) {
4528c2ecf20Sopenharmony_ci		dev_err(as_pci->dev,
4538c2ecf20Sopenharmony_ci			"GPIO_CONTROL%d_REG read failed: %d\n", offset, ret);
4548c2ecf20Sopenharmony_ci		return ret;
4558c2ecf20Sopenharmony_ci	}
4568c2ecf20Sopenharmony_ci
4578c2ecf20Sopenharmony_ci	invert_enable = !!(control & AS3722_GPIO_INV);
4588c2ecf20Sopenharmony_ci	mode = control & AS3722_GPIO_MODE_MASK;
4598c2ecf20Sopenharmony_ci	switch (mode) {
4608c2ecf20Sopenharmony_ci	case AS3722_GPIO_MODE_INPUT:
4618c2ecf20Sopenharmony_ci	case AS3722_GPIO_MODE_INPUT_PULL_UP:
4628c2ecf20Sopenharmony_ci	case AS3722_GPIO_MODE_INPUT_PULL_DOWN:
4638c2ecf20Sopenharmony_ci	case AS3722_GPIO_MODE_IO_OPEN_DRAIN:
4648c2ecf20Sopenharmony_ci	case AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP:
4658c2ecf20Sopenharmony_ci		reg = AS3722_GPIO_SIGNAL_IN_REG;
4668c2ecf20Sopenharmony_ci		break;
4678c2ecf20Sopenharmony_ci	case AS3722_GPIO_MODE_OUTPUT_VDDH:
4688c2ecf20Sopenharmony_ci	case AS3722_GPIO_MODE_OUTPUT_VDDL:
4698c2ecf20Sopenharmony_ci		reg = AS3722_GPIO_SIGNAL_OUT_REG;
4708c2ecf20Sopenharmony_ci		break;
4718c2ecf20Sopenharmony_ci	default:
4728c2ecf20Sopenharmony_ci		return -EINVAL;
4738c2ecf20Sopenharmony_ci	}
4748c2ecf20Sopenharmony_ci
4758c2ecf20Sopenharmony_ci	ret = as3722_read(as3722, reg, &val);
4768c2ecf20Sopenharmony_ci	if (ret < 0) {
4778c2ecf20Sopenharmony_ci		dev_err(as_pci->dev,
4788c2ecf20Sopenharmony_ci			"GPIO_SIGNAL_IN_REG read failed: %d\n", ret);
4798c2ecf20Sopenharmony_ci		return ret;
4808c2ecf20Sopenharmony_ci	}
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_ci	val = !!(val & AS3722_GPIOn_SIGNAL(offset));
4838c2ecf20Sopenharmony_ci	return (invert_enable) ? !val : val;
4848c2ecf20Sopenharmony_ci}
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_cistatic void as3722_gpio_set(struct gpio_chip *chip, unsigned offset,
4878c2ecf20Sopenharmony_ci		int value)
4888c2ecf20Sopenharmony_ci{
4898c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = gpiochip_get_data(chip);
4908c2ecf20Sopenharmony_ci	struct as3722 *as3722 = as_pci->as3722;
4918c2ecf20Sopenharmony_ci	int en_invert;
4928c2ecf20Sopenharmony_ci	u32 val;
4938c2ecf20Sopenharmony_ci	int ret;
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci	ret = as3722_read(as3722, AS3722_GPIOn_CONTROL_REG(offset), &val);
4968c2ecf20Sopenharmony_ci	if (ret < 0) {
4978c2ecf20Sopenharmony_ci		dev_err(as_pci->dev,
4988c2ecf20Sopenharmony_ci			"GPIO_CONTROL%d_REG read failed: %d\n", offset, ret);
4998c2ecf20Sopenharmony_ci		return;
5008c2ecf20Sopenharmony_ci	}
5018c2ecf20Sopenharmony_ci	en_invert = !!(val & AS3722_GPIO_INV);
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_ci	if (value)
5048c2ecf20Sopenharmony_ci		val = (en_invert) ? 0 : AS3722_GPIOn_SIGNAL(offset);
5058c2ecf20Sopenharmony_ci	else
5068c2ecf20Sopenharmony_ci		val = (en_invert) ? AS3722_GPIOn_SIGNAL(offset) : 0;
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci	ret = as3722_update_bits(as3722, AS3722_GPIO_SIGNAL_OUT_REG,
5098c2ecf20Sopenharmony_ci			AS3722_GPIOn_SIGNAL(offset), val);
5108c2ecf20Sopenharmony_ci	if (ret < 0)
5118c2ecf20Sopenharmony_ci		dev_err(as_pci->dev,
5128c2ecf20Sopenharmony_ci			"GPIO_SIGNAL_OUT_REG update failed: %d\n", ret);
5138c2ecf20Sopenharmony_ci}
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_cistatic int as3722_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
5168c2ecf20Sopenharmony_ci{
5178c2ecf20Sopenharmony_ci	return pinctrl_gpio_direction_input(chip->base + offset);
5188c2ecf20Sopenharmony_ci}
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_cistatic int as3722_gpio_direction_output(struct gpio_chip *chip,
5218c2ecf20Sopenharmony_ci		unsigned offset, int value)
5228c2ecf20Sopenharmony_ci{
5238c2ecf20Sopenharmony_ci	as3722_gpio_set(chip, offset, value);
5248c2ecf20Sopenharmony_ci	return pinctrl_gpio_direction_output(chip->base + offset);
5258c2ecf20Sopenharmony_ci}
5268c2ecf20Sopenharmony_ci
5278c2ecf20Sopenharmony_cistatic int as3722_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
5288c2ecf20Sopenharmony_ci{
5298c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = gpiochip_get_data(chip);
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ci	return as3722_irq_get_virq(as_pci->as3722, offset);
5328c2ecf20Sopenharmony_ci}
5338c2ecf20Sopenharmony_ci
5348c2ecf20Sopenharmony_cistatic const struct gpio_chip as3722_gpio_chip = {
5358c2ecf20Sopenharmony_ci	.label			= "as3722-gpio",
5368c2ecf20Sopenharmony_ci	.owner			= THIS_MODULE,
5378c2ecf20Sopenharmony_ci	.request		= gpiochip_generic_request,
5388c2ecf20Sopenharmony_ci	.free			= gpiochip_generic_free,
5398c2ecf20Sopenharmony_ci	.get			= as3722_gpio_get,
5408c2ecf20Sopenharmony_ci	.set			= as3722_gpio_set,
5418c2ecf20Sopenharmony_ci	.direction_input	= as3722_gpio_direction_input,
5428c2ecf20Sopenharmony_ci	.direction_output	= as3722_gpio_direction_output,
5438c2ecf20Sopenharmony_ci	.to_irq			= as3722_gpio_to_irq,
5448c2ecf20Sopenharmony_ci	.can_sleep		= true,
5458c2ecf20Sopenharmony_ci	.ngpio			= AS3722_PIN_NUM,
5468c2ecf20Sopenharmony_ci	.base			= -1,
5478c2ecf20Sopenharmony_ci};
5488c2ecf20Sopenharmony_ci
5498c2ecf20Sopenharmony_cistatic int as3722_pinctrl_probe(struct platform_device *pdev)
5508c2ecf20Sopenharmony_ci{
5518c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci;
5528c2ecf20Sopenharmony_ci	int ret;
5538c2ecf20Sopenharmony_ci
5548c2ecf20Sopenharmony_ci	as_pci = devm_kzalloc(&pdev->dev, sizeof(*as_pci), GFP_KERNEL);
5558c2ecf20Sopenharmony_ci	if (!as_pci)
5568c2ecf20Sopenharmony_ci		return -ENOMEM;
5578c2ecf20Sopenharmony_ci
5588c2ecf20Sopenharmony_ci	as_pci->dev = &pdev->dev;
5598c2ecf20Sopenharmony_ci	as_pci->dev->of_node = pdev->dev.parent->of_node;
5608c2ecf20Sopenharmony_ci	as_pci->as3722 = dev_get_drvdata(pdev->dev.parent);
5618c2ecf20Sopenharmony_ci	platform_set_drvdata(pdev, as_pci);
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_ci	as_pci->pins = as3722_pins_desc;
5648c2ecf20Sopenharmony_ci	as_pci->num_pins = ARRAY_SIZE(as3722_pins_desc);
5658c2ecf20Sopenharmony_ci	as_pci->functions = as3722_pin_function;
5668c2ecf20Sopenharmony_ci	as_pci->num_functions = ARRAY_SIZE(as3722_pin_function);
5678c2ecf20Sopenharmony_ci	as_pci->pin_groups = as3722_pingroups;
5688c2ecf20Sopenharmony_ci	as_pci->num_pin_groups = ARRAY_SIZE(as3722_pingroups);
5698c2ecf20Sopenharmony_ci	as3722_pinctrl_desc.name = dev_name(&pdev->dev);
5708c2ecf20Sopenharmony_ci	as3722_pinctrl_desc.pins = as3722_pins_desc;
5718c2ecf20Sopenharmony_ci	as3722_pinctrl_desc.npins = ARRAY_SIZE(as3722_pins_desc);
5728c2ecf20Sopenharmony_ci	as_pci->pctl = devm_pinctrl_register(&pdev->dev, &as3722_pinctrl_desc,
5738c2ecf20Sopenharmony_ci					     as_pci);
5748c2ecf20Sopenharmony_ci	if (IS_ERR(as_pci->pctl)) {
5758c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
5768c2ecf20Sopenharmony_ci		return PTR_ERR(as_pci->pctl);
5778c2ecf20Sopenharmony_ci	}
5788c2ecf20Sopenharmony_ci
5798c2ecf20Sopenharmony_ci	as_pci->gpio_chip = as3722_gpio_chip;
5808c2ecf20Sopenharmony_ci	as_pci->gpio_chip.parent = &pdev->dev;
5818c2ecf20Sopenharmony_ci	as_pci->gpio_chip.of_node = pdev->dev.parent->of_node;
5828c2ecf20Sopenharmony_ci	ret = gpiochip_add_data(&as_pci->gpio_chip, as_pci);
5838c2ecf20Sopenharmony_ci	if (ret < 0) {
5848c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "Couldn't register gpiochip, %d\n", ret);
5858c2ecf20Sopenharmony_ci		return ret;
5868c2ecf20Sopenharmony_ci	}
5878c2ecf20Sopenharmony_ci
5888c2ecf20Sopenharmony_ci	ret = gpiochip_add_pin_range(&as_pci->gpio_chip, dev_name(&pdev->dev),
5898c2ecf20Sopenharmony_ci				0, 0, AS3722_PIN_NUM);
5908c2ecf20Sopenharmony_ci	if (ret < 0) {
5918c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "Couldn't add pin range, %d\n", ret);
5928c2ecf20Sopenharmony_ci		goto fail_range_add;
5938c2ecf20Sopenharmony_ci	}
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci	return 0;
5968c2ecf20Sopenharmony_ci
5978c2ecf20Sopenharmony_cifail_range_add:
5988c2ecf20Sopenharmony_ci	gpiochip_remove(&as_pci->gpio_chip);
5998c2ecf20Sopenharmony_ci	return ret;
6008c2ecf20Sopenharmony_ci}
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_cistatic int as3722_pinctrl_remove(struct platform_device *pdev)
6038c2ecf20Sopenharmony_ci{
6048c2ecf20Sopenharmony_ci	struct as3722_pctrl_info *as_pci = platform_get_drvdata(pdev);
6058c2ecf20Sopenharmony_ci
6068c2ecf20Sopenharmony_ci	gpiochip_remove(&as_pci->gpio_chip);
6078c2ecf20Sopenharmony_ci	return 0;
6088c2ecf20Sopenharmony_ci}
6098c2ecf20Sopenharmony_ci
6108c2ecf20Sopenharmony_cistatic const struct of_device_id as3722_pinctrl_of_match[] = {
6118c2ecf20Sopenharmony_ci	{ .compatible = "ams,as3722-pinctrl", },
6128c2ecf20Sopenharmony_ci	{ },
6138c2ecf20Sopenharmony_ci};
6148c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, as3722_pinctrl_of_match);
6158c2ecf20Sopenharmony_ci
6168c2ecf20Sopenharmony_cistatic struct platform_driver as3722_pinctrl_driver = {
6178c2ecf20Sopenharmony_ci	.driver = {
6188c2ecf20Sopenharmony_ci		.name = "as3722-pinctrl",
6198c2ecf20Sopenharmony_ci		.of_match_table = as3722_pinctrl_of_match,
6208c2ecf20Sopenharmony_ci	},
6218c2ecf20Sopenharmony_ci	.probe = as3722_pinctrl_probe,
6228c2ecf20Sopenharmony_ci	.remove = as3722_pinctrl_remove,
6238c2ecf20Sopenharmony_ci};
6248c2ecf20Sopenharmony_cimodule_platform_driver(as3722_pinctrl_driver);
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:as3722-pinctrl");
6278c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("AS3722 pin control and GPIO driver");
6288c2ecf20Sopenharmony_ciMODULE_AUTHOR("Laxman Dewangan<ldewangan@nvidia.com>");
6298c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
630