File Index
Files and directories
Sign in
FILE

pinctrl-k230.c

File preview with syntax highlighting.

linux-6.19.14/drivers/pinctrl/pinctrl-k230.c C
  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
 46struct k230_pin_conf {
 47	unsigned int		func;
 48	unsigned long		*configs;
 49	unsigned int		nconfigs;
 50};
 51
 52struct 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
 60struct k230_pmx_func {
 61	const char		*name;
 62	const char		**groups;
 63	unsigned int		*group_idx;
 64	unsigned int		ngroups;
 65};
 66
 67struct 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
 79static 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
 87static 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
 94static 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
102static 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
118static 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
131static 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
156static 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
188static 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 = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL);
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
244static void k230_dt_free_map(struct pinctrl_dev *pctldev,
245			     struct pinctrl_map *map, unsigned int num_maps)
246{
247	kfree(map);
248}
249
250static 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
259static 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
305static 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
368static 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
393static 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
404static 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
411static 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
418static 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
426static 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
437static 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
461static 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
469static 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
511static 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
550static 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
559static 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
589static 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
634static const struct of_device_id k230_dt_ids[] = {
635	{ .compatible = "canaan,k230-pinctrl", },
636	{ /* sentinel */ }
637};
638MODULE_DEVICE_TABLE(of, k230_dt_ids);
639
640static 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};
647module_platform_driver(k230_pinctrl_driver);
648
649MODULE_LICENSE("GPL");
650MODULE_AUTHOR("Ze Huang <18771902331@163.com>");
651MODULE_DESCRIPTION("Canaan K230 pinctrl driver");
~/ Read-only file preview.