summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/mediatek
diff options
context:
space:
mode:
authorZhiyong Tao <zhiyong.tao@mediatek.com>2018-09-08 07:07:33 -0400
committerLinus Walleij <linus.walleij@linaro.org>2018-09-18 17:53:25 -0400
commit805250982bb5c5ce4a6e52e1d87204c5feea0dd1 (patch)
tree94943bc865e0b63c1b94cd0c6aede9334d1191c9 /drivers/pinctrl/mediatek
parentb7d7f9eeca551f9cf1f6418749cd609d371faf55 (diff)
pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings
Add pinctrl-paris core that implements vendor dt-binding which MediaTek tablet, box and smartphone-based SoCs such as MT81xx, MT27xx, and MT67xx SoCs really want to depend on. The driver is just completely rewritten according to pinctrl-mtk-common.c but uses the new logic from pinctrl-mtk-common-v2.c to have an elegant way to support new SoCs in the future. Signed-off-by: Zhiyong Tao <zhiyong.tao@mediatek.com> Signed-off-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/mediatek')
-rw-r--r--drivers/pinctrl/mediatek/Kconfig9
-rw-r--r--drivers/pinctrl/mediatek/Makefile1
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h8
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-paris.c884
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-paris.h65
5 files changed, 967 insertions, 0 deletions
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 6124ef053b14..4a8086e4dd39 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -24,6 +24,15 @@ config PINCTRL_MTK_MOORE
24 select GPIOLIB 24 select GPIOLIB
25 select OF_GPIO 25 select OF_GPIO
26 26
27config PINCTRL_MTK_PARIS
28 bool "MediaTek Paris Core that implements vendor binding"
29 depends on OF
30 select PINMUX
31 select GENERIC_PINCONF
32 select GPIOLIB
33 select EINT_MTK
34 select OF_GPIO
35
27# For ARMv7 SoCs 36# For ARMv7 SoCs
28config PINCTRL_MT2701 37config PINCTRL_MT2701
29 bool "Mediatek MT2701 pin control" 38 bool "Mediatek MT2701 pin control"
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index 5df28e116653..8847dce84a4c 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -3,6 +3,7 @@
3obj-$(CONFIG_EINT_MTK) += mtk-eint.o 3obj-$(CONFIG_EINT_MTK) += mtk-eint.o
4obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o 4obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o
5obj-$(CONFIG_PINCTRL_MTK_MOORE) += pinctrl-moore.o pinctrl-mtk-common-v2.o 5obj-$(CONFIG_PINCTRL_MTK_MOORE) += pinctrl-moore.o pinctrl-mtk-common-v2.o
6obj-$(CONFIG_PINCTRL_MTK_PARIS) += pinctrl-paris.o pinctrl-mtk-common-v2.o
6 7
7# SoC Drivers 8# SoC Drivers
8obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o 9obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index d5819ca98c3c..05b9b391afea 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -174,6 +174,12 @@ struct mtk_pin_desc {
174 struct mtk_func_desc *funcs; 174 struct mtk_func_desc *funcs;
175}; 175};
176 176
177struct mtk_pinctrl_group {
178 const char *name;
179 unsigned long config;
180 unsigned pin;
181};
182
177struct mtk_pinctrl; 183struct mtk_pinctrl;
178 184
179/* struct mtk_pin_soc - the structure that holds SoC-specific data */ 185/* struct mtk_pin_soc - the structure that holds SoC-specific data */
@@ -228,6 +234,8 @@ struct mtk_pinctrl {
228 struct gpio_chip chip; 234 struct gpio_chip chip;
229 const struct mtk_pin_soc *soc; 235 const struct mtk_pin_soc *soc;
230 struct mtk_eint *eint; 236 struct mtk_eint *eint;
237 struct mtk_pinctrl_group *groups;
238 const char **grp_names;
231}; 239};
232 240
233void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set); 241void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
new file mode 100644
index 000000000000..50d689371590
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -0,0 +1,884 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * MediaTek Pinctrl Paris Driver, which implement the vendor per-pin
4 * bindings for MediaTek SoC.
5 *
6 * Copyright (C) 2018 MediaTek Inc.
7 * Author: Sean Wang <sean.wang@mediatek.com>
8 * Zhiyong Tao <zhiyong.tao@mediatek.com>
9 * Hongzhou.Yang <hongzhou.yang@mediatek.com>
10 */
11
12#include <dt-bindings/pinctrl/mt65xx.h>
13#include "pinctrl-paris.h"
14
15#define PINCTRL_PINCTRL_DEV KBUILD_MODNAME
16
17/* Custom pinconf parameters */
18#define MTK_PIN_CONFIG_TDSEL (PIN_CONFIG_END + 1)
19#define MTK_PIN_CONFIG_RDSEL (PIN_CONFIG_END + 2)
20#define MTK_PIN_CONFIG_PU_ADV (PIN_CONFIG_END + 3)
21#define MTK_PIN_CONFIG_PD_ADV (PIN_CONFIG_END + 4)
22
23static const struct pinconf_generic_params mtk_custom_bindings[] = {
24 {"mediatek,tdsel", MTK_PIN_CONFIG_TDSEL, 0},
25 {"mediatek,rdsel", MTK_PIN_CONFIG_RDSEL, 0},
26 {"mediatek,pull-up-adv", MTK_PIN_CONFIG_PU_ADV, 1},
27 {"mediatek,pull-down-adv", MTK_PIN_CONFIG_PD_ADV, 1},
28};
29
30#ifdef CONFIG_DEBUG_FS
31static const struct pin_config_item mtk_conf_items[] = {
32 PCONFDUMP(MTK_PIN_CONFIG_TDSEL, "tdsel", NULL, true),
33 PCONFDUMP(MTK_PIN_CONFIG_RDSEL, "rdsel", NULL, true),
34 PCONFDUMP(MTK_PIN_CONFIG_PU_ADV, "pu-adv", NULL, true),
35 PCONFDUMP(MTK_PIN_CONFIG_PD_ADV, "pd-adv", NULL, true),
36};
37#endif
38
39static const char * const mtk_gpio_functions[] = {
40 "func0", "func1", "func2", "func3",
41 "func4", "func5", "func6", "func7",
42 "func8", "func9", "func10", "func11",
43 "func12", "func13", "func14", "func15",
44};
45
46static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
47 struct pinctrl_gpio_range *range,
48 unsigned int pin)
49{
50 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
51 const struct mtk_pin_desc *desc;
52
53 desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
54
55 return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
56 hw->soc->gpio_m);
57}
58
59static int mtk_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
60 struct pinctrl_gpio_range *range,
61 unsigned int pin, bool input)
62{
63 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
64 const struct mtk_pin_desc *desc;
65
66 desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
67
68 /* hardware would take 0 as input direction */
69 return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !input);
70}
71
72static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
73 unsigned int pin, unsigned long *config)
74{
75 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
76 u32 param = pinconf_to_config_param(*config);
77 int val, val2, err, reg, ret = 1;
78 const struct mtk_pin_desc *desc;
79
80 desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
81
82 switch (param) {
83 case PIN_CONFIG_BIAS_DISABLE:
84 if (hw->soc->bias_disable_get) {
85 err = hw->soc->bias_disable_get(hw, desc, &ret);
86 if (err)
87 return err;
88 } else {
89 return -ENOTSUPP;
90 }
91 break;
92 case PIN_CONFIG_BIAS_PULL_UP:
93 if (hw->soc->bias_get) {
94 err = hw->soc->bias_get(hw, desc, 1, &ret);
95 if (err)
96 return err;
97 } else {
98 return -ENOTSUPP;
99 }
100 break;
101 case PIN_CONFIG_BIAS_PULL_DOWN:
102 if (hw->soc->bias_get) {
103 err = hw->soc->bias_get(hw, desc, 0, &ret);
104 if (err)
105 return err;
106 } else {
107 return -ENOTSUPP;
108 }
109 break;
110 case PIN_CONFIG_SLEW_RATE:
111 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
112 if (err)
113 return err;
114
115 if (!val)
116 return -EINVAL;
117
118 break;
119 case PIN_CONFIG_INPUT_ENABLE:
120 case PIN_CONFIG_OUTPUT_ENABLE:
121 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
122 if (err)
123 return err;
124
125 /* HW takes input mode as zero; output mode as non-zero */
126 if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
127 (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
128 return -EINVAL;
129
130 break;
131 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
132 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
133 if (err)
134 return err;
135
136 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2);
137 if (err)
138 return err;
139
140 if (val || !val2)
141 return -EINVAL;
142
143 break;
144 case PIN_CONFIG_DRIVE_STRENGTH:
145 if (hw->soc->drive_get) {
146 err = hw->soc->drive_get(hw, desc, &ret);
147 if (err)
148 return err;
149 } else {
150 err = -ENOTSUPP;
151 }
152 break;
153 case MTK_PIN_CONFIG_TDSEL:
154 case MTK_PIN_CONFIG_RDSEL:
155 reg = (param == MTK_PIN_CONFIG_TDSEL) ?
156 PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
157
158 err = mtk_hw_get_value(hw, desc, reg, &val);
159 if (err)
160 return err;
161
162 ret = val;
163
164 break;
165 case MTK_PIN_CONFIG_PU_ADV:
166 case MTK_PIN_CONFIG_PD_ADV:
167 if (hw->soc->adv_pull_get) {
168 bool pullup;
169
170 pullup = param == MTK_PIN_CONFIG_PU_ADV;
171 err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
172 if (err)
173 return err;
174 } else {
175 return -ENOTSUPP;
176 }
177 break;
178 default:
179 return -ENOTSUPP;
180 }
181
182 *config = pinconf_to_config_packed(param, ret);
183
184 return 0;
185}
186
187static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
188 enum pin_config_param param,
189 enum pin_config_param arg)
190{
191 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
192 const struct mtk_pin_desc *desc;
193 int err = 0;
194 u32 reg;
195
196 desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
197
198 switch ((u32)param) {
199 case PIN_CONFIG_BIAS_DISABLE:
200 if (hw->soc->bias_disable_set) {
201 err = hw->soc->bias_disable_set(hw, desc);
202 if (err)
203 return err;
204 } else {
205 return -ENOTSUPP;
206 }
207 break;
208 case PIN_CONFIG_BIAS_PULL_UP:
209 if (hw->soc->bias_set) {
210 err = hw->soc->bias_set(hw, desc, 1);
211 if (err)
212 return err;
213 } else {
214 return -ENOTSUPP;
215 }
216 break;
217 case PIN_CONFIG_BIAS_PULL_DOWN:
218 if (hw->soc->bias_set) {
219 err = hw->soc->bias_set(hw, desc, 0);
220 if (err)
221 return err;
222 } else {
223 return -ENOTSUPP;
224 }
225 break;
226 case PIN_CONFIG_OUTPUT_ENABLE:
227 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
228 MTK_DISABLE);
229 if (err)
230 goto err;
231
232 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
233 MTK_OUTPUT);
234 if (err)
235 goto err;
236 break;
237 case PIN_CONFIG_INPUT_ENABLE:
238 if (hw->soc->ies_present) {
239 mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES,
240 MTK_ENABLE);
241 }
242
243 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
244 MTK_INPUT);
245 if (err)
246 goto err;
247 break;
248 case PIN_CONFIG_SLEW_RATE:
249 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR,
250 arg);
251 if (err)
252 goto err;
253
254 break;
255 case PIN_CONFIG_OUTPUT:
256 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
257 MTK_OUTPUT);
258 if (err)
259 goto err;
260
261 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
262 arg);
263 if (err)
264 goto err;
265 break;
266 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
267 /* arg = 1: Input mode & SMT enable ;
268 * arg = 0: Output mode & SMT disable
269 */
270 arg = arg ? 2 : 1;
271 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
272 arg & 1);
273 if (err)
274 goto err;
275
276 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
277 !!(arg & 2));
278 if (err)
279 goto err;
280 break;
281 case PIN_CONFIG_DRIVE_STRENGTH:
282 if (hw->soc->drive_set) {
283 err = hw->soc->drive_set(hw, desc, arg);
284 if (err)
285 return err;
286 } else {
287 return -ENOTSUPP;
288 }
289 break;
290 case MTK_PIN_CONFIG_TDSEL:
291 case MTK_PIN_CONFIG_RDSEL:
292 reg = (param == MTK_PIN_CONFIG_TDSEL) ?
293 PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
294
295 err = mtk_hw_set_value(hw, desc, reg, arg);
296 if (err)
297 goto err;
298 break;
299 case MTK_PIN_CONFIG_PU_ADV:
300 case MTK_PIN_CONFIG_PD_ADV:
301 if (hw->soc->adv_pull_set) {
302 bool pullup;
303
304 pullup = param == MTK_PIN_CONFIG_PU_ADV;
305 err = hw->soc->adv_pull_set(hw, desc, pullup,
306 arg);
307 if (err)
308 return err;
309 } else {
310 return -ENOTSUPP;
311 }
312 break;
313 default:
314 err = -ENOTSUPP;
315 }
316
317err:
318 return err;
319}
320
321static struct mtk_pinctrl_group *
322mtk_pctrl_find_group_by_pin(struct mtk_pinctrl *hw, u32 pin)
323{
324 int i;
325
326 for (i = 0; i < hw->soc->ngrps; i++) {
327 struct mtk_pinctrl_group *grp = hw->groups + i;
328
329 if (grp->pin == pin)
330 return grp;
331 }
332
333 return NULL;
334}
335
336static const struct mtk_func_desc *
337mtk_pctrl_find_function_by_pin(struct mtk_pinctrl *hw, u32 pin_num, u32 fnum)
338{
339 const struct mtk_pin_desc *pin = hw->soc->pins + pin_num;
340 const struct mtk_func_desc *func = pin->funcs;
341
342 while (func && func->name) {
343 if (func->muxval == fnum)
344 return func;
345 func++;
346 }
347
348 return NULL;
349}
350
351static bool mtk_pctrl_is_function_valid(struct mtk_pinctrl *hw, u32 pin_num,
352 u32 fnum)
353{
354 int i;
355
356 for (i = 0; i < hw->soc->npins; i++) {
357 const struct mtk_pin_desc *pin = hw->soc->pins + i;
358
359 if (pin->number == pin_num) {
360 const struct mtk_func_desc *func = pin->funcs;
361
362 while (func && func->name) {
363 if (func->muxval == fnum)
364 return true;
365 func++;
366 }
367
368 break;
369 }
370 }
371
372 return false;
373}
374
375static int mtk_pctrl_dt_node_to_map_func(struct mtk_pinctrl *pctl,
376 u32 pin, u32 fnum,
377 struct mtk_pinctrl_group *grp,
378 struct pinctrl_map **map,
379 unsigned *reserved_maps,
380 unsigned *num_maps)
381{
382 bool ret;
383
384 if (*num_maps == *reserved_maps)
385 return -ENOSPC;
386
387 (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
388 (*map)[*num_maps].data.mux.group = grp->name;
389
390 ret = mtk_pctrl_is_function_valid(pctl, pin, fnum);
391 if (!ret) {
392 dev_err(pctl->dev, "invalid function %d on pin %d .\n",
393 fnum, pin);
394 return -EINVAL;
395 }
396
397 (*map)[*num_maps].data.mux.function = mtk_gpio_functions[fnum];
398 (*num_maps)++;
399
400 return 0;
401}
402
403static int mtk_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
404 struct device_node *node,
405 struct pinctrl_map **map,
406 unsigned *reserved_maps,
407 unsigned *num_maps)
408{
409 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
410 int num_pins, num_funcs, maps_per_pin, i, err;
411 struct mtk_pinctrl_group *grp;
412 unsigned int num_configs;
413 bool has_config = false;
414 unsigned long *configs;
415 u32 pinfunc, pin, func;
416 struct property *pins;
417 unsigned reserve = 0;
418
419 pins = of_find_property(node, "pinmux", NULL);
420 if (!pins) {
421 dev_err(hw->dev, "missing pins property in node %s .\n",
422 node->name);
423 return -EINVAL;
424 }
425
426 err = pinconf_generic_parse_dt_config(node, pctldev, &configs,
427 &num_configs);
428 if (err)
429 return err;
430
431 if (num_configs)
432 has_config = true;
433
434 num_pins = pins->length / sizeof(u32);
435 num_funcs = num_pins;
436 maps_per_pin = 0;
437 if (num_funcs)
438 maps_per_pin++;
439 if (has_config && num_pins >= 1)
440 maps_per_pin++;
441
442 if (!num_pins || !maps_per_pin) {
443 err = -EINVAL;
444 goto exit;
445 }
446
447 reserve = num_pins * maps_per_pin;
448
449 err = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, num_maps,
450 reserve);
451 if (err < 0)
452 goto exit;
453
454 for (i = 0; i < num_pins; i++) {
455 err = of_property_read_u32_index(node, "pinmux", i, &pinfunc);
456 if (err)
457 goto exit;
458
459 pin = MTK_GET_PIN_NO(pinfunc);
460 func = MTK_GET_PIN_FUNC(pinfunc);
461
462 if (pin >= hw->soc->npins ||
463 func >= ARRAY_SIZE(mtk_gpio_functions)) {
464 dev_err(hw->dev, "invalid pins value.\n");
465 err = -EINVAL;
466 goto exit;
467 }
468
469 grp = mtk_pctrl_find_group_by_pin(hw, pin);
470 if (!grp) {
471 dev_err(hw->dev, "unable to match pin %d to group\n",
472 pin);
473 err = -EINVAL;
474 goto exit;
475 }
476
477 err = mtk_pctrl_dt_node_to_map_func(hw, pin, func, grp, map,
478 reserved_maps, num_maps);
479 if (err < 0)
480 goto exit;
481
482 if (has_config) {
483 err = pinctrl_utils_add_map_configs(pctldev, map,
484 reserved_maps,
485 num_maps,
486 grp->name,
487 configs,
488 num_configs,
489 PIN_MAP_TYPE_CONFIGS_GROUP);
490 if (err < 0)
491 goto exit;
492 }
493 }
494
495 err = 0;
496
497exit:
498 kfree(configs);
499 return err;
500}
501
502static int mtk_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
503 struct device_node *np_config,
504 struct pinctrl_map **map,
505 unsigned *num_maps)
506{
507 struct device_node *np;
508 unsigned reserved_maps;
509 int ret;
510
511 *map = NULL;
512 *num_maps = 0;
513 reserved_maps = 0;
514
515 for_each_child_of_node(np_config, np) {
516 ret = mtk_pctrl_dt_subnode_to_map(pctldev, np, map,
517 &reserved_maps,
518 num_maps);
519 if (ret < 0) {
520 pinctrl_utils_free_map(pctldev, *map, *num_maps);
521 of_node_put(np);
522 return ret;
523 }
524 }
525
526 return 0;
527}
528
529static int mtk_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
530{
531 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
532
533 return hw->soc->ngrps;
534}
535
536static const char *mtk_pctrl_get_group_name(struct pinctrl_dev *pctldev,
537 unsigned group)
538{
539 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
540
541 return hw->groups[group].name;
542}
543
544static int mtk_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
545 unsigned group, const unsigned **pins,
546 unsigned *num_pins)
547{
548 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
549
550 *pins = (unsigned *)&hw->groups[group].pin;
551 *num_pins = 1;
552
553 return 0;
554}
555
556static const struct pinctrl_ops mtk_pctlops = {
557 .dt_node_to_map = mtk_pctrl_dt_node_to_map,
558 .dt_free_map = pinctrl_utils_free_map,
559 .get_groups_count = mtk_pctrl_get_groups_count,
560 .get_group_name = mtk_pctrl_get_group_name,
561 .get_group_pins = mtk_pctrl_get_group_pins,
562};
563
564static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
565{
566 return ARRAY_SIZE(mtk_gpio_functions);
567}
568
569static const char *mtk_pmx_get_func_name(struct pinctrl_dev *pctldev,
570 unsigned selector)
571{
572 return mtk_gpio_functions[selector];
573}
574
575static int mtk_pmx_get_func_groups(struct pinctrl_dev *pctldev,
576 unsigned function,
577 const char * const **groups,
578 unsigned * const num_groups)
579{
580 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
581
582 *groups = hw->grp_names;
583 *num_groups = hw->soc->ngrps;
584
585 return 0;
586}
587
588static int mtk_pmx_set_mux(struct pinctrl_dev *pctldev,
589 unsigned function,
590 unsigned group)
591{
592 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
593 struct mtk_pinctrl_group *grp = hw->groups + group;
594 const struct mtk_func_desc *desc_func;
595 const struct mtk_pin_desc *desc;
596 bool ret;
597
598 ret = mtk_pctrl_is_function_valid(hw, grp->pin, function);
599 if (!ret) {
600 dev_err(hw->dev, "invalid function %d on group %d .\n",
601 function, group);
602 return -EINVAL;
603 }
604
605 desc_func = mtk_pctrl_find_function_by_pin(hw, grp->pin, function);
606 if (!desc_func)
607 return -EINVAL;
608
609 desc = (const struct mtk_pin_desc *)&hw->soc->pins[grp->pin];
610 mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE, desc_func->muxval);
611
612 return 0;
613}
614
615static const struct pinmux_ops mtk_pmxops = {
616 .get_functions_count = mtk_pmx_get_funcs_cnt,
617 .get_function_name = mtk_pmx_get_func_name,
618 .get_function_groups = mtk_pmx_get_func_groups,
619 .set_mux = mtk_pmx_set_mux,
620 .gpio_set_direction = mtk_pinmux_gpio_set_direction,
621 .gpio_request_enable = mtk_pinmux_gpio_request_enable,
622};
623
624static int mtk_pconf_group_get(struct pinctrl_dev *pctldev, unsigned group,
625 unsigned long *config)
626{
627 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
628
629 *config = hw->groups[group].config;
630
631 return 0;
632}
633
634static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group,
635 unsigned long *configs, unsigned num_configs)
636{
637 struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
638 struct mtk_pinctrl_group *grp = &hw->groups[group];
639 int i, ret;
640
641 for (i = 0; i < num_configs; i++) {
642 ret = mtk_pinconf_set(pctldev, grp->pin,
643 pinconf_to_config_param(configs[i]),
644 pinconf_to_config_argument(configs[i]));
645 if (ret < 0)
646 return ret;
647
648 grp->config = configs[i];
649 }
650
651 return 0;
652}
653
654static const struct pinconf_ops mtk_confops = {
655 .pin_config_get = mtk_pinconf_get,
656 .pin_config_group_get = mtk_pconf_group_get,
657 .pin_config_group_set = mtk_pconf_group_set,
658};
659
660static struct pinctrl_desc mtk_desc = {
661 .name = PINCTRL_PINCTRL_DEV,
662 .pctlops = &mtk_pctlops,
663 .pmxops = &mtk_pmxops,
664 .confops = &mtk_confops,
665 .owner = THIS_MODULE,
666};
667
668static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
669{
670 struct mtk_pinctrl *hw = gpiochip_get_data(chip);
671 const struct mtk_pin_desc *desc;
672 int value, err;
673
674 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
675
676 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
677 if (err)
678 return err;
679
680 return !value;
681}
682
683static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
684{
685 struct mtk_pinctrl *hw = gpiochip_get_data(chip);
686 const struct mtk_pin_desc *desc;
687 int value, err;
688
689 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
690
691 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
692 if (err)
693 return err;
694
695 return !!value;
696}
697
698static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
699{
700 struct mtk_pinctrl *hw = gpiochip_get_data(chip);
701 const struct mtk_pin_desc *desc;
702
703 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
704
705 mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
706}
707
708static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
709{
710 return pinctrl_gpio_direction_input(chip->base + gpio);
711}
712
713static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
714 int value)
715{
716 mtk_gpio_set(chip, gpio, value);
717
718 return pinctrl_gpio_direction_output(chip->base + gpio);
719}
720
721static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
722 unsigned long config)
723{
724 struct mtk_pinctrl *hw = gpiochip_get_data(chip);
725 const struct mtk_pin_desc *desc;
726 u32 debounce;
727
728 desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset];
729
730 if (!hw->eint ||
731 pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE ||
732 desc->eint.eint_n == EINT_NA)
733 return -ENOTSUPP;
734
735 debounce = pinconf_to_config_argument(config);
736
737 return mtk_eint_set_debounce(hw->eint, desc->eint.eint_n, debounce);
738}
739
740static int mtk_build_gpiochip(struct mtk_pinctrl *hw, struct device_node *np)
741{
742 struct gpio_chip *chip = &hw->chip;
743 int ret;
744
745 chip->label = PINCTRL_PINCTRL_DEV;
746 chip->parent = hw->dev;
747 chip->request = gpiochip_generic_request;
748 chip->free = gpiochip_generic_free;
749 chip->get_direction = mtk_gpio_get_direction;
750 chip->direction_input = mtk_gpio_direction_input;
751 chip->direction_output = mtk_gpio_direction_output;
752 chip->get = mtk_gpio_get;
753 chip->set = mtk_gpio_set;
754 chip->set_config = mtk_gpio_set_config,
755 chip->base = -1;
756 chip->ngpio = hw->soc->npins;
757 chip->of_node = np;
758 chip->of_gpio_n_cells = 2;
759
760 ret = gpiochip_add_data(chip, hw);
761 if (ret < 0)
762 return ret;
763
764 return 0;
765}
766
767static int mtk_pctrl_build_state(struct platform_device *pdev)
768{
769 struct mtk_pinctrl *hw = platform_get_drvdata(pdev);
770 int i;
771
772 /* Allocate groups */
773 hw->groups = devm_kmalloc_array(&pdev->dev, hw->soc->ngrps,
774 sizeof(*hw->groups), GFP_KERNEL);
775 if (!hw->groups)
776 return -ENOMEM;
777
778 /* We assume that one pin is one group, use pin name as group name. */
779 hw->grp_names = devm_kmalloc_array(&pdev->dev, hw->soc->ngrps,
780 sizeof(*hw->grp_names), GFP_KERNEL);
781 if (!hw->grp_names)
782 return -ENOMEM;
783
784 for (i = 0; i < hw->soc->npins; i++) {
785 const struct mtk_pin_desc *pin = hw->soc->pins + i;
786 struct mtk_pinctrl_group *group = hw->groups + i;
787
788 group->name = pin->name;
789 group->pin = pin->number;
790
791 hw->grp_names[i] = pin->name;
792 }
793
794 return 0;
795}
796
797int mtk_paris_pinctrl_probe(struct platform_device *pdev,
798 const struct mtk_pin_soc *soc)
799{
800 struct pinctrl_pin_desc *pins;
801 struct mtk_pinctrl *hw;
802 struct resource *res;
803 int err, i;
804
805 hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL);
806 if (!hw)
807 return -ENOMEM;
808
809 platform_set_drvdata(pdev, hw);
810 hw->soc = soc;
811 hw->dev = &pdev->dev;
812
813 if (!hw->soc->nbase_names) {
814 dev_err(&pdev->dev,
815 "SoC should be assigned at least one register base\n");
816 return -EINVAL;
817 }
818
819 hw->base = devm_kmalloc_array(&pdev->dev, hw->soc->nbase_names,
820 sizeof(*hw->base), GFP_KERNEL);
821 if (IS_ERR(hw->base))
822 return PTR_ERR(hw->base);
823
824 for (i = 0; i < hw->soc->nbase_names; i++) {
825 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
826 hw->soc->base_names[i]);
827 if (!res) {
828 dev_err(&pdev->dev, "missing IO resource\n");
829 return -ENXIO;
830 }
831
832 hw->base[i] = devm_ioremap_resource(&pdev->dev, res);
833 if (IS_ERR(hw->base[i]))
834 return PTR_ERR(hw->base[i]);
835 }
836
837 hw->nbase = hw->soc->nbase_names;
838
839 err = mtk_pctrl_build_state(pdev);
840 if (err) {
841 dev_err(&pdev->dev, "build state failed: %d\n", err);
842 return -EINVAL;
843 }
844
845 /* Copy from internal struct mtk_pin_desc to register to the core */
846 pins = devm_kmalloc_array(&pdev->dev, hw->soc->npins, sizeof(*pins),
847 GFP_KERNEL);
848 if (IS_ERR(pins))
849 return PTR_ERR(pins);
850
851 for (i = 0; i < hw->soc->npins; i++) {
852 pins[i].number = hw->soc->pins[i].number;
853 pins[i].name = hw->soc->pins[i].name;
854 }
855
856 /* Setup pins descriptions per SoC types */
857 mtk_desc.pins = (const struct pinctrl_pin_desc *)pins;
858 mtk_desc.npins = hw->soc->npins;
859 mtk_desc.num_custom_params = ARRAY_SIZE(mtk_custom_bindings);
860 mtk_desc.custom_params = mtk_custom_bindings;
861#ifdef CONFIG_DEBUG_FS
862 mtk_desc.custom_conf_items = mtk_conf_items;
863#endif
864
865 err = devm_pinctrl_register_and_init(&pdev->dev, &mtk_desc, hw,
866 &hw->pctrl);
867 if (err)
868 return err;
869
870 err = pinctrl_enable(hw->pctrl);
871 if (err)
872 return err;
873
874 /* Build gpiochip should be after pinctrl_enable is done */
875 err = mtk_build_gpiochip(hw, pdev->dev.of_node);
876 if (err) {
877 dev_err(&pdev->dev, "Failed to add gpio_chip\n");
878 return err;
879 }
880
881 platform_set_drvdata(pdev, hw);
882
883 return 0;
884}
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.h b/drivers/pinctrl/mediatek/pinctrl-paris.h
new file mode 100644
index 000000000000..e4d204e4ce8d
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.h
@@ -0,0 +1,65 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2018 MediaTek Inc.
4 *
5 * Author: Sean Wang <sean.wang@mediatek.com>
6 * Zhiyong Tao <zhiyong.tao@mediatek.com>
7 * Hongzhou.Yang <hongzhou.yang@mediatek.com>
8 */
9#ifndef __PINCTRL_PARIS_H
10#define __PINCTRL_PARIS_H
11
12#include <linux/gpio.h>
13#include <linux/gpio/driver.h>
14#include <linux/io.h>
15#include <linux/init.h>
16#include <linux/of.h>
17#include <linux/of_platform.h>
18#include <linux/platform_device.h>
19#include <linux/pinctrl/pinctrl.h>
20#include <linux/pinctrl/pinmux.h>
21#include <linux/pinctrl/pinconf.h>
22#include <linux/pinctrl/pinconf-generic.h>
23
24#include "../core.h"
25#include "../pinconf.h"
26#include "../pinctrl-utils.h"
27#include "../pinmux.h"
28#include "mtk-eint.h"
29#include "pinctrl-mtk-common-v2.h"
30
31#define MTK_RANGE(_a) { .range = (_a), .nranges = ARRAY_SIZE(_a), }
32
33#define MTK_EINT_FUNCTION(_eintmux, _eintnum) \
34 { \
35 .eint_m = _eintmux, \
36 .eint_n = _eintnum, \
37 }
38
39#define MTK_FUNCTION(_val, _name) \
40 { \
41 .muxval = _val, \
42 .name = _name, \
43 }
44
45#define MTK_PIN(_number, _name, _eint, _drv_n, ...) { \
46 .number = _number, \
47 .name = _name, \
48 .eint = _eint, \
49 .drv_n = _drv_n, \
50 .funcs = (struct mtk_func_desc[]){ \
51 __VA_ARGS__, { } }, \
52 }
53
54#define PINCTRL_PIN_GROUP(name, id) \
55 { \
56 name, \
57 id##_pins, \
58 ARRAY_SIZE(id##_pins), \
59 id##_funcs, \
60 }
61
62int mtk_paris_pinctrl_probe(struct platform_device *pdev,
63 const struct mtk_pin_soc *soc);
64
65#endif /* __PINCTRL_PARIS_H */