xref: /linux/drivers/pinctrl/pinctrl-k230.c (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
1 // SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2 /*
3  * Copyright (C) 2024 Canaan Bright Sight Co. Ltd
4  * Copyright (C) 2024 Ze Huang <18771902331@163.com>
5  */
6 #include <linux/module.h>
7 #include <linux/device.h>
8 #include <linux/of.h>
9 #include <linux/of_address.h>
10 #include <linux/of_device.h>
11 #include <linux/platform_device.h>
12 #include <linux/pinctrl/pinctrl.h>
13 #include <linux/pinctrl/pinmux.h>
14 #include <linux/pinctrl/pinconf.h>
15 #include <linux/pinctrl/pinconf-generic.h>
16 #include <linux/regmap.h>
17 #include <linux/seq_file.h>
18 
19 #include "core.h"
20 #include "pinconf.h"
21 
22 #define K230_NPINS 64
23 
24 #define K230_SHIFT_ST		(0)
25 #define K230_SHIFT_DS		(1)
26 #define K230_SHIFT_BIAS		(5)
27 #define K230_SHIFT_PD		(5)
28 #define K230_SHIFT_PU		(6)
29 #define K230_SHIFT_OE		(7)
30 #define K230_SHIFT_IE		(8)
31 #define K230_SHIFT_MSC		(9)
32 #define K230_SHIFT_SL		(10)
33 #define K230_SHIFT_SEL		(11)
34 
35 #define K230_PC_ST		BIT(0)
36 #define K230_PC_DS		GENMASK(4, 1)
37 #define K230_PC_PD		BIT(5)
38 #define K230_PC_PU		BIT(6)
39 #define K230_PC_BIAS		GENMASK(6, 5)
40 #define K230_PC_OE		BIT(7)
41 #define K230_PC_IE		BIT(8)
42 #define K230_PC_MSC		BIT(9)
43 #define K230_PC_SL		BIT(10)
44 #define K230_PC_SEL		GENMASK(13, 11)
45 
46 struct k230_pin_conf {
47 	unsigned int		func;
48 	unsigned long		*configs;
49 	unsigned int		nconfigs;
50 };
51 
52 struct k230_pin_group {
53 	const char		*name;
54 	unsigned int		*pins;
55 	unsigned int		num_pins;
56 
57 	struct k230_pin_conf	*data;
58 };
59 
60 struct k230_pmx_func {
61 	const char		*name;
62 	const char		**groups;
63 	unsigned int		*group_idx;
64 	unsigned int		ngroups;
65 };
66 
67 struct k230_pinctrl {
68 	struct device		*dev;
69 	struct pinctrl_desc	pctl;
70 	struct pinctrl_dev	*pctl_dev;
71 	struct regmap		*regmap_base;
72 	void __iomem		*base;
73 	struct k230_pin_group	*groups;
74 	unsigned int		ngroups;
75 	struct k230_pmx_func	*functions;
76 	unsigned int		nfunctions;
77 };
78 
79 static const struct regmap_config k230_regmap_config = {
80 	.name		= "canaan,pinctrl",
81 	.reg_bits	= 32,
82 	.val_bits	= 32,
83 	.max_register	= 0x100,
84 	.reg_stride	= 4,
85 };
86 
k230_get_groups_count(struct pinctrl_dev * pctldev)87 static int k230_get_groups_count(struct pinctrl_dev *pctldev)
88 {
89 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
90 
91 	return info->ngroups;
92 }
93 
k230_get_group_name(struct pinctrl_dev * pctldev,unsigned int selector)94 static const char *k230_get_group_name(struct pinctrl_dev *pctldev,
95 				       unsigned int selector)
96 {
97 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
98 
99 	return info->groups[selector].name;
100 }
101 
k230_get_group_pins(struct pinctrl_dev * pctldev,unsigned int selector,const unsigned int ** pins,unsigned int * num_pins)102 static int k230_get_group_pins(struct pinctrl_dev *pctldev,
103 			       unsigned int selector,
104 			       const unsigned int **pins,
105 			       unsigned int *num_pins)
106 {
107 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
108 
109 	if (selector >= info->ngroups)
110 		return -EINVAL;
111 
112 	*pins = info->groups[selector].pins;
113 	*num_pins = info->groups[selector].num_pins;
114 
115 	return 0;
116 }
117 
k230_name_to_funtion(const struct k230_pinctrl * info,const char * name)118 static inline const struct k230_pmx_func *k230_name_to_funtion(
119 		const struct k230_pinctrl *info, const char *name)
120 {
121 	unsigned int i;
122 
123 	for (i = 0; i < info->nfunctions; i++) {
124 		if (!strcmp(info->functions[i].name, name))
125 			return &info->functions[i];
126 	}
127 
128 	return NULL;
129 }
130 
131 static struct pinctrl_pin_desc k230_pins[] = {
132 	PINCTRL_PIN(0,  "IO0"),  PINCTRL_PIN(1,  "IO1"),  PINCTRL_PIN(2,  "IO2"),
133 	PINCTRL_PIN(3,  "IO3"),  PINCTRL_PIN(4,  "IO4"),  PINCTRL_PIN(5,  "IO5"),
134 	PINCTRL_PIN(6,  "IO6"),  PINCTRL_PIN(7,  "IO7"),  PINCTRL_PIN(8,  "IO8"),
135 	PINCTRL_PIN(9,  "IO9"),  PINCTRL_PIN(10, "IO10"), PINCTRL_PIN(11, "IO11"),
136 	PINCTRL_PIN(12, "IO12"), PINCTRL_PIN(13, "IO13"), PINCTRL_PIN(14, "IO14"),
137 	PINCTRL_PIN(15, "IO15"), PINCTRL_PIN(16, "IO16"), PINCTRL_PIN(17, "IO17"),
138 	PINCTRL_PIN(18, "IO18"), PINCTRL_PIN(19, "IO19"), PINCTRL_PIN(20, "IO20"),
139 	PINCTRL_PIN(21, "IO21"), PINCTRL_PIN(22, "IO22"), PINCTRL_PIN(23, "IO23"),
140 	PINCTRL_PIN(24, "IO24"), PINCTRL_PIN(25, "IO25"), PINCTRL_PIN(26, "IO26"),
141 	PINCTRL_PIN(27, "IO27"), PINCTRL_PIN(28, "IO28"), PINCTRL_PIN(29, "IO29"),
142 	PINCTRL_PIN(30, "IO30"), PINCTRL_PIN(31, "IO31"), PINCTRL_PIN(32, "IO32"),
143 	PINCTRL_PIN(33, "IO33"), PINCTRL_PIN(34, "IO34"), PINCTRL_PIN(35, "IO35"),
144 	PINCTRL_PIN(36, "IO36"), PINCTRL_PIN(37, "IO37"), PINCTRL_PIN(38, "IO38"),
145 	PINCTRL_PIN(39, "IO39"), PINCTRL_PIN(40, "IO40"), PINCTRL_PIN(41, "IO41"),
146 	PINCTRL_PIN(42, "IO42"), PINCTRL_PIN(43, "IO43"), PINCTRL_PIN(44, "IO44"),
147 	PINCTRL_PIN(45, "IO45"), PINCTRL_PIN(46, "IO46"), PINCTRL_PIN(47, "IO47"),
148 	PINCTRL_PIN(48, "IO48"), PINCTRL_PIN(49, "IO49"), PINCTRL_PIN(50, "IO50"),
149 	PINCTRL_PIN(51, "IO51"), PINCTRL_PIN(52, "IO52"), PINCTRL_PIN(53, "IO53"),
150 	PINCTRL_PIN(54, "IO54"), PINCTRL_PIN(55, "IO55"), PINCTRL_PIN(56, "IO56"),
151 	PINCTRL_PIN(57, "IO57"), PINCTRL_PIN(58, "IO58"), PINCTRL_PIN(59, "IO59"),
152 	PINCTRL_PIN(60, "IO60"), PINCTRL_PIN(61, "IO61"), PINCTRL_PIN(62, "IO62"),
153 	PINCTRL_PIN(63, "IO63")
154 };
155 
k230_pinctrl_pin_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int offset)156 static void k230_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
157 				      struct seq_file *s, unsigned int offset)
158 {
159 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
160 	u32 val, bias, drive, input, slew, schmitt, power;
161 	struct k230_pin_group *grp = k230_pins[offset].drv_data;
162 	static const char * const biasing[] = {
163 			"pull none", "pull down", "pull up", "" };
164 	static const char * const enable[] = {
165 			"disable", "enable" };
166 	static const char * const power_source[] = {
167 			"3V3", "1V8" };
168 
169 	regmap_read(info->regmap_base, offset * 4, &val);
170 
171 	drive	= (val & K230_PC_DS) >> K230_SHIFT_DS;
172 	bias	= (val & K230_PC_BIAS) >> K230_SHIFT_BIAS;
173 	input	= (val & K230_PC_IE) >> K230_SHIFT_IE;
174 	slew	= (val & K230_PC_SL) >> K230_SHIFT_SL;
175 	schmitt	= (val & K230_PC_ST) >> K230_SHIFT_ST;
176 	power	= (val & K230_PC_MSC) >> K230_SHIFT_MSC;
177 
178 	seq_printf(s, "%s - strength %d - %s - %s - slewrate %s - schmitt %s - %s",
179 		   grp ? grp->name : "unknown",
180 		   drive,
181 		   biasing[bias],
182 		   input ? "input" : "output",
183 		   enable[slew],
184 		   enable[schmitt],
185 		   power_source[power]);
186 }
187 
k230_dt_node_to_map(struct pinctrl_dev * pctldev,struct device_node * np_config,struct pinctrl_map ** map,unsigned int * num_maps)188 static int k230_dt_node_to_map(struct pinctrl_dev *pctldev,
189 			       struct device_node *np_config,
190 			       struct pinctrl_map **map,
191 			       unsigned int *num_maps)
192 {
193 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
194 	struct device *dev = info->pctl_dev->dev;
195 	const struct k230_pmx_func *func;
196 	const struct k230_pin_group *grp;
197 	struct pinctrl_map *new_map;
198 	int map_num, i, j, idx;
199 	unsigned int grp_id;
200 
201 	func = k230_name_to_funtion(info, np_config->name);
202 	if (!func) {
203 		dev_err(dev, "function %s not found\n", np_config->name);
204 		return -EINVAL;
205 	}
206 
207 	map_num = 0;
208 	for (i = 0; i < func->ngroups; ++i) {
209 		grp_id = func->group_idx[i];
210 		/* npins of config map plus a mux map */
211 		map_num += info->groups[grp_id].num_pins + 1;
212 	}
213 
214 	new_map = kzalloc_objs(*new_map, map_num);
215 	if (!new_map)
216 		return -ENOMEM;
217 	*map = new_map;
218 	*num_maps = map_num;
219 
220 	idx = 0;
221 	for (i = 0; i < func->ngroups; ++i) {
222 		grp_id = func->group_idx[i];
223 		grp = &info->groups[grp_id];
224 		new_map[idx].type = PIN_MAP_TYPE_MUX_GROUP;
225 		new_map[idx].data.mux.group = grp->name;
226 		new_map[idx].data.mux.function = np_config->name;
227 		idx++;
228 
229 		for (j = 0; j < grp->num_pins; ++j) {
230 			new_map[idx].type = PIN_MAP_TYPE_CONFIGS_PIN;
231 			new_map[idx].data.configs.group_or_pin =
232 				pin_get_name(pctldev, grp->pins[j]);
233 			new_map[idx].data.configs.configs =
234 				grp->data[j].configs;
235 			new_map[idx].data.configs.num_configs =
236 				grp->data[j].nconfigs;
237 			idx++;
238 		}
239 	}
240 
241 	return 0;
242 }
243 
k230_dt_free_map(struct pinctrl_dev * pctldev,struct pinctrl_map * map,unsigned int num_maps)244 static void k230_dt_free_map(struct pinctrl_dev *pctldev,
245 			     struct pinctrl_map *map, unsigned int num_maps)
246 {
247 	kfree(map);
248 }
249 
250 static const struct pinctrl_ops k230_pctrl_ops = {
251 	.get_groups_count	= k230_get_groups_count,
252 	.get_group_name		= k230_get_group_name,
253 	.get_group_pins		= k230_get_group_pins,
254 	.pin_dbg_show		= k230_pinctrl_pin_dbg_show,
255 	.dt_node_to_map		= k230_dt_node_to_map,
256 	.dt_free_map		= k230_dt_free_map,
257 };
258 
k230_pinconf_get(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * config)259 static int k230_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
260 			    unsigned long *config)
261 {
262 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
263 	enum pin_config_param param = pinconf_to_config_param(*config);
264 	unsigned int val, arg;
265 
266 	regmap_read(info->regmap_base, pin * 4, &val);
267 
268 	switch (param) {
269 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
270 		arg = (val & K230_PC_ST) ? 1 : 0;
271 		break;
272 	case PIN_CONFIG_DRIVE_STRENGTH:
273 		arg = (val & K230_PC_DS) >> K230_SHIFT_DS;
274 		break;
275 	case PIN_CONFIG_BIAS_DISABLE:
276 		arg = (val & K230_PC_BIAS) ? 0 : 1;
277 		break;
278 	case PIN_CONFIG_BIAS_PULL_DOWN:
279 		arg = (val & K230_PC_PD) ? 1 : 0;
280 		break;
281 	case PIN_CONFIG_BIAS_PULL_UP:
282 		arg = (val & K230_PC_PU) ? 1 : 0;
283 		break;
284 	case PIN_CONFIG_OUTPUT_ENABLE:
285 		arg = (val & K230_PC_OE) ? 1 : 0;
286 		break;
287 	case PIN_CONFIG_INPUT_ENABLE:
288 		arg = (val & K230_PC_IE) ? 1 : 0;
289 		break;
290 	case PIN_CONFIG_POWER_SOURCE:
291 		arg = (val & K230_PC_MSC) ? 1 : 0;
292 		break;
293 	case PIN_CONFIG_SLEW_RATE:
294 		arg = (val & K230_PC_SL) ? 1 : 0;
295 		break;
296 	default:
297 		return -EINVAL;
298 	}
299 
300 	*config = pinconf_to_config_packed(param, arg);
301 
302 	return 0;
303 }
304 
k230_pinconf_set_param(struct pinctrl_dev * pctldev,unsigned int pin,enum pin_config_param param,unsigned int arg)305 static int k230_pinconf_set_param(struct pinctrl_dev *pctldev, unsigned int pin,
306 				  enum pin_config_param param, unsigned int arg)
307 {
308 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
309 	unsigned int val;
310 
311 	regmap_read(info->regmap_base, pin * 4, &val);
312 
313 	switch (param) {
314 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
315 		if (arg)
316 			val |= K230_PC_ST;
317 		else
318 			val &= ~K230_PC_ST;
319 		break;
320 	case PIN_CONFIG_DRIVE_STRENGTH:
321 		val &= ~K230_PC_DS;
322 		val |= (arg << K230_SHIFT_DS) & K230_PC_DS;
323 		break;
324 	case PIN_CONFIG_BIAS_DISABLE:
325 		val &= ~K230_PC_BIAS;
326 		break;
327 	case PIN_CONFIG_BIAS_PULL_DOWN:
328 		if (!arg)
329 			return -EINVAL;
330 		val |= K230_PC_PD;
331 		break;
332 	case PIN_CONFIG_BIAS_PULL_UP:
333 		if (!arg)
334 			return -EINVAL;
335 		val |= K230_PC_PU;
336 		break;
337 	case PIN_CONFIG_OUTPUT_ENABLE:
338 		if (!arg)
339 			return -EINVAL;
340 		val |= K230_PC_OE;
341 		break;
342 	case PIN_CONFIG_INPUT_ENABLE:
343 		if (!arg)
344 			return -EINVAL;
345 		val |= K230_PC_IE;
346 		break;
347 	case PIN_CONFIG_POWER_SOURCE:
348 		if (arg)
349 			val |= K230_PC_MSC;
350 		else
351 			val &= ~K230_PC_MSC;
352 		break;
353 	case PIN_CONFIG_SLEW_RATE:
354 		if (arg)
355 			val |= K230_PC_SL;
356 		else
357 			val &= ~K230_PC_SL;
358 		break;
359 	default:
360 		return -EINVAL;
361 	}
362 
363 	regmap_write(info->regmap_base, pin * 4, val);
364 
365 	return 0;
366 }
367 
k230_pinconf_set(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * configs,unsigned int num_configs)368 static int k230_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
369 			    unsigned long *configs, unsigned int num_configs)
370 {
371 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
372 	struct device *dev = info->pctl_dev->dev;
373 	enum pin_config_param param;
374 	unsigned int arg, i;
375 	int ret;
376 
377 	if (pin >= K230_NPINS) {
378 		dev_err(dev, "pin number out of range\n");
379 		return -EINVAL;
380 	}
381 
382 	for (i = 0; i < num_configs; i++) {
383 		param = pinconf_to_config_param(configs[i]);
384 		arg = pinconf_to_config_argument(configs[i]);
385 		ret = k230_pinconf_set_param(pctldev, pin, param, arg);
386 		if (ret)
387 			return ret;
388 	}
389 
390 	return 0;
391 }
392 
k230_pconf_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int pin)393 static void k230_pconf_dbg_show(struct pinctrl_dev *pctldev,
394 				struct seq_file *s, unsigned int pin)
395 {
396 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
397 	unsigned int val;
398 
399 	regmap_read(info->regmap_base, pin * 4, &val);
400 
401 	seq_printf(s, " 0x%08x", val);
402 }
403 
404 static const struct pinconf_ops k230_pinconf_ops = {
405 	.is_generic		= true,
406 	.pin_config_get		= k230_pinconf_get,
407 	.pin_config_set		= k230_pinconf_set,
408 	.pin_config_dbg_show	= k230_pconf_dbg_show,
409 };
410 
k230_get_functions_count(struct pinctrl_dev * pctldev)411 static int k230_get_functions_count(struct pinctrl_dev *pctldev)
412 {
413 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
414 
415 	return info->nfunctions;
416 }
417 
k230_get_fname(struct pinctrl_dev * pctldev,unsigned int selector)418 static const char *k230_get_fname(struct pinctrl_dev *pctldev,
419 				  unsigned int selector)
420 {
421 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
422 
423 	return info->functions[selector].name;
424 }
425 
k230_get_groups(struct pinctrl_dev * pctldev,unsigned int selector,const char * const ** groups,unsigned int * num_groups)426 static int k230_get_groups(struct pinctrl_dev *pctldev, unsigned int selector,
427 			   const char * const **groups, unsigned int *num_groups)
428 {
429 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
430 
431 	*groups = info->functions[selector].groups;
432 	*num_groups = info->functions[selector].ngroups;
433 
434 	return 0;
435 }
436 
k230_set_mux(struct pinctrl_dev * pctldev,unsigned int selector,unsigned int group)437 static int k230_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
438 			unsigned int group)
439 {
440 	struct k230_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
441 	const struct k230_pin_conf *data = info->groups[group].data;
442 	struct k230_pin_group *grp = &info->groups[group];
443 	const unsigned int *pins = grp->pins;
444 	struct regmap *regmap;
445 	unsigned int value, mask;
446 	int cnt, reg;
447 
448 	regmap = info->regmap_base;
449 
450 	for (cnt = 0; cnt < grp->num_pins; cnt++) {
451 		reg = pins[cnt] * 4;
452 		value = data[cnt].func << K230_SHIFT_SEL;
453 		mask = K230_PC_SEL;
454 		regmap_update_bits(regmap, reg, mask, value);
455 		k230_pins[pins[cnt]].drv_data = grp;
456 	}
457 
458 	return 0;
459 }
460 
461 static const struct pinmux_ops k230_pmxops = {
462 	.get_functions_count	= k230_get_functions_count,
463 	.get_function_name	= k230_get_fname,
464 	.get_function_groups	= k230_get_groups,
465 	.set_mux		= k230_set_mux,
466 	.strict			= true,
467 };
468 
k230_pinctrl_parse_groups(struct device_node * np,struct k230_pin_group * grp,struct k230_pinctrl * info,unsigned int index)469 static int k230_pinctrl_parse_groups(struct device_node *np,
470 				     struct k230_pin_group *grp,
471 				     struct k230_pinctrl *info,
472 				     unsigned int index)
473 {
474 	struct device *dev = info->dev;
475 	const __be32 *list;
476 	int size, i, ret;
477 
478 	grp->name = np->name;
479 
480 	list = of_get_property(np, "pinmux", &size);
481 	if (!list) {
482 		dev_err(dev, "failed to get pinmux property\n");
483 		return -EINVAL;
484 	}
485 	size /= sizeof(*list);
486 
487 	grp->num_pins = size;
488 	grp->pins = devm_kcalloc(dev, grp->num_pins, sizeof(*grp->pins),
489 				 GFP_KERNEL);
490 	grp->data = devm_kcalloc(dev, grp->num_pins, sizeof(*grp->data),
491 				 GFP_KERNEL);
492 	if (!grp->pins || !grp->data)
493 		return -ENOMEM;
494 
495 	for (i = 0; i < size; i++) {
496 		unsigned int mux_data = be32_to_cpu(*list++);
497 
498 		grp->pins[i] = (mux_data >> 8);
499 		grp->data[i].func = (mux_data & 0xff);
500 
501 		ret = pinconf_generic_parse_dt_config(np, NULL,
502 						      &grp->data[i].configs,
503 						      &grp->data[i].nconfigs);
504 		if (ret)
505 			return ret;
506 	}
507 
508 	return 0;
509 }
510 
k230_pinctrl_parse_functions(struct device_node * np,struct k230_pinctrl * info,unsigned int index)511 static int k230_pinctrl_parse_functions(struct device_node *np,
512 					struct k230_pinctrl *info,
513 					unsigned int index)
514 {
515 	struct device *dev = info->dev;
516 	struct k230_pmx_func *func;
517 	struct k230_pin_group *grp;
518 	static unsigned int idx, i;
519 	int ret;
520 
521 	func = &info->functions[index];
522 
523 	func->name = np->name;
524 	func->ngroups = of_get_child_count(np);
525 	if (func->ngroups <= 0)
526 		return 0;
527 
528 	func->groups = devm_kcalloc(dev, func->ngroups,
529 				    sizeof(*func->groups), GFP_KERNEL);
530 	func->group_idx = devm_kcalloc(dev, func->ngroups,
531 				       sizeof(*func->group_idx), GFP_KERNEL);
532 	if (!func->groups || !func->group_idx)
533 		return -ENOMEM;
534 
535 	i = 0;
536 
537 	for_each_child_of_node_scoped(np, child) {
538 		func->groups[i] = child->name;
539 		func->group_idx[i] = idx;
540 		grp = &info->groups[idx];
541 		idx++;
542 		ret = k230_pinctrl_parse_groups(child, grp, info, i++);
543 		if (ret)
544 			return ret;
545 	}
546 
547 	return 0;
548 }
549 
k230_pinctrl_child_count(struct k230_pinctrl * info,struct device_node * np)550 static void k230_pinctrl_child_count(struct k230_pinctrl *info,
551 				     struct device_node *np)
552 {
553 	for_each_child_of_node_scoped(np, child) {
554 		info->nfunctions++;
555 		info->ngroups += of_get_child_count(child);
556 	}
557 }
558 
k230_pinctrl_parse_dt(struct platform_device * pdev,struct k230_pinctrl * info)559 static int k230_pinctrl_parse_dt(struct platform_device *pdev,
560 				 struct k230_pinctrl *info)
561 {
562 	struct device *dev = &pdev->dev;
563 	struct device_node *np = dev->of_node;
564 	unsigned int i;
565 	int ret;
566 
567 	k230_pinctrl_child_count(info, np);
568 
569 	info->functions = devm_kcalloc(dev, info->nfunctions,
570 				       sizeof(*info->functions), GFP_KERNEL);
571 	info->groups = devm_kcalloc(dev, info->ngroups,
572 				    sizeof(*info->groups), GFP_KERNEL);
573 	if (!info->functions || !info->groups)
574 		return -ENOMEM;
575 
576 	i = 0;
577 
578 	for_each_child_of_node_scoped(np, child) {
579 		ret = k230_pinctrl_parse_functions(child, info, i++);
580 		if (ret) {
581 			dev_err(dev, "failed to parse function\n");
582 			return ret;
583 		}
584 	}
585 
586 	return 0;
587 }
588 
k230_pinctrl_probe(struct platform_device * pdev)589 static int k230_pinctrl_probe(struct platform_device *pdev)
590 {
591 	struct device *dev = &pdev->dev;
592 	struct k230_pinctrl *info;
593 	struct pinctrl_desc *pctl;
594 	int ret;
595 
596 	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
597 	if (!info)
598 		return -ENOMEM;
599 
600 	info->dev = dev;
601 
602 	pctl = &info->pctl;
603 
604 	pctl->name	= "k230-pinctrl";
605 	pctl->owner	= THIS_MODULE;
606 	pctl->pins	= k230_pins;
607 	pctl->npins	= ARRAY_SIZE(k230_pins);
608 	pctl->pctlops	= &k230_pctrl_ops;
609 	pctl->pmxops	= &k230_pmxops;
610 	pctl->confops	= &k230_pinconf_ops;
611 
612 	info->base = devm_platform_ioremap_resource(pdev, 0);
613 	if (IS_ERR(info->base))
614 		return PTR_ERR(info->base);
615 
616 	info->regmap_base = devm_regmap_init_mmio(dev, info->base,
617 						  &k230_regmap_config);
618 	if (IS_ERR(info->regmap_base))
619 		return dev_err_probe(dev, PTR_ERR(info->regmap_base),
620 				     "failed to init regmap\n");
621 
622 	ret = k230_pinctrl_parse_dt(pdev, info);
623 	if (ret)
624 		return ret;
625 
626 	info->pctl_dev = devm_pinctrl_register(dev, pctl, info);
627 	if (IS_ERR(info->pctl_dev))
628 		return dev_err_probe(dev, PTR_ERR(info->pctl_dev),
629 				     "devm_pinctrl_register failed\n");
630 
631 	return 0;
632 }
633 
634 static const struct of_device_id k230_dt_ids[] = {
635 	{ .compatible = "canaan,k230-pinctrl", },
636 	{ /* sentinel */ }
637 };
638 MODULE_DEVICE_TABLE(of, k230_dt_ids);
639 
640 static struct platform_driver k230_pinctrl_driver = {
641 	.probe = k230_pinctrl_probe,
642 	.driver = {
643 		.name = "k230-pinctrl",
644 		.of_match_table = k230_dt_ids,
645 	},
646 };
647 module_platform_driver(k230_pinctrl_driver);
648 
649 MODULE_LICENSE("GPL");
650 MODULE_AUTHOR("Ze Huang <18771902331@163.com>");
651 MODULE_DESCRIPTION("Canaan K230 pinctrl driver");
652