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