xref: /openbmc/linux/drivers/pinctrl/sprd/pinctrl-sprd.c (revision 41d32cfce1ae616413761d07986e1fb4b907e808)
1*41d32cfcSBaolin Wang /*
2*41d32cfcSBaolin Wang  * Spreadtrum pin controller driver
3*41d32cfcSBaolin Wang  * Copyright (C) 2017 Spreadtrum  - http://www.spreadtrum.com
4*41d32cfcSBaolin Wang  *
5*41d32cfcSBaolin Wang  * This program is free software; you can redistribute it and/or
6*41d32cfcSBaolin Wang  * modify it under the terms of the GNU General Public License
7*41d32cfcSBaolin Wang  * version 2 as published by the Free Software Foundation.
8*41d32cfcSBaolin Wang  *
9*41d32cfcSBaolin Wang  * This program is distributed in the hope that it will be useful, but
10*41d32cfcSBaolin Wang  * WITHOUT ANY WARRANTY; without even the implied warranty of
11*41d32cfcSBaolin Wang  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12*41d32cfcSBaolin Wang  * General Public License for more details.
13*41d32cfcSBaolin Wang  */
14*41d32cfcSBaolin Wang 
15*41d32cfcSBaolin Wang #include <linux/debugfs.h>
16*41d32cfcSBaolin Wang #include <linux/err.h>
17*41d32cfcSBaolin Wang #include <linux/init.h>
18*41d32cfcSBaolin Wang #include <linux/io.h>
19*41d32cfcSBaolin Wang #include <linux/kernel.h>
20*41d32cfcSBaolin Wang #include <linux/module.h>
21*41d32cfcSBaolin Wang #include <linux/of.h>
22*41d32cfcSBaolin Wang #include <linux/of_device.h>
23*41d32cfcSBaolin Wang #include <linux/platform_device.h>
24*41d32cfcSBaolin Wang #include <linux/pinctrl/machine.h>
25*41d32cfcSBaolin Wang #include <linux/pinctrl/pinconf.h>
26*41d32cfcSBaolin Wang #include <linux/pinctrl/pinconf-generic.h>
27*41d32cfcSBaolin Wang #include <linux/pinctrl/pinctrl.h>
28*41d32cfcSBaolin Wang #include <linux/pinctrl/pinmux.h>
29*41d32cfcSBaolin Wang #include <linux/slab.h>
30*41d32cfcSBaolin Wang 
31*41d32cfcSBaolin Wang #include "../core.h"
32*41d32cfcSBaolin Wang #include "../pinmux.h"
33*41d32cfcSBaolin Wang #include "../pinconf.h"
34*41d32cfcSBaolin Wang #include "../pinctrl-utils.h"
35*41d32cfcSBaolin Wang #include "pinctrl-sprd.h"
36*41d32cfcSBaolin Wang 
37*41d32cfcSBaolin Wang #define PINCTRL_BIT_MASK(width)		(~(~0UL << (width)))
38*41d32cfcSBaolin Wang #define PINCTRL_REG_OFFSET		0x20
39*41d32cfcSBaolin Wang #define PINCTRL_REG_MISC_OFFSET		0x4020
40*41d32cfcSBaolin Wang #define PINCTRL_REG_LEN			0x4
41*41d32cfcSBaolin Wang 
42*41d32cfcSBaolin Wang #define PIN_FUNC_MASK			(BIT(4) | BIT(5))
43*41d32cfcSBaolin Wang #define PIN_FUNC_SEL_1			~PIN_FUNC_MASK
44*41d32cfcSBaolin Wang #define PIN_FUNC_SEL_2			BIT(4)
45*41d32cfcSBaolin Wang #define PIN_FUNC_SEL_3			BIT(5)
46*41d32cfcSBaolin Wang #define PIN_FUNC_SEL_4			PIN_FUNC_MASK
47*41d32cfcSBaolin Wang 
48*41d32cfcSBaolin Wang #define AP_SLEEP_MODE			BIT(13)
49*41d32cfcSBaolin Wang #define PUBCP_SLEEP_MODE		BIT(14)
50*41d32cfcSBaolin Wang #define TGLDSP_SLEEP_MODE		BIT(15)
51*41d32cfcSBaolin Wang #define AGDSP_SLEEP_MODE		BIT(16)
52*41d32cfcSBaolin Wang #define SLEEP_MODE_MASK			GENMASK(3, 0)
53*41d32cfcSBaolin Wang #define SLEEP_MODE_SHIFT		13
54*41d32cfcSBaolin Wang 
55*41d32cfcSBaolin Wang #define SLEEP_INPUT			BIT(1)
56*41d32cfcSBaolin Wang #define SLEEP_INPUT_MASK		0x1
57*41d32cfcSBaolin Wang #define SLEEP_INPUT_SHIFT		1
58*41d32cfcSBaolin Wang 
59*41d32cfcSBaolin Wang #define SLEEP_OUTPUT			BIT(0)
60*41d32cfcSBaolin Wang #define SLEEP_OUTPUT_MASK		0x1
61*41d32cfcSBaolin Wang #define SLEEP_OUTPUT_SHIFT		0
62*41d32cfcSBaolin Wang 
63*41d32cfcSBaolin Wang #define DRIVE_STRENGTH_MASK		GENMASK(3, 0)
64*41d32cfcSBaolin Wang #define DRIVE_STRENGTH_SHIFT		19
65*41d32cfcSBaolin Wang 
66*41d32cfcSBaolin Wang #define SLEEP_PULL_DOWN			BIT(2)
67*41d32cfcSBaolin Wang #define SLEEP_PULL_DOWN_MASK		0x1
68*41d32cfcSBaolin Wang #define SLEEP_PULL_DOWN_SHIFT		2
69*41d32cfcSBaolin Wang 
70*41d32cfcSBaolin Wang #define PULL_DOWN			BIT(6)
71*41d32cfcSBaolin Wang #define PULL_DOWN_MASK			0x1
72*41d32cfcSBaolin Wang #define PULL_DOWN_SHIFT			6
73*41d32cfcSBaolin Wang 
74*41d32cfcSBaolin Wang #define SLEEP_PULL_UP			BIT(3)
75*41d32cfcSBaolin Wang #define SLEEP_PULL_UP_MASK		0x1
76*41d32cfcSBaolin Wang #define SLEEP_PULL_UP_SHIFT		3
77*41d32cfcSBaolin Wang 
78*41d32cfcSBaolin Wang #define PULL_UP_20K			(BIT(12) | BIT(7))
79*41d32cfcSBaolin Wang #define PULL_UP_4_7K			BIT(12)
80*41d32cfcSBaolin Wang #define PULL_UP_MASK			0x21
81*41d32cfcSBaolin Wang #define PULL_UP_SHIFT			7
82*41d32cfcSBaolin Wang 
83*41d32cfcSBaolin Wang #define INPUT_SCHMITT			BIT(11)
84*41d32cfcSBaolin Wang #define INPUT_SCHMITT_MASK		0x1
85*41d32cfcSBaolin Wang #define INPUT_SCHMITT_SHIFT		11
86*41d32cfcSBaolin Wang 
87*41d32cfcSBaolin Wang enum pin_sleep_mode {
88*41d32cfcSBaolin Wang 	AP_SLEEP = BIT(0),
89*41d32cfcSBaolin Wang 	PUBCP_SLEEP = BIT(1),
90*41d32cfcSBaolin Wang 	TGLDSP_SLEEP = BIT(2),
91*41d32cfcSBaolin Wang 	AGDSP_SLEEP = BIT(3),
92*41d32cfcSBaolin Wang };
93*41d32cfcSBaolin Wang 
94*41d32cfcSBaolin Wang enum pin_func_sel {
95*41d32cfcSBaolin Wang 	PIN_FUNC_1,
96*41d32cfcSBaolin Wang 	PIN_FUNC_2,
97*41d32cfcSBaolin Wang 	PIN_FUNC_3,
98*41d32cfcSBaolin Wang 	PIN_FUNC_4,
99*41d32cfcSBaolin Wang 	PIN_FUNC_MAX,
100*41d32cfcSBaolin Wang };
101*41d32cfcSBaolin Wang 
102*41d32cfcSBaolin Wang /**
103*41d32cfcSBaolin Wang  * struct sprd_pin: represent one pin's description
104*41d32cfcSBaolin Wang  * @name: pin name
105*41d32cfcSBaolin Wang  * @number: pin number
106*41d32cfcSBaolin Wang  * @type: pin type, can be GLOBAL_CTRL_PIN/COMMON_PIN/MISC_PIN
107*41d32cfcSBaolin Wang  * @reg: pin register address
108*41d32cfcSBaolin Wang  * @bit_offset: bit offset in pin register
109*41d32cfcSBaolin Wang  * @bit_width: bit width in pin register
110*41d32cfcSBaolin Wang  */
111*41d32cfcSBaolin Wang struct sprd_pin {
112*41d32cfcSBaolin Wang 	const char *name;
113*41d32cfcSBaolin Wang 	unsigned int number;
114*41d32cfcSBaolin Wang 	enum pin_type type;
115*41d32cfcSBaolin Wang 	unsigned long reg;
116*41d32cfcSBaolin Wang 	unsigned long bit_offset;
117*41d32cfcSBaolin Wang 	unsigned long bit_width;
118*41d32cfcSBaolin Wang };
119*41d32cfcSBaolin Wang 
120*41d32cfcSBaolin Wang /**
121*41d32cfcSBaolin Wang  * struct sprd_pin_group: represent one group's description
122*41d32cfcSBaolin Wang  * @name: group name
123*41d32cfcSBaolin Wang  * @npins: pin numbers of this group
124*41d32cfcSBaolin Wang  * @pins: pointer to pins array
125*41d32cfcSBaolin Wang  */
126*41d32cfcSBaolin Wang struct sprd_pin_group {
127*41d32cfcSBaolin Wang 	const char *name;
128*41d32cfcSBaolin Wang 	unsigned int npins;
129*41d32cfcSBaolin Wang 	unsigned int *pins;
130*41d32cfcSBaolin Wang };
131*41d32cfcSBaolin Wang 
132*41d32cfcSBaolin Wang /**
133*41d32cfcSBaolin Wang  * struct sprd_pinctrl_soc_info: represent the SoC's pins description
134*41d32cfcSBaolin Wang  * @groups: pointer to groups of pins
135*41d32cfcSBaolin Wang  * @ngroups: group numbers of the whole SoC
136*41d32cfcSBaolin Wang  * @pins: pointer to pins description
137*41d32cfcSBaolin Wang  * @npins: pin numbers of the whole SoC
138*41d32cfcSBaolin Wang  * @grp_names: pointer to group names array
139*41d32cfcSBaolin Wang  */
140*41d32cfcSBaolin Wang struct sprd_pinctrl_soc_info {
141*41d32cfcSBaolin Wang 	struct sprd_pin_group *groups;
142*41d32cfcSBaolin Wang 	unsigned int ngroups;
143*41d32cfcSBaolin Wang 	struct sprd_pin *pins;
144*41d32cfcSBaolin Wang 	unsigned int npins;
145*41d32cfcSBaolin Wang 	const char **grp_names;
146*41d32cfcSBaolin Wang };
147*41d32cfcSBaolin Wang 
148*41d32cfcSBaolin Wang /**
149*41d32cfcSBaolin Wang  * struct sprd_pinctrl: represent the pin controller device
150*41d32cfcSBaolin Wang  * @dev: pointer to the device structure
151*41d32cfcSBaolin Wang  * @pctl: pointer to the pinctrl handle
152*41d32cfcSBaolin Wang  * @base: base address of the controller
153*41d32cfcSBaolin Wang  * @info: pointer to SoC's pins description information
154*41d32cfcSBaolin Wang  */
155*41d32cfcSBaolin Wang struct sprd_pinctrl {
156*41d32cfcSBaolin Wang 	struct device *dev;
157*41d32cfcSBaolin Wang 	struct pinctrl_dev *pctl;
158*41d32cfcSBaolin Wang 	void __iomem *base;
159*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info;
160*41d32cfcSBaolin Wang };
161*41d32cfcSBaolin Wang 
162*41d32cfcSBaolin Wang enum sprd_pinconf_params {
163*41d32cfcSBaolin Wang 	SPRD_PIN_CONFIG_CONTROL = PIN_CONFIG_END + 1,
164*41d32cfcSBaolin Wang 	SPRD_PIN_CONFIG_SLEEP_MODE = PIN_CONFIG_END + 2,
165*41d32cfcSBaolin Wang };
166*41d32cfcSBaolin Wang 
167*41d32cfcSBaolin Wang static int sprd_pinctrl_get_id_by_name(struct sprd_pinctrl *sprd_pctl,
168*41d32cfcSBaolin Wang 				       const char *name)
169*41d32cfcSBaolin Wang {
170*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
171*41d32cfcSBaolin Wang 	int i;
172*41d32cfcSBaolin Wang 
173*41d32cfcSBaolin Wang 	for (i = 0; i < info->npins; i++) {
174*41d32cfcSBaolin Wang 		if (!strcmp(info->pins[i].name, name))
175*41d32cfcSBaolin Wang 			return info->pins[i].number;
176*41d32cfcSBaolin Wang 	}
177*41d32cfcSBaolin Wang 
178*41d32cfcSBaolin Wang 	return -ENODEV;
179*41d32cfcSBaolin Wang }
180*41d32cfcSBaolin Wang 
181*41d32cfcSBaolin Wang static struct sprd_pin *
182*41d32cfcSBaolin Wang sprd_pinctrl_get_pin_by_id(struct sprd_pinctrl *sprd_pctl, unsigned int id)
183*41d32cfcSBaolin Wang {
184*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
185*41d32cfcSBaolin Wang 	struct sprd_pin *pin = NULL;
186*41d32cfcSBaolin Wang 	int i;
187*41d32cfcSBaolin Wang 
188*41d32cfcSBaolin Wang 	for (i = 0; i < info->npins; i++) {
189*41d32cfcSBaolin Wang 		if (info->pins[i].number == id) {
190*41d32cfcSBaolin Wang 			pin = &info->pins[i];
191*41d32cfcSBaolin Wang 			break;
192*41d32cfcSBaolin Wang 		}
193*41d32cfcSBaolin Wang 	}
194*41d32cfcSBaolin Wang 
195*41d32cfcSBaolin Wang 	return pin;
196*41d32cfcSBaolin Wang }
197*41d32cfcSBaolin Wang 
198*41d32cfcSBaolin Wang static const struct sprd_pin_group *
199*41d32cfcSBaolin Wang sprd_pinctrl_find_group_by_name(struct sprd_pinctrl *sprd_pctl,
200*41d32cfcSBaolin Wang 				const char *name)
201*41d32cfcSBaolin Wang {
202*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
203*41d32cfcSBaolin Wang 	const struct sprd_pin_group *grp = NULL;
204*41d32cfcSBaolin Wang 	int i;
205*41d32cfcSBaolin Wang 
206*41d32cfcSBaolin Wang 	for (i = 0; i < info->ngroups; i++) {
207*41d32cfcSBaolin Wang 		if (!strcmp(info->groups[i].name, name)) {
208*41d32cfcSBaolin Wang 			grp = &info->groups[i];
209*41d32cfcSBaolin Wang 			break;
210*41d32cfcSBaolin Wang 		}
211*41d32cfcSBaolin Wang 	}
212*41d32cfcSBaolin Wang 
213*41d32cfcSBaolin Wang 	return grp;
214*41d32cfcSBaolin Wang }
215*41d32cfcSBaolin Wang 
216*41d32cfcSBaolin Wang static int sprd_pctrl_group_count(struct pinctrl_dev *pctldev)
217*41d32cfcSBaolin Wang {
218*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
219*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = pctl->info;
220*41d32cfcSBaolin Wang 
221*41d32cfcSBaolin Wang 	return info->ngroups;
222*41d32cfcSBaolin Wang }
223*41d32cfcSBaolin Wang 
224*41d32cfcSBaolin Wang static const char *sprd_pctrl_group_name(struct pinctrl_dev *pctldev,
225*41d32cfcSBaolin Wang 					 unsigned int selector)
226*41d32cfcSBaolin Wang {
227*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
228*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = pctl->info;
229*41d32cfcSBaolin Wang 
230*41d32cfcSBaolin Wang 	return info->groups[selector].name;
231*41d32cfcSBaolin Wang }
232*41d32cfcSBaolin Wang 
233*41d32cfcSBaolin Wang static int sprd_pctrl_group_pins(struct pinctrl_dev *pctldev,
234*41d32cfcSBaolin Wang 				 unsigned int selector,
235*41d32cfcSBaolin Wang 				 const unsigned int **pins,
236*41d32cfcSBaolin Wang 				 unsigned int *npins)
237*41d32cfcSBaolin Wang {
238*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
239*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = pctl->info;
240*41d32cfcSBaolin Wang 
241*41d32cfcSBaolin Wang 	if (selector >= info->ngroups)
242*41d32cfcSBaolin Wang 		return -EINVAL;
243*41d32cfcSBaolin Wang 
244*41d32cfcSBaolin Wang 	*pins = info->groups[selector].pins;
245*41d32cfcSBaolin Wang 	*npins = info->groups[selector].npins;
246*41d32cfcSBaolin Wang 
247*41d32cfcSBaolin Wang 	return 0;
248*41d32cfcSBaolin Wang }
249*41d32cfcSBaolin Wang 
250*41d32cfcSBaolin Wang static int sprd_dt_node_to_map(struct pinctrl_dev *pctldev,
251*41d32cfcSBaolin Wang 			       struct device_node *np,
252*41d32cfcSBaolin Wang 			       struct pinctrl_map **map,
253*41d32cfcSBaolin Wang 			       unsigned int *num_maps)
254*41d32cfcSBaolin Wang {
255*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
256*41d32cfcSBaolin Wang 	const struct sprd_pin_group *grp;
257*41d32cfcSBaolin Wang 	unsigned long *configs = NULL;
258*41d32cfcSBaolin Wang 	unsigned int num_configs = 0;
259*41d32cfcSBaolin Wang 	unsigned int reserved_maps = 0;
260*41d32cfcSBaolin Wang 	unsigned int reserve = 0;
261*41d32cfcSBaolin Wang 	const char *function;
262*41d32cfcSBaolin Wang 	enum pinctrl_map_type type;
263*41d32cfcSBaolin Wang 	int ret;
264*41d32cfcSBaolin Wang 
265*41d32cfcSBaolin Wang 	grp = sprd_pinctrl_find_group_by_name(pctl, np->name);
266*41d32cfcSBaolin Wang 	if (!grp) {
267*41d32cfcSBaolin Wang 		dev_err(pctl->dev, "unable to find group for node %s\n",
268*41d32cfcSBaolin Wang 			of_node_full_name(np));
269*41d32cfcSBaolin Wang 		return -EINVAL;
270*41d32cfcSBaolin Wang 	}
271*41d32cfcSBaolin Wang 
272*41d32cfcSBaolin Wang 	ret = of_property_count_strings(np, "pins");
273*41d32cfcSBaolin Wang 	if (ret < 0)
274*41d32cfcSBaolin Wang 		return ret;
275*41d32cfcSBaolin Wang 
276*41d32cfcSBaolin Wang 	if (ret == 1)
277*41d32cfcSBaolin Wang 		type = PIN_MAP_TYPE_CONFIGS_PIN;
278*41d32cfcSBaolin Wang 	else
279*41d32cfcSBaolin Wang 		type = PIN_MAP_TYPE_CONFIGS_GROUP;
280*41d32cfcSBaolin Wang 
281*41d32cfcSBaolin Wang 	ret = of_property_read_string(np, "function", &function);
282*41d32cfcSBaolin Wang 	if (ret < 0) {
283*41d32cfcSBaolin Wang 		if (ret != -EINVAL)
284*41d32cfcSBaolin Wang 			dev_err(pctl->dev,
285*41d32cfcSBaolin Wang 				"%s: could not parse property function\n",
286*41d32cfcSBaolin Wang 				of_node_full_name(np));
287*41d32cfcSBaolin Wang 		function = NULL;
288*41d32cfcSBaolin Wang 	}
289*41d32cfcSBaolin Wang 
290*41d32cfcSBaolin Wang 	ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
291*41d32cfcSBaolin Wang 					      &num_configs);
292*41d32cfcSBaolin Wang 	if (ret < 0) {
293*41d32cfcSBaolin Wang 		dev_err(pctl->dev, "%s: could not parse node property\n",
294*41d32cfcSBaolin Wang 			of_node_full_name(np));
295*41d32cfcSBaolin Wang 		return ret;
296*41d32cfcSBaolin Wang 	}
297*41d32cfcSBaolin Wang 
298*41d32cfcSBaolin Wang 	*map = NULL;
299*41d32cfcSBaolin Wang 	*num_maps = 0;
300*41d32cfcSBaolin Wang 
301*41d32cfcSBaolin Wang 	if (function != NULL)
302*41d32cfcSBaolin Wang 		reserve++;
303*41d32cfcSBaolin Wang 	if (num_configs)
304*41d32cfcSBaolin Wang 		reserve++;
305*41d32cfcSBaolin Wang 
306*41d32cfcSBaolin Wang 	ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps,
307*41d32cfcSBaolin Wang 					num_maps, reserve);
308*41d32cfcSBaolin Wang 	if (ret < 0)
309*41d32cfcSBaolin Wang 		goto out;
310*41d32cfcSBaolin Wang 
311*41d32cfcSBaolin Wang 	if (function) {
312*41d32cfcSBaolin Wang 		ret = pinctrl_utils_add_map_mux(pctldev, map,
313*41d32cfcSBaolin Wang 						&reserved_maps, num_maps,
314*41d32cfcSBaolin Wang 						grp->name, function);
315*41d32cfcSBaolin Wang 		if (ret < 0)
316*41d32cfcSBaolin Wang 			goto out;
317*41d32cfcSBaolin Wang 	}
318*41d32cfcSBaolin Wang 
319*41d32cfcSBaolin Wang 	if (num_configs) {
320*41d32cfcSBaolin Wang 		const char *group_or_pin;
321*41d32cfcSBaolin Wang 		unsigned int pin_id;
322*41d32cfcSBaolin Wang 
323*41d32cfcSBaolin Wang 		if (type == PIN_MAP_TYPE_CONFIGS_PIN) {
324*41d32cfcSBaolin Wang 			pin_id = grp->pins[0];
325*41d32cfcSBaolin Wang 			group_or_pin = pin_get_name(pctldev, pin_id);
326*41d32cfcSBaolin Wang 		} else {
327*41d32cfcSBaolin Wang 			group_or_pin = grp->name;
328*41d32cfcSBaolin Wang 		}
329*41d32cfcSBaolin Wang 
330*41d32cfcSBaolin Wang 		ret = pinctrl_utils_add_map_configs(pctldev, map,
331*41d32cfcSBaolin Wang 						    &reserved_maps, num_maps,
332*41d32cfcSBaolin Wang 						    group_or_pin, configs,
333*41d32cfcSBaolin Wang 						    num_configs, type);
334*41d32cfcSBaolin Wang 	}
335*41d32cfcSBaolin Wang 
336*41d32cfcSBaolin Wang out:
337*41d32cfcSBaolin Wang 	kfree(configs);
338*41d32cfcSBaolin Wang 	return ret;
339*41d32cfcSBaolin Wang }
340*41d32cfcSBaolin Wang 
341*41d32cfcSBaolin Wang static void sprd_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
342*41d32cfcSBaolin Wang 				unsigned int offset)
343*41d32cfcSBaolin Wang {
344*41d32cfcSBaolin Wang 	seq_printf(s, "%s", dev_name(pctldev->dev));
345*41d32cfcSBaolin Wang }
346*41d32cfcSBaolin Wang 
347*41d32cfcSBaolin Wang static const struct pinctrl_ops sprd_pctrl_ops = {
348*41d32cfcSBaolin Wang 	.get_groups_count = sprd_pctrl_group_count,
349*41d32cfcSBaolin Wang 	.get_group_name = sprd_pctrl_group_name,
350*41d32cfcSBaolin Wang 	.get_group_pins = sprd_pctrl_group_pins,
351*41d32cfcSBaolin Wang 	.pin_dbg_show = sprd_pctrl_dbg_show,
352*41d32cfcSBaolin Wang 	.dt_node_to_map = sprd_dt_node_to_map,
353*41d32cfcSBaolin Wang 	.dt_free_map = pinctrl_utils_free_map,
354*41d32cfcSBaolin Wang };
355*41d32cfcSBaolin Wang 
356*41d32cfcSBaolin Wang int sprd_pmx_get_function_count(struct pinctrl_dev *pctldev)
357*41d32cfcSBaolin Wang {
358*41d32cfcSBaolin Wang 	return PIN_FUNC_MAX;
359*41d32cfcSBaolin Wang }
360*41d32cfcSBaolin Wang 
361*41d32cfcSBaolin Wang const char *sprd_pmx_get_function_name(struct pinctrl_dev *pctldev,
362*41d32cfcSBaolin Wang 				       unsigned int selector)
363*41d32cfcSBaolin Wang {
364*41d32cfcSBaolin Wang 	switch (selector) {
365*41d32cfcSBaolin Wang 	case PIN_FUNC_1:
366*41d32cfcSBaolin Wang 		return "func1";
367*41d32cfcSBaolin Wang 	case PIN_FUNC_2:
368*41d32cfcSBaolin Wang 		return "func2";
369*41d32cfcSBaolin Wang 	case PIN_FUNC_3:
370*41d32cfcSBaolin Wang 		return "func3";
371*41d32cfcSBaolin Wang 	case PIN_FUNC_4:
372*41d32cfcSBaolin Wang 		return "func4";
373*41d32cfcSBaolin Wang 	default:
374*41d32cfcSBaolin Wang 		return "null";
375*41d32cfcSBaolin Wang 	}
376*41d32cfcSBaolin Wang }
377*41d32cfcSBaolin Wang 
378*41d32cfcSBaolin Wang int sprd_pmx_get_function_groups(struct pinctrl_dev *pctldev,
379*41d32cfcSBaolin Wang 				 unsigned int selector,
380*41d32cfcSBaolin Wang 				 const char * const **groups,
381*41d32cfcSBaolin Wang 				 unsigned int * const num_groups)
382*41d32cfcSBaolin Wang {
383*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
384*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = pctl->info;
385*41d32cfcSBaolin Wang 
386*41d32cfcSBaolin Wang 	*groups = info->grp_names;
387*41d32cfcSBaolin Wang 	*num_groups = info->ngroups;
388*41d32cfcSBaolin Wang 
389*41d32cfcSBaolin Wang 	return 0;
390*41d32cfcSBaolin Wang }
391*41d32cfcSBaolin Wang 
392*41d32cfcSBaolin Wang static int sprd_pmx_set_mux(struct pinctrl_dev *pctldev,
393*41d32cfcSBaolin Wang 			    unsigned int func_selector,
394*41d32cfcSBaolin Wang 			    unsigned int group_selector)
395*41d32cfcSBaolin Wang {
396*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
397*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = pctl->info;
398*41d32cfcSBaolin Wang 	struct sprd_pin_group *grp = &info->groups[group_selector];
399*41d32cfcSBaolin Wang 	unsigned int i, grp_pins = grp->npins;
400*41d32cfcSBaolin Wang 	unsigned long reg;
401*41d32cfcSBaolin Wang 	unsigned int val = 0;
402*41d32cfcSBaolin Wang 
403*41d32cfcSBaolin Wang 	if (group_selector > info->ngroups)
404*41d32cfcSBaolin Wang 		return -EINVAL;
405*41d32cfcSBaolin Wang 
406*41d32cfcSBaolin Wang 	switch (func_selector) {
407*41d32cfcSBaolin Wang 	case PIN_FUNC_1:
408*41d32cfcSBaolin Wang 		val &= PIN_FUNC_SEL_1;
409*41d32cfcSBaolin Wang 		break;
410*41d32cfcSBaolin Wang 	case PIN_FUNC_2:
411*41d32cfcSBaolin Wang 		val |= PIN_FUNC_SEL_2;
412*41d32cfcSBaolin Wang 		break;
413*41d32cfcSBaolin Wang 	case PIN_FUNC_3:
414*41d32cfcSBaolin Wang 		val |= PIN_FUNC_SEL_3;
415*41d32cfcSBaolin Wang 		break;
416*41d32cfcSBaolin Wang 	case PIN_FUNC_4:
417*41d32cfcSBaolin Wang 		val |= PIN_FUNC_SEL_4;
418*41d32cfcSBaolin Wang 		break;
419*41d32cfcSBaolin Wang 	default:
420*41d32cfcSBaolin Wang 		break;
421*41d32cfcSBaolin Wang 	}
422*41d32cfcSBaolin Wang 
423*41d32cfcSBaolin Wang 	for (i = 0; i < grp_pins; i++) {
424*41d32cfcSBaolin Wang 		unsigned int pin_id = grp->pins[i];
425*41d32cfcSBaolin Wang 		struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
426*41d32cfcSBaolin Wang 
427*41d32cfcSBaolin Wang 		if (!pin || pin->type != COMMON_PIN)
428*41d32cfcSBaolin Wang 			continue;
429*41d32cfcSBaolin Wang 
430*41d32cfcSBaolin Wang 		reg = readl((void __iomem *)pin->reg);
431*41d32cfcSBaolin Wang 		reg &= ~PIN_FUNC_MASK;
432*41d32cfcSBaolin Wang 		reg |= val;
433*41d32cfcSBaolin Wang 		writel(reg, (void __iomem *)pin->reg);
434*41d32cfcSBaolin Wang 	}
435*41d32cfcSBaolin Wang 
436*41d32cfcSBaolin Wang 	return 0;
437*41d32cfcSBaolin Wang }
438*41d32cfcSBaolin Wang 
439*41d32cfcSBaolin Wang static const struct pinmux_ops sprd_pmx_ops = {
440*41d32cfcSBaolin Wang 	.get_functions_count = sprd_pmx_get_function_count,
441*41d32cfcSBaolin Wang 	.get_function_name = sprd_pmx_get_function_name,
442*41d32cfcSBaolin Wang 	.get_function_groups = sprd_pmx_get_function_groups,
443*41d32cfcSBaolin Wang 	.set_mux = sprd_pmx_set_mux,
444*41d32cfcSBaolin Wang };
445*41d32cfcSBaolin Wang 
446*41d32cfcSBaolin Wang static int sprd_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin_id,
447*41d32cfcSBaolin Wang 			    unsigned long *config)
448*41d32cfcSBaolin Wang {
449*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
450*41d32cfcSBaolin Wang 	struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
451*41d32cfcSBaolin Wang 	unsigned int param = pinconf_to_config_param(*config);
452*41d32cfcSBaolin Wang 	unsigned int reg, arg;
453*41d32cfcSBaolin Wang 
454*41d32cfcSBaolin Wang 	if (!pin)
455*41d32cfcSBaolin Wang 		return -EINVAL;
456*41d32cfcSBaolin Wang 
457*41d32cfcSBaolin Wang 	if (pin->type == GLOBAL_CTRL_PIN) {
458*41d32cfcSBaolin Wang 		reg = (readl((void __iomem *)pin->reg) >>
459*41d32cfcSBaolin Wang 			   pin->bit_offset) & PINCTRL_BIT_MASK(pin->bit_width);
460*41d32cfcSBaolin Wang 	} else {
461*41d32cfcSBaolin Wang 		reg = readl((void __iomem *)pin->reg);
462*41d32cfcSBaolin Wang 	}
463*41d32cfcSBaolin Wang 
464*41d32cfcSBaolin Wang 	if (pin->type == GLOBAL_CTRL_PIN &&
465*41d32cfcSBaolin Wang 	    param == SPRD_PIN_CONFIG_CONTROL) {
466*41d32cfcSBaolin Wang 		arg = reg;
467*41d32cfcSBaolin Wang 	} else if (pin->type == COMMON_PIN) {
468*41d32cfcSBaolin Wang 		switch (param) {
469*41d32cfcSBaolin Wang 		case SPRD_PIN_CONFIG_SLEEP_MODE:
470*41d32cfcSBaolin Wang 			arg = (reg >> SLEEP_MODE_SHIFT) & SLEEP_MODE_MASK;
471*41d32cfcSBaolin Wang 			break;
472*41d32cfcSBaolin Wang 		case PIN_CONFIG_INPUT_ENABLE:
473*41d32cfcSBaolin Wang 			arg = (reg >> SLEEP_INPUT_SHIFT) & SLEEP_INPUT_MASK;
474*41d32cfcSBaolin Wang 			break;
475*41d32cfcSBaolin Wang 		case PIN_CONFIG_OUTPUT:
476*41d32cfcSBaolin Wang 			arg = reg & SLEEP_OUTPUT_MASK;
477*41d32cfcSBaolin Wang 			break;
478*41d32cfcSBaolin Wang 		case PIN_CONFIG_SLEEP_HARDWARE_STATE:
479*41d32cfcSBaolin Wang 			arg = 0;
480*41d32cfcSBaolin Wang 			break;
481*41d32cfcSBaolin Wang 		default:
482*41d32cfcSBaolin Wang 			return -ENOTSUPP;
483*41d32cfcSBaolin Wang 		}
484*41d32cfcSBaolin Wang 	} else if (pin->type == MISC_PIN) {
485*41d32cfcSBaolin Wang 		switch (param) {
486*41d32cfcSBaolin Wang 		case PIN_CONFIG_DRIVE_STRENGTH:
487*41d32cfcSBaolin Wang 			arg = (reg >> DRIVE_STRENGTH_SHIFT) &
488*41d32cfcSBaolin Wang 				DRIVE_STRENGTH_MASK;
489*41d32cfcSBaolin Wang 			break;
490*41d32cfcSBaolin Wang 		case PIN_CONFIG_BIAS_PULL_DOWN:
491*41d32cfcSBaolin Wang 			/* combine sleep pull down and pull down config */
492*41d32cfcSBaolin Wang 			arg = ((reg >> SLEEP_PULL_DOWN_SHIFT) &
493*41d32cfcSBaolin Wang 			       SLEEP_PULL_DOWN_MASK) << 16;
494*41d32cfcSBaolin Wang 			arg |= (reg >> PULL_DOWN_SHIFT) & PULL_DOWN_MASK;
495*41d32cfcSBaolin Wang 			break;
496*41d32cfcSBaolin Wang 		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
497*41d32cfcSBaolin Wang 			arg = (reg >> INPUT_SCHMITT_SHIFT) & INPUT_SCHMITT_MASK;
498*41d32cfcSBaolin Wang 			break;
499*41d32cfcSBaolin Wang 		case PIN_CONFIG_BIAS_PULL_UP:
500*41d32cfcSBaolin Wang 			/* combine sleep pull up and pull up config */
501*41d32cfcSBaolin Wang 			arg = ((reg >> SLEEP_PULL_UP_SHIFT) &
502*41d32cfcSBaolin Wang 			       SLEEP_PULL_UP_MASK) << 16;
503*41d32cfcSBaolin Wang 			arg |= (reg >> PULL_UP_SHIFT) & PULL_UP_MASK;
504*41d32cfcSBaolin Wang 			break;
505*41d32cfcSBaolin Wang 		case PIN_CONFIG_SLEEP_HARDWARE_STATE:
506*41d32cfcSBaolin Wang 			arg = 0;
507*41d32cfcSBaolin Wang 			break;
508*41d32cfcSBaolin Wang 		default:
509*41d32cfcSBaolin Wang 			return -ENOTSUPP;
510*41d32cfcSBaolin Wang 		}
511*41d32cfcSBaolin Wang 	} else {
512*41d32cfcSBaolin Wang 		return -ENOTSUPP;
513*41d32cfcSBaolin Wang 	}
514*41d32cfcSBaolin Wang 
515*41d32cfcSBaolin Wang 	*config = pinconf_to_config_packed(param, arg);
516*41d32cfcSBaolin Wang 	return 0;
517*41d32cfcSBaolin Wang }
518*41d32cfcSBaolin Wang 
519*41d32cfcSBaolin Wang static unsigned int sprd_pinconf_drive(unsigned int mA)
520*41d32cfcSBaolin Wang {
521*41d32cfcSBaolin Wang 	unsigned int val = 0;
522*41d32cfcSBaolin Wang 
523*41d32cfcSBaolin Wang 	switch (mA) {
524*41d32cfcSBaolin Wang 	case 2:
525*41d32cfcSBaolin Wang 		break;
526*41d32cfcSBaolin Wang 	case 4:
527*41d32cfcSBaolin Wang 		val |= BIT(19);
528*41d32cfcSBaolin Wang 		break;
529*41d32cfcSBaolin Wang 	case 6:
530*41d32cfcSBaolin Wang 		val |= BIT(20);
531*41d32cfcSBaolin Wang 		break;
532*41d32cfcSBaolin Wang 	case 8:
533*41d32cfcSBaolin Wang 		val |= BIT(19) | BIT(20);
534*41d32cfcSBaolin Wang 		break;
535*41d32cfcSBaolin Wang 	case 10:
536*41d32cfcSBaolin Wang 		val |= BIT(21);
537*41d32cfcSBaolin Wang 		break;
538*41d32cfcSBaolin Wang 	case 12:
539*41d32cfcSBaolin Wang 		val |= BIT(21) | BIT(19);
540*41d32cfcSBaolin Wang 		break;
541*41d32cfcSBaolin Wang 	case 14:
542*41d32cfcSBaolin Wang 		val |= BIT(21) | BIT(20);
543*41d32cfcSBaolin Wang 		break;
544*41d32cfcSBaolin Wang 	case 16:
545*41d32cfcSBaolin Wang 		val |= BIT(19) | BIT(20) | BIT(21);
546*41d32cfcSBaolin Wang 		break;
547*41d32cfcSBaolin Wang 	case 20:
548*41d32cfcSBaolin Wang 		val |= BIT(22);
549*41d32cfcSBaolin Wang 		break;
550*41d32cfcSBaolin Wang 	case 21:
551*41d32cfcSBaolin Wang 		val |= BIT(22) | BIT(19);
552*41d32cfcSBaolin Wang 		break;
553*41d32cfcSBaolin Wang 	case 24:
554*41d32cfcSBaolin Wang 		val |= BIT(22) | BIT(20);
555*41d32cfcSBaolin Wang 		break;
556*41d32cfcSBaolin Wang 	case 25:
557*41d32cfcSBaolin Wang 		val |= BIT(22) | BIT(20) | BIT(19);
558*41d32cfcSBaolin Wang 		break;
559*41d32cfcSBaolin Wang 	case 27:
560*41d32cfcSBaolin Wang 		val |= BIT(22) | BIT(21);
561*41d32cfcSBaolin Wang 		break;
562*41d32cfcSBaolin Wang 	case 29:
563*41d32cfcSBaolin Wang 		val |= BIT(22) | BIT(21) | BIT(19);
564*41d32cfcSBaolin Wang 		break;
565*41d32cfcSBaolin Wang 	case 31:
566*41d32cfcSBaolin Wang 		val |= BIT(22) | BIT(21) | BIT(20);
567*41d32cfcSBaolin Wang 		break;
568*41d32cfcSBaolin Wang 	case 33:
569*41d32cfcSBaolin Wang 		val |= BIT(22) | BIT(21) | BIT(20) | BIT(19);
570*41d32cfcSBaolin Wang 		break;
571*41d32cfcSBaolin Wang 	default:
572*41d32cfcSBaolin Wang 		break;
573*41d32cfcSBaolin Wang 	}
574*41d32cfcSBaolin Wang 
575*41d32cfcSBaolin Wang 	return val;
576*41d32cfcSBaolin Wang }
577*41d32cfcSBaolin Wang 
578*41d32cfcSBaolin Wang static bool sprd_pinctrl_check_sleep_config(unsigned long *configs,
579*41d32cfcSBaolin Wang 					    unsigned int num_configs)
580*41d32cfcSBaolin Wang {
581*41d32cfcSBaolin Wang 	unsigned int param;
582*41d32cfcSBaolin Wang 	int i;
583*41d32cfcSBaolin Wang 
584*41d32cfcSBaolin Wang 	for (i = 0; i < num_configs; i++) {
585*41d32cfcSBaolin Wang 		param = pinconf_to_config_param(configs[i]);
586*41d32cfcSBaolin Wang 		if (param == PIN_CONFIG_SLEEP_HARDWARE_STATE)
587*41d32cfcSBaolin Wang 			return true;
588*41d32cfcSBaolin Wang 	}
589*41d32cfcSBaolin Wang 
590*41d32cfcSBaolin Wang 	return false;
591*41d32cfcSBaolin Wang }
592*41d32cfcSBaolin Wang 
593*41d32cfcSBaolin Wang static int sprd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin_id,
594*41d32cfcSBaolin Wang 			    unsigned long *configs, unsigned int num_configs)
595*41d32cfcSBaolin Wang {
596*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
597*41d32cfcSBaolin Wang 	struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
598*41d32cfcSBaolin Wang 	bool is_sleep_config;
599*41d32cfcSBaolin Wang 	unsigned long reg;
600*41d32cfcSBaolin Wang 	int i;
601*41d32cfcSBaolin Wang 
602*41d32cfcSBaolin Wang 	if (!pin)
603*41d32cfcSBaolin Wang 		return -EINVAL;
604*41d32cfcSBaolin Wang 
605*41d32cfcSBaolin Wang 	is_sleep_config = sprd_pinctrl_check_sleep_config(configs, num_configs);
606*41d32cfcSBaolin Wang 
607*41d32cfcSBaolin Wang 	for (i = 0; i < num_configs; i++) {
608*41d32cfcSBaolin Wang 		unsigned int param, arg, shift, mask, val;
609*41d32cfcSBaolin Wang 
610*41d32cfcSBaolin Wang 		param = pinconf_to_config_param(configs[i]);
611*41d32cfcSBaolin Wang 		arg = pinconf_to_config_argument(configs[i]);
612*41d32cfcSBaolin Wang 
613*41d32cfcSBaolin Wang 		val = 0;
614*41d32cfcSBaolin Wang 		shift = 0;
615*41d32cfcSBaolin Wang 		mask = 0;
616*41d32cfcSBaolin Wang 		if (pin->type == GLOBAL_CTRL_PIN &&
617*41d32cfcSBaolin Wang 		    param == SPRD_PIN_CONFIG_CONTROL) {
618*41d32cfcSBaolin Wang 			val = arg;
619*41d32cfcSBaolin Wang 		} else if (pin->type == COMMON_PIN) {
620*41d32cfcSBaolin Wang 			switch (param) {
621*41d32cfcSBaolin Wang 			case SPRD_PIN_CONFIG_SLEEP_MODE:
622*41d32cfcSBaolin Wang 				if (arg & AP_SLEEP)
623*41d32cfcSBaolin Wang 					val |= AP_SLEEP_MODE;
624*41d32cfcSBaolin Wang 				if (arg & PUBCP_SLEEP)
625*41d32cfcSBaolin Wang 					val |= PUBCP_SLEEP_MODE;
626*41d32cfcSBaolin Wang 				if (arg & TGLDSP_SLEEP)
627*41d32cfcSBaolin Wang 					val |= TGLDSP_SLEEP_MODE;
628*41d32cfcSBaolin Wang 				if (arg & AGDSP_SLEEP)
629*41d32cfcSBaolin Wang 					val |= AGDSP_SLEEP_MODE;
630*41d32cfcSBaolin Wang 
631*41d32cfcSBaolin Wang 				mask = SLEEP_MODE_MASK;
632*41d32cfcSBaolin Wang 				shift = SLEEP_MODE_SHIFT;
633*41d32cfcSBaolin Wang 				break;
634*41d32cfcSBaolin Wang 			case PIN_CONFIG_INPUT_ENABLE:
635*41d32cfcSBaolin Wang 				if (is_sleep_config == true) {
636*41d32cfcSBaolin Wang 					if (arg > 0)
637*41d32cfcSBaolin Wang 						val |= SLEEP_INPUT;
638*41d32cfcSBaolin Wang 					else
639*41d32cfcSBaolin Wang 						val &= ~SLEEP_INPUT;
640*41d32cfcSBaolin Wang 
641*41d32cfcSBaolin Wang 					mask = SLEEP_INPUT_MASK;
642*41d32cfcSBaolin Wang 					shift = SLEEP_INPUT_SHIFT;
643*41d32cfcSBaolin Wang 				}
644*41d32cfcSBaolin Wang 				break;
645*41d32cfcSBaolin Wang 			case PIN_CONFIG_OUTPUT:
646*41d32cfcSBaolin Wang 				if (is_sleep_config == true) {
647*41d32cfcSBaolin Wang 					val |= SLEEP_OUTPUT;
648*41d32cfcSBaolin Wang 					mask = SLEEP_OUTPUT_MASK;
649*41d32cfcSBaolin Wang 					shift = SLEEP_OUTPUT_SHIFT;
650*41d32cfcSBaolin Wang 				}
651*41d32cfcSBaolin Wang 				break;
652*41d32cfcSBaolin Wang 			case PIN_CONFIG_SLEEP_HARDWARE_STATE:
653*41d32cfcSBaolin Wang 				continue;
654*41d32cfcSBaolin Wang 			default:
655*41d32cfcSBaolin Wang 				return -ENOTSUPP;
656*41d32cfcSBaolin Wang 			}
657*41d32cfcSBaolin Wang 		} else if (pin->type == MISC_PIN) {
658*41d32cfcSBaolin Wang 			switch (param) {
659*41d32cfcSBaolin Wang 			case PIN_CONFIG_DRIVE_STRENGTH:
660*41d32cfcSBaolin Wang 				if (arg < 2 || arg > 60)
661*41d32cfcSBaolin Wang 					return -EINVAL;
662*41d32cfcSBaolin Wang 
663*41d32cfcSBaolin Wang 				val = sprd_pinconf_drive(arg);
664*41d32cfcSBaolin Wang 				mask = DRIVE_STRENGTH_MASK;
665*41d32cfcSBaolin Wang 				shift = DRIVE_STRENGTH_SHIFT;
666*41d32cfcSBaolin Wang 				break;
667*41d32cfcSBaolin Wang 			case PIN_CONFIG_BIAS_PULL_DOWN:
668*41d32cfcSBaolin Wang 				if (is_sleep_config == true) {
669*41d32cfcSBaolin Wang 					val |= SLEEP_PULL_DOWN;
670*41d32cfcSBaolin Wang 					mask = SLEEP_PULL_DOWN_MASK;
671*41d32cfcSBaolin Wang 					shift = SLEEP_PULL_DOWN_SHIFT;
672*41d32cfcSBaolin Wang 				} else {
673*41d32cfcSBaolin Wang 					val |= PULL_DOWN;
674*41d32cfcSBaolin Wang 					mask = PULL_DOWN_MASK;
675*41d32cfcSBaolin Wang 					shift = PULL_DOWN_SHIFT;
676*41d32cfcSBaolin Wang 				}
677*41d32cfcSBaolin Wang 				break;
678*41d32cfcSBaolin Wang 			case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
679*41d32cfcSBaolin Wang 				if (arg > 0)
680*41d32cfcSBaolin Wang 					val |= INPUT_SCHMITT;
681*41d32cfcSBaolin Wang 				else
682*41d32cfcSBaolin Wang 					val &= ~INPUT_SCHMITT;
683*41d32cfcSBaolin Wang 
684*41d32cfcSBaolin Wang 				mask = INPUT_SCHMITT_MASK;
685*41d32cfcSBaolin Wang 				shift = INPUT_SCHMITT_SHIFT;
686*41d32cfcSBaolin Wang 				break;
687*41d32cfcSBaolin Wang 			case PIN_CONFIG_BIAS_PULL_UP:
688*41d32cfcSBaolin Wang 				if (is_sleep_config == true) {
689*41d32cfcSBaolin Wang 					val |= SLEEP_PULL_UP;
690*41d32cfcSBaolin Wang 					mask = SLEEP_PULL_UP_MASK;
691*41d32cfcSBaolin Wang 					shift = SLEEP_PULL_UP_SHIFT;
692*41d32cfcSBaolin Wang 				} else {
693*41d32cfcSBaolin Wang 					if (arg == 20000)
694*41d32cfcSBaolin Wang 						val |= PULL_UP_20K;
695*41d32cfcSBaolin Wang 					else if (arg == 4700)
696*41d32cfcSBaolin Wang 						val |= PULL_UP_4_7K;
697*41d32cfcSBaolin Wang 
698*41d32cfcSBaolin Wang 					mask = PULL_UP_MASK;
699*41d32cfcSBaolin Wang 					shift = PULL_UP_SHIFT;
700*41d32cfcSBaolin Wang 				}
701*41d32cfcSBaolin Wang 				break;
702*41d32cfcSBaolin Wang 			case PIN_CONFIG_SLEEP_HARDWARE_STATE:
703*41d32cfcSBaolin Wang 				continue;
704*41d32cfcSBaolin Wang 			default:
705*41d32cfcSBaolin Wang 				return -ENOTSUPP;
706*41d32cfcSBaolin Wang 			}
707*41d32cfcSBaolin Wang 		} else {
708*41d32cfcSBaolin Wang 			return -ENOTSUPP;
709*41d32cfcSBaolin Wang 		}
710*41d32cfcSBaolin Wang 
711*41d32cfcSBaolin Wang 		if (pin->type == GLOBAL_CTRL_PIN) {
712*41d32cfcSBaolin Wang 			reg = readl((void __iomem *)pin->reg);
713*41d32cfcSBaolin Wang 			reg &= ~(PINCTRL_BIT_MASK(pin->bit_width)
714*41d32cfcSBaolin Wang 				<< pin->bit_offset);
715*41d32cfcSBaolin Wang 			reg |= (val & PINCTRL_BIT_MASK(pin->bit_width))
716*41d32cfcSBaolin Wang 				<< pin->bit_offset;
717*41d32cfcSBaolin Wang 			writel(reg, (void __iomem *)pin->reg);
718*41d32cfcSBaolin Wang 		} else {
719*41d32cfcSBaolin Wang 			reg = readl((void __iomem *)pin->reg);
720*41d32cfcSBaolin Wang 			reg &= ~(mask << shift);
721*41d32cfcSBaolin Wang 			reg |= val;
722*41d32cfcSBaolin Wang 			writel(reg, (void __iomem *)pin->reg);
723*41d32cfcSBaolin Wang 		}
724*41d32cfcSBaolin Wang 	}
725*41d32cfcSBaolin Wang 
726*41d32cfcSBaolin Wang 	return 0;
727*41d32cfcSBaolin Wang }
728*41d32cfcSBaolin Wang 
729*41d32cfcSBaolin Wang static int sprd_pinconf_group_get(struct pinctrl_dev *pctldev,
730*41d32cfcSBaolin Wang 				  unsigned int selector, unsigned long *config)
731*41d32cfcSBaolin Wang {
732*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
733*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = pctl->info;
734*41d32cfcSBaolin Wang 	struct sprd_pin_group *grp;
735*41d32cfcSBaolin Wang 	unsigned int pin_id;
736*41d32cfcSBaolin Wang 
737*41d32cfcSBaolin Wang 	if (selector > info->ngroups)
738*41d32cfcSBaolin Wang 		return -EINVAL;
739*41d32cfcSBaolin Wang 
740*41d32cfcSBaolin Wang 	grp = &info->groups[selector];
741*41d32cfcSBaolin Wang 	pin_id = grp->pins[0];
742*41d32cfcSBaolin Wang 
743*41d32cfcSBaolin Wang 	return sprd_pinconf_get(pctldev, pin_id, config);
744*41d32cfcSBaolin Wang }
745*41d32cfcSBaolin Wang 
746*41d32cfcSBaolin Wang static int sprd_pinconf_group_set(struct pinctrl_dev *pctldev,
747*41d32cfcSBaolin Wang 				  unsigned int selector,
748*41d32cfcSBaolin Wang 				  unsigned long *configs,
749*41d32cfcSBaolin Wang 				  unsigned int num_configs)
750*41d32cfcSBaolin Wang {
751*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
752*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = pctl->info;
753*41d32cfcSBaolin Wang 	struct sprd_pin_group *grp;
754*41d32cfcSBaolin Wang 	int ret, i;
755*41d32cfcSBaolin Wang 
756*41d32cfcSBaolin Wang 	if (selector > info->ngroups)
757*41d32cfcSBaolin Wang 		return -EINVAL;
758*41d32cfcSBaolin Wang 
759*41d32cfcSBaolin Wang 	grp = &info->groups[selector];
760*41d32cfcSBaolin Wang 
761*41d32cfcSBaolin Wang 	for (i = 0; i < grp->npins; i++) {
762*41d32cfcSBaolin Wang 		unsigned int pin_id = grp->pins[i];
763*41d32cfcSBaolin Wang 
764*41d32cfcSBaolin Wang 		ret = sprd_pinconf_set(pctldev, pin_id, configs, num_configs);
765*41d32cfcSBaolin Wang 		if (ret)
766*41d32cfcSBaolin Wang 			return ret;
767*41d32cfcSBaolin Wang 	}
768*41d32cfcSBaolin Wang 
769*41d32cfcSBaolin Wang 	return 0;
770*41d32cfcSBaolin Wang }
771*41d32cfcSBaolin Wang 
772*41d32cfcSBaolin Wang static int sprd_pinconf_get_config(struct pinctrl_dev *pctldev,
773*41d32cfcSBaolin Wang 				   unsigned int pin_id,
774*41d32cfcSBaolin Wang 				   unsigned long *config)
775*41d32cfcSBaolin Wang {
776*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
777*41d32cfcSBaolin Wang 	struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
778*41d32cfcSBaolin Wang 
779*41d32cfcSBaolin Wang 	if (!pin)
780*41d32cfcSBaolin Wang 		return -EINVAL;
781*41d32cfcSBaolin Wang 
782*41d32cfcSBaolin Wang 	if (pin->type == GLOBAL_CTRL_PIN) {
783*41d32cfcSBaolin Wang 		*config = (readl((void __iomem *)pin->reg) >>
784*41d32cfcSBaolin Wang 			   pin->bit_offset) & PINCTRL_BIT_MASK(pin->bit_width);
785*41d32cfcSBaolin Wang 	} else {
786*41d32cfcSBaolin Wang 		*config = readl((void __iomem *)pin->reg);
787*41d32cfcSBaolin Wang 	}
788*41d32cfcSBaolin Wang 
789*41d32cfcSBaolin Wang 	return 0;
790*41d32cfcSBaolin Wang }
791*41d32cfcSBaolin Wang 
792*41d32cfcSBaolin Wang static void sprd_pinconf_dbg_show(struct pinctrl_dev *pctldev,
793*41d32cfcSBaolin Wang 				  struct seq_file *s, unsigned int pin_id)
794*41d32cfcSBaolin Wang {
795*41d32cfcSBaolin Wang 	unsigned long config;
796*41d32cfcSBaolin Wang 	int ret;
797*41d32cfcSBaolin Wang 
798*41d32cfcSBaolin Wang 	ret = sprd_pinconf_get_config(pctldev, pin_id, &config);
799*41d32cfcSBaolin Wang 	if (ret)
800*41d32cfcSBaolin Wang 		return;
801*41d32cfcSBaolin Wang 
802*41d32cfcSBaolin Wang 	seq_printf(s, "0x%lx", config);
803*41d32cfcSBaolin Wang }
804*41d32cfcSBaolin Wang 
805*41d32cfcSBaolin Wang static void sprd_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
806*41d32cfcSBaolin Wang 					struct seq_file *s,
807*41d32cfcSBaolin Wang 					unsigned int selector)
808*41d32cfcSBaolin Wang {
809*41d32cfcSBaolin Wang 	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
810*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = pctl->info;
811*41d32cfcSBaolin Wang 	struct sprd_pin_group *grp;
812*41d32cfcSBaolin Wang 	unsigned long config;
813*41d32cfcSBaolin Wang 	const char *name;
814*41d32cfcSBaolin Wang 	int i, ret;
815*41d32cfcSBaolin Wang 
816*41d32cfcSBaolin Wang 	if (selector > info->ngroups)
817*41d32cfcSBaolin Wang 		return;
818*41d32cfcSBaolin Wang 
819*41d32cfcSBaolin Wang 	grp = &info->groups[selector];
820*41d32cfcSBaolin Wang 
821*41d32cfcSBaolin Wang 	seq_printf(s, "\n");
822*41d32cfcSBaolin Wang 	for (i = 0; i < grp->npins; i++, config++) {
823*41d32cfcSBaolin Wang 		unsigned int pin_id = grp->pins[i];
824*41d32cfcSBaolin Wang 
825*41d32cfcSBaolin Wang 		name = pin_get_name(pctldev, pin_id);
826*41d32cfcSBaolin Wang 		ret = sprd_pinconf_get_config(pctldev, pin_id, &config);
827*41d32cfcSBaolin Wang 		if (ret)
828*41d32cfcSBaolin Wang 			return;
829*41d32cfcSBaolin Wang 
830*41d32cfcSBaolin Wang 		seq_printf(s, "%s: 0x%lx ", name, config);
831*41d32cfcSBaolin Wang 	}
832*41d32cfcSBaolin Wang }
833*41d32cfcSBaolin Wang 
834*41d32cfcSBaolin Wang static const struct pinconf_ops sprd_pinconf_ops = {
835*41d32cfcSBaolin Wang 	.is_generic = true,
836*41d32cfcSBaolin Wang 	.pin_config_get = sprd_pinconf_get,
837*41d32cfcSBaolin Wang 	.pin_config_set = sprd_pinconf_set,
838*41d32cfcSBaolin Wang 	.pin_config_group_get = sprd_pinconf_group_get,
839*41d32cfcSBaolin Wang 	.pin_config_group_set = sprd_pinconf_group_set,
840*41d32cfcSBaolin Wang 	.pin_config_dbg_show = sprd_pinconf_dbg_show,
841*41d32cfcSBaolin Wang 	.pin_config_group_dbg_show = sprd_pinconf_group_dbg_show,
842*41d32cfcSBaolin Wang };
843*41d32cfcSBaolin Wang 
844*41d32cfcSBaolin Wang static const struct pinconf_generic_params sprd_dt_params[] = {
845*41d32cfcSBaolin Wang 	{"sprd,control", SPRD_PIN_CONFIG_CONTROL, 0},
846*41d32cfcSBaolin Wang 	{"sprd,sleep-mode", SPRD_PIN_CONFIG_SLEEP_MODE, 0},
847*41d32cfcSBaolin Wang };
848*41d32cfcSBaolin Wang 
849*41d32cfcSBaolin Wang #ifdef CONFIG_DEBUG_FS
850*41d32cfcSBaolin Wang static const struct pin_config_item sprd_conf_items[] = {
851*41d32cfcSBaolin Wang 	PCONFDUMP(SPRD_PIN_CONFIG_CONTROL, "global control", NULL, true),
852*41d32cfcSBaolin Wang 	PCONFDUMP(SPRD_PIN_CONFIG_SLEEP_MODE, "sleep mode", NULL, true),
853*41d32cfcSBaolin Wang };
854*41d32cfcSBaolin Wang #endif
855*41d32cfcSBaolin Wang 
856*41d32cfcSBaolin Wang static struct pinctrl_desc sprd_pinctrl_desc = {
857*41d32cfcSBaolin Wang 	.pctlops = &sprd_pctrl_ops,
858*41d32cfcSBaolin Wang 	.pmxops = &sprd_pmx_ops,
859*41d32cfcSBaolin Wang 	.confops = &sprd_pinconf_ops,
860*41d32cfcSBaolin Wang 	.num_custom_params = ARRAY_SIZE(sprd_dt_params),
861*41d32cfcSBaolin Wang 	.custom_params = sprd_dt_params,
862*41d32cfcSBaolin Wang #ifdef CONFIG_DEBUG_FS
863*41d32cfcSBaolin Wang 	.custom_conf_items = sprd_conf_items,
864*41d32cfcSBaolin Wang #endif
865*41d32cfcSBaolin Wang 	.owner = THIS_MODULE,
866*41d32cfcSBaolin Wang };
867*41d32cfcSBaolin Wang 
868*41d32cfcSBaolin Wang static int sprd_pinctrl_parse_groups(struct device_node *np,
869*41d32cfcSBaolin Wang 				     struct sprd_pinctrl *sprd_pctl,
870*41d32cfcSBaolin Wang 				     struct sprd_pin_group *grp)
871*41d32cfcSBaolin Wang {
872*41d32cfcSBaolin Wang 	struct property *prop;
873*41d32cfcSBaolin Wang 	const char *pin_name;
874*41d32cfcSBaolin Wang 	int ret, i = 0;
875*41d32cfcSBaolin Wang 
876*41d32cfcSBaolin Wang 	ret = of_property_count_strings(np, "pins");
877*41d32cfcSBaolin Wang 	if (ret < 0)
878*41d32cfcSBaolin Wang 		return ret;
879*41d32cfcSBaolin Wang 
880*41d32cfcSBaolin Wang 	grp->name = np->name;
881*41d32cfcSBaolin Wang 	grp->npins = ret;
882*41d32cfcSBaolin Wang 	grp->pins = devm_kzalloc(sprd_pctl->dev, grp->npins *
883*41d32cfcSBaolin Wang 				 sizeof(unsigned int), GFP_KERNEL);
884*41d32cfcSBaolin Wang 	if (!grp->pins)
885*41d32cfcSBaolin Wang 		return -ENOMEM;
886*41d32cfcSBaolin Wang 
887*41d32cfcSBaolin Wang 	of_property_for_each_string(np, "pins", prop, pin_name) {
888*41d32cfcSBaolin Wang 		ret = sprd_pinctrl_get_id_by_name(sprd_pctl, pin_name);
889*41d32cfcSBaolin Wang 		if (ret >= 0)
890*41d32cfcSBaolin Wang 			grp->pins[i++] = ret;
891*41d32cfcSBaolin Wang 	}
892*41d32cfcSBaolin Wang 
893*41d32cfcSBaolin Wang 	for (i = 0; i < grp->npins; i++) {
894*41d32cfcSBaolin Wang 		dev_dbg(sprd_pctl->dev,
895*41d32cfcSBaolin Wang 			"Group[%s] contains [%d] pins: id = %d\n",
896*41d32cfcSBaolin Wang 			grp->name, grp->npins, grp->pins[i]);
897*41d32cfcSBaolin Wang 	}
898*41d32cfcSBaolin Wang 
899*41d32cfcSBaolin Wang 	return 0;
900*41d32cfcSBaolin Wang }
901*41d32cfcSBaolin Wang 
902*41d32cfcSBaolin Wang static unsigned int sprd_pinctrl_get_groups(struct device_node *np)
903*41d32cfcSBaolin Wang {
904*41d32cfcSBaolin Wang 	struct device_node *child;
905*41d32cfcSBaolin Wang 	unsigned int group_cnt, cnt;
906*41d32cfcSBaolin Wang 
907*41d32cfcSBaolin Wang 	group_cnt = of_get_child_count(np);
908*41d32cfcSBaolin Wang 
909*41d32cfcSBaolin Wang 	for_each_child_of_node(np, child) {
910*41d32cfcSBaolin Wang 		cnt = of_get_child_count(child);
911*41d32cfcSBaolin Wang 		if (cnt > 0)
912*41d32cfcSBaolin Wang 			group_cnt += cnt;
913*41d32cfcSBaolin Wang 	}
914*41d32cfcSBaolin Wang 
915*41d32cfcSBaolin Wang 	return group_cnt;
916*41d32cfcSBaolin Wang }
917*41d32cfcSBaolin Wang 
918*41d32cfcSBaolin Wang static int sprd_pinctrl_parse_dt(struct sprd_pinctrl *sprd_pctl)
919*41d32cfcSBaolin Wang {
920*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
921*41d32cfcSBaolin Wang 	struct device_node *np = sprd_pctl->dev->of_node;
922*41d32cfcSBaolin Wang 	struct device_node *child, *sub_child;
923*41d32cfcSBaolin Wang 	struct sprd_pin_group *grp;
924*41d32cfcSBaolin Wang 	const char **temp;
925*41d32cfcSBaolin Wang 	int ret;
926*41d32cfcSBaolin Wang 
927*41d32cfcSBaolin Wang 	if (!np)
928*41d32cfcSBaolin Wang 		return -ENODEV;
929*41d32cfcSBaolin Wang 
930*41d32cfcSBaolin Wang 	info->ngroups = sprd_pinctrl_get_groups(np);
931*41d32cfcSBaolin Wang 	if (!info->ngroups)
932*41d32cfcSBaolin Wang 		return 0;
933*41d32cfcSBaolin Wang 
934*41d32cfcSBaolin Wang 	info->groups = devm_kzalloc(sprd_pctl->dev, info->ngroups *
935*41d32cfcSBaolin Wang 				    sizeof(struct sprd_pin_group),
936*41d32cfcSBaolin Wang 				    GFP_KERNEL);
937*41d32cfcSBaolin Wang 	if (!info->groups)
938*41d32cfcSBaolin Wang 		return -ENOMEM;
939*41d32cfcSBaolin Wang 
940*41d32cfcSBaolin Wang 	info->grp_names = devm_kzalloc(sprd_pctl->dev,
941*41d32cfcSBaolin Wang 				       info->ngroups * sizeof(char *),
942*41d32cfcSBaolin Wang 				       GFP_KERNEL);
943*41d32cfcSBaolin Wang 	if (!info->grp_names)
944*41d32cfcSBaolin Wang 		return -ENOMEM;
945*41d32cfcSBaolin Wang 
946*41d32cfcSBaolin Wang 	temp = info->grp_names;
947*41d32cfcSBaolin Wang 	grp = info->groups;
948*41d32cfcSBaolin Wang 
949*41d32cfcSBaolin Wang 	for_each_child_of_node(np, child) {
950*41d32cfcSBaolin Wang 		ret = sprd_pinctrl_parse_groups(child, sprd_pctl, grp);
951*41d32cfcSBaolin Wang 		if (ret)
952*41d32cfcSBaolin Wang 			return ret;
953*41d32cfcSBaolin Wang 
954*41d32cfcSBaolin Wang 		*temp++ = grp->name;
955*41d32cfcSBaolin Wang 		grp++;
956*41d32cfcSBaolin Wang 
957*41d32cfcSBaolin Wang 		if (of_get_child_count(child) > 0) {
958*41d32cfcSBaolin Wang 			for_each_child_of_node(child, sub_child) {
959*41d32cfcSBaolin Wang 				ret = sprd_pinctrl_parse_groups(sub_child,
960*41d32cfcSBaolin Wang 								sprd_pctl, grp);
961*41d32cfcSBaolin Wang 				if (ret)
962*41d32cfcSBaolin Wang 					return ret;
963*41d32cfcSBaolin Wang 
964*41d32cfcSBaolin Wang 				*temp++ = grp->name;
965*41d32cfcSBaolin Wang 				grp++;
966*41d32cfcSBaolin Wang 			}
967*41d32cfcSBaolin Wang 		}
968*41d32cfcSBaolin Wang 	}
969*41d32cfcSBaolin Wang 
970*41d32cfcSBaolin Wang 	return 0;
971*41d32cfcSBaolin Wang }
972*41d32cfcSBaolin Wang 
973*41d32cfcSBaolin Wang static int sprd_pinctrl_add_pins(struct sprd_pinctrl *sprd_pctl,
974*41d32cfcSBaolin Wang 				 struct sprd_pins_info *sprd_soc_pin_info,
975*41d32cfcSBaolin Wang 				 int pins_cnt)
976*41d32cfcSBaolin Wang {
977*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
978*41d32cfcSBaolin Wang 	unsigned int ctrl_pin = 0, com_pin = 0;
979*41d32cfcSBaolin Wang 	struct sprd_pin *pin;
980*41d32cfcSBaolin Wang 	int i;
981*41d32cfcSBaolin Wang 
982*41d32cfcSBaolin Wang 	info->npins = pins_cnt;
983*41d32cfcSBaolin Wang 	info->pins = devm_kzalloc(sprd_pctl->dev,
984*41d32cfcSBaolin Wang 				  info->npins * sizeof(struct sprd_pin),
985*41d32cfcSBaolin Wang 				  GFP_KERNEL);
986*41d32cfcSBaolin Wang 	if (!info->pins)
987*41d32cfcSBaolin Wang 		return -ENOMEM;
988*41d32cfcSBaolin Wang 
989*41d32cfcSBaolin Wang 	for (i = 0, pin = info->pins; i < info->npins; i++, pin++) {
990*41d32cfcSBaolin Wang 		unsigned int reg;
991*41d32cfcSBaolin Wang 
992*41d32cfcSBaolin Wang 		pin->name = sprd_soc_pin_info[i].name;
993*41d32cfcSBaolin Wang 		pin->type = sprd_soc_pin_info[i].type;
994*41d32cfcSBaolin Wang 		pin->number = sprd_soc_pin_info[i].num;
995*41d32cfcSBaolin Wang 		reg = sprd_soc_pin_info[i].reg;
996*41d32cfcSBaolin Wang 		if (pin->type == GLOBAL_CTRL_PIN) {
997*41d32cfcSBaolin Wang 			pin->reg = (unsigned long)sprd_pctl->base +
998*41d32cfcSBaolin Wang 				PINCTRL_REG_LEN * reg;
999*41d32cfcSBaolin Wang 			pin->bit_offset = sprd_soc_pin_info[i].bit_offset;
1000*41d32cfcSBaolin Wang 			pin->bit_width = sprd_soc_pin_info[i].bit_width;
1001*41d32cfcSBaolin Wang 			ctrl_pin++;
1002*41d32cfcSBaolin Wang 		} else if (pin->type == COMMON_PIN) {
1003*41d32cfcSBaolin Wang 			pin->reg = (unsigned long)sprd_pctl->base +
1004*41d32cfcSBaolin Wang 				PINCTRL_REG_OFFSET + PINCTRL_REG_LEN *
1005*41d32cfcSBaolin Wang 				(i - ctrl_pin);
1006*41d32cfcSBaolin Wang 			com_pin++;
1007*41d32cfcSBaolin Wang 		} else if (pin->type == MISC_PIN) {
1008*41d32cfcSBaolin Wang 			pin->reg = (unsigned long)sprd_pctl->base +
1009*41d32cfcSBaolin Wang 				PINCTRL_REG_MISC_OFFSET + PINCTRL_REG_LEN *
1010*41d32cfcSBaolin Wang 				(i - ctrl_pin - com_pin);
1011*41d32cfcSBaolin Wang 		}
1012*41d32cfcSBaolin Wang 	}
1013*41d32cfcSBaolin Wang 
1014*41d32cfcSBaolin Wang 	for (i = 0, pin = info->pins; i < info->npins; pin++, i++) {
1015*41d32cfcSBaolin Wang 		dev_dbg(sprd_pctl->dev, "pin name[%s-%d], type = %d, "
1016*41d32cfcSBaolin Wang 			"bit offset = %ld, bit width = %ld, reg = 0x%lx\n",
1017*41d32cfcSBaolin Wang 			pin->name, pin->number, pin->type,
1018*41d32cfcSBaolin Wang 			pin->bit_offset, pin->bit_width, pin->reg);
1019*41d32cfcSBaolin Wang 	}
1020*41d32cfcSBaolin Wang 
1021*41d32cfcSBaolin Wang 	return 0;
1022*41d32cfcSBaolin Wang }
1023*41d32cfcSBaolin Wang 
1024*41d32cfcSBaolin Wang int sprd_pinctrl_core_probe(struct platform_device *pdev,
1025*41d32cfcSBaolin Wang 			    struct sprd_pins_info *sprd_soc_pin_info,
1026*41d32cfcSBaolin Wang 			    int pins_cnt)
1027*41d32cfcSBaolin Wang {
1028*41d32cfcSBaolin Wang 	struct sprd_pinctrl *sprd_pctl;
1029*41d32cfcSBaolin Wang 	struct sprd_pinctrl_soc_info *pinctrl_info;
1030*41d32cfcSBaolin Wang 	struct pinctrl_pin_desc *pin_desc;
1031*41d32cfcSBaolin Wang 	struct resource *res;
1032*41d32cfcSBaolin Wang 	int ret, i;
1033*41d32cfcSBaolin Wang 
1034*41d32cfcSBaolin Wang 	sprd_pctl = devm_kzalloc(&pdev->dev, sizeof(struct sprd_pinctrl),
1035*41d32cfcSBaolin Wang 				 GFP_KERNEL);
1036*41d32cfcSBaolin Wang 	if (!sprd_pctl)
1037*41d32cfcSBaolin Wang 		return -ENOMEM;
1038*41d32cfcSBaolin Wang 
1039*41d32cfcSBaolin Wang 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1040*41d32cfcSBaolin Wang 	sprd_pctl->base = devm_ioremap_resource(&pdev->dev, res);
1041*41d32cfcSBaolin Wang 	if (IS_ERR(sprd_pctl->base))
1042*41d32cfcSBaolin Wang 		return PTR_ERR(sprd_pctl->base);
1043*41d32cfcSBaolin Wang 
1044*41d32cfcSBaolin Wang 	pinctrl_info = devm_kzalloc(&pdev->dev,
1045*41d32cfcSBaolin Wang 				    sizeof(struct sprd_pinctrl_soc_info),
1046*41d32cfcSBaolin Wang 				    GFP_KERNEL);
1047*41d32cfcSBaolin Wang 	if (!pinctrl_info)
1048*41d32cfcSBaolin Wang 		return -ENOMEM;
1049*41d32cfcSBaolin Wang 
1050*41d32cfcSBaolin Wang 	sprd_pctl->info = pinctrl_info;
1051*41d32cfcSBaolin Wang 	sprd_pctl->dev = &pdev->dev;
1052*41d32cfcSBaolin Wang 	platform_set_drvdata(pdev, sprd_pctl);
1053*41d32cfcSBaolin Wang 
1054*41d32cfcSBaolin Wang 	ret = sprd_pinctrl_add_pins(sprd_pctl, sprd_soc_pin_info, pins_cnt);
1055*41d32cfcSBaolin Wang 	if (ret) {
1056*41d32cfcSBaolin Wang 		dev_err(&pdev->dev, "fail to add pins information\n");
1057*41d32cfcSBaolin Wang 		return ret;
1058*41d32cfcSBaolin Wang 	}
1059*41d32cfcSBaolin Wang 
1060*41d32cfcSBaolin Wang 	pin_desc = devm_kzalloc(&pdev->dev, pinctrl_info->npins *
1061*41d32cfcSBaolin Wang 				sizeof(struct pinctrl_pin_desc),
1062*41d32cfcSBaolin Wang 				GFP_KERNEL);
1063*41d32cfcSBaolin Wang 	if (!pin_desc)
1064*41d32cfcSBaolin Wang 		return -ENOMEM;
1065*41d32cfcSBaolin Wang 
1066*41d32cfcSBaolin Wang 	for (i = 0; i < pinctrl_info->npins; i++) {
1067*41d32cfcSBaolin Wang 		pin_desc[i].number = pinctrl_info->pins[i].number;
1068*41d32cfcSBaolin Wang 		pin_desc[i].name = pinctrl_info->pins[i].name;
1069*41d32cfcSBaolin Wang 		pin_desc[i].drv_data = pinctrl_info;
1070*41d32cfcSBaolin Wang 	}
1071*41d32cfcSBaolin Wang 
1072*41d32cfcSBaolin Wang 	sprd_pinctrl_desc.pins = pin_desc;
1073*41d32cfcSBaolin Wang 	sprd_pinctrl_desc.name = dev_name(&pdev->dev);
1074*41d32cfcSBaolin Wang 	sprd_pinctrl_desc.npins = pinctrl_info->npins;
1075*41d32cfcSBaolin Wang 
1076*41d32cfcSBaolin Wang 	sprd_pctl->pctl = pinctrl_register(&sprd_pinctrl_desc,
1077*41d32cfcSBaolin Wang 					   &pdev->dev, (void *)sprd_pctl);
1078*41d32cfcSBaolin Wang 	if (IS_ERR(sprd_pctl->pctl)) {
1079*41d32cfcSBaolin Wang 		dev_err(&pdev->dev, "could not register pinctrl driver\n");
1080*41d32cfcSBaolin Wang 		return PTR_ERR(sprd_pctl->pctl);
1081*41d32cfcSBaolin Wang 	}
1082*41d32cfcSBaolin Wang 
1083*41d32cfcSBaolin Wang 	ret = sprd_pinctrl_parse_dt(sprd_pctl);
1084*41d32cfcSBaolin Wang 	if (ret) {
1085*41d32cfcSBaolin Wang 		dev_err(&pdev->dev, "fail to parse dt properties\n");
1086*41d32cfcSBaolin Wang 		pinctrl_unregister(sprd_pctl->pctl);
1087*41d32cfcSBaolin Wang 		return ret;
1088*41d32cfcSBaolin Wang 	}
1089*41d32cfcSBaolin Wang 
1090*41d32cfcSBaolin Wang 	return 0;
1091*41d32cfcSBaolin Wang }
1092*41d32cfcSBaolin Wang 
1093*41d32cfcSBaolin Wang int sprd_pinctrl_remove(struct platform_device *pdev)
1094*41d32cfcSBaolin Wang {
1095*41d32cfcSBaolin Wang 	struct sprd_pinctrl *sprd_pctl = platform_get_drvdata(pdev);
1096*41d32cfcSBaolin Wang 
1097*41d32cfcSBaolin Wang 	pinctrl_unregister(sprd_pctl->pctl);
1098*41d32cfcSBaolin Wang 	return 0;
1099*41d32cfcSBaolin Wang }
1100*41d32cfcSBaolin Wang 
1101*41d32cfcSBaolin Wang void sprd_pinctrl_shutdown(struct platform_device *pdev)
1102*41d32cfcSBaolin Wang {
1103*41d32cfcSBaolin Wang 	struct pinctrl *pinctl = devm_pinctrl_get(&pdev->dev);
1104*41d32cfcSBaolin Wang 	struct pinctrl_state *state;
1105*41d32cfcSBaolin Wang 
1106*41d32cfcSBaolin Wang 	state = pinctrl_lookup_state(pinctl, "shutdown");
1107*41d32cfcSBaolin Wang 	if (!IS_ERR(state))
1108*41d32cfcSBaolin Wang 		pinctrl_select_state(pinctl, state);
1109*41d32cfcSBaolin Wang }
1110*41d32cfcSBaolin Wang 
1111*41d32cfcSBaolin Wang MODULE_DESCRIPTION("SPREADTRUM Pin Controller Driver");
1112*41d32cfcSBaolin Wang MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>");
1113*41d32cfcSBaolin Wang MODULE_LICENSE("GPL v2");
1114