xref: /linux/drivers/pinctrl/pinctrl-k230.c (revision 2d32fba02e0e5b67fb3a4ea51dde80c0db83f1c1)
1545887eaSZe Huang // SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2545887eaSZe Huang /*
3545887eaSZe Huang  * Copyright (C) 2024 Canaan Bright Sight Co. Ltd
4545887eaSZe Huang  * Copyright (C) 2024 Ze Huang <18771902331@163.com>
5545887eaSZe Huang  */
6545887eaSZe Huang #include <linux/module.h>
7545887eaSZe Huang #include <linux/device.h>
8545887eaSZe Huang #include <linux/of.h>
9545887eaSZe Huang #include <linux/of_address.h>
10545887eaSZe Huang #include <linux/of_device.h>
11545887eaSZe Huang #include <linux/platform_device.h>
12545887eaSZe Huang #include <linux/pinctrl/pinctrl.h>
13545887eaSZe Huang #include <linux/pinctrl/pinmux.h>
14545887eaSZe Huang #include <linux/pinctrl/pinconf.h>
15545887eaSZe Huang #include <linux/pinctrl/pinconf-generic.h>
16545887eaSZe Huang #include <linux/regmap.h>
17545887eaSZe Huang #include <linux/seq_file.h>
18545887eaSZe Huang 
19545887eaSZe Huang #include "core.h"
20545887eaSZe Huang #include "pinconf.h"
21545887eaSZe Huang 
22545887eaSZe Huang #define K230_NPINS 64
23545887eaSZe Huang 
24545887eaSZe Huang #define K230_SHIFT_ST		(0)
25545887eaSZe Huang #define K230_SHIFT_DS		(1)
26545887eaSZe Huang #define K230_SHIFT_BIAS		(5)
27545887eaSZe Huang #define K230_SHIFT_PD		(5)
28545887eaSZe Huang #define K230_SHIFT_PU		(6)
29545887eaSZe Huang #define K230_SHIFT_OE		(7)
30545887eaSZe Huang #define K230_SHIFT_IE		(8)
31545887eaSZe Huang #define K230_SHIFT_MSC		(9)
32545887eaSZe Huang #define K230_SHIFT_SL		(10)
33545887eaSZe Huang #define K230_SHIFT_SEL		(11)
34545887eaSZe Huang 
35545887eaSZe Huang #define K230_PC_ST		BIT(0)
36545887eaSZe Huang #define K230_PC_DS		GENMASK(4, 1)
37545887eaSZe Huang #define K230_PC_PD		BIT(5)
38545887eaSZe Huang #define K230_PC_PU		BIT(6)
39545887eaSZe Huang #define K230_PC_BIAS		GENMASK(6, 5)
40545887eaSZe Huang #define K230_PC_OE		BIT(7)
41545887eaSZe Huang #define K230_PC_IE		BIT(8)
42545887eaSZe Huang #define K230_PC_MSC		BIT(9)
43545887eaSZe Huang #define K230_PC_SL		BIT(10)
44545887eaSZe Huang #define K230_PC_SEL		GENMASK(13, 11)
45545887eaSZe Huang 
46545887eaSZe Huang struct k230_pin_conf {
47545887eaSZe Huang 	unsigned int		func;
48545887eaSZe Huang 	unsigned long		*configs;
49545887eaSZe Huang 	unsigned int		nconfigs;
50545887eaSZe Huang };
51545887eaSZe Huang 
52545887eaSZe Huang struct k230_pin_group {
53545887eaSZe Huang 	const char		*name;
54545887eaSZe Huang 	unsigned int		*pins;
55545887eaSZe Huang 	unsigned int		num_pins;
56545887eaSZe Huang 
57545887eaSZe Huang 	struct k230_pin_conf	*data;
58545887eaSZe Huang };
59545887eaSZe Huang 
60545887eaSZe Huang struct k230_pmx_func {
61545887eaSZe Huang 	const char		*name;
62545887eaSZe Huang 	const char		**groups;
63545887eaSZe Huang 	unsigned int		*group_idx;
64545887eaSZe Huang 	unsigned int		ngroups;
65545887eaSZe Huang };
66545887eaSZe Huang 
67545887eaSZe Huang struct k230_pinctrl {
68545887eaSZe Huang 	struct pinctrl_desc	pctl;
69545887eaSZe Huang 	struct pinctrl_dev	*pctl_dev;
70545887eaSZe Huang 	struct regmap		*regmap_base;
71545887eaSZe Huang 	void __iomem		*base;
72545887eaSZe Huang 	struct k230_pin_group	*groups;
73545887eaSZe Huang 	unsigned int		ngroups;
74545887eaSZe Huang 	struct k230_pmx_func	*functions;
75545887eaSZe Huang 	unsigned int		nfunctions;
76545887eaSZe Huang };
77545887eaSZe Huang 
78545887eaSZe Huang static const struct regmap_config k230_regmap_config = {
79545887eaSZe Huang 	.name		= "canaan,pinctrl",
80545887eaSZe Huang 	.reg_bits	= 32,
81545887eaSZe Huang 	.val_bits	= 32,
82545887eaSZe Huang 	.max_register	= 0x100,
83545887eaSZe Huang 	.reg_stride	= 4,
84545887eaSZe Huang };
85545887eaSZe Huang 
k230_get_groups_count(struct pinctrl_dev * pctldev)86545887eaSZe Huang static int k230_get_groups_count(struct pinctrl_dev *pctldev)
87545887eaSZe Huang {
88545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
89545887eaSZe Huang 
90545887eaSZe Huang 	return info->ngroups;
91545887eaSZe Huang }
92545887eaSZe Huang 
k230_get_group_name(struct pinctrl_dev * pctldev,unsigned int selector)93545887eaSZe Huang static const char *k230_get_group_name(struct pinctrl_dev *pctldev,
94545887eaSZe Huang 				       unsigned int selector)
95545887eaSZe Huang {
96545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
97545887eaSZe Huang 
98545887eaSZe Huang 	return info->groups[selector].name;
99545887eaSZe Huang }
100545887eaSZe Huang 
k230_get_group_pins(struct pinctrl_dev * pctldev,unsigned int selector,const unsigned int ** pins,unsigned int * num_pins)101545887eaSZe Huang static int k230_get_group_pins(struct pinctrl_dev *pctldev,
102545887eaSZe Huang 			       unsigned int selector,
103545887eaSZe Huang 			       const unsigned int **pins,
104545887eaSZe Huang 			       unsigned int *num_pins)
105545887eaSZe Huang {
106545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
107545887eaSZe Huang 
108545887eaSZe Huang 	if (selector >= info->ngroups)
109545887eaSZe Huang 		return -EINVAL;
110545887eaSZe Huang 
111545887eaSZe Huang 	*pins = info->groups[selector].pins;
112545887eaSZe Huang 	*num_pins = info->groups[selector].num_pins;
113545887eaSZe Huang 
114545887eaSZe Huang 	return 0;
115545887eaSZe Huang }
116545887eaSZe Huang 
k230_name_to_funtion(const struct k230_pinctrl * info,const char * name)117545887eaSZe Huang static inline const struct k230_pmx_func *k230_name_to_funtion(
118545887eaSZe Huang 		const struct k230_pinctrl *info, const char *name)
119545887eaSZe Huang {
120545887eaSZe Huang 	unsigned int i;
121545887eaSZe Huang 
122545887eaSZe Huang 	for (i = 0; i < info->nfunctions; i++) {
123545887eaSZe Huang 		if (!strcmp(info->functions[i].name, name))
124545887eaSZe Huang 			return &info->functions[i];
125545887eaSZe Huang 	}
126545887eaSZe Huang 
127545887eaSZe Huang 	return NULL;
128545887eaSZe Huang }
129545887eaSZe Huang 
130545887eaSZe Huang static struct pinctrl_pin_desc k230_pins[] = {
131545887eaSZe Huang 	PINCTRL_PIN(0,  "IO0"),  PINCTRL_PIN(1,  "IO1"),  PINCTRL_PIN(2,  "IO2"),
132545887eaSZe Huang 	PINCTRL_PIN(3,  "IO3"),  PINCTRL_PIN(4,  "IO4"),  PINCTRL_PIN(5,  "IO5"),
133545887eaSZe Huang 	PINCTRL_PIN(6,  "IO6"),  PINCTRL_PIN(7,  "IO7"),  PINCTRL_PIN(8,  "IO8"),
134545887eaSZe Huang 	PINCTRL_PIN(9,  "IO9"),  PINCTRL_PIN(10, "IO10"), PINCTRL_PIN(11, "IO11"),
135545887eaSZe Huang 	PINCTRL_PIN(12, "IO12"), PINCTRL_PIN(13, "IO13"), PINCTRL_PIN(14, "IO14"),
136545887eaSZe Huang 	PINCTRL_PIN(15, "IO15"), PINCTRL_PIN(16, "IO16"), PINCTRL_PIN(17, "IO17"),
137545887eaSZe Huang 	PINCTRL_PIN(18, "IO18"), PINCTRL_PIN(19, "IO19"), PINCTRL_PIN(20, "IO20"),
138545887eaSZe Huang 	PINCTRL_PIN(21, "IO21"), PINCTRL_PIN(22, "IO22"), PINCTRL_PIN(23, "IO23"),
139545887eaSZe Huang 	PINCTRL_PIN(24, "IO24"), PINCTRL_PIN(25, "IO25"), PINCTRL_PIN(26, "IO26"),
140545887eaSZe Huang 	PINCTRL_PIN(27, "IO27"), PINCTRL_PIN(28, "IO28"), PINCTRL_PIN(29, "IO29"),
141545887eaSZe Huang 	PINCTRL_PIN(30, "IO30"), PINCTRL_PIN(31, "IO31"), PINCTRL_PIN(32, "IO32"),
142545887eaSZe Huang 	PINCTRL_PIN(33, "IO33"), PINCTRL_PIN(34, "IO34"), PINCTRL_PIN(35, "IO35"),
143545887eaSZe Huang 	PINCTRL_PIN(36, "IO36"), PINCTRL_PIN(37, "IO37"), PINCTRL_PIN(38, "IO38"),
144545887eaSZe Huang 	PINCTRL_PIN(39, "IO39"), PINCTRL_PIN(40, "IO40"), PINCTRL_PIN(41, "IO41"),
145545887eaSZe Huang 	PINCTRL_PIN(42, "IO42"), PINCTRL_PIN(43, "IO43"), PINCTRL_PIN(44, "IO44"),
146545887eaSZe Huang 	PINCTRL_PIN(45, "IO45"), PINCTRL_PIN(46, "IO46"), PINCTRL_PIN(47, "IO47"),
147545887eaSZe Huang 	PINCTRL_PIN(48, "IO48"), PINCTRL_PIN(49, "IO49"), PINCTRL_PIN(50, "IO50"),
148545887eaSZe Huang 	PINCTRL_PIN(51, "IO51"), PINCTRL_PIN(52, "IO52"), PINCTRL_PIN(53, "IO53"),
149545887eaSZe Huang 	PINCTRL_PIN(54, "IO54"), PINCTRL_PIN(55, "IO55"), PINCTRL_PIN(56, "IO56"),
150545887eaSZe Huang 	PINCTRL_PIN(57, "IO57"), PINCTRL_PIN(58, "IO58"), PINCTRL_PIN(59, "IO59"),
151545887eaSZe Huang 	PINCTRL_PIN(60, "IO60"), PINCTRL_PIN(61, "IO61"), PINCTRL_PIN(62, "IO62"),
152545887eaSZe Huang 	PINCTRL_PIN(63, "IO63")
153545887eaSZe Huang };
154545887eaSZe Huang 
k230_pinctrl_pin_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int offset)155545887eaSZe Huang static void k230_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
156545887eaSZe Huang 				      struct seq_file *s, unsigned int offset)
157545887eaSZe Huang {
158545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
159*26948688SLinus Walleij 	u32 val, bias, drive, input, slew, schmitt, power;
160545887eaSZe Huang 	struct k230_pin_group *grp = k230_pins[offset].drv_data;
161545887eaSZe Huang 	static const char * const biasing[] = {
162545887eaSZe Huang 			"pull none", "pull down", "pull up", "" };
163545887eaSZe Huang 	static const char * const enable[] = {
164545887eaSZe Huang 			"disable", "enable" };
165545887eaSZe Huang 	static const char * const power_source[] = {
166545887eaSZe Huang 			"3V3", "1V8" };
167545887eaSZe Huang 
168545887eaSZe Huang 	regmap_read(info->regmap_base, offset * 4, &val);
169545887eaSZe Huang 
170545887eaSZe Huang 	drive	= (val & K230_PC_DS) >> K230_SHIFT_DS;
171545887eaSZe Huang 	bias	= (val & K230_PC_BIAS) >> K230_SHIFT_BIAS;
172545887eaSZe Huang 	input	= (val & K230_PC_IE) >> K230_SHIFT_IE;
173545887eaSZe Huang 	slew	= (val & K230_PC_SL) >> K230_SHIFT_SL;
174545887eaSZe Huang 	schmitt	= (val & K230_PC_ST) >> K230_SHIFT_ST;
175545887eaSZe Huang 	power	= (val & K230_PC_MSC) >> K230_SHIFT_MSC;
176545887eaSZe Huang 
177545887eaSZe Huang 	seq_printf(s, "%s - strength %d - %s - %s - slewrate %s - schmitt %s - %s",
178545887eaSZe Huang 		   grp ? grp->name : "unknown",
179545887eaSZe Huang 		   drive,
180545887eaSZe Huang 		   biasing[bias],
181545887eaSZe Huang 		   input ? "input" : "output",
182545887eaSZe Huang 		   enable[slew],
183545887eaSZe Huang 		   enable[schmitt],
184545887eaSZe Huang 		   power_source[power]);
185545887eaSZe Huang }
186545887eaSZe Huang 
k230_dt_node_to_map(struct pinctrl_dev * pctldev,struct device_node * np_config,struct pinctrl_map ** map,unsigned int * num_maps)187545887eaSZe Huang static int k230_dt_node_to_map(struct pinctrl_dev *pctldev,
188545887eaSZe Huang 			       struct device_node *np_config,
189545887eaSZe Huang 			       struct pinctrl_map **map,
190545887eaSZe Huang 			       unsigned int *num_maps)
191545887eaSZe Huang {
192545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
193545887eaSZe Huang 	struct device *dev = info->pctl_dev->dev;
194545887eaSZe Huang 	const struct k230_pmx_func *func;
195545887eaSZe Huang 	const struct k230_pin_group *grp;
196545887eaSZe Huang 	struct pinctrl_map *new_map;
197545887eaSZe Huang 	int map_num, i, j, idx;
198545887eaSZe Huang 	unsigned int grp_id;
199545887eaSZe Huang 
200545887eaSZe Huang 	func = k230_name_to_funtion(info, np_config->name);
201545887eaSZe Huang 	if (!func) {
202545887eaSZe Huang 		dev_err(dev, "function %s not found\n", np_config->name);
203545887eaSZe Huang 		return -EINVAL;
204545887eaSZe Huang 	}
205545887eaSZe Huang 
206545887eaSZe Huang 	map_num = 0;
207545887eaSZe Huang 	for (i = 0; i < func->ngroups; ++i) {
208545887eaSZe Huang 		grp_id = func->group_idx[i];
209545887eaSZe Huang 		/* npins of config map plus a mux map */
210545887eaSZe Huang 		map_num += info->groups[grp_id].num_pins + 1;
211545887eaSZe Huang 	}
212545887eaSZe Huang 
213545887eaSZe Huang 	new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL);
214545887eaSZe Huang 	if (!new_map)
215545887eaSZe Huang 		return -ENOMEM;
216545887eaSZe Huang 	*map = new_map;
217545887eaSZe Huang 	*num_maps = map_num;
218545887eaSZe Huang 
219545887eaSZe Huang 	idx = 0;
220545887eaSZe Huang 	for (i = 0; i < func->ngroups; ++i) {
221545887eaSZe Huang 		grp_id = func->group_idx[i];
222545887eaSZe Huang 		grp = &info->groups[grp_id];
223545887eaSZe Huang 		new_map[idx].type = PIN_MAP_TYPE_MUX_GROUP;
224545887eaSZe Huang 		new_map[idx].data.mux.group = grp->name;
225545887eaSZe Huang 		new_map[idx].data.mux.function = np_config->name;
226545887eaSZe Huang 		idx++;
227545887eaSZe Huang 
228545887eaSZe Huang 		for (j = 0; j < grp->num_pins; ++j) {
229545887eaSZe Huang 			new_map[idx].type = PIN_MAP_TYPE_CONFIGS_PIN;
230545887eaSZe Huang 			new_map[idx].data.configs.group_or_pin =
231545887eaSZe Huang 				pin_get_name(pctldev, grp->pins[j]);
232545887eaSZe Huang 			new_map[idx].data.configs.configs =
233545887eaSZe Huang 				grp->data[j].configs;
234545887eaSZe Huang 			new_map[idx].data.configs.num_configs =
235545887eaSZe Huang 				grp->data[j].nconfigs;
236545887eaSZe Huang 			idx++;
237545887eaSZe Huang 		}
238545887eaSZe Huang 	}
239545887eaSZe Huang 
240545887eaSZe Huang 	return 0;
241545887eaSZe Huang }
242545887eaSZe Huang 
k230_dt_free_map(struct pinctrl_dev * pctldev,struct pinctrl_map * map,unsigned int num_maps)243545887eaSZe Huang static void k230_dt_free_map(struct pinctrl_dev *pctldev,
244545887eaSZe Huang 			     struct pinctrl_map *map, unsigned int num_maps)
245545887eaSZe Huang {
246545887eaSZe Huang 	kfree(map);
247545887eaSZe Huang }
248545887eaSZe Huang 
249545887eaSZe Huang static const struct pinctrl_ops k230_pctrl_ops = {
250545887eaSZe Huang 	.get_groups_count	= k230_get_groups_count,
251545887eaSZe Huang 	.get_group_name		= k230_get_group_name,
252545887eaSZe Huang 	.get_group_pins		= k230_get_group_pins,
253545887eaSZe Huang 	.pin_dbg_show		= k230_pinctrl_pin_dbg_show,
254545887eaSZe Huang 	.dt_node_to_map		= k230_dt_node_to_map,
255545887eaSZe Huang 	.dt_free_map		= k230_dt_free_map,
256545887eaSZe Huang };
257545887eaSZe Huang 
k230_pinconf_get(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * config)258545887eaSZe Huang static int k230_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
259545887eaSZe Huang 			    unsigned long *config)
260545887eaSZe Huang {
261545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
262545887eaSZe Huang 	enum pin_config_param param = pinconf_to_config_param(*config);
263545887eaSZe Huang 	unsigned int val, arg;
264545887eaSZe Huang 
265545887eaSZe Huang 	regmap_read(info->regmap_base, pin * 4, &val);
266545887eaSZe Huang 
267545887eaSZe Huang 	switch (param) {
268545887eaSZe Huang 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
269545887eaSZe Huang 		arg = (val & K230_PC_ST) ? 1 : 0;
270545887eaSZe Huang 		break;
271545887eaSZe Huang 	case PIN_CONFIG_DRIVE_STRENGTH:
272545887eaSZe Huang 		arg = (val & K230_PC_DS) >> K230_SHIFT_DS;
273545887eaSZe Huang 		break;
274545887eaSZe Huang 	case PIN_CONFIG_BIAS_DISABLE:
275545887eaSZe Huang 		arg = (val & K230_PC_BIAS) ? 0 : 1;
276545887eaSZe Huang 		break;
277545887eaSZe Huang 	case PIN_CONFIG_BIAS_PULL_DOWN:
278545887eaSZe Huang 		arg = (val & K230_PC_PD) ? 1 : 0;
279545887eaSZe Huang 		break;
280545887eaSZe Huang 	case PIN_CONFIG_BIAS_PULL_UP:
281545887eaSZe Huang 		arg = (val & K230_PC_PU) ? 1 : 0;
282545887eaSZe Huang 		break;
283545887eaSZe Huang 	case PIN_CONFIG_OUTPUT_ENABLE:
284545887eaSZe Huang 		arg = (val & K230_PC_OE) ? 1 : 0;
285545887eaSZe Huang 		break;
286545887eaSZe Huang 	case PIN_CONFIG_INPUT_ENABLE:
287545887eaSZe Huang 		arg = (val & K230_PC_IE) ? 1 : 0;
288545887eaSZe Huang 		break;
289545887eaSZe Huang 	case PIN_CONFIG_POWER_SOURCE:
290545887eaSZe Huang 		arg = (val & K230_PC_MSC) ? 1 : 0;
291545887eaSZe Huang 		break;
292545887eaSZe Huang 	case PIN_CONFIG_SLEW_RATE:
293545887eaSZe Huang 		arg = (val & K230_PC_SL) ? 1 : 0;
294545887eaSZe Huang 		break;
295545887eaSZe Huang 	default:
296545887eaSZe Huang 		return -EINVAL;
297545887eaSZe Huang 	}
298545887eaSZe Huang 
299545887eaSZe Huang 	*config = pinconf_to_config_packed(param, arg);
300545887eaSZe Huang 
301545887eaSZe Huang 	return 0;
302545887eaSZe Huang }
303545887eaSZe Huang 
k230_pinconf_set_param(struct pinctrl_dev * pctldev,unsigned int pin,enum pin_config_param param,unsigned int arg)304545887eaSZe Huang static int k230_pinconf_set_param(struct pinctrl_dev *pctldev, unsigned int pin,
305545887eaSZe Huang 				  enum pin_config_param param, unsigned int arg)
306545887eaSZe Huang {
307545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
308545887eaSZe Huang 	unsigned int val;
309545887eaSZe Huang 
310545887eaSZe Huang 	regmap_read(info->regmap_base, pin * 4, &val);
311545887eaSZe Huang 
312545887eaSZe Huang 	switch (param) {
313545887eaSZe Huang 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
314545887eaSZe Huang 		if (arg)
315545887eaSZe Huang 			val |= K230_PC_ST;
316545887eaSZe Huang 		else
317545887eaSZe Huang 			val &= ~K230_PC_ST;
318545887eaSZe Huang 		break;
319545887eaSZe Huang 	case PIN_CONFIG_DRIVE_STRENGTH:
320545887eaSZe Huang 		val &= ~K230_PC_DS;
321545887eaSZe Huang 		val |= (arg << K230_SHIFT_DS) & K230_PC_DS;
322545887eaSZe Huang 		break;
323545887eaSZe Huang 	case PIN_CONFIG_BIAS_DISABLE:
324545887eaSZe Huang 		val &= ~K230_PC_BIAS;
325545887eaSZe Huang 		break;
326545887eaSZe Huang 	case PIN_CONFIG_BIAS_PULL_DOWN:
327545887eaSZe Huang 		if (!arg)
328545887eaSZe Huang 			return -EINVAL;
329545887eaSZe Huang 		val |= K230_PC_PD;
330545887eaSZe Huang 		break;
331545887eaSZe Huang 	case PIN_CONFIG_BIAS_PULL_UP:
332545887eaSZe Huang 		if (!arg)
333545887eaSZe Huang 			return -EINVAL;
334545887eaSZe Huang 		val |= K230_PC_PU;
335545887eaSZe Huang 		break;
336545887eaSZe Huang 	case PIN_CONFIG_OUTPUT_ENABLE:
337545887eaSZe Huang 		if (!arg)
338545887eaSZe Huang 			return -EINVAL;
339545887eaSZe Huang 		val |= K230_PC_OE;
340545887eaSZe Huang 		break;
341545887eaSZe Huang 	case PIN_CONFIG_INPUT_ENABLE:
342545887eaSZe Huang 		if (!arg)
343545887eaSZe Huang 			return -EINVAL;
344545887eaSZe Huang 		val |= K230_PC_IE;
345545887eaSZe Huang 		break;
346545887eaSZe Huang 	case PIN_CONFIG_POWER_SOURCE:
347545887eaSZe Huang 		if (arg)
348545887eaSZe Huang 			val |= K230_PC_MSC;
349545887eaSZe Huang 		else
350545887eaSZe Huang 			val &= ~K230_PC_MSC;
351545887eaSZe Huang 		break;
352545887eaSZe Huang 	case PIN_CONFIG_SLEW_RATE:
353545887eaSZe Huang 		if (arg)
354545887eaSZe Huang 			val |= K230_PC_SL;
355545887eaSZe Huang 		else
356545887eaSZe Huang 			val &= ~K230_PC_SL;
357545887eaSZe Huang 		break;
358545887eaSZe Huang 	default:
359545887eaSZe Huang 		return -EINVAL;
360545887eaSZe Huang 	}
361545887eaSZe Huang 
362545887eaSZe Huang 	regmap_write(info->regmap_base, pin * 4, val);
363545887eaSZe Huang 
364545887eaSZe Huang 	return 0;
365545887eaSZe Huang }
366545887eaSZe Huang 
k230_pinconf_set(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * configs,unsigned int num_configs)367545887eaSZe Huang static int k230_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
368545887eaSZe Huang 			    unsigned long *configs, unsigned int num_configs)
369545887eaSZe Huang {
370545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
371545887eaSZe Huang 	struct device *dev = info->pctl_dev->dev;
372545887eaSZe Huang 	enum pin_config_param param;
373545887eaSZe Huang 	unsigned int arg, i;
374545887eaSZe Huang 	int ret;
375545887eaSZe Huang 
376545887eaSZe Huang 	if (pin >= K230_NPINS) {
377545887eaSZe Huang 		dev_err(dev, "pin number out of range\n");
378545887eaSZe Huang 		return -EINVAL;
379545887eaSZe Huang 	}
380545887eaSZe Huang 
381545887eaSZe Huang 	for (i = 0; i < num_configs; i++) {
382545887eaSZe Huang 		param = pinconf_to_config_param(configs[i]);
383545887eaSZe Huang 		arg = pinconf_to_config_argument(configs[i]);
384545887eaSZe Huang 		ret = k230_pinconf_set_param(pctldev, pin, param, arg);
385545887eaSZe Huang 		if (ret)
386545887eaSZe Huang 			return ret;
387545887eaSZe Huang 	}
388545887eaSZe Huang 
389545887eaSZe Huang 	return 0;
390545887eaSZe Huang }
391545887eaSZe Huang 
k230_pconf_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int pin)392545887eaSZe Huang static void k230_pconf_dbg_show(struct pinctrl_dev *pctldev,
393545887eaSZe Huang 				struct seq_file *s, unsigned int pin)
394545887eaSZe Huang {
395545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
396545887eaSZe Huang 	unsigned int val;
397545887eaSZe Huang 
398545887eaSZe Huang 	regmap_read(info->regmap_base, pin * 4, &val);
399545887eaSZe Huang 
400545887eaSZe Huang 	seq_printf(s, " 0x%08x", val);
401545887eaSZe Huang }
402545887eaSZe Huang 
403545887eaSZe Huang static const struct pinconf_ops k230_pinconf_ops = {
404545887eaSZe Huang 	.is_generic		= true,
405545887eaSZe Huang 	.pin_config_get		= k230_pinconf_get,
406545887eaSZe Huang 	.pin_config_set		= k230_pinconf_set,
407545887eaSZe Huang 	.pin_config_dbg_show	= k230_pconf_dbg_show,
408545887eaSZe Huang };
409545887eaSZe Huang 
k230_get_functions_count(struct pinctrl_dev * pctldev)410545887eaSZe Huang static int k230_get_functions_count(struct pinctrl_dev *pctldev)
411545887eaSZe Huang {
412545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
413545887eaSZe Huang 
414545887eaSZe Huang 	return info->nfunctions;
415545887eaSZe Huang }
416545887eaSZe Huang 
k230_get_fname(struct pinctrl_dev * pctldev,unsigned int selector)417545887eaSZe Huang static const char *k230_get_fname(struct pinctrl_dev *pctldev,
418545887eaSZe Huang 				  unsigned int selector)
419545887eaSZe Huang {
420545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
421545887eaSZe Huang 
422545887eaSZe Huang 	return info->functions[selector].name;
423545887eaSZe Huang }
424545887eaSZe Huang 
k230_get_groups(struct pinctrl_dev * pctldev,unsigned int selector,const char * const ** groups,unsigned int * num_groups)425545887eaSZe Huang static int k230_get_groups(struct pinctrl_dev *pctldev, unsigned int selector,
426545887eaSZe Huang 			   const char * const **groups, unsigned int *num_groups)
427545887eaSZe Huang {
428545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
429545887eaSZe Huang 
430545887eaSZe Huang 	*groups = info->functions[selector].groups;
431545887eaSZe Huang 	*num_groups = info->functions[selector].ngroups;
432545887eaSZe Huang 
433545887eaSZe Huang 	return 0;
434545887eaSZe Huang }
435545887eaSZe Huang 
k230_set_mux(struct pinctrl_dev * pctldev,unsigned int selector,unsigned int group)436545887eaSZe Huang static int k230_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
437545887eaSZe Huang 			unsigned int group)
438545887eaSZe Huang {
439545887eaSZe Huang 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
440545887eaSZe Huang 	const struct k230_pin_conf *data = info->groups[group].data;
441545887eaSZe Huang 	struct k230_pin_group *grp = &info->groups[group];
442545887eaSZe Huang 	const unsigned int *pins = grp->pins;
443545887eaSZe Huang 	struct regmap *regmap;
444545887eaSZe Huang 	unsigned int value, mask;
445545887eaSZe Huang 	int cnt, reg;
446545887eaSZe Huang 
447545887eaSZe Huang 	regmap = info->regmap_base;
448545887eaSZe Huang 
449545887eaSZe Huang 	for (cnt = 0; cnt < grp->num_pins; cnt++) {
450545887eaSZe Huang 		reg = pins[cnt] * 4;
451545887eaSZe Huang 		value = data[cnt].func << K230_SHIFT_SEL;
452545887eaSZe Huang 		mask = K230_PC_SEL;
453545887eaSZe Huang 		regmap_update_bits(regmap, reg, mask, value);
454545887eaSZe Huang 		k230_pins[pins[cnt]].drv_data = grp;
455545887eaSZe Huang 	}
456545887eaSZe Huang 
457545887eaSZe Huang 	return 0;
458545887eaSZe Huang }
459545887eaSZe Huang 
460545887eaSZe Huang static const struct pinmux_ops k230_pmxops = {
461545887eaSZe Huang 	.get_functions_count	= k230_get_functions_count,
462545887eaSZe Huang 	.get_function_name	= k230_get_fname,
463545887eaSZe Huang 	.get_function_groups	= k230_get_groups,
464545887eaSZe Huang 	.set_mux		= k230_set_mux,
465545887eaSZe Huang 	.strict			= true,
466545887eaSZe Huang };
467545887eaSZe Huang 
k230_pinctrl_parse_groups(struct device_node * np,struct k230_pin_group * grp,struct k230_pinctrl * info,unsigned int index)468545887eaSZe Huang static int k230_pinctrl_parse_groups(struct device_node *np,
469545887eaSZe Huang 				     struct k230_pin_group *grp,
470545887eaSZe Huang 				     struct k230_pinctrl *info,
471545887eaSZe Huang 				     unsigned int index)
472545887eaSZe Huang {
473545887eaSZe Huang 	struct device *dev = info->pctl_dev->dev;
474545887eaSZe Huang 	const __be32 *list;
475545887eaSZe Huang 	int size, i, ret;
476545887eaSZe Huang 
477545887eaSZe Huang 	grp->name = np->name;
478545887eaSZe Huang 
479545887eaSZe Huang 	list = of_get_property(np, "pinmux", &size);
480545887eaSZe Huang 	size /= sizeof(*list);
481545887eaSZe Huang 
482545887eaSZe Huang 	grp->num_pins = size;
483545887eaSZe Huang 	grp->pins = devm_kcalloc(dev, grp->num_pins, sizeof(*grp->pins),
484545887eaSZe Huang 				 GFP_KERNEL);
485545887eaSZe Huang 	grp->data = devm_kcalloc(dev, grp->num_pins, sizeof(*grp->data),
486545887eaSZe Huang 				 GFP_KERNEL);
487545887eaSZe Huang 	if (!grp->pins || !grp->data)
488545887eaSZe Huang 		return -ENOMEM;
489545887eaSZe Huang 
490545887eaSZe Huang 	for (i = 0; i < size; i++) {
491545887eaSZe Huang 		unsigned int mux_data = be32_to_cpu(*list++);
492545887eaSZe Huang 
493545887eaSZe Huang 		grp->pins[i] = (mux_data >> 8);
494545887eaSZe Huang 		grp->data[i].func = (mux_data & 0xff);
495545887eaSZe Huang 
496545887eaSZe Huang 		ret = pinconf_generic_parse_dt_config(np, NULL,
497545887eaSZe Huang 						      &grp->data[i].configs,
498545887eaSZe Huang 						      &grp->data[i].nconfigs);
499545887eaSZe Huang 		if (ret)
500545887eaSZe Huang 			return ret;
501545887eaSZe Huang 	}
502545887eaSZe Huang 
503545887eaSZe Huang 	return 0;
504545887eaSZe Huang }
505545887eaSZe Huang 
k230_pinctrl_parse_functions(struct device_node * np,struct k230_pinctrl * info,unsigned int index)506545887eaSZe Huang static int k230_pinctrl_parse_functions(struct device_node *np,
507545887eaSZe Huang 					struct k230_pinctrl *info,
508545887eaSZe Huang 					unsigned int index)
509545887eaSZe Huang {
510545887eaSZe Huang 	struct device *dev = info->pctl_dev->dev;
511545887eaSZe Huang 	struct k230_pmx_func *func;
512545887eaSZe Huang 	struct k230_pin_group *grp;
513545887eaSZe Huang 	static unsigned int idx, i;
514545887eaSZe Huang 	int ret;
515545887eaSZe Huang 
516545887eaSZe Huang 	func = &info->functions[index];
517545887eaSZe Huang 
518545887eaSZe Huang 	func->name = np->name;
519545887eaSZe Huang 	func->ngroups = of_get_child_count(np);
520545887eaSZe Huang 	if (func->ngroups <= 0)
521545887eaSZe Huang 		return 0;
522545887eaSZe Huang 
523545887eaSZe Huang 	func->groups = devm_kcalloc(dev, func->ngroups,
524545887eaSZe Huang 				    sizeof(*func->groups), GFP_KERNEL);
525545887eaSZe Huang 	func->group_idx = devm_kcalloc(dev, func->ngroups,
526545887eaSZe Huang 				       sizeof(*func->group_idx), GFP_KERNEL);
527545887eaSZe Huang 	if (!func->groups || !func->group_idx)
528545887eaSZe Huang 		return -ENOMEM;
529545887eaSZe Huang 
530545887eaSZe Huang 	i = 0;
531545887eaSZe Huang 
532545887eaSZe Huang 	for_each_child_of_node_scoped(np, child) {
533545887eaSZe Huang 		func->groups[i] = child->name;
534545887eaSZe Huang 		func->group_idx[i] = idx;
535545887eaSZe Huang 		grp = &info->groups[idx];
536545887eaSZe Huang 		idx++;
537545887eaSZe Huang 		ret = k230_pinctrl_parse_groups(child, grp, info, i++);
538545887eaSZe Huang 		if (ret)
539545887eaSZe Huang 			return ret;
540545887eaSZe Huang 	}
541545887eaSZe Huang 
542545887eaSZe Huang 	return 0;
543545887eaSZe Huang }
544545887eaSZe Huang 
k230_pinctrl_child_count(struct k230_pinctrl * info,struct device_node * np)545545887eaSZe Huang static void k230_pinctrl_child_count(struct k230_pinctrl *info,
546545887eaSZe Huang 				     struct device_node *np)
547545887eaSZe Huang {
548545887eaSZe Huang 	for_each_child_of_node_scoped(np, child) {
549545887eaSZe Huang 		info->nfunctions++;
550545887eaSZe Huang 		info->ngroups += of_get_child_count(child);
551545887eaSZe Huang 	}
552545887eaSZe Huang }
553545887eaSZe Huang 
k230_pinctrl_parse_dt(struct platform_device * pdev,struct k230_pinctrl * info)554545887eaSZe Huang static int k230_pinctrl_parse_dt(struct platform_device *pdev,
555545887eaSZe Huang 				 struct k230_pinctrl *info)
556545887eaSZe Huang {
557545887eaSZe Huang 	struct device *dev = &pdev->dev;
558545887eaSZe Huang 	struct device_node *np = dev->of_node;
559545887eaSZe Huang 	unsigned int i;
560545887eaSZe Huang 	int ret;
561545887eaSZe Huang 
562545887eaSZe Huang 	k230_pinctrl_child_count(info, np);
563545887eaSZe Huang 
564545887eaSZe Huang 	info->functions = devm_kcalloc(dev, info->nfunctions,
565545887eaSZe Huang 				       sizeof(*info->functions), GFP_KERNEL);
566545887eaSZe Huang 	info->groups = devm_kcalloc(dev, info->ngroups,
567545887eaSZe Huang 				    sizeof(*info->groups), GFP_KERNEL);
568545887eaSZe Huang 	if (!info->functions || !info->groups)
569545887eaSZe Huang 		return -ENOMEM;
570545887eaSZe Huang 
571545887eaSZe Huang 	i = 0;
572545887eaSZe Huang 
573545887eaSZe Huang 	for_each_child_of_node_scoped(np, child) {
574545887eaSZe Huang 		ret = k230_pinctrl_parse_functions(child, info, i++);
575545887eaSZe Huang 		if (ret) {
576545887eaSZe Huang 			dev_err(dev, "failed to parse function\n");
577545887eaSZe Huang 			return ret;
578545887eaSZe Huang 		}
579545887eaSZe Huang 	}
580545887eaSZe Huang 
581545887eaSZe Huang 	return 0;
582545887eaSZe Huang }
583545887eaSZe Huang 
k230_pinctrl_probe(struct platform_device * pdev)584545887eaSZe Huang static int k230_pinctrl_probe(struct platform_device *pdev)
585545887eaSZe Huang {
586545887eaSZe Huang 	struct device *dev = &pdev->dev;
587545887eaSZe Huang 	struct k230_pinctrl *info;
588545887eaSZe Huang 	struct pinctrl_desc *pctl;
589545887eaSZe Huang 
590545887eaSZe Huang 	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
591545887eaSZe Huang 	if (!info)
592545887eaSZe Huang 		return -ENOMEM;
593545887eaSZe Huang 
594545887eaSZe Huang 	pctl = &info->pctl;
595545887eaSZe Huang 
596545887eaSZe Huang 	pctl->name	= "k230-pinctrl";
597545887eaSZe Huang 	pctl->owner	= THIS_MODULE;
598545887eaSZe Huang 	pctl->pins	= k230_pins;
599545887eaSZe Huang 	pctl->npins	= ARRAY_SIZE(k230_pins);
600545887eaSZe Huang 	pctl->pctlops	= &k230_pctrl_ops;
601545887eaSZe Huang 	pctl->pmxops	= &k230_pmxops;
602545887eaSZe Huang 	pctl->confops	= &k230_pinconf_ops;
603545887eaSZe Huang 
604545887eaSZe Huang 	info->base = devm_platform_ioremap_resource(pdev, 0);
605545887eaSZe Huang 	if (IS_ERR(info->base))
606545887eaSZe Huang 		return PTR_ERR(info->base);
607545887eaSZe Huang 
608545887eaSZe Huang 	info->regmap_base = devm_regmap_init_mmio(dev, info->base,
609545887eaSZe Huang 						  &k230_regmap_config);
610545887eaSZe Huang 	if (IS_ERR(info->regmap_base))
611545887eaSZe Huang 		return dev_err_probe(dev, PTR_ERR(info->regmap_base),
612545887eaSZe Huang 				     "failed to init regmap\n");
613545887eaSZe Huang 
614545887eaSZe Huang 	info->pctl_dev = devm_pinctrl_register(dev, pctl, info);
615545887eaSZe Huang 	if (IS_ERR(info->pctl_dev))
616545887eaSZe Huang 		return dev_err_probe(dev, PTR_ERR(info->pctl_dev),
617545887eaSZe Huang 				     "devm_pinctrl_register failed\n");
618545887eaSZe Huang 
619545887eaSZe Huang 	k230_pinctrl_parse_dt(pdev, info);
620545887eaSZe Huang 
621545887eaSZe Huang 	return 0;
622545887eaSZe Huang }
623545887eaSZe Huang 
624545887eaSZe Huang static const struct of_device_id k230_dt_ids[] = {
625545887eaSZe Huang 	{ .compatible = "canaan,k230-pinctrl", },
626545887eaSZe Huang 	{ /* sintenel */ }
627545887eaSZe Huang };
628545887eaSZe Huang MODULE_DEVICE_TABLE(of, k230_dt_ids);
629545887eaSZe Huang 
630545887eaSZe Huang static struct platform_driver k230_pinctrl_driver = {
631545887eaSZe Huang 	.probe = k230_pinctrl_probe,
632545887eaSZe Huang 	.driver = {
633545887eaSZe Huang 		.name = "k230-pinctrl",
634545887eaSZe Huang 		.of_match_table = k230_dt_ids,
635545887eaSZe Huang 	},
636545887eaSZe Huang };
637545887eaSZe Huang module_platform_driver(k230_pinctrl_driver);
638545887eaSZe Huang 
639545887eaSZe Huang MODULE_LICENSE("GPL");
640545887eaSZe Huang MODULE_AUTHOR("Ze Huang <18771902331@163.com>");
641545887eaSZe Huang MODULE_DESCRIPTION("Canaan K230 pinctrl driver");
642