16e261d10SSrinivas Kandagatla // SPDX-License-Identifier: GPL-2.0-only
26e261d10SSrinivas Kandagatla /*
36e261d10SSrinivas Kandagatla  * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
46e261d10SSrinivas Kandagatla  * Copyright (c) 2020 Linaro Ltd.
56e261d10SSrinivas Kandagatla  */
66e261d10SSrinivas Kandagatla 
703e9491fSAndy Shevchenko #include <linux/bitfield.h>
86e261d10SSrinivas Kandagatla #include <linux/clk.h>
96e261d10SSrinivas Kandagatla #include <linux/gpio/driver.h>
106e261d10SSrinivas Kandagatla #include <linux/module.h>
11060f03e9SRob Herring #include <linux/of.h>
12060f03e9SRob Herring #include <linux/platform_device.h>
13aa9430f8SAndy Shevchenko #include <linux/seq_file.h>
14aa9430f8SAndy Shevchenko 
156e261d10SSrinivas Kandagatla #include <linux/pinctrl/pinconf-generic.h>
166e261d10SSrinivas Kandagatla #include <linux/pinctrl/pinconf.h>
176e261d10SSrinivas Kandagatla #include <linux/pinctrl/pinmux.h>
18aa9430f8SAndy Shevchenko 
196e261d10SSrinivas Kandagatla #include "../pinctrl-utils.h"
20aa9430f8SAndy Shevchenko 
219ce49018SSrinivasa Rao Mandadapu #include "pinctrl-lpass-lpi.h"
226e261d10SSrinivas Kandagatla 
23fae1466dSKrzysztof Kozlowski #define MAX_NR_GPIO		23
24fae1466dSKrzysztof Kozlowski #define GPIO_FUNC		0
256e261d10SSrinivas Kandagatla #define MAX_LPI_NUM_CLKS	2
266e261d10SSrinivas Kandagatla 
276e261d10SSrinivas Kandagatla struct lpi_pinctrl {
286e261d10SSrinivas Kandagatla 	struct device *dev;
296e261d10SSrinivas Kandagatla 	struct pinctrl_dev *ctrl;
306e261d10SSrinivas Kandagatla 	struct gpio_chip chip;
316e261d10SSrinivas Kandagatla 	struct pinctrl_desc desc;
326e261d10SSrinivas Kandagatla 	char __iomem *tlmm_base;
336e261d10SSrinivas Kandagatla 	char __iomem *slew_base;
346e261d10SSrinivas Kandagatla 	struct clk_bulk_data clks[MAX_LPI_NUM_CLKS];
35*c8befdc4SKrzysztof Kozlowski 	/* Protects from concurrent register updates */
36*c8befdc4SKrzysztof Kozlowski 	struct mutex lock;
37fae1466dSKrzysztof Kozlowski 	DECLARE_BITMAP(ever_gpio, MAX_NR_GPIO);
386e261d10SSrinivas Kandagatla 	const struct lpi_pinctrl_variant_data *data;
396e261d10SSrinivas Kandagatla };
406e261d10SSrinivas Kandagatla 
lpi_gpio_read(struct lpi_pinctrl * state,unsigned int pin,unsigned int addr)416e261d10SSrinivas Kandagatla static int lpi_gpio_read(struct lpi_pinctrl *state, unsigned int pin,
426e261d10SSrinivas Kandagatla 			 unsigned int addr)
436e261d10SSrinivas Kandagatla {
446e261d10SSrinivas Kandagatla 	return ioread32(state->tlmm_base + LPI_TLMM_REG_OFFSET * pin + addr);
456e261d10SSrinivas Kandagatla }
466e261d10SSrinivas Kandagatla 
lpi_gpio_write(struct lpi_pinctrl * state,unsigned int pin,unsigned int addr,unsigned int val)476e261d10SSrinivas Kandagatla static int lpi_gpio_write(struct lpi_pinctrl *state, unsigned int pin,
486e261d10SSrinivas Kandagatla 			  unsigned int addr, unsigned int val)
496e261d10SSrinivas Kandagatla {
506e261d10SSrinivas Kandagatla 	iowrite32(val, state->tlmm_base + LPI_TLMM_REG_OFFSET * pin + addr);
516e261d10SSrinivas Kandagatla 
526e261d10SSrinivas Kandagatla 	return 0;
536e261d10SSrinivas Kandagatla }
546e261d10SSrinivas Kandagatla 
556e261d10SSrinivas Kandagatla static const struct pinctrl_ops lpi_gpio_pinctrl_ops = {
56be73368dSSrinivasa Rao Mandadapu 	.get_groups_count	= pinctrl_generic_get_group_count,
57be73368dSSrinivasa Rao Mandadapu 	.get_group_name		= pinctrl_generic_get_group_name,
58be73368dSSrinivasa Rao Mandadapu 	.get_group_pins		= pinctrl_generic_get_group_pins,
596e261d10SSrinivas Kandagatla 	.dt_node_to_map		= pinconf_generic_dt_node_to_map_group,
606e261d10SSrinivas Kandagatla 	.dt_free_map		= pinctrl_utils_free_map,
616e261d10SSrinivas Kandagatla };
626e261d10SSrinivas Kandagatla 
lpi_gpio_get_functions_count(struct pinctrl_dev * pctldev)636e261d10SSrinivas Kandagatla static int lpi_gpio_get_functions_count(struct pinctrl_dev *pctldev)
646e261d10SSrinivas Kandagatla {
656e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
666e261d10SSrinivas Kandagatla 
676e261d10SSrinivas Kandagatla 	return pctrl->data->nfunctions;
686e261d10SSrinivas Kandagatla }
696e261d10SSrinivas Kandagatla 
lpi_gpio_get_function_name(struct pinctrl_dev * pctldev,unsigned int function)706e261d10SSrinivas Kandagatla static const char *lpi_gpio_get_function_name(struct pinctrl_dev *pctldev,
716e261d10SSrinivas Kandagatla 					      unsigned int function)
726e261d10SSrinivas Kandagatla {
736e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
746e261d10SSrinivas Kandagatla 
756e261d10SSrinivas Kandagatla 	return pctrl->data->functions[function].name;
766e261d10SSrinivas Kandagatla }
776e261d10SSrinivas Kandagatla 
lpi_gpio_get_function_groups(struct pinctrl_dev * pctldev,unsigned int function,const char * const ** groups,unsigned * const num_qgroups)786e261d10SSrinivas Kandagatla static int lpi_gpio_get_function_groups(struct pinctrl_dev *pctldev,
796e261d10SSrinivas Kandagatla 					unsigned int function,
806e261d10SSrinivas Kandagatla 					const char *const **groups,
816e261d10SSrinivas Kandagatla 					unsigned *const num_qgroups)
826e261d10SSrinivas Kandagatla {
836e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
846e261d10SSrinivas Kandagatla 
856e261d10SSrinivas Kandagatla 	*groups = pctrl->data->functions[function].groups;
866e261d10SSrinivas Kandagatla 	*num_qgroups = pctrl->data->functions[function].ngroups;
876e261d10SSrinivas Kandagatla 
886e261d10SSrinivas Kandagatla 	return 0;
896e261d10SSrinivas Kandagatla }
906e261d10SSrinivas Kandagatla 
lpi_gpio_set_mux(struct pinctrl_dev * pctldev,unsigned int function,unsigned int group)916e261d10SSrinivas Kandagatla static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
92926cf596SKrzysztof Kozlowski 			    unsigned int group)
936e261d10SSrinivas Kandagatla {
946e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
95926cf596SKrzysztof Kozlowski 	const struct lpi_pingroup *g = &pctrl->data->groups[group];
966e261d10SSrinivas Kandagatla 	u32 val;
976e261d10SSrinivas Kandagatla 	int i, pin = g->pin;
986e261d10SSrinivas Kandagatla 
996e261d10SSrinivas Kandagatla 	for (i = 0; i < g->nfuncs; i++) {
1006e261d10SSrinivas Kandagatla 		if (g->funcs[i] == function)
1016e261d10SSrinivas Kandagatla 			break;
1026e261d10SSrinivas Kandagatla 	}
1036e261d10SSrinivas Kandagatla 
1046e261d10SSrinivas Kandagatla 	if (WARN_ON(i == g->nfuncs))
1056e261d10SSrinivas Kandagatla 		return -EINVAL;
1066e261d10SSrinivas Kandagatla 
107*c8befdc4SKrzysztof Kozlowski 	mutex_lock(&pctrl->lock);
1086e261d10SSrinivas Kandagatla 	val = lpi_gpio_read(pctrl, pin, LPI_GPIO_CFG_REG);
109fae1466dSKrzysztof Kozlowski 
110fae1466dSKrzysztof Kozlowski 	/*
111fae1466dSKrzysztof Kozlowski 	 * If this is the first time muxing to GPIO and the direction is
112fae1466dSKrzysztof Kozlowski 	 * output, make sure that we're not going to be glitching the pin
113fae1466dSKrzysztof Kozlowski 	 * by reading the current state of the pin and setting it as the
114fae1466dSKrzysztof Kozlowski 	 * output.
115fae1466dSKrzysztof Kozlowski 	 */
116fae1466dSKrzysztof Kozlowski 	if (i == GPIO_FUNC && (val & LPI_GPIO_OE_MASK) &&
117fae1466dSKrzysztof Kozlowski 	    !test_and_set_bit(group, pctrl->ever_gpio)) {
118fae1466dSKrzysztof Kozlowski 		u32 io_val = lpi_gpio_read(pctrl, group, LPI_GPIO_VALUE_REG);
119fae1466dSKrzysztof Kozlowski 
120fae1466dSKrzysztof Kozlowski 		if (io_val & LPI_GPIO_VALUE_IN_MASK) {
121fae1466dSKrzysztof Kozlowski 			if (!(io_val & LPI_GPIO_VALUE_OUT_MASK))
122fae1466dSKrzysztof Kozlowski 				lpi_gpio_write(pctrl, group, LPI_GPIO_VALUE_REG,
123fae1466dSKrzysztof Kozlowski 					       io_val | LPI_GPIO_VALUE_OUT_MASK);
124fae1466dSKrzysztof Kozlowski 		} else {
125fae1466dSKrzysztof Kozlowski 			if (io_val & LPI_GPIO_VALUE_OUT_MASK)
126fae1466dSKrzysztof Kozlowski 				lpi_gpio_write(pctrl, group, LPI_GPIO_VALUE_REG,
127fae1466dSKrzysztof Kozlowski 					       io_val & ~LPI_GPIO_VALUE_OUT_MASK);
128fae1466dSKrzysztof Kozlowski 		}
129fae1466dSKrzysztof Kozlowski 	}
130fae1466dSKrzysztof Kozlowski 
1316e261d10SSrinivas Kandagatla 	u32p_replace_bits(&val, i, LPI_GPIO_FUNCTION_MASK);
1326e261d10SSrinivas Kandagatla 	lpi_gpio_write(pctrl, pin, LPI_GPIO_CFG_REG, val);
133*c8befdc4SKrzysztof Kozlowski 	mutex_unlock(&pctrl->lock);
1346e261d10SSrinivas Kandagatla 
1356e261d10SSrinivas Kandagatla 	return 0;
1366e261d10SSrinivas Kandagatla }
1376e261d10SSrinivas Kandagatla 
1386e261d10SSrinivas Kandagatla static const struct pinmux_ops lpi_gpio_pinmux_ops = {
1396e261d10SSrinivas Kandagatla 	.get_functions_count	= lpi_gpio_get_functions_count,
1406e261d10SSrinivas Kandagatla 	.get_function_name	= lpi_gpio_get_function_name,
1416e261d10SSrinivas Kandagatla 	.get_function_groups	= lpi_gpio_get_function_groups,
1426e261d10SSrinivas Kandagatla 	.set_mux		= lpi_gpio_set_mux,
1436e261d10SSrinivas Kandagatla };
1446e261d10SSrinivas Kandagatla 
lpi_config_get(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * config)1456e261d10SSrinivas Kandagatla static int lpi_config_get(struct pinctrl_dev *pctldev,
1466e261d10SSrinivas Kandagatla 			  unsigned int pin, unsigned long *config)
1476e261d10SSrinivas Kandagatla {
1486e261d10SSrinivas Kandagatla 	unsigned int param = pinconf_to_config_param(*config);
1496e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *state = dev_get_drvdata(pctldev->dev);
1506e261d10SSrinivas Kandagatla 	unsigned int arg = 0;
1516e261d10SSrinivas Kandagatla 	int is_out;
1526e261d10SSrinivas Kandagatla 	int pull;
1536e261d10SSrinivas Kandagatla 	u32 ctl_reg;
1546e261d10SSrinivas Kandagatla 
1556e261d10SSrinivas Kandagatla 	ctl_reg = lpi_gpio_read(state, pin, LPI_GPIO_CFG_REG);
1566e261d10SSrinivas Kandagatla 	is_out = ctl_reg & LPI_GPIO_OE_MASK;
1576e261d10SSrinivas Kandagatla 	pull = FIELD_GET(LPI_GPIO_PULL_MASK, ctl_reg);
1586e261d10SSrinivas Kandagatla 
1596e261d10SSrinivas Kandagatla 	switch (param) {
1606e261d10SSrinivas Kandagatla 	case PIN_CONFIG_BIAS_DISABLE:
1616e261d10SSrinivas Kandagatla 		if (pull == LPI_GPIO_BIAS_DISABLE)
1626e261d10SSrinivas Kandagatla 			arg = 1;
1636e261d10SSrinivas Kandagatla 		break;
1646e261d10SSrinivas Kandagatla 	case PIN_CONFIG_BIAS_PULL_DOWN:
1656e261d10SSrinivas Kandagatla 		if (pull == LPI_GPIO_PULL_DOWN)
1666e261d10SSrinivas Kandagatla 			arg = 1;
1676e261d10SSrinivas Kandagatla 		break;
1686e261d10SSrinivas Kandagatla 	case PIN_CONFIG_BIAS_BUS_HOLD:
1696e261d10SSrinivas Kandagatla 		if (pull == LPI_GPIO_KEEPER)
1706e261d10SSrinivas Kandagatla 			arg = 1;
1716e261d10SSrinivas Kandagatla 		break;
1726e261d10SSrinivas Kandagatla 	case PIN_CONFIG_BIAS_PULL_UP:
1736e261d10SSrinivas Kandagatla 		if (pull == LPI_GPIO_PULL_UP)
1746e261d10SSrinivas Kandagatla 			arg = 1;
1756e261d10SSrinivas Kandagatla 		break;
1766e261d10SSrinivas Kandagatla 	case PIN_CONFIG_INPUT_ENABLE:
1776e261d10SSrinivas Kandagatla 	case PIN_CONFIG_OUTPUT:
1786e261d10SSrinivas Kandagatla 		if (is_out)
1796e261d10SSrinivas Kandagatla 			arg = 1;
1806e261d10SSrinivas Kandagatla 		break;
1816e261d10SSrinivas Kandagatla 	default:
1826e261d10SSrinivas Kandagatla 		return -EINVAL;
1836e261d10SSrinivas Kandagatla 	}
1846e261d10SSrinivas Kandagatla 
1856e261d10SSrinivas Kandagatla 	*config = pinconf_to_config_packed(param, arg);
1866e261d10SSrinivas Kandagatla 	return 0;
1876e261d10SSrinivas Kandagatla }
1886e261d10SSrinivas Kandagatla 
lpi_config_set(struct pinctrl_dev * pctldev,unsigned int group,unsigned long * configs,unsigned int nconfs)1896e261d10SSrinivas Kandagatla static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group,
1906e261d10SSrinivas Kandagatla 			  unsigned long *configs, unsigned int nconfs)
1916e261d10SSrinivas Kandagatla {
1926e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *pctrl = dev_get_drvdata(pctldev->dev);
1932a9be380SJonathan Marek 	unsigned int param, arg, pullup = LPI_GPIO_BIAS_DISABLE, strength = 2;
1946e261d10SSrinivas Kandagatla 	bool value, output_enabled = false;
1956e261d10SSrinivas Kandagatla 	const struct lpi_pingroup *g;
1966e261d10SSrinivas Kandagatla 	unsigned long sval;
1976e261d10SSrinivas Kandagatla 	int i, slew_offset;
1986e261d10SSrinivas Kandagatla 	u32 val;
1996e261d10SSrinivas Kandagatla 
2006e261d10SSrinivas Kandagatla 	g = &pctrl->data->groups[group];
2016e261d10SSrinivas Kandagatla 	for (i = 0; i < nconfs; i++) {
2026e261d10SSrinivas Kandagatla 		param = pinconf_to_config_param(configs[i]);
2036e261d10SSrinivas Kandagatla 		arg = pinconf_to_config_argument(configs[i]);
2046e261d10SSrinivas Kandagatla 
2056e261d10SSrinivas Kandagatla 		switch (param) {
2066e261d10SSrinivas Kandagatla 		case PIN_CONFIG_BIAS_DISABLE:
2076e261d10SSrinivas Kandagatla 			pullup = LPI_GPIO_BIAS_DISABLE;
2086e261d10SSrinivas Kandagatla 			break;
2096e261d10SSrinivas Kandagatla 		case PIN_CONFIG_BIAS_PULL_DOWN:
2106e261d10SSrinivas Kandagatla 			pullup = LPI_GPIO_PULL_DOWN;
2116e261d10SSrinivas Kandagatla 			break;
2126e261d10SSrinivas Kandagatla 		case PIN_CONFIG_BIAS_BUS_HOLD:
2136e261d10SSrinivas Kandagatla 			pullup = LPI_GPIO_KEEPER;
2146e261d10SSrinivas Kandagatla 			break;
2156e261d10SSrinivas Kandagatla 		case PIN_CONFIG_BIAS_PULL_UP:
2166e261d10SSrinivas Kandagatla 			pullup = LPI_GPIO_PULL_UP;
2176e261d10SSrinivas Kandagatla 			break;
2186e261d10SSrinivas Kandagatla 		case PIN_CONFIG_INPUT_ENABLE:
2196e261d10SSrinivas Kandagatla 			output_enabled = false;
2206e261d10SSrinivas Kandagatla 			break;
2216e261d10SSrinivas Kandagatla 		case PIN_CONFIG_OUTPUT:
2226e261d10SSrinivas Kandagatla 			output_enabled = true;
2236e261d10SSrinivas Kandagatla 			value = arg;
2246e261d10SSrinivas Kandagatla 			break;
2256e261d10SSrinivas Kandagatla 		case PIN_CONFIG_DRIVE_STRENGTH:
2266e261d10SSrinivas Kandagatla 			strength = arg;
2276e261d10SSrinivas Kandagatla 			break;
2286e261d10SSrinivas Kandagatla 		case PIN_CONFIG_SLEW_RATE:
2296e261d10SSrinivas Kandagatla 			if (arg > LPI_SLEW_RATE_MAX) {
2306e261d10SSrinivas Kandagatla 				dev_err(pctldev->dev, "invalid slew rate %u for pin: %d\n",
2316e261d10SSrinivas Kandagatla 					arg, group);
2326e261d10SSrinivas Kandagatla 				return -EINVAL;
2336e261d10SSrinivas Kandagatla 			}
2346e261d10SSrinivas Kandagatla 
2356e261d10SSrinivas Kandagatla 			slew_offset = g->slew_offset;
23664547110SSrinivasa Rao Mandadapu 			if (slew_offset == LPI_NO_SLEW)
2376e261d10SSrinivas Kandagatla 				break;
2386e261d10SSrinivas Kandagatla 
239*c8befdc4SKrzysztof Kozlowski 			mutex_lock(&pctrl->lock);
2406e261d10SSrinivas Kandagatla 
2416e261d10SSrinivas Kandagatla 			sval = ioread32(pctrl->slew_base + LPI_SLEW_RATE_CTL_REG);
2426e261d10SSrinivas Kandagatla 			sval &= ~(LPI_SLEW_RATE_MASK << slew_offset);
2436e261d10SSrinivas Kandagatla 			sval |= arg << slew_offset;
2446e261d10SSrinivas Kandagatla 			iowrite32(sval, pctrl->slew_base + LPI_SLEW_RATE_CTL_REG);
2456e261d10SSrinivas Kandagatla 
246*c8befdc4SKrzysztof Kozlowski 			mutex_unlock(&pctrl->lock);
2476e261d10SSrinivas Kandagatla 			break;
2486e261d10SSrinivas Kandagatla 		default:
2496e261d10SSrinivas Kandagatla 			return -EINVAL;
2506e261d10SSrinivas Kandagatla 		}
2516e261d10SSrinivas Kandagatla 	}
2526e261d10SSrinivas Kandagatla 
253163bfb0cSKrzysztof Kozlowski 	/*
254163bfb0cSKrzysztof Kozlowski 	 * As per Hardware Programming Guide, when configuring pin as output,
255163bfb0cSKrzysztof Kozlowski 	 * set the pin value before setting output-enable (OE).
256163bfb0cSKrzysztof Kozlowski 	 */
257163bfb0cSKrzysztof Kozlowski 	if (output_enabled) {
258163bfb0cSKrzysztof Kozlowski 		val = u32_encode_bits(value ? 1 : 0, LPI_GPIO_VALUE_OUT_MASK);
259163bfb0cSKrzysztof Kozlowski 		lpi_gpio_write(pctrl, group, LPI_GPIO_VALUE_REG, val);
260163bfb0cSKrzysztof Kozlowski 	}
261163bfb0cSKrzysztof Kozlowski 
262*c8befdc4SKrzysztof Kozlowski 	mutex_lock(&pctrl->lock);
2636e261d10SSrinivas Kandagatla 	val = lpi_gpio_read(pctrl, group, LPI_GPIO_CFG_REG);
2646e261d10SSrinivas Kandagatla 
2656e261d10SSrinivas Kandagatla 	u32p_replace_bits(&val, pullup, LPI_GPIO_PULL_MASK);
2666e261d10SSrinivas Kandagatla 	u32p_replace_bits(&val, LPI_GPIO_DS_TO_VAL(strength),
2676e261d10SSrinivas Kandagatla 			  LPI_GPIO_OUT_STRENGTH_MASK);
2686e261d10SSrinivas Kandagatla 	u32p_replace_bits(&val, output_enabled, LPI_GPIO_OE_MASK);
2696e261d10SSrinivas Kandagatla 
2706e261d10SSrinivas Kandagatla 	lpi_gpio_write(pctrl, group, LPI_GPIO_CFG_REG, val);
271*c8befdc4SKrzysztof Kozlowski 	mutex_unlock(&pctrl->lock);
2726e261d10SSrinivas Kandagatla 
2736e261d10SSrinivas Kandagatla 	return 0;
2746e261d10SSrinivas Kandagatla }
2756e261d10SSrinivas Kandagatla 
2766e261d10SSrinivas Kandagatla static const struct pinconf_ops lpi_gpio_pinconf_ops = {
2776e261d10SSrinivas Kandagatla 	.is_generic			= true,
2786e261d10SSrinivas Kandagatla 	.pin_config_group_get		= lpi_config_get,
2796e261d10SSrinivas Kandagatla 	.pin_config_group_set		= lpi_config_set,
2806e261d10SSrinivas Kandagatla };
2816e261d10SSrinivas Kandagatla 
lpi_gpio_direction_input(struct gpio_chip * chip,unsigned int pin)2826e261d10SSrinivas Kandagatla static int lpi_gpio_direction_input(struct gpio_chip *chip, unsigned int pin)
2836e261d10SSrinivas Kandagatla {
2846e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *state = gpiochip_get_data(chip);
2856e261d10SSrinivas Kandagatla 	unsigned long config;
2866e261d10SSrinivas Kandagatla 
2876e261d10SSrinivas Kandagatla 	config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1);
2886e261d10SSrinivas Kandagatla 
2896e261d10SSrinivas Kandagatla 	return lpi_config_set(state->ctrl, pin, &config, 1);
2906e261d10SSrinivas Kandagatla }
2916e261d10SSrinivas Kandagatla 
lpi_gpio_direction_output(struct gpio_chip * chip,unsigned int pin,int val)2926e261d10SSrinivas Kandagatla static int lpi_gpio_direction_output(struct gpio_chip *chip,
2936e261d10SSrinivas Kandagatla 				     unsigned int pin, int val)
2946e261d10SSrinivas Kandagatla {
2956e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *state = gpiochip_get_data(chip);
2966e261d10SSrinivas Kandagatla 	unsigned long config;
2976e261d10SSrinivas Kandagatla 
2986e261d10SSrinivas Kandagatla 	config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val);
2996e261d10SSrinivas Kandagatla 
3006e261d10SSrinivas Kandagatla 	return lpi_config_set(state->ctrl, pin, &config, 1);
3016e261d10SSrinivas Kandagatla }
3026e261d10SSrinivas Kandagatla 
lpi_gpio_get(struct gpio_chip * chip,unsigned int pin)3036e261d10SSrinivas Kandagatla static int lpi_gpio_get(struct gpio_chip *chip, unsigned int pin)
3046e261d10SSrinivas Kandagatla {
3056e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *state = gpiochip_get_data(chip);
3066e261d10SSrinivas Kandagatla 
3076e261d10SSrinivas Kandagatla 	return lpi_gpio_read(state, pin, LPI_GPIO_VALUE_REG) &
3086e261d10SSrinivas Kandagatla 		LPI_GPIO_VALUE_IN_MASK;
3096e261d10SSrinivas Kandagatla }
3106e261d10SSrinivas Kandagatla 
lpi_gpio_set(struct gpio_chip * chip,unsigned int pin,int value)3116e261d10SSrinivas Kandagatla static void lpi_gpio_set(struct gpio_chip *chip, unsigned int pin, int value)
3126e261d10SSrinivas Kandagatla {
3136e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *state = gpiochip_get_data(chip);
3146e261d10SSrinivas Kandagatla 	unsigned long config;
3156e261d10SSrinivas Kandagatla 
3166e261d10SSrinivas Kandagatla 	config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value);
3176e261d10SSrinivas Kandagatla 
3186e261d10SSrinivas Kandagatla 	lpi_config_set(state->ctrl, pin, &config, 1);
3196e261d10SSrinivas Kandagatla }
3206e261d10SSrinivas Kandagatla 
3216e261d10SSrinivas Kandagatla #ifdef CONFIG_DEBUG_FS
3226e261d10SSrinivas Kandagatla #include <linux/seq_file.h>
3236e261d10SSrinivas Kandagatla 
lpi_regval_to_drive(u32 val)3246e261d10SSrinivas Kandagatla static unsigned int lpi_regval_to_drive(u32 val)
3256e261d10SSrinivas Kandagatla {
3266e261d10SSrinivas Kandagatla 	return (val + 1) * 2;
3276e261d10SSrinivas Kandagatla }
3286e261d10SSrinivas Kandagatla 
lpi_gpio_dbg_show_one(struct seq_file * s,struct pinctrl_dev * pctldev,struct gpio_chip * chip,unsigned int offset,unsigned int gpio)3296e261d10SSrinivas Kandagatla static void lpi_gpio_dbg_show_one(struct seq_file *s,
3306e261d10SSrinivas Kandagatla 				  struct pinctrl_dev *pctldev,
3316e261d10SSrinivas Kandagatla 				  struct gpio_chip *chip,
3326e261d10SSrinivas Kandagatla 				  unsigned int offset,
3336e261d10SSrinivas Kandagatla 				  unsigned int gpio)
3346e261d10SSrinivas Kandagatla {
3356e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *state = gpiochip_get_data(chip);
3366e261d10SSrinivas Kandagatla 	struct pinctrl_pin_desc pindesc;
3376e261d10SSrinivas Kandagatla 	unsigned int func;
3386e261d10SSrinivas Kandagatla 	int is_out;
3396e261d10SSrinivas Kandagatla 	int drive;
3406e261d10SSrinivas Kandagatla 	int pull;
3416e261d10SSrinivas Kandagatla 	u32 ctl_reg;
3426e261d10SSrinivas Kandagatla 
3436e261d10SSrinivas Kandagatla 	static const char * const pulls[] = {
3446e261d10SSrinivas Kandagatla 		"no pull",
3456e261d10SSrinivas Kandagatla 		"pull down",
3466e261d10SSrinivas Kandagatla 		"keeper",
3476e261d10SSrinivas Kandagatla 		"pull up"
3486e261d10SSrinivas Kandagatla 	};
3496e261d10SSrinivas Kandagatla 
3506e261d10SSrinivas Kandagatla 	pctldev = pctldev ? : state->ctrl;
3516e261d10SSrinivas Kandagatla 	pindesc = pctldev->desc->pins[offset];
3526e261d10SSrinivas Kandagatla 	ctl_reg = lpi_gpio_read(state, offset, LPI_GPIO_CFG_REG);
3536e261d10SSrinivas Kandagatla 	is_out = ctl_reg & LPI_GPIO_OE_MASK;
3546e261d10SSrinivas Kandagatla 
3556e261d10SSrinivas Kandagatla 	func = FIELD_GET(LPI_GPIO_FUNCTION_MASK, ctl_reg);
3566e261d10SSrinivas Kandagatla 	drive = FIELD_GET(LPI_GPIO_OUT_STRENGTH_MASK, ctl_reg);
3576e261d10SSrinivas Kandagatla 	pull = FIELD_GET(LPI_GPIO_PULL_MASK, ctl_reg);
3586e261d10SSrinivas Kandagatla 
3596e261d10SSrinivas Kandagatla 	seq_printf(s, " %-8s: %-3s %d", pindesc.name, is_out ? "out" : "in", func);
3606e261d10SSrinivas Kandagatla 	seq_printf(s, " %dmA", lpi_regval_to_drive(drive));
3616e261d10SSrinivas Kandagatla 	seq_printf(s, " %s", pulls[pull]);
3626e261d10SSrinivas Kandagatla }
3636e261d10SSrinivas Kandagatla 
lpi_gpio_dbg_show(struct seq_file * s,struct gpio_chip * chip)3646e261d10SSrinivas Kandagatla static void lpi_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
3656e261d10SSrinivas Kandagatla {
3666e261d10SSrinivas Kandagatla 	unsigned int gpio = chip->base;
3676e261d10SSrinivas Kandagatla 	unsigned int i;
3686e261d10SSrinivas Kandagatla 
3696e261d10SSrinivas Kandagatla 	for (i = 0; i < chip->ngpio; i++, gpio++) {
3706e261d10SSrinivas Kandagatla 		lpi_gpio_dbg_show_one(s, NULL, chip, i, gpio);
3716e261d10SSrinivas Kandagatla 		seq_puts(s, "\n");
3726e261d10SSrinivas Kandagatla 	}
3736e261d10SSrinivas Kandagatla }
3746e261d10SSrinivas Kandagatla 
3756e261d10SSrinivas Kandagatla #else
3766e261d10SSrinivas Kandagatla #define lpi_gpio_dbg_show NULL
3776e261d10SSrinivas Kandagatla #endif
3786e261d10SSrinivas Kandagatla 
3796e261d10SSrinivas Kandagatla static const struct gpio_chip lpi_gpio_template = {
3806e261d10SSrinivas Kandagatla 	.direction_input	= lpi_gpio_direction_input,
3816e261d10SSrinivas Kandagatla 	.direction_output	= lpi_gpio_direction_output,
3826e261d10SSrinivas Kandagatla 	.get			= lpi_gpio_get,
3836e261d10SSrinivas Kandagatla 	.set			= lpi_gpio_set,
3846e261d10SSrinivas Kandagatla 	.request		= gpiochip_generic_request,
3856e261d10SSrinivas Kandagatla 	.free			= gpiochip_generic_free,
3866e261d10SSrinivas Kandagatla 	.dbg_show		= lpi_gpio_dbg_show,
3876e261d10SSrinivas Kandagatla };
3886e261d10SSrinivas Kandagatla 
lpi_build_pin_desc_groups(struct lpi_pinctrl * pctrl)389be73368dSSrinivasa Rao Mandadapu static int lpi_build_pin_desc_groups(struct lpi_pinctrl *pctrl)
390be73368dSSrinivasa Rao Mandadapu {
391be73368dSSrinivasa Rao Mandadapu 	int i, ret;
392be73368dSSrinivasa Rao Mandadapu 
393be73368dSSrinivasa Rao Mandadapu 	for (i = 0; i < pctrl->data->npins; i++) {
394be73368dSSrinivasa Rao Mandadapu 		const struct pinctrl_pin_desc *pin_info = pctrl->desc.pins + i;
395be73368dSSrinivasa Rao Mandadapu 
396be73368dSSrinivasa Rao Mandadapu 		ret = pinctrl_generic_add_group(pctrl->ctrl, pin_info->name,
397be73368dSSrinivasa Rao Mandadapu 						  (int *)&pin_info->number, 1, NULL);
398be73368dSSrinivasa Rao Mandadapu 		if (ret < 0)
399be73368dSSrinivasa Rao Mandadapu 			goto err_pinctrl;
400be73368dSSrinivasa Rao Mandadapu 	}
401be73368dSSrinivasa Rao Mandadapu 
402be73368dSSrinivasa Rao Mandadapu 	return 0;
403be73368dSSrinivasa Rao Mandadapu 
404be73368dSSrinivasa Rao Mandadapu err_pinctrl:
405be73368dSSrinivasa Rao Mandadapu 	for (; i > 0; i--)
406be73368dSSrinivasa Rao Mandadapu 		pinctrl_generic_remove_group(pctrl->ctrl, i - 1);
407be73368dSSrinivasa Rao Mandadapu 
408be73368dSSrinivasa Rao Mandadapu 	return ret;
409be73368dSSrinivasa Rao Mandadapu }
410be73368dSSrinivasa Rao Mandadapu 
lpi_pinctrl_probe(struct platform_device * pdev)4119ce49018SSrinivasa Rao Mandadapu int lpi_pinctrl_probe(struct platform_device *pdev)
4126e261d10SSrinivas Kandagatla {
4136e261d10SSrinivas Kandagatla 	const struct lpi_pinctrl_variant_data *data;
4146e261d10SSrinivas Kandagatla 	struct device *dev = &pdev->dev;
4156e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *pctrl;
4166e261d10SSrinivas Kandagatla 	int ret;
4176e261d10SSrinivas Kandagatla 
4186e261d10SSrinivas Kandagatla 	pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
4196e261d10SSrinivas Kandagatla 	if (!pctrl)
4206e261d10SSrinivas Kandagatla 		return -ENOMEM;
4216e261d10SSrinivas Kandagatla 
4226e261d10SSrinivas Kandagatla 	platform_set_drvdata(pdev, pctrl);
4236e261d10SSrinivas Kandagatla 
4246e261d10SSrinivas Kandagatla 	data = of_device_get_match_data(dev);
4256e261d10SSrinivas Kandagatla 	if (!data)
4266e261d10SSrinivas Kandagatla 		return -EINVAL;
4276e261d10SSrinivas Kandagatla 
428fae1466dSKrzysztof Kozlowski 	if (WARN_ON(data->npins > MAX_NR_GPIO))
429fae1466dSKrzysztof Kozlowski 		return -EINVAL;
430fae1466dSKrzysztof Kozlowski 
4316e261d10SSrinivas Kandagatla 	pctrl->data = data;
4326e261d10SSrinivas Kandagatla 	pctrl->dev = &pdev->dev;
4336e261d10SSrinivas Kandagatla 
4346e261d10SSrinivas Kandagatla 	pctrl->clks[0].id = "core";
4356e261d10SSrinivas Kandagatla 	pctrl->clks[1].id = "audio";
4366e261d10SSrinivas Kandagatla 
4376e261d10SSrinivas Kandagatla 	pctrl->tlmm_base = devm_platform_ioremap_resource(pdev, 0);
4386e261d10SSrinivas Kandagatla 	if (IS_ERR(pctrl->tlmm_base))
4396e261d10SSrinivas Kandagatla 		return dev_err_probe(dev, PTR_ERR(pctrl->tlmm_base),
4406e261d10SSrinivas Kandagatla 				     "TLMM resource not provided\n");
4416e261d10SSrinivas Kandagatla 
4426e261d10SSrinivas Kandagatla 	pctrl->slew_base = devm_platform_ioremap_resource(pdev, 1);
4436e261d10SSrinivas Kandagatla 	if (IS_ERR(pctrl->slew_base))
4446e261d10SSrinivas Kandagatla 		return dev_err_probe(dev, PTR_ERR(pctrl->slew_base),
4456e261d10SSrinivas Kandagatla 				     "Slew resource not provided\n");
4466e261d10SSrinivas Kandagatla 
447a6a5c173SSrinivasa Rao Mandadapu 	ret = devm_clk_bulk_get_optional(dev, MAX_LPI_NUM_CLKS, pctrl->clks);
4486e261d10SSrinivas Kandagatla 	if (ret)
449a6a5c173SSrinivasa Rao Mandadapu 		return ret;
4506e261d10SSrinivas Kandagatla 
4516e261d10SSrinivas Kandagatla 	ret = clk_bulk_prepare_enable(MAX_LPI_NUM_CLKS, pctrl->clks);
4526e261d10SSrinivas Kandagatla 	if (ret)
4536e261d10SSrinivas Kandagatla 		return dev_err_probe(dev, ret, "Can't enable clocks\n");
4546e261d10SSrinivas Kandagatla 
4556e261d10SSrinivas Kandagatla 	pctrl->desc.pctlops = &lpi_gpio_pinctrl_ops;
4566e261d10SSrinivas Kandagatla 	pctrl->desc.pmxops = &lpi_gpio_pinmux_ops;
4576e261d10SSrinivas Kandagatla 	pctrl->desc.confops = &lpi_gpio_pinconf_ops;
4586e261d10SSrinivas Kandagatla 	pctrl->desc.owner = THIS_MODULE;
4596e261d10SSrinivas Kandagatla 	pctrl->desc.name = dev_name(dev);
4606e261d10SSrinivas Kandagatla 	pctrl->desc.pins = data->pins;
4616e261d10SSrinivas Kandagatla 	pctrl->desc.npins = data->npins;
4626e261d10SSrinivas Kandagatla 	pctrl->chip = lpi_gpio_template;
4636e261d10SSrinivas Kandagatla 	pctrl->chip.parent = dev;
4646e261d10SSrinivas Kandagatla 	pctrl->chip.base = -1;
4656e261d10SSrinivas Kandagatla 	pctrl->chip.ngpio = data->npins;
4666e261d10SSrinivas Kandagatla 	pctrl->chip.label = dev_name(dev);
4676e261d10SSrinivas Kandagatla 	pctrl->chip.can_sleep = false;
4686e261d10SSrinivas Kandagatla 
469*c8befdc4SKrzysztof Kozlowski 	mutex_init(&pctrl->lock);
4706e261d10SSrinivas Kandagatla 
4716e261d10SSrinivas Kandagatla 	pctrl->ctrl = devm_pinctrl_register(dev, &pctrl->desc, pctrl);
4726e261d10SSrinivas Kandagatla 	if (IS_ERR(pctrl->ctrl)) {
4736e261d10SSrinivas Kandagatla 		ret = PTR_ERR(pctrl->ctrl);
4746e261d10SSrinivas Kandagatla 		dev_err(dev, "failed to add pin controller\n");
4756e261d10SSrinivas Kandagatla 		goto err_pinctrl;
4766e261d10SSrinivas Kandagatla 	}
4776e261d10SSrinivas Kandagatla 
478be73368dSSrinivasa Rao Mandadapu 	ret = lpi_build_pin_desc_groups(pctrl);
479be73368dSSrinivasa Rao Mandadapu 	if (ret)
480be73368dSSrinivasa Rao Mandadapu 		goto err_pinctrl;
481be73368dSSrinivasa Rao Mandadapu 
4826e261d10SSrinivas Kandagatla 	ret = devm_gpiochip_add_data(dev, &pctrl->chip, pctrl);
4836e261d10SSrinivas Kandagatla 	if (ret) {
4846e261d10SSrinivas Kandagatla 		dev_err(pctrl->dev, "can't add gpio chip\n");
4856e261d10SSrinivas Kandagatla 		goto err_pinctrl;
4866e261d10SSrinivas Kandagatla 	}
4876e261d10SSrinivas Kandagatla 
4886e261d10SSrinivas Kandagatla 	return 0;
4896e261d10SSrinivas Kandagatla 
4906e261d10SSrinivas Kandagatla err_pinctrl:
491*c8befdc4SKrzysztof Kozlowski 	mutex_destroy(&pctrl->lock);
4926e261d10SSrinivas Kandagatla 	clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks);
4936e261d10SSrinivas Kandagatla 
4946e261d10SSrinivas Kandagatla 	return ret;
4956e261d10SSrinivas Kandagatla }
4969ce49018SSrinivasa Rao Mandadapu EXPORT_SYMBOL_GPL(lpi_pinctrl_probe);
4976e261d10SSrinivas Kandagatla 
lpi_pinctrl_remove(struct platform_device * pdev)4989ce49018SSrinivasa Rao Mandadapu int lpi_pinctrl_remove(struct platform_device *pdev)
4996e261d10SSrinivas Kandagatla {
5006e261d10SSrinivas Kandagatla 	struct lpi_pinctrl *pctrl = platform_get_drvdata(pdev);
501be73368dSSrinivasa Rao Mandadapu 	int i;
5026e261d10SSrinivas Kandagatla 
503*c8befdc4SKrzysztof Kozlowski 	mutex_destroy(&pctrl->lock);
5046e261d10SSrinivas Kandagatla 	clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks);
5056e261d10SSrinivas Kandagatla 
506be73368dSSrinivasa Rao Mandadapu 	for (i = 0; i < pctrl->data->npins; i++)
507be73368dSSrinivasa Rao Mandadapu 		pinctrl_generic_remove_group(pctrl->ctrl, i);
508be73368dSSrinivasa Rao Mandadapu 
5096e261d10SSrinivas Kandagatla 	return 0;
5106e261d10SSrinivas Kandagatla }
5119ce49018SSrinivasa Rao Mandadapu EXPORT_SYMBOL_GPL(lpi_pinctrl_remove);
5126e261d10SSrinivas Kandagatla 
5136e261d10SSrinivas Kandagatla MODULE_DESCRIPTION("QTI LPI GPIO pin control driver");
5146e261d10SSrinivas Kandagatla MODULE_LICENSE("GPL");
515