1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * mt65xx pinctrl driver based on Allwinner A1X pinctrl driver. |
4 | * Copyright (c) 2014 MediaTek Inc. |
5 | * Author: Hongzhou.Yang <hongzhou.yang@mediatek.com> |
6 | */ |
7 | |
8 | #include <linux/io.h> |
9 | #include <linux/gpio/driver.h> |
10 | #include <linux/of.h> |
11 | #include <linux/of_irq.h> |
12 | #include <linux/pinctrl/consumer.h> |
13 | #include <linux/pinctrl/machine.h> |
14 | #include <linux/pinctrl/pinconf.h> |
15 | #include <linux/pinctrl/pinconf-generic.h> |
16 | #include <linux/pinctrl/pinctrl.h> |
17 | #include <linux/pinctrl/pinmux.h> |
18 | #include <linux/platform_device.h> |
19 | #include <linux/slab.h> |
20 | #include <linux/bitops.h> |
21 | #include <linux/regmap.h> |
22 | #include <linux/mfd/syscon.h> |
23 | #include <linux/delay.h> |
24 | #include <linux/interrupt.h> |
25 | #include <linux/pm.h> |
26 | #include <dt-bindings/pinctrl/mt65xx.h> |
27 | |
28 | #include "../core.h" |
29 | #include "../pinconf.h" |
30 | #include "../pinctrl-utils.h" |
31 | #include "mtk-eint.h" |
32 | #include "pinctrl-mtk-common.h" |
33 | |
34 | #define GPIO_MODE_BITS 3 |
35 | #define GPIO_MODE_PREFIX "GPIO" |
36 | |
37 | static const char * const mtk_gpio_functions[] = { |
38 | "func0" , "func1" , "func2" , "func3" , |
39 | "func4" , "func5" , "func6" , "func7" , |
40 | "func8" , "func9" , "func10" , "func11" , |
41 | "func12" , "func13" , "func14" , "func15" , |
42 | }; |
43 | |
44 | /* |
45 | * There are two base address for pull related configuration |
46 | * in mt8135, and different GPIO pins use different base address. |
47 | * When pin number greater than type1_start and less than type1_end, |
48 | * should use the second base address. |
49 | */ |
50 | static struct regmap *mtk_get_regmap(struct mtk_pinctrl *pctl, |
51 | unsigned long pin) |
52 | { |
53 | if (pin >= pctl->devdata->type1_start && pin < pctl->devdata->type1_end) |
54 | return pctl->regmap2; |
55 | return pctl->regmap1; |
56 | } |
57 | |
58 | static unsigned int mtk_get_port(struct mtk_pinctrl *pctl, unsigned long pin) |
59 | { |
60 | /* Different SoC has different mask and port shift. */ |
61 | return ((pin >> pctl->devdata->mode_shf) & pctl->devdata->port_mask) |
62 | << pctl->devdata->port_shf; |
63 | } |
64 | |
65 | static int mtk_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, |
66 | struct pinctrl_gpio_range *range, unsigned offset, |
67 | bool input) |
68 | { |
69 | unsigned int reg_addr; |
70 | unsigned int bit; |
71 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
72 | |
73 | reg_addr = mtk_get_port(pctl, pin: offset) + pctl->devdata->dir_offset; |
74 | bit = BIT(offset & pctl->devdata->mode_mask); |
75 | |
76 | if (pctl->devdata->spec_dir_set) |
77 | pctl->devdata->spec_dir_set(®_addr, offset); |
78 | |
79 | if (input) |
80 | /* Different SoC has different alignment offset. */ |
81 | reg_addr = CLR_ADDR(reg_addr, pctl); |
82 | else |
83 | reg_addr = SET_ADDR(reg_addr, pctl); |
84 | |
85 | regmap_write(map: mtk_get_regmap(pctl, pin: offset), reg: reg_addr, val: bit); |
86 | return 0; |
87 | } |
88 | |
89 | static void mtk_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
90 | { |
91 | unsigned int reg_addr; |
92 | unsigned int bit; |
93 | struct mtk_pinctrl *pctl = gpiochip_get_data(gc: chip); |
94 | |
95 | reg_addr = mtk_get_port(pctl, pin: offset) + pctl->devdata->dout_offset; |
96 | bit = BIT(offset & pctl->devdata->mode_mask); |
97 | |
98 | if (value) |
99 | reg_addr = SET_ADDR(reg_addr, pctl); |
100 | else |
101 | reg_addr = CLR_ADDR(reg_addr, pctl); |
102 | |
103 | regmap_write(map: mtk_get_regmap(pctl, pin: offset), reg: reg_addr, val: bit); |
104 | } |
105 | |
106 | static int mtk_pconf_set_ies_smt(struct mtk_pinctrl *pctl, unsigned pin, |
107 | int value, enum pin_config_param arg) |
108 | { |
109 | unsigned int reg_addr, offset; |
110 | unsigned int bit; |
111 | |
112 | /** |
113 | * Due to some soc are not support ies/smt config, add this special |
114 | * control to handle it. |
115 | */ |
116 | if (!pctl->devdata->spec_ies_smt_set && |
117 | pctl->devdata->ies_offset == MTK_PINCTRL_NOT_SUPPORT && |
118 | arg == PIN_CONFIG_INPUT_ENABLE) |
119 | return -EINVAL; |
120 | |
121 | if (!pctl->devdata->spec_ies_smt_set && |
122 | pctl->devdata->smt_offset == MTK_PINCTRL_NOT_SUPPORT && |
123 | arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE) |
124 | return -EINVAL; |
125 | |
126 | /* |
127 | * Due to some pins are irregular, their input enable and smt |
128 | * control register are discontinuous, so we need this special handle. |
129 | */ |
130 | if (pctl->devdata->spec_ies_smt_set) { |
131 | return pctl->devdata->spec_ies_smt_set(mtk_get_regmap(pctl, pin), |
132 | pctl->devdata, pin, value, arg); |
133 | } |
134 | |
135 | if (arg == PIN_CONFIG_INPUT_ENABLE) |
136 | offset = pctl->devdata->ies_offset; |
137 | else |
138 | offset = pctl->devdata->smt_offset; |
139 | |
140 | bit = BIT(offset & pctl->devdata->mode_mask); |
141 | |
142 | if (value) |
143 | reg_addr = SET_ADDR(mtk_get_port(pctl, pin) + offset, pctl); |
144 | else |
145 | reg_addr = CLR_ADDR(mtk_get_port(pctl, pin) + offset, pctl); |
146 | |
147 | regmap_write(map: mtk_get_regmap(pctl, pin), reg: reg_addr, val: bit); |
148 | return 0; |
149 | } |
150 | |
151 | int mtk_pconf_spec_set_ies_smt_range(struct regmap *regmap, |
152 | const struct mtk_pinctrl_devdata *devdata, |
153 | unsigned int pin, int value, enum pin_config_param arg) |
154 | { |
155 | const struct mtk_pin_ies_smt_set *ies_smt_infos = NULL; |
156 | unsigned int i, info_num, reg_addr, bit; |
157 | |
158 | switch (arg) { |
159 | case PIN_CONFIG_INPUT_ENABLE: |
160 | ies_smt_infos = devdata->spec_ies; |
161 | info_num = devdata->n_spec_ies; |
162 | break; |
163 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: |
164 | ies_smt_infos = devdata->spec_smt; |
165 | info_num = devdata->n_spec_smt; |
166 | break; |
167 | default: |
168 | break; |
169 | } |
170 | |
171 | if (!ies_smt_infos) |
172 | return -EINVAL; |
173 | |
174 | for (i = 0; i < info_num; i++) { |
175 | if (pin >= ies_smt_infos[i].start && |
176 | pin <= ies_smt_infos[i].end) { |
177 | break; |
178 | } |
179 | } |
180 | |
181 | if (i == info_num) |
182 | return -EINVAL; |
183 | |
184 | if (value) |
185 | reg_addr = ies_smt_infos[i].offset + devdata->port_align; |
186 | else |
187 | reg_addr = ies_smt_infos[i].offset + (devdata->port_align << 1); |
188 | |
189 | bit = BIT(ies_smt_infos[i].bit); |
190 | regmap_write(map: regmap, reg: reg_addr, val: bit); |
191 | return 0; |
192 | } |
193 | |
194 | static const struct mtk_pin_drv_grp *mtk_find_pin_drv_grp_by_pin( |
195 | struct mtk_pinctrl *pctl, unsigned long pin) { |
196 | int i; |
197 | |
198 | for (i = 0; i < pctl->devdata->n_pin_drv_grps; i++) { |
199 | const struct mtk_pin_drv_grp *pin_drv = |
200 | pctl->devdata->pin_drv_grp + i; |
201 | if (pin == pin_drv->pin) |
202 | return pin_drv; |
203 | } |
204 | |
205 | return NULL; |
206 | } |
207 | |
208 | static int mtk_pconf_set_driving(struct mtk_pinctrl *pctl, |
209 | unsigned int pin, unsigned char driving) |
210 | { |
211 | const struct mtk_pin_drv_grp *pin_drv; |
212 | unsigned int val; |
213 | unsigned int bits, mask, shift; |
214 | const struct mtk_drv_group_desc *drv_grp; |
215 | |
216 | if (pin >= pctl->devdata->npins) |
217 | return -EINVAL; |
218 | |
219 | pin_drv = mtk_find_pin_drv_grp_by_pin(pctl, pin); |
220 | if (!pin_drv || pin_drv->grp > pctl->devdata->n_grp_cls) |
221 | return -EINVAL; |
222 | |
223 | drv_grp = pctl->devdata->grp_desc + pin_drv->grp; |
224 | if (driving >= drv_grp->min_drv && driving <= drv_grp->max_drv |
225 | && !(driving % drv_grp->step)) { |
226 | val = driving / drv_grp->step - 1; |
227 | bits = drv_grp->high_bit - drv_grp->low_bit + 1; |
228 | mask = BIT(bits) - 1; |
229 | shift = pin_drv->bit + drv_grp->low_bit; |
230 | mask <<= shift; |
231 | val <<= shift; |
232 | return regmap_update_bits(map: mtk_get_regmap(pctl, pin), |
233 | reg: pin_drv->offset, mask, val); |
234 | } |
235 | |
236 | return -EINVAL; |
237 | } |
238 | |
239 | int mtk_pctrl_spec_pull_set_samereg(struct regmap *regmap, |
240 | const struct mtk_pinctrl_devdata *devdata, |
241 | unsigned int pin, bool isup, unsigned int r1r0) |
242 | { |
243 | unsigned int i; |
244 | unsigned int reg_pupd, reg_set, reg_rst; |
245 | unsigned int bit_pupd, bit_r0, bit_r1; |
246 | const struct mtk_pin_spec_pupd_set_samereg *spec_pupd_pin; |
247 | bool find = false; |
248 | |
249 | if (!devdata->spec_pupd) |
250 | return -EINVAL; |
251 | |
252 | for (i = 0; i < devdata->n_spec_pupd; i++) { |
253 | if (pin == devdata->spec_pupd[i].pin) { |
254 | find = true; |
255 | break; |
256 | } |
257 | } |
258 | |
259 | if (!find) |
260 | return -EINVAL; |
261 | |
262 | spec_pupd_pin = devdata->spec_pupd + i; |
263 | reg_set = spec_pupd_pin->offset + devdata->port_align; |
264 | reg_rst = spec_pupd_pin->offset + (devdata->port_align << 1); |
265 | |
266 | if (isup) |
267 | reg_pupd = reg_rst; |
268 | else |
269 | reg_pupd = reg_set; |
270 | |
271 | bit_pupd = BIT(spec_pupd_pin->pupd_bit); |
272 | regmap_write(map: regmap, reg: reg_pupd, val: bit_pupd); |
273 | |
274 | bit_r0 = BIT(spec_pupd_pin->r0_bit); |
275 | bit_r1 = BIT(spec_pupd_pin->r1_bit); |
276 | |
277 | switch (r1r0) { |
278 | case MTK_PUPD_SET_R1R0_00: |
279 | regmap_write(map: regmap, reg: reg_rst, val: bit_r0); |
280 | regmap_write(map: regmap, reg: reg_rst, val: bit_r1); |
281 | break; |
282 | case MTK_PUPD_SET_R1R0_01: |
283 | regmap_write(map: regmap, reg: reg_set, val: bit_r0); |
284 | regmap_write(map: regmap, reg: reg_rst, val: bit_r1); |
285 | break; |
286 | case MTK_PUPD_SET_R1R0_10: |
287 | regmap_write(map: regmap, reg: reg_rst, val: bit_r0); |
288 | regmap_write(map: regmap, reg: reg_set, val: bit_r1); |
289 | break; |
290 | case MTK_PUPD_SET_R1R0_11: |
291 | regmap_write(map: regmap, reg: reg_set, val: bit_r0); |
292 | regmap_write(map: regmap, reg: reg_set, val: bit_r1); |
293 | break; |
294 | default: |
295 | return -EINVAL; |
296 | } |
297 | |
298 | return 0; |
299 | } |
300 | |
301 | static int mtk_pconf_set_pull_select(struct mtk_pinctrl *pctl, |
302 | unsigned int pin, bool enable, bool isup, unsigned int arg) |
303 | { |
304 | unsigned int bit; |
305 | unsigned int reg_pullen, reg_pullsel, r1r0; |
306 | int ret; |
307 | |
308 | /* Some pins' pull setting are very different, |
309 | * they have separate pull up/down bit, R0 and R1 |
310 | * resistor bit, so we need this special handle. |
311 | */ |
312 | if (pctl->devdata->spec_pull_set) { |
313 | /* For special pins, bias-disable is set by R1R0, |
314 | * the parameter should be "MTK_PUPD_SET_R1R0_00". |
315 | */ |
316 | r1r0 = enable ? arg : MTK_PUPD_SET_R1R0_00; |
317 | ret = pctl->devdata->spec_pull_set(mtk_get_regmap(pctl, pin), |
318 | pctl->devdata, pin, isup, |
319 | r1r0); |
320 | if (!ret) |
321 | return 0; |
322 | } |
323 | |
324 | /* For generic pull config, default arg value should be 0 or 1. */ |
325 | if (arg != 0 && arg != 1) { |
326 | dev_err(pctl->dev, "invalid pull-up argument %d on pin %d .\n" , |
327 | arg, pin); |
328 | return -EINVAL; |
329 | } |
330 | |
331 | if (pctl->devdata->mt8365_set_clr_mode) { |
332 | bit = pin & pctl->devdata->mode_mask; |
333 | reg_pullen = mtk_get_port(pctl, pin) + |
334 | pctl->devdata->pullen_offset; |
335 | reg_pullsel = mtk_get_port(pctl, pin) + |
336 | pctl->devdata->pullsel_offset; |
337 | ret = pctl->devdata->mt8365_set_clr_mode(mtk_get_regmap(pctl, pin), |
338 | bit, reg_pullen, reg_pullsel, |
339 | enable, isup); |
340 | if (ret) |
341 | return -EINVAL; |
342 | |
343 | return 0; |
344 | } |
345 | |
346 | bit = BIT(pin & pctl->devdata->mode_mask); |
347 | if (enable) |
348 | reg_pullen = SET_ADDR(mtk_get_port(pctl, pin) + |
349 | pctl->devdata->pullen_offset, pctl); |
350 | else |
351 | reg_pullen = CLR_ADDR(mtk_get_port(pctl, pin) + |
352 | pctl->devdata->pullen_offset, pctl); |
353 | |
354 | if (isup) |
355 | reg_pullsel = SET_ADDR(mtk_get_port(pctl, pin) + |
356 | pctl->devdata->pullsel_offset, pctl); |
357 | else |
358 | reg_pullsel = CLR_ADDR(mtk_get_port(pctl, pin) + |
359 | pctl->devdata->pullsel_offset, pctl); |
360 | |
361 | regmap_write(map: mtk_get_regmap(pctl, pin), reg: reg_pullen, val: bit); |
362 | regmap_write(map: mtk_get_regmap(pctl, pin), reg: reg_pullsel, val: bit); |
363 | return 0; |
364 | } |
365 | |
366 | static int mtk_pconf_parse_conf(struct pinctrl_dev *pctldev, |
367 | unsigned int pin, enum pin_config_param param, |
368 | enum pin_config_param arg) |
369 | { |
370 | int ret = 0; |
371 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
372 | |
373 | switch (param) { |
374 | case PIN_CONFIG_BIAS_DISABLE: |
375 | ret = mtk_pconf_set_pull_select(pctl, pin, enable: false, isup: false, arg); |
376 | break; |
377 | case PIN_CONFIG_BIAS_PULL_UP: |
378 | ret = mtk_pconf_set_pull_select(pctl, pin, enable: true, isup: true, arg); |
379 | break; |
380 | case PIN_CONFIG_BIAS_PULL_DOWN: |
381 | ret = mtk_pconf_set_pull_select(pctl, pin, enable: true, isup: false, arg); |
382 | break; |
383 | case PIN_CONFIG_INPUT_ENABLE: |
384 | mtk_pmx_gpio_set_direction(pctldev, NULL, offset: pin, input: true); |
385 | ret = mtk_pconf_set_ies_smt(pctl, pin, value: arg, arg: param); |
386 | break; |
387 | case PIN_CONFIG_OUTPUT: |
388 | mtk_gpio_set(chip: pctl->chip, offset: pin, value: arg); |
389 | ret = mtk_pmx_gpio_set_direction(pctldev, NULL, offset: pin, input: false); |
390 | break; |
391 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: |
392 | mtk_pmx_gpio_set_direction(pctldev, NULL, offset: pin, input: true); |
393 | ret = mtk_pconf_set_ies_smt(pctl, pin, value: arg, arg: param); |
394 | break; |
395 | case PIN_CONFIG_DRIVE_STRENGTH: |
396 | ret = mtk_pconf_set_driving(pctl, pin, driving: arg); |
397 | break; |
398 | default: |
399 | ret = -EINVAL; |
400 | } |
401 | |
402 | return ret; |
403 | } |
404 | |
405 | static int mtk_pconf_group_get(struct pinctrl_dev *pctldev, |
406 | unsigned group, |
407 | unsigned long *config) |
408 | { |
409 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
410 | |
411 | *config = pctl->groups[group].config; |
412 | |
413 | return 0; |
414 | } |
415 | |
416 | static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, |
417 | unsigned long *configs, unsigned num_configs) |
418 | { |
419 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
420 | struct mtk_pinctrl_group *g = &pctl->groups[group]; |
421 | int i, ret; |
422 | |
423 | for (i = 0; i < num_configs; i++) { |
424 | ret = mtk_pconf_parse_conf(pctldev, pin: g->pin, |
425 | param: pinconf_to_config_param(config: configs[i]), |
426 | arg: pinconf_to_config_argument(config: configs[i])); |
427 | if (ret < 0) |
428 | return ret; |
429 | |
430 | g->config = configs[i]; |
431 | } |
432 | |
433 | return 0; |
434 | } |
435 | |
436 | static const struct pinconf_ops mtk_pconf_ops = { |
437 | .pin_config_group_get = mtk_pconf_group_get, |
438 | .pin_config_group_set = mtk_pconf_group_set, |
439 | }; |
440 | |
441 | static struct mtk_pinctrl_group * |
442 | mtk_pctrl_find_group_by_pin(struct mtk_pinctrl *pctl, u32 pin) |
443 | { |
444 | int i; |
445 | |
446 | for (i = 0; i < pctl->ngroups; i++) { |
447 | struct mtk_pinctrl_group *grp = pctl->groups + i; |
448 | |
449 | if (grp->pin == pin) |
450 | return grp; |
451 | } |
452 | |
453 | return NULL; |
454 | } |
455 | |
456 | static const struct mtk_desc_function *mtk_pctrl_find_function_by_pin( |
457 | struct mtk_pinctrl *pctl, u32 pin_num, u32 fnum) |
458 | { |
459 | const struct mtk_desc_pin *pin = pctl->devdata->pins + pin_num; |
460 | const struct mtk_desc_function *func = pin->functions; |
461 | |
462 | while (func && func->name) { |
463 | if (func->muxval == fnum) |
464 | return func; |
465 | func++; |
466 | } |
467 | |
468 | return NULL; |
469 | } |
470 | |
471 | static bool mtk_pctrl_is_function_valid(struct mtk_pinctrl *pctl, |
472 | u32 pin_num, u32 fnum) |
473 | { |
474 | int i; |
475 | |
476 | for (i = 0; i < pctl->devdata->npins; i++) { |
477 | const struct mtk_desc_pin *pin = pctl->devdata->pins + i; |
478 | |
479 | if (pin->pin.number == pin_num) { |
480 | const struct mtk_desc_function *func = |
481 | pin->functions; |
482 | |
483 | while (func && func->name) { |
484 | if (func->muxval == fnum) |
485 | return true; |
486 | func++; |
487 | } |
488 | |
489 | break; |
490 | } |
491 | } |
492 | |
493 | return false; |
494 | } |
495 | |
496 | static int mtk_pctrl_dt_node_to_map_func(struct mtk_pinctrl *pctl, |
497 | u32 pin, u32 fnum, struct mtk_pinctrl_group *grp, |
498 | struct pinctrl_map **map, unsigned *reserved_maps, |
499 | unsigned *num_maps) |
500 | { |
501 | bool ret; |
502 | |
503 | if (*num_maps == *reserved_maps) |
504 | return -ENOSPC; |
505 | |
506 | (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP; |
507 | (*map)[*num_maps].data.mux.group = grp->name; |
508 | |
509 | ret = mtk_pctrl_is_function_valid(pctl, pin_num: pin, fnum); |
510 | if (!ret) { |
511 | dev_err(pctl->dev, "invalid function %d on pin %d .\n" , |
512 | fnum, pin); |
513 | return -EINVAL; |
514 | } |
515 | |
516 | (*map)[*num_maps].data.mux.function = mtk_gpio_functions[fnum]; |
517 | (*num_maps)++; |
518 | |
519 | return 0; |
520 | } |
521 | |
522 | static int mtk_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, |
523 | struct device_node *node, |
524 | struct pinctrl_map **map, |
525 | unsigned *reserved_maps, |
526 | unsigned *num_maps) |
527 | { |
528 | struct property *pins; |
529 | u32 pinfunc, pin, func; |
530 | int num_pins, num_funcs, maps_per_pin; |
531 | unsigned long *configs; |
532 | unsigned int num_configs; |
533 | bool has_config = false; |
534 | int i, err; |
535 | unsigned reserve = 0; |
536 | struct mtk_pinctrl_group *grp; |
537 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
538 | |
539 | pins = of_find_property(np: node, name: "pinmux" , NULL); |
540 | if (!pins) { |
541 | dev_err(pctl->dev, "missing pins property in node %pOFn .\n" , |
542 | node); |
543 | return -EINVAL; |
544 | } |
545 | |
546 | err = pinconf_generic_parse_dt_config(np: node, pctldev, configs: &configs, |
547 | nconfigs: &num_configs); |
548 | if (err) |
549 | return err; |
550 | |
551 | if (num_configs) |
552 | has_config = true; |
553 | |
554 | num_pins = pins->length / sizeof(u32); |
555 | num_funcs = num_pins; |
556 | maps_per_pin = 0; |
557 | if (num_funcs) |
558 | maps_per_pin++; |
559 | if (has_config && num_pins >= 1) |
560 | maps_per_pin++; |
561 | |
562 | if (!num_pins || !maps_per_pin) { |
563 | err = -EINVAL; |
564 | goto exit; |
565 | } |
566 | |
567 | reserve = num_pins * maps_per_pin; |
568 | |
569 | err = pinctrl_utils_reserve_map(pctldev, map, |
570 | reserved_maps, num_maps, reserve); |
571 | if (err < 0) |
572 | goto exit; |
573 | |
574 | for (i = 0; i < num_pins; i++) { |
575 | err = of_property_read_u32_index(np: node, propname: "pinmux" , |
576 | index: i, out_value: &pinfunc); |
577 | if (err) |
578 | goto exit; |
579 | |
580 | pin = MTK_GET_PIN_NO(pinfunc); |
581 | func = MTK_GET_PIN_FUNC(pinfunc); |
582 | |
583 | if (pin >= pctl->devdata->npins || |
584 | func >= ARRAY_SIZE(mtk_gpio_functions)) { |
585 | dev_err(pctl->dev, "invalid pins value.\n" ); |
586 | err = -EINVAL; |
587 | goto exit; |
588 | } |
589 | |
590 | grp = mtk_pctrl_find_group_by_pin(pctl, pin); |
591 | if (!grp) { |
592 | dev_err(pctl->dev, "unable to match pin %d to group\n" , |
593 | pin); |
594 | err = -EINVAL; |
595 | goto exit; |
596 | } |
597 | |
598 | err = mtk_pctrl_dt_node_to_map_func(pctl, pin, fnum: func, grp, map, |
599 | reserved_maps, num_maps); |
600 | if (err < 0) |
601 | goto exit; |
602 | |
603 | if (has_config) { |
604 | err = pinctrl_utils_add_map_configs(pctldev, map, |
605 | reserved_maps, num_maps, group: grp->name, |
606 | configs, num_configs, |
607 | type: PIN_MAP_TYPE_CONFIGS_GROUP); |
608 | if (err < 0) |
609 | goto exit; |
610 | } |
611 | } |
612 | |
613 | err = 0; |
614 | |
615 | exit: |
616 | kfree(objp: configs); |
617 | return err; |
618 | } |
619 | |
620 | static int mtk_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, |
621 | struct device_node *np_config, |
622 | struct pinctrl_map **map, unsigned *num_maps) |
623 | { |
624 | struct device_node *np; |
625 | unsigned reserved_maps; |
626 | int ret; |
627 | |
628 | *map = NULL; |
629 | *num_maps = 0; |
630 | reserved_maps = 0; |
631 | |
632 | for_each_child_of_node(np_config, np) { |
633 | ret = mtk_pctrl_dt_subnode_to_map(pctldev, node: np, map, |
634 | reserved_maps: &reserved_maps, num_maps); |
635 | if (ret < 0) { |
636 | pinctrl_utils_free_map(pctldev, map: *map, num_maps: *num_maps); |
637 | of_node_put(node: np); |
638 | return ret; |
639 | } |
640 | } |
641 | |
642 | return 0; |
643 | } |
644 | |
645 | static int mtk_pctrl_get_groups_count(struct pinctrl_dev *pctldev) |
646 | { |
647 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
648 | |
649 | return pctl->ngroups; |
650 | } |
651 | |
652 | static const char *mtk_pctrl_get_group_name(struct pinctrl_dev *pctldev, |
653 | unsigned group) |
654 | { |
655 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
656 | |
657 | return pctl->groups[group].name; |
658 | } |
659 | |
660 | static int mtk_pctrl_get_group_pins(struct pinctrl_dev *pctldev, |
661 | unsigned group, |
662 | const unsigned **pins, |
663 | unsigned *num_pins) |
664 | { |
665 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
666 | |
667 | *pins = (unsigned *)&pctl->groups[group].pin; |
668 | *num_pins = 1; |
669 | |
670 | return 0; |
671 | } |
672 | |
673 | static const struct pinctrl_ops mtk_pctrl_ops = { |
674 | .dt_node_to_map = mtk_pctrl_dt_node_to_map, |
675 | .dt_free_map = pinctrl_utils_free_map, |
676 | .get_groups_count = mtk_pctrl_get_groups_count, |
677 | .get_group_name = mtk_pctrl_get_group_name, |
678 | .get_group_pins = mtk_pctrl_get_group_pins, |
679 | }; |
680 | |
681 | static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev) |
682 | { |
683 | return ARRAY_SIZE(mtk_gpio_functions); |
684 | } |
685 | |
686 | static const char *mtk_pmx_get_func_name(struct pinctrl_dev *pctldev, |
687 | unsigned selector) |
688 | { |
689 | return mtk_gpio_functions[selector]; |
690 | } |
691 | |
692 | static int mtk_pmx_get_func_groups(struct pinctrl_dev *pctldev, |
693 | unsigned function, |
694 | const char * const **groups, |
695 | unsigned * const num_groups) |
696 | { |
697 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
698 | |
699 | *groups = pctl->grp_names; |
700 | *num_groups = pctl->ngroups; |
701 | |
702 | return 0; |
703 | } |
704 | |
705 | static int mtk_pmx_set_mode(struct pinctrl_dev *pctldev, |
706 | unsigned long pin, unsigned long mode) |
707 | { |
708 | unsigned int reg_addr; |
709 | unsigned char bit; |
710 | unsigned int val; |
711 | unsigned int mask = (1L << GPIO_MODE_BITS) - 1; |
712 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
713 | |
714 | if (pctl->devdata->spec_pinmux_set) |
715 | pctl->devdata->spec_pinmux_set(mtk_get_regmap(pctl, pin), |
716 | pin, mode); |
717 | |
718 | reg_addr = ((pin / pctl->devdata->mode_per_reg) << pctl->devdata->port_shf) |
719 | + pctl->devdata->pinmux_offset; |
720 | |
721 | mode &= mask; |
722 | bit = pin % pctl->devdata->mode_per_reg; |
723 | mask <<= (GPIO_MODE_BITS * bit); |
724 | val = (mode << (GPIO_MODE_BITS * bit)); |
725 | return regmap_update_bits(map: mtk_get_regmap(pctl, pin), |
726 | reg: reg_addr, mask, val); |
727 | } |
728 | |
729 | static const struct mtk_desc_pin * |
730 | mtk_find_pin_by_eint_num(struct mtk_pinctrl *pctl, unsigned int eint_num) |
731 | { |
732 | int i; |
733 | const struct mtk_desc_pin *pin; |
734 | |
735 | for (i = 0; i < pctl->devdata->npins; i++) { |
736 | pin = pctl->devdata->pins + i; |
737 | if (pin->eint.eintnum == eint_num) |
738 | return pin; |
739 | } |
740 | |
741 | return NULL; |
742 | } |
743 | |
744 | static int mtk_pmx_set_mux(struct pinctrl_dev *pctldev, |
745 | unsigned function, |
746 | unsigned group) |
747 | { |
748 | bool ret; |
749 | const struct mtk_desc_function *desc; |
750 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
751 | struct mtk_pinctrl_group *g = pctl->groups + group; |
752 | |
753 | ret = mtk_pctrl_is_function_valid(pctl, pin_num: g->pin, fnum: function); |
754 | if (!ret) { |
755 | dev_err(pctl->dev, "invalid function %d on group %d .\n" , |
756 | function, group); |
757 | return -EINVAL; |
758 | } |
759 | |
760 | desc = mtk_pctrl_find_function_by_pin(pctl, pin_num: g->pin, fnum: function); |
761 | if (!desc) |
762 | return -EINVAL; |
763 | mtk_pmx_set_mode(pctldev, pin: g->pin, mode: desc->muxval); |
764 | return 0; |
765 | } |
766 | |
767 | static int mtk_pmx_find_gpio_mode(struct mtk_pinctrl *pctl, |
768 | unsigned offset) |
769 | { |
770 | const struct mtk_desc_pin *pin = pctl->devdata->pins + offset; |
771 | const struct mtk_desc_function *func = pin->functions; |
772 | |
773 | while (func && func->name) { |
774 | if (!strncmp(func->name, GPIO_MODE_PREFIX, |
775 | sizeof(GPIO_MODE_PREFIX)-1)) |
776 | return func->muxval; |
777 | func++; |
778 | } |
779 | return -EINVAL; |
780 | } |
781 | |
782 | static int mtk_pmx_gpio_request_enable(struct pinctrl_dev *pctldev, |
783 | struct pinctrl_gpio_range *range, |
784 | unsigned offset) |
785 | { |
786 | int muxval; |
787 | struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
788 | |
789 | muxval = mtk_pmx_find_gpio_mode(pctl, offset); |
790 | |
791 | if (muxval < 0) { |
792 | dev_err(pctl->dev, "invalid gpio pin %d.\n" , offset); |
793 | return -EINVAL; |
794 | } |
795 | |
796 | mtk_pmx_set_mode(pctldev, pin: offset, mode: muxval); |
797 | mtk_pconf_set_ies_smt(pctl, pin: offset, value: 1, arg: PIN_CONFIG_INPUT_ENABLE); |
798 | |
799 | return 0; |
800 | } |
801 | |
802 | static const struct pinmux_ops mtk_pmx_ops = { |
803 | .get_functions_count = mtk_pmx_get_funcs_cnt, |
804 | .get_function_name = mtk_pmx_get_func_name, |
805 | .get_function_groups = mtk_pmx_get_func_groups, |
806 | .set_mux = mtk_pmx_set_mux, |
807 | .gpio_set_direction = mtk_pmx_gpio_set_direction, |
808 | .gpio_request_enable = mtk_pmx_gpio_request_enable, |
809 | }; |
810 | |
811 | static int mtk_gpio_direction_output(struct gpio_chip *chip, |
812 | unsigned offset, int value) |
813 | { |
814 | mtk_gpio_set(chip, offset, value); |
815 | return pinctrl_gpio_direction_output(gc: chip, offset); |
816 | } |
817 | |
818 | static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned offset) |
819 | { |
820 | unsigned int reg_addr; |
821 | unsigned int bit; |
822 | unsigned int read_val = 0; |
823 | |
824 | struct mtk_pinctrl *pctl = gpiochip_get_data(gc: chip); |
825 | |
826 | reg_addr = mtk_get_port(pctl, pin: offset) + pctl->devdata->dir_offset; |
827 | bit = BIT(offset & pctl->devdata->mode_mask); |
828 | |
829 | if (pctl->devdata->spec_dir_set) |
830 | pctl->devdata->spec_dir_set(®_addr, offset); |
831 | |
832 | regmap_read(map: pctl->regmap1, reg: reg_addr, val: &read_val); |
833 | if (read_val & bit) |
834 | return GPIO_LINE_DIRECTION_OUT; |
835 | |
836 | return GPIO_LINE_DIRECTION_IN; |
837 | } |
838 | |
839 | static int mtk_gpio_get(struct gpio_chip *chip, unsigned offset) |
840 | { |
841 | unsigned int reg_addr; |
842 | unsigned int bit; |
843 | unsigned int read_val = 0; |
844 | struct mtk_pinctrl *pctl = gpiochip_get_data(gc: chip); |
845 | |
846 | reg_addr = mtk_get_port(pctl, pin: offset) + |
847 | pctl->devdata->din_offset; |
848 | |
849 | bit = BIT(offset & pctl->devdata->mode_mask); |
850 | regmap_read(map: pctl->regmap1, reg: reg_addr, val: &read_val); |
851 | return !!(read_val & bit); |
852 | } |
853 | |
854 | static int mtk_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
855 | { |
856 | struct mtk_pinctrl *pctl = gpiochip_get_data(gc: chip); |
857 | const struct mtk_desc_pin *pin; |
858 | unsigned long eint_n; |
859 | |
860 | pin = pctl->devdata->pins + offset; |
861 | if (pin->eint.eintnum == NO_EINT_SUPPORT) |
862 | return -EINVAL; |
863 | |
864 | eint_n = pin->eint.eintnum; |
865 | |
866 | return mtk_eint_find_irq(eint: pctl->eint, eint_n); |
867 | } |
868 | |
869 | static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned offset, |
870 | unsigned long config) |
871 | { |
872 | struct mtk_pinctrl *pctl = gpiochip_get_data(gc: chip); |
873 | const struct mtk_desc_pin *pin; |
874 | unsigned long eint_n; |
875 | u32 debounce; |
876 | |
877 | if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) |
878 | return -ENOTSUPP; |
879 | |
880 | pin = pctl->devdata->pins + offset; |
881 | if (pin->eint.eintnum == NO_EINT_SUPPORT) |
882 | return -EINVAL; |
883 | |
884 | debounce = pinconf_to_config_argument(config); |
885 | eint_n = pin->eint.eintnum; |
886 | |
887 | return mtk_eint_set_debounce(eint: pctl->eint, eint_n, debounce); |
888 | } |
889 | |
890 | static const struct gpio_chip mtk_gpio_chip = { |
891 | .owner = THIS_MODULE, |
892 | .request = gpiochip_generic_request, |
893 | .free = gpiochip_generic_free, |
894 | .get_direction = mtk_gpio_get_direction, |
895 | .direction_input = pinctrl_gpio_direction_input, |
896 | .direction_output = mtk_gpio_direction_output, |
897 | .get = mtk_gpio_get, |
898 | .set = mtk_gpio_set, |
899 | .to_irq = mtk_gpio_to_irq, |
900 | .set_config = mtk_gpio_set_config, |
901 | }; |
902 | |
903 | static int mtk_eint_suspend(struct device *device) |
904 | { |
905 | struct mtk_pinctrl *pctl = dev_get_drvdata(dev: device); |
906 | |
907 | return mtk_eint_do_suspend(eint: pctl->eint); |
908 | } |
909 | |
910 | static int mtk_eint_resume(struct device *device) |
911 | { |
912 | struct mtk_pinctrl *pctl = dev_get_drvdata(dev: device); |
913 | |
914 | return mtk_eint_do_resume(eint: pctl->eint); |
915 | } |
916 | |
917 | EXPORT_GPL_DEV_SLEEP_PM_OPS(mtk_eint_pm_ops) = { |
918 | NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_eint_suspend, mtk_eint_resume) |
919 | }; |
920 | |
921 | static int mtk_pctrl_build_state(struct platform_device *pdev) |
922 | { |
923 | struct mtk_pinctrl *pctl = platform_get_drvdata(pdev); |
924 | int i; |
925 | |
926 | pctl->ngroups = pctl->devdata->npins; |
927 | |
928 | /* Allocate groups */ |
929 | pctl->groups = devm_kcalloc(dev: &pdev->dev, n: pctl->ngroups, |
930 | size: sizeof(*pctl->groups), GFP_KERNEL); |
931 | if (!pctl->groups) |
932 | return -ENOMEM; |
933 | |
934 | /* We assume that one pin is one group, use pin name as group name. */ |
935 | pctl->grp_names = devm_kcalloc(dev: &pdev->dev, n: pctl->ngroups, |
936 | size: sizeof(*pctl->grp_names), GFP_KERNEL); |
937 | if (!pctl->grp_names) |
938 | return -ENOMEM; |
939 | |
940 | for (i = 0; i < pctl->devdata->npins; i++) { |
941 | const struct mtk_desc_pin *pin = pctl->devdata->pins + i; |
942 | struct mtk_pinctrl_group *group = pctl->groups + i; |
943 | |
944 | group->name = pin->pin.name; |
945 | group->pin = pin->pin.number; |
946 | |
947 | pctl->grp_names[i] = pin->pin.name; |
948 | } |
949 | |
950 | return 0; |
951 | } |
952 | |
953 | static int |
954 | mtk_xt_get_gpio_n(void *data, unsigned long eint_n, unsigned int *gpio_n, |
955 | struct gpio_chip **gpio_chip) |
956 | { |
957 | struct mtk_pinctrl *pctl = (struct mtk_pinctrl *)data; |
958 | const struct mtk_desc_pin *pin; |
959 | |
960 | pin = mtk_find_pin_by_eint_num(pctl, eint_num: eint_n); |
961 | if (!pin) |
962 | return -EINVAL; |
963 | |
964 | *gpio_chip = pctl->chip; |
965 | *gpio_n = pin->pin.number; |
966 | |
967 | return 0; |
968 | } |
969 | |
970 | static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n) |
971 | { |
972 | struct mtk_pinctrl *pctl = (struct mtk_pinctrl *)data; |
973 | const struct mtk_desc_pin *pin; |
974 | |
975 | pin = mtk_find_pin_by_eint_num(pctl, eint_num: eint_n); |
976 | if (!pin) |
977 | return -EINVAL; |
978 | |
979 | return mtk_gpio_get(chip: pctl->chip, offset: pin->pin.number); |
980 | } |
981 | |
982 | static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n) |
983 | { |
984 | struct mtk_pinctrl *pctl = (struct mtk_pinctrl *)data; |
985 | const struct mtk_desc_pin *pin; |
986 | |
987 | pin = mtk_find_pin_by_eint_num(pctl, eint_num: eint_n); |
988 | if (!pin) |
989 | return -EINVAL; |
990 | |
991 | /* set mux to INT mode */ |
992 | mtk_pmx_set_mode(pctldev: pctl->pctl_dev, pin: pin->pin.number, mode: pin->eint.eintmux); |
993 | /* set gpio direction to input */ |
994 | mtk_pmx_gpio_set_direction(pctldev: pctl->pctl_dev, NULL, offset: pin->pin.number, |
995 | input: true); |
996 | /* set input-enable */ |
997 | mtk_pconf_set_ies_smt(pctl, pin: pin->pin.number, value: 1, |
998 | arg: PIN_CONFIG_INPUT_ENABLE); |
999 | |
1000 | return 0; |
1001 | } |
1002 | |
1003 | static const struct mtk_eint_xt mtk_eint_xt = { |
1004 | .get_gpio_n = mtk_xt_get_gpio_n, |
1005 | .get_gpio_state = mtk_xt_get_gpio_state, |
1006 | .set_gpio_as_eint = mtk_xt_set_gpio_as_eint, |
1007 | }; |
1008 | |
1009 | static int mtk_eint_init(struct mtk_pinctrl *pctl, struct platform_device *pdev) |
1010 | { |
1011 | struct device_node *np = pdev->dev.of_node; |
1012 | |
1013 | if (!of_property_read_bool(np, propname: "interrupt-controller" )) |
1014 | return -ENODEV; |
1015 | |
1016 | pctl->eint = devm_kzalloc(dev: pctl->dev, size: sizeof(*pctl->eint), GFP_KERNEL); |
1017 | if (!pctl->eint) |
1018 | return -ENOMEM; |
1019 | |
1020 | pctl->eint->base = devm_platform_ioremap_resource(pdev, index: 0); |
1021 | if (IS_ERR(ptr: pctl->eint->base)) |
1022 | return PTR_ERR(ptr: pctl->eint->base); |
1023 | |
1024 | pctl->eint->irq = irq_of_parse_and_map(node: np, index: 0); |
1025 | if (!pctl->eint->irq) |
1026 | return -EINVAL; |
1027 | |
1028 | pctl->eint->dev = &pdev->dev; |
1029 | /* |
1030 | * If pctl->eint->regs == NULL, it would fall back into using a generic |
1031 | * register map in mtk_eint_do_init calls. |
1032 | */ |
1033 | pctl->eint->regs = pctl->devdata->eint_regs; |
1034 | pctl->eint->hw = &pctl->devdata->eint_hw; |
1035 | pctl->eint->pctl = pctl; |
1036 | pctl->eint->gpio_xlate = &mtk_eint_xt; |
1037 | |
1038 | return mtk_eint_do_init(eint: pctl->eint); |
1039 | } |
1040 | |
1041 | /* This is used as a common probe function */ |
1042 | int mtk_pctrl_init(struct platform_device *pdev, |
1043 | const struct mtk_pinctrl_devdata *data, |
1044 | struct regmap *regmap) |
1045 | { |
1046 | struct device *dev = &pdev->dev; |
1047 | struct pinctrl_pin_desc *pins; |
1048 | struct mtk_pinctrl *pctl; |
1049 | struct device_node *np = pdev->dev.of_node, *node; |
1050 | int ret, i; |
1051 | |
1052 | pctl = devm_kzalloc(dev: &pdev->dev, size: sizeof(*pctl), GFP_KERNEL); |
1053 | if (!pctl) |
1054 | return -ENOMEM; |
1055 | |
1056 | platform_set_drvdata(pdev, data: pctl); |
1057 | |
1058 | node = of_parse_phandle(np, phandle_name: "mediatek,pctl-regmap" , index: 0); |
1059 | if (node) { |
1060 | pctl->regmap1 = syscon_node_to_regmap(np: node); |
1061 | of_node_put(node); |
1062 | if (IS_ERR(ptr: pctl->regmap1)) |
1063 | return PTR_ERR(ptr: pctl->regmap1); |
1064 | } else if (regmap) { |
1065 | pctl->regmap1 = regmap; |
1066 | } else { |
1067 | return dev_err_probe(dev, err: -EINVAL, fmt: "Cannot find pinctrl regmap.\n" ); |
1068 | } |
1069 | |
1070 | /* Only 8135 has two base addr, other SoCs have only one. */ |
1071 | node = of_parse_phandle(np, phandle_name: "mediatek,pctl-regmap" , index: 1); |
1072 | if (node) { |
1073 | pctl->regmap2 = syscon_node_to_regmap(np: node); |
1074 | of_node_put(node); |
1075 | if (IS_ERR(ptr: pctl->regmap2)) |
1076 | return PTR_ERR(ptr: pctl->regmap2); |
1077 | } |
1078 | |
1079 | pctl->devdata = data; |
1080 | ret = mtk_pctrl_build_state(pdev); |
1081 | if (ret) |
1082 | return dev_err_probe(dev, err: ret, fmt: "build state failed\n" ); |
1083 | |
1084 | pins = devm_kcalloc(dev: &pdev->dev, n: pctl->devdata->npins, size: sizeof(*pins), |
1085 | GFP_KERNEL); |
1086 | if (!pins) |
1087 | return -ENOMEM; |
1088 | |
1089 | for (i = 0; i < pctl->devdata->npins; i++) |
1090 | pins[i] = pctl->devdata->pins[i].pin; |
1091 | |
1092 | pctl->pctl_desc.name = dev_name(dev: &pdev->dev); |
1093 | pctl->pctl_desc.owner = THIS_MODULE; |
1094 | pctl->pctl_desc.pins = pins; |
1095 | pctl->pctl_desc.npins = pctl->devdata->npins; |
1096 | pctl->pctl_desc.confops = &mtk_pconf_ops; |
1097 | pctl->pctl_desc.pctlops = &mtk_pctrl_ops; |
1098 | pctl->pctl_desc.pmxops = &mtk_pmx_ops; |
1099 | pctl->dev = &pdev->dev; |
1100 | |
1101 | pctl->pctl_dev = devm_pinctrl_register(dev: &pdev->dev, pctldesc: &pctl->pctl_desc, |
1102 | driver_data: pctl); |
1103 | if (IS_ERR(ptr: pctl->pctl_dev)) |
1104 | return dev_err_probe(dev, err: PTR_ERR(ptr: pctl->pctl_dev), |
1105 | fmt: "Couldn't register pinctrl driver\n" ); |
1106 | |
1107 | pctl->chip = devm_kzalloc(dev: &pdev->dev, size: sizeof(*pctl->chip), GFP_KERNEL); |
1108 | if (!pctl->chip) |
1109 | return -ENOMEM; |
1110 | |
1111 | *pctl->chip = mtk_gpio_chip; |
1112 | pctl->chip->ngpio = pctl->devdata->npins; |
1113 | pctl->chip->label = dev_name(dev: &pdev->dev); |
1114 | pctl->chip->parent = &pdev->dev; |
1115 | pctl->chip->base = -1; |
1116 | |
1117 | ret = gpiochip_add_data(pctl->chip, pctl); |
1118 | if (ret) |
1119 | return -EINVAL; |
1120 | |
1121 | /* Register the GPIO to pin mappings. */ |
1122 | ret = gpiochip_add_pin_range(gc: pctl->chip, pinctl_name: dev_name(dev: &pdev->dev), |
1123 | gpio_offset: 0, pin_offset: 0, npins: pctl->devdata->npins); |
1124 | if (ret) { |
1125 | ret = -EINVAL; |
1126 | goto chip_error; |
1127 | } |
1128 | |
1129 | ret = mtk_eint_init(pctl, pdev); |
1130 | if (ret) |
1131 | goto chip_error; |
1132 | |
1133 | return 0; |
1134 | |
1135 | chip_error: |
1136 | gpiochip_remove(gc: pctl->chip); |
1137 | return ret; |
1138 | } |
1139 | |
1140 | int mtk_pctrl_common_probe(struct platform_device *pdev) |
1141 | { |
1142 | struct device *dev = &pdev->dev; |
1143 | const struct mtk_pinctrl_devdata *data = device_get_match_data(dev); |
1144 | |
1145 | if (!data) |
1146 | return -ENODEV; |
1147 | |
1148 | return mtk_pctrl_init(pdev, data, NULL); |
1149 | } |
1150 | |