12df723d4SLaxman Dewangan /*
22df723d4SLaxman Dewangan  * MAX77620 pin control driver.
32df723d4SLaxman Dewangan  *
42df723d4SLaxman Dewangan  * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
52df723d4SLaxman Dewangan  *
62df723d4SLaxman Dewangan  * Author:
72df723d4SLaxman Dewangan  *	Chaitanya Bandi <bandik@nvidia.com>
82df723d4SLaxman Dewangan  *	Laxman Dewangan <ldewangan@nvidia.com>
92df723d4SLaxman Dewangan  *
102df723d4SLaxman Dewangan  * This program is free software; you can redistribute it and/or modify it
112df723d4SLaxman Dewangan  * under the terms and conditions of the GNU General Public License,
122df723d4SLaxman Dewangan  * version 2, as published by the Free Software Foundation.
132df723d4SLaxman Dewangan  */
142df723d4SLaxman Dewangan 
152df723d4SLaxman Dewangan #include <linux/mfd/max77620.h>
162df723d4SLaxman Dewangan #include <linux/module.h>
172df723d4SLaxman Dewangan #include <linux/of.h>
182df723d4SLaxman Dewangan #include <linux/pinctrl/pinctrl.h>
192df723d4SLaxman Dewangan #include <linux/pinctrl/pinconf-generic.h>
202df723d4SLaxman Dewangan #include <linux/pinctrl/pinconf.h>
212df723d4SLaxman Dewangan #include <linux/pinctrl/pinmux.h>
222df723d4SLaxman Dewangan #include <linux/platform_device.h>
232df723d4SLaxman Dewangan #include <linux/regmap.h>
242df723d4SLaxman Dewangan 
252df723d4SLaxman Dewangan #include "core.h"
262df723d4SLaxman Dewangan #include "pinconf.h"
272df723d4SLaxman Dewangan #include "pinctrl-utils.h"
282df723d4SLaxman Dewangan 
292df723d4SLaxman Dewangan #define MAX77620_PIN_NUM 8
302df723d4SLaxman Dewangan 
312df723d4SLaxman Dewangan enum max77620_pin_ppdrv {
322df723d4SLaxman Dewangan 	MAX77620_PIN_UNCONFIG_DRV,
332df723d4SLaxman Dewangan 	MAX77620_PIN_OD_DRV,
342df723d4SLaxman Dewangan 	MAX77620_PIN_PP_DRV,
352df723d4SLaxman Dewangan };
362df723d4SLaxman Dewangan 
372df723d4SLaxman Dewangan enum max77620_pinconf_param {
382df723d4SLaxman Dewangan 	MAX77620_ACTIVE_FPS_SOURCE = PIN_CONFIG_END + 1,
392df723d4SLaxman Dewangan 	MAX77620_ACTIVE_FPS_POWER_ON_SLOTS,
402df723d4SLaxman Dewangan 	MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS,
412df723d4SLaxman Dewangan 	MAX77620_SUSPEND_FPS_SOURCE,
422df723d4SLaxman Dewangan 	MAX77620_SUSPEND_FPS_POWER_ON_SLOTS,
432df723d4SLaxman Dewangan 	MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS,
442df723d4SLaxman Dewangan };
452df723d4SLaxman Dewangan 
462df723d4SLaxman Dewangan struct max77620_pin_function {
472df723d4SLaxman Dewangan 	const char *name;
482df723d4SLaxman Dewangan 	const char * const *groups;
492df723d4SLaxman Dewangan 	unsigned int ngroups;
502df723d4SLaxman Dewangan 	int mux_option;
512df723d4SLaxman Dewangan };
522df723d4SLaxman Dewangan 
532df723d4SLaxman Dewangan struct max77620_cfg_param {
542df723d4SLaxman Dewangan 	const char *property;
552df723d4SLaxman Dewangan 	enum max77620_pinconf_param param;
562df723d4SLaxman Dewangan };
572df723d4SLaxman Dewangan 
582df723d4SLaxman Dewangan static const struct pinconf_generic_params max77620_cfg_params[] = {
592df723d4SLaxman Dewangan 	{
602df723d4SLaxman Dewangan 		.property = "maxim,active-fps-source",
612df723d4SLaxman Dewangan 		.param = MAX77620_ACTIVE_FPS_SOURCE,
622df723d4SLaxman Dewangan 	}, {
632df723d4SLaxman Dewangan 		.property = "maxim,active-fps-power-up-slot",
642df723d4SLaxman Dewangan 		.param = MAX77620_ACTIVE_FPS_POWER_ON_SLOTS,
652df723d4SLaxman Dewangan 	}, {
662df723d4SLaxman Dewangan 		.property = "maxim,active-fps-power-down-slot",
672df723d4SLaxman Dewangan 		.param = MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS,
682df723d4SLaxman Dewangan 	}, {
692df723d4SLaxman Dewangan 		.property = "maxim,suspend-fps-source",
702df723d4SLaxman Dewangan 		.param = MAX77620_SUSPEND_FPS_SOURCE,
712df723d4SLaxman Dewangan 	}, {
722df723d4SLaxman Dewangan 		.property = "maxim,suspend-fps-power-up-slot",
732df723d4SLaxman Dewangan 		.param = MAX77620_SUSPEND_FPS_POWER_ON_SLOTS,
742df723d4SLaxman Dewangan 	}, {
752df723d4SLaxman Dewangan 		.property = "maxim,suspend-fps-power-down-slot",
762df723d4SLaxman Dewangan 		.param = MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS,
772df723d4SLaxman Dewangan 	},
782df723d4SLaxman Dewangan };
792df723d4SLaxman Dewangan 
802df723d4SLaxman Dewangan enum max77620_alternate_pinmux_option {
812df723d4SLaxman Dewangan 	MAX77620_PINMUX_GPIO				= 0,
822df723d4SLaxman Dewangan 	MAX77620_PINMUX_LOW_POWER_MODE_CONTROL_IN	= 1,
832df723d4SLaxman Dewangan 	MAX77620_PINMUX_FLEXIBLE_POWER_SEQUENCER_OUT	= 2,
842df723d4SLaxman Dewangan 	MAX77620_PINMUX_32K_OUT1			= 3,
852df723d4SLaxman Dewangan 	MAX77620_PINMUX_SD0_DYNAMIC_VOLTAGE_SCALING_IN	= 4,
862df723d4SLaxman Dewangan 	MAX77620_PINMUX_SD1_DYNAMIC_VOLTAGE_SCALING_IN	= 5,
872df723d4SLaxman Dewangan 	MAX77620_PINMUX_REFERENCE_OUT			= 6,
882df723d4SLaxman Dewangan };
892df723d4SLaxman Dewangan 
902df723d4SLaxman Dewangan struct max77620_pingroup {
912df723d4SLaxman Dewangan 	const char *name;
922df723d4SLaxman Dewangan 	const unsigned int pins[1];
932df723d4SLaxman Dewangan 	unsigned int npins;
942df723d4SLaxman Dewangan 	enum max77620_alternate_pinmux_option alt_option;
952df723d4SLaxman Dewangan };
962df723d4SLaxman Dewangan 
972df723d4SLaxman Dewangan struct max77620_pin_info {
982df723d4SLaxman Dewangan 	enum max77620_pin_ppdrv drv_type;
992df723d4SLaxman Dewangan 	int pull_config;
1002df723d4SLaxman Dewangan };
1012df723d4SLaxman Dewangan 
1022df723d4SLaxman Dewangan struct max77620_fps_config {
1032df723d4SLaxman Dewangan 	int active_fps_src;
1042df723d4SLaxman Dewangan 	int active_power_up_slots;
1052df723d4SLaxman Dewangan 	int active_power_down_slots;
1062df723d4SLaxman Dewangan 	int suspend_fps_src;
1072df723d4SLaxman Dewangan 	int suspend_power_up_slots;
1082df723d4SLaxman Dewangan 	int suspend_power_down_slots;
1092df723d4SLaxman Dewangan };
1102df723d4SLaxman Dewangan 
1112df723d4SLaxman Dewangan struct max77620_pctrl_info {
1122df723d4SLaxman Dewangan 	struct device *dev;
1132df723d4SLaxman Dewangan 	struct pinctrl_dev *pctl;
1142df723d4SLaxman Dewangan 	struct regmap *rmap;
1152df723d4SLaxman Dewangan 	int pins_current_opt[MAX77620_GPIO_NR];
1162df723d4SLaxman Dewangan 	const struct max77620_pin_function *functions;
1172df723d4SLaxman Dewangan 	unsigned int num_functions;
1182df723d4SLaxman Dewangan 	const struct max77620_pingroup *pin_groups;
1192df723d4SLaxman Dewangan 	int num_pin_groups;
1202df723d4SLaxman Dewangan 	const struct pinctrl_pin_desc *pins;
1212df723d4SLaxman Dewangan 	unsigned int num_pins;
1222df723d4SLaxman Dewangan 	struct max77620_pin_info pin_info[MAX77620_PIN_NUM];
1232df723d4SLaxman Dewangan 	struct max77620_fps_config fps_config[MAX77620_PIN_NUM];
1242df723d4SLaxman Dewangan };
1252df723d4SLaxman Dewangan 
1262df723d4SLaxman Dewangan static const struct pinctrl_pin_desc max77620_pins_desc[] = {
1272df723d4SLaxman Dewangan 	PINCTRL_PIN(MAX77620_GPIO0, "gpio0"),
1282df723d4SLaxman Dewangan 	PINCTRL_PIN(MAX77620_GPIO1, "gpio1"),
1292df723d4SLaxman Dewangan 	PINCTRL_PIN(MAX77620_GPIO2, "gpio2"),
1302df723d4SLaxman Dewangan 	PINCTRL_PIN(MAX77620_GPIO3, "gpio3"),
1312df723d4SLaxman Dewangan 	PINCTRL_PIN(MAX77620_GPIO4, "gpio4"),
1322df723d4SLaxman Dewangan 	PINCTRL_PIN(MAX77620_GPIO5, "gpio5"),
1332df723d4SLaxman Dewangan 	PINCTRL_PIN(MAX77620_GPIO6, "gpio6"),
1342df723d4SLaxman Dewangan 	PINCTRL_PIN(MAX77620_GPIO7, "gpio7"),
1352df723d4SLaxman Dewangan };
1362df723d4SLaxman Dewangan 
1372df723d4SLaxman Dewangan static const char * const gpio_groups[] = {
1382df723d4SLaxman Dewangan 	"gpio0",
1392df723d4SLaxman Dewangan 	"gpio1",
1402df723d4SLaxman Dewangan 	"gpio2",
1412df723d4SLaxman Dewangan 	"gpio3",
1422df723d4SLaxman Dewangan 	"gpio4",
1432df723d4SLaxman Dewangan 	"gpio5",
1442df723d4SLaxman Dewangan 	"gpio6",
1452df723d4SLaxman Dewangan 	"gpio7",
1462df723d4SLaxman Dewangan };
1472df723d4SLaxman Dewangan 
1482df723d4SLaxman Dewangan #define FUNCTION_GROUP(fname, mux)			\
1492df723d4SLaxman Dewangan 	{						\
1502df723d4SLaxman Dewangan 		.name = fname,				\
1512df723d4SLaxman Dewangan 		.groups = gpio_groups,			\
1522df723d4SLaxman Dewangan 		.ngroups = ARRAY_SIZE(gpio_groups),	\
1532df723d4SLaxman Dewangan 		.mux_option = MAX77620_PINMUX_##mux,	\
1542df723d4SLaxman Dewangan 	}
1552df723d4SLaxman Dewangan 
1562df723d4SLaxman Dewangan static const struct max77620_pin_function max77620_pin_function[] = {
1572df723d4SLaxman Dewangan 	FUNCTION_GROUP("gpio", GPIO),
1582df723d4SLaxman Dewangan 	FUNCTION_GROUP("lpm-control-in", LOW_POWER_MODE_CONTROL_IN),
1592df723d4SLaxman Dewangan 	FUNCTION_GROUP("fps-out", FLEXIBLE_POWER_SEQUENCER_OUT),
1602df723d4SLaxman Dewangan 	FUNCTION_GROUP("32k-out1", 32K_OUT1),
1612df723d4SLaxman Dewangan 	FUNCTION_GROUP("sd0-dvs-in", SD0_DYNAMIC_VOLTAGE_SCALING_IN),
1622df723d4SLaxman Dewangan 	FUNCTION_GROUP("sd1-dvs-in", SD1_DYNAMIC_VOLTAGE_SCALING_IN),
1632df723d4SLaxman Dewangan 	FUNCTION_GROUP("reference-out", REFERENCE_OUT),
1642df723d4SLaxman Dewangan };
1652df723d4SLaxman Dewangan 
1662df723d4SLaxman Dewangan #define MAX77620_PINGROUP(pg_name, pin_id, option) \
1672df723d4SLaxman Dewangan 	{								\
1682df723d4SLaxman Dewangan 		.name = #pg_name,					\
1692df723d4SLaxman Dewangan 		.pins = {MAX77620_##pin_id},				\
1702df723d4SLaxman Dewangan 		.npins = 1,						\
1712df723d4SLaxman Dewangan 		.alt_option = MAX77620_PINMUX_##option,			\
1722df723d4SLaxman Dewangan 	}
1732df723d4SLaxman Dewangan 
1742df723d4SLaxman Dewangan static const struct max77620_pingroup max77620_pingroups[] = {
1752df723d4SLaxman Dewangan 	MAX77620_PINGROUP(gpio0, GPIO0, LOW_POWER_MODE_CONTROL_IN),
1762df723d4SLaxman Dewangan 	MAX77620_PINGROUP(gpio1, GPIO1, FLEXIBLE_POWER_SEQUENCER_OUT),
1772df723d4SLaxman Dewangan 	MAX77620_PINGROUP(gpio2, GPIO2, FLEXIBLE_POWER_SEQUENCER_OUT),
1782df723d4SLaxman Dewangan 	MAX77620_PINGROUP(gpio3, GPIO3, FLEXIBLE_POWER_SEQUENCER_OUT),
1792df723d4SLaxman Dewangan 	MAX77620_PINGROUP(gpio4, GPIO4, 32K_OUT1),
1802df723d4SLaxman Dewangan 	MAX77620_PINGROUP(gpio5, GPIO5, SD0_DYNAMIC_VOLTAGE_SCALING_IN),
1812df723d4SLaxman Dewangan 	MAX77620_PINGROUP(gpio6, GPIO6, SD1_DYNAMIC_VOLTAGE_SCALING_IN),
1822df723d4SLaxman Dewangan 	MAX77620_PINGROUP(gpio7, GPIO7, REFERENCE_OUT),
1832df723d4SLaxman Dewangan };
1842df723d4SLaxman Dewangan 
1852df723d4SLaxman Dewangan static int max77620_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
1862df723d4SLaxman Dewangan {
1872df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
1882df723d4SLaxman Dewangan 
1892df723d4SLaxman Dewangan 	return mpci->num_pin_groups;
1902df723d4SLaxman Dewangan }
1912df723d4SLaxman Dewangan 
1922df723d4SLaxman Dewangan static const char *max77620_pinctrl_get_group_name(
1932df723d4SLaxman Dewangan 		struct pinctrl_dev *pctldev, unsigned int group)
1942df723d4SLaxman Dewangan {
1952df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
1962df723d4SLaxman Dewangan 
1972df723d4SLaxman Dewangan 	return mpci->pin_groups[group].name;
1982df723d4SLaxman Dewangan }
1992df723d4SLaxman Dewangan 
2002df723d4SLaxman Dewangan static int max77620_pinctrl_get_group_pins(
2012df723d4SLaxman Dewangan 		struct pinctrl_dev *pctldev, unsigned int group,
2022df723d4SLaxman Dewangan 		const unsigned int **pins, unsigned int *num_pins)
2032df723d4SLaxman Dewangan {
2042df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
2052df723d4SLaxman Dewangan 
2062df723d4SLaxman Dewangan 	*pins = mpci->pin_groups[group].pins;
2072df723d4SLaxman Dewangan 	*num_pins = mpci->pin_groups[group].npins;
2082df723d4SLaxman Dewangan 
2092df723d4SLaxman Dewangan 	return 0;
2102df723d4SLaxman Dewangan }
2112df723d4SLaxman Dewangan 
2122df723d4SLaxman Dewangan static const struct pinctrl_ops max77620_pinctrl_ops = {
2132df723d4SLaxman Dewangan 	.get_groups_count = max77620_pinctrl_get_groups_count,
2142df723d4SLaxman Dewangan 	.get_group_name = max77620_pinctrl_get_group_name,
2152df723d4SLaxman Dewangan 	.get_group_pins = max77620_pinctrl_get_group_pins,
2162df723d4SLaxman Dewangan 	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
2172df723d4SLaxman Dewangan 	.dt_free_map = pinctrl_utils_free_map,
2182df723d4SLaxman Dewangan };
2192df723d4SLaxman Dewangan 
2202df723d4SLaxman Dewangan static int max77620_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
2212df723d4SLaxman Dewangan {
2222df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
2232df723d4SLaxman Dewangan 
2242df723d4SLaxman Dewangan 	return mpci->num_functions;
2252df723d4SLaxman Dewangan }
2262df723d4SLaxman Dewangan 
2272df723d4SLaxman Dewangan static const char *max77620_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
2282df723d4SLaxman Dewangan 						  unsigned int function)
2292df723d4SLaxman Dewangan {
2302df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
2312df723d4SLaxman Dewangan 
2322df723d4SLaxman Dewangan 	return mpci->functions[function].name;
2332df723d4SLaxman Dewangan }
2342df723d4SLaxman Dewangan 
2352df723d4SLaxman Dewangan static int max77620_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
2362df723d4SLaxman Dewangan 					    unsigned int function,
2372df723d4SLaxman Dewangan 					    const char * const **groups,
2382df723d4SLaxman Dewangan 					    unsigned int * const num_groups)
2392df723d4SLaxman Dewangan {
2402df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
2412df723d4SLaxman Dewangan 
2422df723d4SLaxman Dewangan 	*groups = mpci->functions[function].groups;
2432df723d4SLaxman Dewangan 	*num_groups = mpci->functions[function].ngroups;
2442df723d4SLaxman Dewangan 
2452df723d4SLaxman Dewangan 	return 0;
2462df723d4SLaxman Dewangan }
2472df723d4SLaxman Dewangan 
2482df723d4SLaxman Dewangan static int max77620_pinctrl_enable(struct pinctrl_dev *pctldev,
2492df723d4SLaxman Dewangan 				   unsigned int function, unsigned int group)
2502df723d4SLaxman Dewangan {
2512df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
2522df723d4SLaxman Dewangan 	u8 val;
2532df723d4SLaxman Dewangan 	int ret;
2542df723d4SLaxman Dewangan 
2552df723d4SLaxman Dewangan 	if (function == MAX77620_PINMUX_GPIO) {
2562df723d4SLaxman Dewangan 		val = 0;
2572df723d4SLaxman Dewangan 	} else if (function == mpci->pin_groups[group].alt_option) {
2582df723d4SLaxman Dewangan 		val = 1 << group;
2592df723d4SLaxman Dewangan 	} else {
2602df723d4SLaxman Dewangan 		dev_err(mpci->dev, "GPIO %u doesn't have function %u\n",
2612df723d4SLaxman Dewangan 			group, function);
2622df723d4SLaxman Dewangan 		return -EINVAL;
2632df723d4SLaxman Dewangan 	}
2642df723d4SLaxman Dewangan 	ret = regmap_update_bits(mpci->rmap, MAX77620_REG_AME_GPIO,
2652df723d4SLaxman Dewangan 				 BIT(group), val);
2662df723d4SLaxman Dewangan 	if (ret < 0)
2672df723d4SLaxman Dewangan 		dev_err(mpci->dev, "REG AME GPIO update failed: %d\n", ret);
2682df723d4SLaxman Dewangan 
2692df723d4SLaxman Dewangan 	return ret;
2702df723d4SLaxman Dewangan }
2712df723d4SLaxman Dewangan 
2722df723d4SLaxman Dewangan static const struct pinmux_ops max77620_pinmux_ops = {
2732df723d4SLaxman Dewangan 	.get_functions_count	= max77620_pinctrl_get_funcs_count,
2742df723d4SLaxman Dewangan 	.get_function_name	= max77620_pinctrl_get_func_name,
2752df723d4SLaxman Dewangan 	.get_function_groups	= max77620_pinctrl_get_func_groups,
2762df723d4SLaxman Dewangan 	.set_mux		= max77620_pinctrl_enable,
2772df723d4SLaxman Dewangan };
2782df723d4SLaxman Dewangan 
2792df723d4SLaxman Dewangan static int max77620_pinconf_get(struct pinctrl_dev *pctldev,
2802df723d4SLaxman Dewangan 				unsigned int pin, unsigned long *config)
2812df723d4SLaxman Dewangan {
2822df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
2832df723d4SLaxman Dewangan 	struct device *dev = mpci->dev;
2842df723d4SLaxman Dewangan 	enum pin_config_param param = pinconf_to_config_param(*config);
2852df723d4SLaxman Dewangan 	unsigned int val;
2862df723d4SLaxman Dewangan 	int arg = 0;
2872df723d4SLaxman Dewangan 	int ret;
2882df723d4SLaxman Dewangan 
2892df723d4SLaxman Dewangan 	switch (param) {
2902df723d4SLaxman Dewangan 	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
2912df723d4SLaxman Dewangan 		if (mpci->pin_info[pin].drv_type == MAX77620_PIN_OD_DRV)
2922df723d4SLaxman Dewangan 			arg = 1;
2932df723d4SLaxman Dewangan 		break;
2942df723d4SLaxman Dewangan 
2952df723d4SLaxman Dewangan 	case PIN_CONFIG_DRIVE_PUSH_PULL:
2962df723d4SLaxman Dewangan 		if (mpci->pin_info[pin].drv_type == MAX77620_PIN_PP_DRV)
2972df723d4SLaxman Dewangan 			arg = 1;
2982df723d4SLaxman Dewangan 		break;
2992df723d4SLaxman Dewangan 
3002df723d4SLaxman Dewangan 	case PIN_CONFIG_BIAS_PULL_UP:
3012df723d4SLaxman Dewangan 		ret = regmap_read(mpci->rmap, MAX77620_REG_PUE_GPIO, &val);
3022df723d4SLaxman Dewangan 		if (ret < 0) {
3032df723d4SLaxman Dewangan 			dev_err(dev, "Reg PUE_GPIO read failed: %d\n", ret);
3042df723d4SLaxman Dewangan 			return ret;
3052df723d4SLaxman Dewangan 		}
3062df723d4SLaxman Dewangan 		if (val & BIT(pin))
3072df723d4SLaxman Dewangan 			arg = 1;
3082df723d4SLaxman Dewangan 		break;
3092df723d4SLaxman Dewangan 
3102df723d4SLaxman Dewangan 	case PIN_CONFIG_BIAS_PULL_DOWN:
3112df723d4SLaxman Dewangan 		ret = regmap_read(mpci->rmap, MAX77620_REG_PDE_GPIO, &val);
3122df723d4SLaxman Dewangan 		if (ret < 0) {
3132df723d4SLaxman Dewangan 			dev_err(dev, "Reg PDE_GPIO read failed: %d\n", ret);
3142df723d4SLaxman Dewangan 			return ret;
3152df723d4SLaxman Dewangan 		}
3162df723d4SLaxman Dewangan 		if (val & BIT(pin))
3172df723d4SLaxman Dewangan 			arg = 1;
3182df723d4SLaxman Dewangan 		break;
3192df723d4SLaxman Dewangan 
3202df723d4SLaxman Dewangan 	default:
3212df723d4SLaxman Dewangan 		dev_err(dev, "Properties not supported\n");
3222df723d4SLaxman Dewangan 		return -ENOTSUPP;
3232df723d4SLaxman Dewangan 	}
3242df723d4SLaxman Dewangan 
3252df723d4SLaxman Dewangan 	*config = pinconf_to_config_packed(param, (u16)arg);
3262df723d4SLaxman Dewangan 
3272df723d4SLaxman Dewangan 	return 0;
3282df723d4SLaxman Dewangan }
3292df723d4SLaxman Dewangan 
3302df723d4SLaxman Dewangan static int max77620_get_default_fps(struct max77620_pctrl_info *mpci,
3312df723d4SLaxman Dewangan 				    int addr, int *fps)
3322df723d4SLaxman Dewangan {
3332df723d4SLaxman Dewangan 	unsigned int val;
3342df723d4SLaxman Dewangan 	int ret;
3352df723d4SLaxman Dewangan 
3362df723d4SLaxman Dewangan 	ret = regmap_read(mpci->rmap, addr, &val);
3372df723d4SLaxman Dewangan 	if (ret < 0) {
3382df723d4SLaxman Dewangan 		dev_err(mpci->dev, "Reg PUE_GPIO read failed: %d\n", ret);
3392df723d4SLaxman Dewangan 		return ret;
3402df723d4SLaxman Dewangan 	}
3412df723d4SLaxman Dewangan 	*fps = (val & MAX77620_FPS_SRC_MASK) >> MAX77620_FPS_SRC_SHIFT;
3422df723d4SLaxman Dewangan 
3432df723d4SLaxman Dewangan 	return 0;
3442df723d4SLaxman Dewangan }
3452df723d4SLaxman Dewangan 
3462df723d4SLaxman Dewangan static int max77620_set_fps_param(struct max77620_pctrl_info *mpci,
3472df723d4SLaxman Dewangan 				  int pin, int param)
3482df723d4SLaxman Dewangan {
3492df723d4SLaxman Dewangan 	struct max77620_fps_config *fps_config = &mpci->fps_config[pin];
3502df723d4SLaxman Dewangan 	int addr, ret;
3512df723d4SLaxman Dewangan 	int param_val;
3522df723d4SLaxman Dewangan 	int mask, shift;
3532df723d4SLaxman Dewangan 
3542df723d4SLaxman Dewangan 	if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
3552df723d4SLaxman Dewangan 		return 0;
3562df723d4SLaxman Dewangan 
3572df723d4SLaxman Dewangan 	addr = MAX77620_REG_FPS_GPIO1 + pin - 1;
3582df723d4SLaxman Dewangan 	switch (param) {
3592df723d4SLaxman Dewangan 	case MAX77620_ACTIVE_FPS_SOURCE:
3602df723d4SLaxman Dewangan 	case MAX77620_SUSPEND_FPS_SOURCE:
3612df723d4SLaxman Dewangan 		mask = MAX77620_FPS_SRC_MASK;
3622df723d4SLaxman Dewangan 		shift = MAX77620_FPS_SRC_SHIFT;
3632df723d4SLaxman Dewangan 		param_val = fps_config->active_fps_src;
3642df723d4SLaxman Dewangan 		if (param == MAX77620_SUSPEND_FPS_SOURCE)
3652df723d4SLaxman Dewangan 			param_val = fps_config->suspend_fps_src;
3662df723d4SLaxman Dewangan 		break;
3672df723d4SLaxman Dewangan 
3682df723d4SLaxman Dewangan 	case MAX77620_ACTIVE_FPS_POWER_ON_SLOTS:
3692df723d4SLaxman Dewangan 	case MAX77620_SUSPEND_FPS_POWER_ON_SLOTS:
3702df723d4SLaxman Dewangan 		mask = MAX77620_FPS_PU_PERIOD_MASK;
3712df723d4SLaxman Dewangan 		shift = MAX77620_FPS_PU_PERIOD_SHIFT;
3722df723d4SLaxman Dewangan 		param_val = fps_config->active_power_up_slots;
3732df723d4SLaxman Dewangan 		if (param == MAX77620_SUSPEND_FPS_POWER_ON_SLOTS)
3742df723d4SLaxman Dewangan 			param_val = fps_config->suspend_power_up_slots;
3752df723d4SLaxman Dewangan 		break;
3762df723d4SLaxman Dewangan 
3772df723d4SLaxman Dewangan 	case MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS:
3782df723d4SLaxman Dewangan 	case MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS:
3792df723d4SLaxman Dewangan 		mask = MAX77620_FPS_PD_PERIOD_MASK;
3802df723d4SLaxman Dewangan 		shift = MAX77620_FPS_PD_PERIOD_SHIFT;
3812df723d4SLaxman Dewangan 		param_val = fps_config->active_power_down_slots;
3822df723d4SLaxman Dewangan 		if (param == MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS)
3832df723d4SLaxman Dewangan 			param_val = fps_config->suspend_power_down_slots;
3842df723d4SLaxman Dewangan 		break;
3852df723d4SLaxman Dewangan 
3862df723d4SLaxman Dewangan 	default:
3872df723d4SLaxman Dewangan 		dev_err(mpci->dev, "Invalid parameter %d for pin %d\n",
3882df723d4SLaxman Dewangan 			param, pin);
3892df723d4SLaxman Dewangan 		return -EINVAL;
3902df723d4SLaxman Dewangan 	}
3912df723d4SLaxman Dewangan 
3922df723d4SLaxman Dewangan 	if (param_val < 0)
3932df723d4SLaxman Dewangan 		return 0;
3942df723d4SLaxman Dewangan 
3952df723d4SLaxman Dewangan 	ret = regmap_update_bits(mpci->rmap, addr, mask, param_val << shift);
3962df723d4SLaxman Dewangan 	if (ret < 0)
3972df723d4SLaxman Dewangan 		dev_err(mpci->dev, "Reg 0x%02x update failed %d\n", addr, ret);
3982df723d4SLaxman Dewangan 
3992df723d4SLaxman Dewangan 	return ret;
4002df723d4SLaxman Dewangan }
4012df723d4SLaxman Dewangan 
4022df723d4SLaxman Dewangan static int max77620_pinconf_set(struct pinctrl_dev *pctldev,
4032df723d4SLaxman Dewangan 				unsigned int pin, unsigned long *configs,
4042df723d4SLaxman Dewangan 				unsigned int num_configs)
4052df723d4SLaxman Dewangan {
4062df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
4072df723d4SLaxman Dewangan 	struct device *dev = mpci->dev;
4082df723d4SLaxman Dewangan 	struct max77620_fps_config *fps_config;
4092df723d4SLaxman Dewangan 	int param;
4102df723d4SLaxman Dewangan 	u16 param_val;
4112df723d4SLaxman Dewangan 	unsigned int val;
4122df723d4SLaxman Dewangan 	unsigned int pu_val;
4132df723d4SLaxman Dewangan 	unsigned int pd_val;
4142df723d4SLaxman Dewangan 	int addr, ret;
4152df723d4SLaxman Dewangan 	int i;
4162df723d4SLaxman Dewangan 
4172df723d4SLaxman Dewangan 	for (i = 0; i < num_configs; i++) {
4182df723d4SLaxman Dewangan 		param = pinconf_to_config_param(configs[i]);
4192df723d4SLaxman Dewangan 		param_val = pinconf_to_config_argument(configs[i]);
4202df723d4SLaxman Dewangan 
4212df723d4SLaxman Dewangan 		switch (param) {
4222df723d4SLaxman Dewangan 		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
4232df723d4SLaxman Dewangan 			val = param_val ? 0 : 1;
4242df723d4SLaxman Dewangan 			ret = regmap_update_bits(mpci->rmap,
4252df723d4SLaxman Dewangan 						 MAX77620_REG_GPIO0 + pin,
4262df723d4SLaxman Dewangan 						 MAX77620_CNFG_GPIO_DRV_MASK,
4272df723d4SLaxman Dewangan 						 val);
4282df723d4SLaxman Dewangan 			if (ret < 0) {
4292df723d4SLaxman Dewangan 				dev_err(dev, "Reg 0x%02x update failed %d\n",
4302df723d4SLaxman Dewangan 					MAX77620_REG_GPIO0 + pin, ret);
4312df723d4SLaxman Dewangan 				return ret;
4322df723d4SLaxman Dewangan 			}
4332df723d4SLaxman Dewangan 			mpci->pin_info[pin].drv_type = val ?
4342df723d4SLaxman Dewangan 				MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV;
4352df723d4SLaxman Dewangan 			break;
4362df723d4SLaxman Dewangan 
4372df723d4SLaxman Dewangan 		case PIN_CONFIG_DRIVE_PUSH_PULL:
4382df723d4SLaxman Dewangan 			val = param_val ? 1 : 0;
4392df723d4SLaxman Dewangan 			ret = regmap_update_bits(mpci->rmap,
4402df723d4SLaxman Dewangan 						 MAX77620_REG_GPIO0 + pin,
4412df723d4SLaxman Dewangan 						 MAX77620_CNFG_GPIO_DRV_MASK,
4422df723d4SLaxman Dewangan 						 val);
4432df723d4SLaxman Dewangan 			if (ret < 0) {
4442df723d4SLaxman Dewangan 				dev_err(dev, "Reg 0x%02x update failed %d\n",
4452df723d4SLaxman Dewangan 					MAX77620_REG_GPIO0 + pin, ret);
4462df723d4SLaxman Dewangan 				return ret;
4472df723d4SLaxman Dewangan 			}
4482df723d4SLaxman Dewangan 			mpci->pin_info[pin].drv_type = val ?
4492df723d4SLaxman Dewangan 				MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV;
4502df723d4SLaxman Dewangan 			break;
4512df723d4SLaxman Dewangan 
4522df723d4SLaxman Dewangan 		case MAX77620_ACTIVE_FPS_SOURCE:
4532df723d4SLaxman Dewangan 		case MAX77620_ACTIVE_FPS_POWER_ON_SLOTS:
4542df723d4SLaxman Dewangan 		case MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS:
4552df723d4SLaxman Dewangan 			if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
4562df723d4SLaxman Dewangan 				return -EINVAL;
4572df723d4SLaxman Dewangan 
4582df723d4SLaxman Dewangan 			fps_config = &mpci->fps_config[pin];
4592df723d4SLaxman Dewangan 
4602df723d4SLaxman Dewangan 			if ((param == MAX77620_ACTIVE_FPS_SOURCE) &&
4612df723d4SLaxman Dewangan 			    (param_val == MAX77620_FPS_SRC_DEF)) {
4622df723d4SLaxman Dewangan 				addr = MAX77620_REG_FPS_GPIO1 + pin - 1;
4632df723d4SLaxman Dewangan 				ret = max77620_get_default_fps(
4642df723d4SLaxman Dewangan 						mpci, addr,
4652df723d4SLaxman Dewangan 						&fps_config->active_fps_src);
4662df723d4SLaxman Dewangan 				if (ret < 0)
4672df723d4SLaxman Dewangan 					return ret;
4682df723d4SLaxman Dewangan 				break;
4692df723d4SLaxman Dewangan 			}
4702df723d4SLaxman Dewangan 
4712df723d4SLaxman Dewangan 			if (param == MAX77620_ACTIVE_FPS_SOURCE)
4722df723d4SLaxman Dewangan 				fps_config->active_fps_src = param_val;
4732df723d4SLaxman Dewangan 			else if (param == MAX77620_ACTIVE_FPS_POWER_ON_SLOTS)
4742df723d4SLaxman Dewangan 				fps_config->active_power_up_slots = param_val;
4752df723d4SLaxman Dewangan 			else
4762df723d4SLaxman Dewangan 				fps_config->active_power_down_slots = param_val;
4772df723d4SLaxman Dewangan 
4782df723d4SLaxman Dewangan 			ret = max77620_set_fps_param(mpci, pin, param);
4792df723d4SLaxman Dewangan 			if (ret < 0)
4802df723d4SLaxman Dewangan 				return ret;
4812df723d4SLaxman Dewangan 			break;
4822df723d4SLaxman Dewangan 
4832df723d4SLaxman Dewangan 		case MAX77620_SUSPEND_FPS_SOURCE:
4842df723d4SLaxman Dewangan 		case MAX77620_SUSPEND_FPS_POWER_ON_SLOTS:
4852df723d4SLaxman Dewangan 		case MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS:
4862df723d4SLaxman Dewangan 			if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
4872df723d4SLaxman Dewangan 				return -EINVAL;
4882df723d4SLaxman Dewangan 
4892df723d4SLaxman Dewangan 			fps_config = &mpci->fps_config[pin];
4902df723d4SLaxman Dewangan 
4912df723d4SLaxman Dewangan 			if ((param == MAX77620_SUSPEND_FPS_SOURCE) &&
4922df723d4SLaxman Dewangan 			    (param_val == MAX77620_FPS_SRC_DEF)) {
4932df723d4SLaxman Dewangan 				addr = MAX77620_REG_FPS_GPIO1 + pin - 1;
4942df723d4SLaxman Dewangan 				ret = max77620_get_default_fps(
4952df723d4SLaxman Dewangan 						mpci, addr,
4962df723d4SLaxman Dewangan 						&fps_config->suspend_fps_src);
4972df723d4SLaxman Dewangan 				if (ret < 0)
4982df723d4SLaxman Dewangan 					return ret;
4992df723d4SLaxman Dewangan 				break;
5002df723d4SLaxman Dewangan 			}
5012df723d4SLaxman Dewangan 
5022df723d4SLaxman Dewangan 			if (param == MAX77620_SUSPEND_FPS_SOURCE)
5032df723d4SLaxman Dewangan 				fps_config->suspend_fps_src = param_val;
5042df723d4SLaxman Dewangan 			else if (param == MAX77620_SUSPEND_FPS_POWER_ON_SLOTS)
5052df723d4SLaxman Dewangan 				fps_config->suspend_power_up_slots = param_val;
5062df723d4SLaxman Dewangan 			else
5072df723d4SLaxman Dewangan 				fps_config->suspend_power_down_slots =
5082df723d4SLaxman Dewangan 								param_val;
5092df723d4SLaxman Dewangan 			break;
5102df723d4SLaxman Dewangan 
5112df723d4SLaxman Dewangan 		case PIN_CONFIG_BIAS_PULL_UP:
5122df723d4SLaxman Dewangan 		case PIN_CONFIG_BIAS_PULL_DOWN:
5132df723d4SLaxman Dewangan 			pu_val = (param == PIN_CONFIG_BIAS_PULL_UP) ?
5142df723d4SLaxman Dewangan 							BIT(pin) : 0;
5152df723d4SLaxman Dewangan 			pd_val = (param == PIN_CONFIG_BIAS_PULL_DOWN) ?
5162df723d4SLaxman Dewangan 							BIT(pin) : 0;
5172df723d4SLaxman Dewangan 
5182df723d4SLaxman Dewangan 			ret = regmap_update_bits(mpci->rmap,
5192df723d4SLaxman Dewangan 						 MAX77620_REG_PUE_GPIO,
5202df723d4SLaxman Dewangan 						 BIT(pin), pu_val);
5212df723d4SLaxman Dewangan 			if (ret < 0) {
5222df723d4SLaxman Dewangan 				dev_err(dev, "PUE_GPIO update failed: %d\n",
5232df723d4SLaxman Dewangan 					ret);
5242df723d4SLaxman Dewangan 				return ret;
5252df723d4SLaxman Dewangan 			}
5262df723d4SLaxman Dewangan 
5272df723d4SLaxman Dewangan 			ret = regmap_update_bits(mpci->rmap,
5282df723d4SLaxman Dewangan 						 MAX77620_REG_PDE_GPIO,
5292df723d4SLaxman Dewangan 						 BIT(pin), pd_val);
5302df723d4SLaxman Dewangan 			if (ret < 0) {
5312df723d4SLaxman Dewangan 				dev_err(dev, "PDE_GPIO update failed: %d\n",
5322df723d4SLaxman Dewangan 					ret);
5332df723d4SLaxman Dewangan 				return ret;
5342df723d4SLaxman Dewangan 			}
5352df723d4SLaxman Dewangan 			break;
5362df723d4SLaxman Dewangan 
5372df723d4SLaxman Dewangan 		default:
5382df723d4SLaxman Dewangan 			dev_err(dev, "Properties not supported\n");
5392df723d4SLaxman Dewangan 			return -ENOTSUPP;
5402df723d4SLaxman Dewangan 		}
5412df723d4SLaxman Dewangan 	}
5422df723d4SLaxman Dewangan 
5432df723d4SLaxman Dewangan 	return 0;
5442df723d4SLaxman Dewangan }
5452df723d4SLaxman Dewangan 
5462df723d4SLaxman Dewangan static const struct pinconf_ops max77620_pinconf_ops = {
5472df723d4SLaxman Dewangan 	.pin_config_get = max77620_pinconf_get,
5482df723d4SLaxman Dewangan 	.pin_config_set = max77620_pinconf_set,
5492df723d4SLaxman Dewangan };
5502df723d4SLaxman Dewangan 
5512df723d4SLaxman Dewangan static struct pinctrl_desc max77620_pinctrl_desc = {
5522df723d4SLaxman Dewangan 	.pctlops = &max77620_pinctrl_ops,
5532df723d4SLaxman Dewangan 	.pmxops = &max77620_pinmux_ops,
5542df723d4SLaxman Dewangan 	.confops = &max77620_pinconf_ops,
5552df723d4SLaxman Dewangan };
5562df723d4SLaxman Dewangan 
5572df723d4SLaxman Dewangan static int max77620_pinctrl_probe(struct platform_device *pdev)
5582df723d4SLaxman Dewangan {
5592df723d4SLaxman Dewangan 	struct max77620_chip *max77620 = dev_get_drvdata(pdev->dev.parent);
5602df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci;
5612df723d4SLaxman Dewangan 	int i;
5622df723d4SLaxman Dewangan 
5632df723d4SLaxman Dewangan 	mpci = devm_kzalloc(&pdev->dev, sizeof(*mpci), GFP_KERNEL);
5642df723d4SLaxman Dewangan 	if (!mpci)
5652df723d4SLaxman Dewangan 		return -ENOMEM;
5662df723d4SLaxman Dewangan 
5672df723d4SLaxman Dewangan 	mpci->dev = &pdev->dev;
5682df723d4SLaxman Dewangan 	mpci->dev->of_node = pdev->dev.parent->of_node;
5692df723d4SLaxman Dewangan 	mpci->rmap = max77620->rmap;
5702df723d4SLaxman Dewangan 
5712df723d4SLaxman Dewangan 	mpci->pins = max77620_pins_desc;
5722df723d4SLaxman Dewangan 	mpci->num_pins = ARRAY_SIZE(max77620_pins_desc);
5732df723d4SLaxman Dewangan 	mpci->functions = max77620_pin_function;
5742df723d4SLaxman Dewangan 	mpci->num_functions = ARRAY_SIZE(max77620_pin_function);
5752df723d4SLaxman Dewangan 	mpci->pin_groups = max77620_pingroups;
5762df723d4SLaxman Dewangan 	mpci->num_pin_groups = ARRAY_SIZE(max77620_pingroups);
5772df723d4SLaxman Dewangan 	platform_set_drvdata(pdev, mpci);
5782df723d4SLaxman Dewangan 
5792df723d4SLaxman Dewangan 	max77620_pinctrl_desc.name = dev_name(&pdev->dev);
5802df723d4SLaxman Dewangan 	max77620_pinctrl_desc.pins = max77620_pins_desc;
5812df723d4SLaxman Dewangan 	max77620_pinctrl_desc.npins = ARRAY_SIZE(max77620_pins_desc);
5822df723d4SLaxman Dewangan 	max77620_pinctrl_desc.num_custom_params =
5832df723d4SLaxman Dewangan 				ARRAY_SIZE(max77620_cfg_params);
5842df723d4SLaxman Dewangan 	max77620_pinctrl_desc.custom_params = max77620_cfg_params;
5852df723d4SLaxman Dewangan 
5862df723d4SLaxman Dewangan 	for (i = 0; i < MAX77620_PIN_NUM; ++i) {
5872df723d4SLaxman Dewangan 		mpci->fps_config[i].active_fps_src = -1;
5882df723d4SLaxman Dewangan 		mpci->fps_config[i].active_power_up_slots = -1;
5892df723d4SLaxman Dewangan 		mpci->fps_config[i].active_power_down_slots = -1;
5902df723d4SLaxman Dewangan 		mpci->fps_config[i].suspend_fps_src = -1;
5912df723d4SLaxman Dewangan 		mpci->fps_config[i].suspend_power_up_slots = -1;
5922df723d4SLaxman Dewangan 		mpci->fps_config[i].suspend_power_down_slots = -1;
5932df723d4SLaxman Dewangan 	}
5942df723d4SLaxman Dewangan 
5952df723d4SLaxman Dewangan 	mpci->pctl = devm_pinctrl_register(&pdev->dev, &max77620_pinctrl_desc,
5962df723d4SLaxman Dewangan 					   mpci);
5972df723d4SLaxman Dewangan 	if (IS_ERR(mpci->pctl)) {
5982df723d4SLaxman Dewangan 		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
5992df723d4SLaxman Dewangan 		return PTR_ERR(mpci->pctl);
6002df723d4SLaxman Dewangan 	}
6012df723d4SLaxman Dewangan 
6022df723d4SLaxman Dewangan 	return 0;
6032df723d4SLaxman Dewangan }
6042df723d4SLaxman Dewangan 
6052df723d4SLaxman Dewangan #ifdef CONFIG_PM_SLEEP
6062df723d4SLaxman Dewangan static int max77620_suspend_fps_param[] = {
6072df723d4SLaxman Dewangan 	MAX77620_SUSPEND_FPS_SOURCE,
6082df723d4SLaxman Dewangan 	MAX77620_SUSPEND_FPS_POWER_ON_SLOTS,
6092df723d4SLaxman Dewangan 	MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS,
6102df723d4SLaxman Dewangan };
6112df723d4SLaxman Dewangan 
6122df723d4SLaxman Dewangan static int max77620_active_fps_param[] = {
6132df723d4SLaxman Dewangan 	MAX77620_ACTIVE_FPS_SOURCE,
6142df723d4SLaxman Dewangan 	MAX77620_ACTIVE_FPS_POWER_ON_SLOTS,
6152df723d4SLaxman Dewangan 	MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS,
6162df723d4SLaxman Dewangan };
6172df723d4SLaxman Dewangan 
6182df723d4SLaxman Dewangan static int max77620_pinctrl_suspend(struct device *dev)
6192df723d4SLaxman Dewangan {
6202df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci = dev_get_drvdata(dev);
6212df723d4SLaxman Dewangan 	int pin, p;
6222df723d4SLaxman Dewangan 
6232df723d4SLaxman Dewangan 	for (pin = 0; pin < MAX77620_PIN_NUM; ++pin) {
6242df723d4SLaxman Dewangan 		if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
6252df723d4SLaxman Dewangan 			continue;
6262df723d4SLaxman Dewangan 		for (p = 0; p < 3; ++p)
6272df723d4SLaxman Dewangan 			max77620_set_fps_param(
6282df723d4SLaxman Dewangan 				mpci, pin, max77620_suspend_fps_param[p]);
6292df723d4SLaxman Dewangan 	}
6302df723d4SLaxman Dewangan 
6312df723d4SLaxman Dewangan 	return 0;
6322df723d4SLaxman Dewangan };
6332df723d4SLaxman Dewangan 
6342df723d4SLaxman Dewangan static int max77620_pinctrl_resume(struct device *dev)
6352df723d4SLaxman Dewangan {
6362df723d4SLaxman Dewangan 	struct max77620_pctrl_info *mpci = dev_get_drvdata(dev);
6372df723d4SLaxman Dewangan 	int pin, p;
6382df723d4SLaxman Dewangan 
6392df723d4SLaxman Dewangan 	for (pin = 0; pin < MAX77620_PIN_NUM; ++pin) {
6402df723d4SLaxman Dewangan 		if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
6412df723d4SLaxman Dewangan 			continue;
6422df723d4SLaxman Dewangan 		for (p = 0; p < 3; ++p)
6432df723d4SLaxman Dewangan 			max77620_set_fps_param(
6442df723d4SLaxman Dewangan 				mpci, pin, max77620_active_fps_param[p]);
6452df723d4SLaxman Dewangan 	}
6462df723d4SLaxman Dewangan 
6472df723d4SLaxman Dewangan 	return 0;
6482df723d4SLaxman Dewangan }
6492df723d4SLaxman Dewangan #endif
6502df723d4SLaxman Dewangan 
6512df723d4SLaxman Dewangan static const struct dev_pm_ops max77620_pinctrl_pm_ops = {
6522df723d4SLaxman Dewangan 	SET_SYSTEM_SLEEP_PM_OPS(
6532df723d4SLaxman Dewangan 		max77620_pinctrl_suspend, max77620_pinctrl_resume)
6542df723d4SLaxman Dewangan };
6552df723d4SLaxman Dewangan 
6562df723d4SLaxman Dewangan static const struct platform_device_id max77620_pinctrl_devtype[] = {
6572df723d4SLaxman Dewangan 	{ .name = "max77620-pinctrl", },
6582df723d4SLaxman Dewangan 	{ .name = "max20024-pinctrl", },
6592df723d4SLaxman Dewangan 	{},
6602df723d4SLaxman Dewangan };
6612df723d4SLaxman Dewangan MODULE_DEVICE_TABLE(platform, max77620_pinctrl_devtype);
6622df723d4SLaxman Dewangan 
6632df723d4SLaxman Dewangan static struct platform_driver max77620_pinctrl_driver = {
6642df723d4SLaxman Dewangan 	.driver = {
6652df723d4SLaxman Dewangan 		.name = "max77620-pinctrl",
6662df723d4SLaxman Dewangan 		.pm = &max77620_pinctrl_pm_ops,
6672df723d4SLaxman Dewangan 	},
6682df723d4SLaxman Dewangan 	.probe = max77620_pinctrl_probe,
6692df723d4SLaxman Dewangan 	.id_table = max77620_pinctrl_devtype,
6702df723d4SLaxman Dewangan };
6712df723d4SLaxman Dewangan 
6722df723d4SLaxman Dewangan module_platform_driver(max77620_pinctrl_driver);
6732df723d4SLaxman Dewangan 
6742df723d4SLaxman Dewangan MODULE_DESCRIPTION("MAX77620/MAX20024 pin control driver");
6752df723d4SLaxman Dewangan MODULE_AUTHOR("Chaitanya Bandi<bandik@nvidia.com>");
6762df723d4SLaxman Dewangan MODULE_AUTHOR("Laxman Dewangan<ldewangan@nvidia.com>");
6772df723d4SLaxman Dewangan MODULE_ALIAS("platform:max77620-pinctrl");
6782df723d4SLaxman Dewangan MODULE_LICENSE("GPL v2");
679