Commit | Line | Data |
---|---|---|
2874c5fd | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
ea479996 | 2 | /* |
924764aa | 3 | * Pinctrl driver for Rockchip RK805/RK806 PMIC |
ea479996 JC |
4 | * |
5 | * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd | |
924764aa | 6 | * Copyright (c) 2021 Rockchip Electronics Co., Ltd. |
ea479996 JC |
7 | * |
8 | * Author: Joseph Chen <chenjh@rock-chips.com> | |
924764aa | 9 | * Author: Xu Shengfei <xsf@rock-chips.com> |
ea479996 | 10 | * |
ea479996 JC |
11 | * Based on the pinctrl-as3722 driver |
12 | */ | |
13 | ||
14 | #include <linux/gpio/driver.h> | |
15 | #include <linux/kernel.h> | |
16 | #include <linux/module.h> | |
17 | #include <linux/mfd/rk808.h> | |
ea479996 | 18 | #include <linux/platform_device.h> |
ce852837 AS |
19 | #include <linux/pm.h> |
20 | #include <linux/property.h> | |
21 | #include <linux/slab.h> | |
22 | ||
ea479996 JC |
23 | #include <linux/pinctrl/consumer.h> |
24 | #include <linux/pinctrl/machine.h> | |
25 | #include <linux/pinctrl/pinctrl.h> | |
26 | #include <linux/pinctrl/pinconf-generic.h> | |
27 | #include <linux/pinctrl/pinconf.h> | |
28 | #include <linux/pinctrl/pinmux.h> | |
ea479996 JC |
29 | |
30 | #include "core.h" | |
31 | #include "pinconf.h" | |
32 | #include "pinctrl-utils.h" | |
33 | ||
34 | struct rk805_pin_function { | |
35 | const char *name; | |
36 | const char *const *groups; | |
37 | unsigned int ngroups; | |
38 | int mux_option; | |
39 | }; | |
40 | ||
41 | struct rk805_pin_group { | |
42 | const char *name; | |
43 | const unsigned int pins[1]; | |
44 | unsigned int npins; | |
45 | }; | |
46 | ||
47 | /* | |
48 | * @reg: gpio setting register; | |
924764aa | 49 | * @fun_reg: functions select register; |
ea479996 JC |
50 | * @fun_mask: functions select mask value, when set is gpio; |
51 | * @dir_mask: input or output mask value, when set is output, otherwise input; | |
52 | * @val_mask: gpio set value, when set is level high, otherwise low; | |
53 | * | |
54 | * Different PMIC has different pin features, belowing 3 mask members are not | |
55 | * all necessary for every PMIC. For example, RK805 has 2 pins that can be used | |
56 | * as output only GPIOs, so func_mask and dir_mask are not needed. RK816 has 1 | |
57 | * pin that can be used as TS/GPIO, so fun_mask, dir_mask and val_mask are all | |
58 | * necessary. | |
59 | */ | |
60 | struct rk805_pin_config { | |
61 | u8 reg; | |
924764aa | 62 | u8 fun_reg; |
ea479996 JC |
63 | u8 fun_msk; |
64 | u8 dir_msk; | |
65 | u8 val_msk; | |
66 | }; | |
67 | ||
68 | struct rk805_pctrl_info { | |
69 | struct rk808 *rk808; | |
70 | struct device *dev; | |
71 | struct pinctrl_dev *pctl; | |
72 | struct gpio_chip gpio_chip; | |
73 | struct pinctrl_desc pinctrl_desc; | |
74 | const struct rk805_pin_function *functions; | |
75 | unsigned int num_functions; | |
76 | const struct rk805_pin_group *groups; | |
77 | int num_pin_groups; | |
78 | const struct pinctrl_pin_desc *pins; | |
79 | unsigned int num_pins; | |
8068071c | 80 | const struct rk805_pin_config *pin_cfg; |
ea479996 JC |
81 | }; |
82 | ||
83 | enum rk805_pinmux_option { | |
84 | RK805_PINMUX_GPIO, | |
85 | }; | |
86 | ||
924764aa SR |
87 | enum rk806_pinmux_option { |
88 | RK806_PINMUX_FUN0 = 0, | |
89 | RK806_PINMUX_FUN1, | |
90 | RK806_PINMUX_FUN2, | |
91 | RK806_PINMUX_FUN3, | |
92 | RK806_PINMUX_FUN4, | |
93 | RK806_PINMUX_FUN5, | |
94 | }; | |
95 | ||
1bd97d64 AB |
96 | enum rk816_pinmux_option { |
97 | RK816_PINMUX_THERMISTOR, | |
98 | RK816_PINMUX_GPIO, | |
99 | }; | |
100 | ||
ea479996 JC |
101 | enum { |
102 | RK805_GPIO0, | |
103 | RK805_GPIO1, | |
104 | }; | |
105 | ||
924764aa SR |
106 | enum { |
107 | RK806_GPIO_DVS1, | |
108 | RK806_GPIO_DVS2, | |
109 | RK806_GPIO_DVS3 | |
110 | }; | |
111 | ||
1bd97d64 AB |
112 | enum { |
113 | RK816_GPIO0, | |
114 | }; | |
115 | ||
ea479996 JC |
116 | static const char *const rk805_gpio_groups[] = { |
117 | "gpio0", | |
118 | "gpio1", | |
119 | }; | |
120 | ||
924764aa SR |
121 | static const char *const rk806_gpio_groups[] = { |
122 | "gpio_pwrctrl1", | |
123 | "gpio_pwrctrl2", | |
124 | "gpio_pwrctrl3", | |
125 | }; | |
126 | ||
1bd97d64 AB |
127 | static const char *const rk816_gpio_groups[] = { |
128 | "gpio0", | |
129 | }; | |
130 | ||
ea479996 JC |
131 | /* RK805: 2 output only GPIOs */ |
132 | static const struct pinctrl_pin_desc rk805_pins_desc[] = { | |
133 | PINCTRL_PIN(RK805_GPIO0, "gpio0"), | |
134 | PINCTRL_PIN(RK805_GPIO1, "gpio1"), | |
135 | }; | |
136 | ||
924764aa SR |
137 | /* RK806 */ |
138 | static const struct pinctrl_pin_desc rk806_pins_desc[] = { | |
139 | PINCTRL_PIN(RK806_GPIO_DVS1, "gpio_pwrctrl1"), | |
140 | PINCTRL_PIN(RK806_GPIO_DVS2, "gpio_pwrctrl2"), | |
141 | PINCTRL_PIN(RK806_GPIO_DVS3, "gpio_pwrctrl3"), | |
142 | }; | |
143 | ||
1bd97d64 AB |
144 | /* RK816 */ |
145 | static const struct pinctrl_pin_desc rk816_pins_desc[] = { | |
146 | PINCTRL_PIN(RK816_GPIO0, "gpio0"), | |
147 | }; | |
148 | ||
ea479996 JC |
149 | static const struct rk805_pin_function rk805_pin_functions[] = { |
150 | { | |
151 | .name = "gpio", | |
152 | .groups = rk805_gpio_groups, | |
153 | .ngroups = ARRAY_SIZE(rk805_gpio_groups), | |
154 | .mux_option = RK805_PINMUX_GPIO, | |
155 | }, | |
156 | }; | |
157 | ||
924764aa SR |
158 | static const struct rk805_pin_function rk806_pin_functions[] = { |
159 | { | |
160 | .name = "pin_fun0", | |
161 | .groups = rk806_gpio_groups, | |
162 | .ngroups = ARRAY_SIZE(rk806_gpio_groups), | |
163 | .mux_option = RK806_PINMUX_FUN0, | |
164 | }, | |
165 | { | |
166 | .name = "pin_fun1", | |
167 | .groups = rk806_gpio_groups, | |
168 | .ngroups = ARRAY_SIZE(rk806_gpio_groups), | |
169 | .mux_option = RK806_PINMUX_FUN1, | |
170 | }, | |
171 | { | |
172 | .name = "pin_fun2", | |
173 | .groups = rk806_gpio_groups, | |
174 | .ngroups = ARRAY_SIZE(rk806_gpio_groups), | |
175 | .mux_option = RK806_PINMUX_FUN2, | |
176 | }, | |
177 | { | |
178 | .name = "pin_fun3", | |
179 | .groups = rk806_gpio_groups, | |
180 | .ngroups = ARRAY_SIZE(rk806_gpio_groups), | |
181 | .mux_option = RK806_PINMUX_FUN3, | |
182 | }, | |
183 | { | |
184 | .name = "pin_fun4", | |
185 | .groups = rk806_gpio_groups, | |
186 | .ngroups = ARRAY_SIZE(rk806_gpio_groups), | |
187 | .mux_option = RK806_PINMUX_FUN4, | |
188 | }, | |
189 | { | |
190 | .name = "pin_fun5", | |
191 | .groups = rk806_gpio_groups, | |
192 | .ngroups = ARRAY_SIZE(rk806_gpio_groups), | |
193 | .mux_option = RK806_PINMUX_FUN5, | |
194 | }, | |
195 | }; | |
196 | ||
1bd97d64 AB |
197 | static const struct rk805_pin_function rk816_pin_functions[] = { |
198 | { | |
199 | .name = "gpio", | |
200 | .groups = rk816_gpio_groups, | |
201 | .ngroups = ARRAY_SIZE(rk816_gpio_groups), | |
202 | .mux_option = RK816_PINMUX_GPIO, | |
203 | }, | |
204 | { | |
205 | .name = "thermistor", | |
206 | .groups = rk816_gpio_groups, | |
207 | .ngroups = ARRAY_SIZE(rk816_gpio_groups), | |
208 | .mux_option = RK816_PINMUX_THERMISTOR, | |
209 | }, | |
210 | }; | |
211 | ||
ea479996 JC |
212 | static const struct rk805_pin_group rk805_pin_groups[] = { |
213 | { | |
214 | .name = "gpio0", | |
215 | .pins = { RK805_GPIO0 }, | |
216 | .npins = 1, | |
217 | }, | |
218 | { | |
219 | .name = "gpio1", | |
220 | .pins = { RK805_GPIO1 }, | |
221 | .npins = 1, | |
222 | }, | |
223 | }; | |
224 | ||
924764aa SR |
225 | static const struct rk805_pin_group rk806_pin_groups[] = { |
226 | { | |
227 | .name = "gpio_pwrctrl1", | |
228 | .pins = { RK806_GPIO_DVS1 }, | |
229 | .npins = 1, | |
230 | }, | |
231 | { | |
232 | .name = "gpio_pwrctrl2", | |
233 | .pins = { RK806_GPIO_DVS2 }, | |
234 | .npins = 1, | |
235 | }, | |
236 | { | |
237 | .name = "gpio_pwrctrl3", | |
238 | .pins = { RK806_GPIO_DVS3 }, | |
239 | .npins = 1, | |
240 | } | |
241 | }; | |
242 | ||
1bd97d64 AB |
243 | static const struct rk805_pin_group rk816_pin_groups[] = { |
244 | { | |
245 | .name = "gpio0", | |
246 | .pins = { RK816_GPIO0 }, | |
247 | .npins = 1, | |
248 | }, | |
249 | }; | |
250 | ||
ea479996 JC |
251 | #define RK805_GPIO0_VAL_MSK BIT(0) |
252 | #define RK805_GPIO1_VAL_MSK BIT(1) | |
253 | ||
8068071c | 254 | static const struct rk805_pin_config rk805_gpio_cfgs[] = { |
ea479996 JC |
255 | { |
256 | .reg = RK805_OUT_REG, | |
257 | .val_msk = RK805_GPIO0_VAL_MSK, | |
258 | }, | |
259 | { | |
260 | .reg = RK805_OUT_REG, | |
261 | .val_msk = RK805_GPIO1_VAL_MSK, | |
262 | }, | |
263 | }; | |
264 | ||
924764aa SR |
265 | #define RK806_PWRCTRL1_DR BIT(0) |
266 | #define RK806_PWRCTRL2_DR BIT(1) | |
267 | #define RK806_PWRCTRL3_DR BIT(2) | |
268 | #define RK806_PWRCTRL1_DATA BIT(4) | |
269 | #define RK806_PWRCTRL2_DATA BIT(5) | |
270 | #define RK806_PWRCTRL3_DATA BIT(6) | |
271 | #define RK806_PWRCTRL1_FUN GENMASK(2, 0) | |
272 | #define RK806_PWRCTRL2_FUN GENMASK(6, 4) | |
273 | #define RK806_PWRCTRL3_FUN GENMASK(2, 0) | |
274 | ||
275 | static struct rk805_pin_config rk806_gpio_cfgs[] = { | |
276 | { | |
277 | .fun_reg = RK806_SLEEP_CONFIG0, | |
278 | .fun_msk = RK806_PWRCTRL1_FUN, | |
279 | .reg = RK806_SLEEP_GPIO, | |
280 | .val_msk = RK806_PWRCTRL1_DATA, | |
281 | .dir_msk = RK806_PWRCTRL1_DR, | |
282 | }, | |
283 | { | |
284 | .fun_reg = RK806_SLEEP_CONFIG0, | |
285 | .fun_msk = RK806_PWRCTRL2_FUN, | |
286 | .reg = RK806_SLEEP_GPIO, | |
287 | .val_msk = RK806_PWRCTRL2_DATA, | |
288 | .dir_msk = RK806_PWRCTRL2_DR, | |
289 | }, | |
290 | { | |
291 | .fun_reg = RK806_SLEEP_CONFIG1, | |
292 | .fun_msk = RK806_PWRCTRL3_FUN, | |
293 | .reg = RK806_SLEEP_GPIO, | |
294 | .val_msk = RK806_PWRCTRL3_DATA, | |
295 | .dir_msk = RK806_PWRCTRL3_DR, | |
296 | } | |
297 | }; | |
298 | ||
1bd97d64 AB |
299 | #define RK816_FUN_MASK BIT(2) |
300 | #define RK816_VAL_MASK BIT(3) | |
301 | #define RK816_DIR_MASK BIT(4) | |
302 | ||
303 | static struct rk805_pin_config rk816_gpio_cfgs[] = { | |
304 | { | |
305 | .fun_reg = RK818_IO_POL_REG, | |
306 | .fun_msk = RK816_FUN_MASK, | |
307 | .reg = RK818_IO_POL_REG, | |
308 | .val_msk = RK816_VAL_MASK, | |
309 | .dir_msk = RK816_DIR_MASK, | |
310 | }, | |
311 | }; | |
312 | ||
ea479996 JC |
313 | /* generic gpio chip */ |
314 | static int rk805_gpio_get(struct gpio_chip *chip, unsigned int offset) | |
315 | { | |
316 | struct rk805_pctrl_info *pci = gpiochip_get_data(chip); | |
317 | int ret, val; | |
318 | ||
319 | ret = regmap_read(pci->rk808->regmap, pci->pin_cfg[offset].reg, &val); | |
320 | if (ret) { | |
321 | dev_err(pci->dev, "get gpio%d value failed\n", offset); | |
322 | return ret; | |
323 | } | |
324 | ||
325 | return !!(val & pci->pin_cfg[offset].val_msk); | |
326 | } | |
327 | ||
328 | static void rk805_gpio_set(struct gpio_chip *chip, | |
329 | unsigned int offset, | |
330 | int value) | |
331 | { | |
332 | struct rk805_pctrl_info *pci = gpiochip_get_data(chip); | |
333 | int ret; | |
334 | ||
335 | ret = regmap_update_bits(pci->rk808->regmap, | |
336 | pci->pin_cfg[offset].reg, | |
337 | pci->pin_cfg[offset].val_msk, | |
338 | value ? pci->pin_cfg[offset].val_msk : 0); | |
339 | if (ret) | |
340 | dev_err(pci->dev, "set gpio%d value %d failed\n", | |
341 | offset, value); | |
342 | } | |
343 | ||
ea479996 JC |
344 | static int rk805_gpio_direction_output(struct gpio_chip *chip, |
345 | unsigned int offset, int value) | |
346 | { | |
347 | rk805_gpio_set(chip, offset, value); | |
b679d6c0 | 348 | return pinctrl_gpio_direction_output(chip, offset); |
ea479996 JC |
349 | } |
350 | ||
351 | static int rk805_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) | |
352 | { | |
353 | struct rk805_pctrl_info *pci = gpiochip_get_data(chip); | |
354 | unsigned int val; | |
355 | int ret; | |
356 | ||
357 | /* default output*/ | |
358 | if (!pci->pin_cfg[offset].dir_msk) | |
3c827873 | 359 | return GPIO_LINE_DIRECTION_OUT; |
ea479996 JC |
360 | |
361 | ret = regmap_read(pci->rk808->regmap, | |
362 | pci->pin_cfg[offset].reg, | |
363 | &val); | |
364 | if (ret) { | |
365 | dev_err(pci->dev, "get gpio%d direction failed\n", offset); | |
366 | return ret; | |
367 | } | |
368 | ||
3c827873 MV |
369 | if (val & pci->pin_cfg[offset].dir_msk) |
370 | return GPIO_LINE_DIRECTION_OUT; | |
371 | ||
372 | return GPIO_LINE_DIRECTION_IN; | |
ea479996 JC |
373 | } |
374 | ||
6e28aaab | 375 | static const struct gpio_chip rk805_gpio_chip = { |
ea479996 JC |
376 | .label = "rk805-gpio", |
377 | .request = gpiochip_generic_request, | |
378 | .free = gpiochip_generic_free, | |
379 | .get_direction = rk805_gpio_get_direction, | |
380 | .get = rk805_gpio_get, | |
381 | .set = rk805_gpio_set, | |
5835b3f2 | 382 | .direction_input = pinctrl_gpio_direction_input, |
ea479996 JC |
383 | .direction_output = rk805_gpio_direction_output, |
384 | .can_sleep = true, | |
385 | .base = -1, | |
386 | .owner = THIS_MODULE, | |
387 | }; | |
388 | ||
389 | /* generic pinctrl */ | |
390 | static int rk805_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) | |
391 | { | |
392 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
393 | ||
394 | return pci->num_pin_groups; | |
395 | } | |
396 | ||
397 | static const char *rk805_pinctrl_get_group_name(struct pinctrl_dev *pctldev, | |
398 | unsigned int group) | |
399 | { | |
400 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
401 | ||
402 | return pci->groups[group].name; | |
403 | } | |
404 | ||
405 | static int rk805_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, | |
406 | unsigned int group, | |
407 | const unsigned int **pins, | |
408 | unsigned int *num_pins) | |
409 | { | |
410 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
411 | ||
412 | *pins = pci->groups[group].pins; | |
413 | *num_pins = pci->groups[group].npins; | |
414 | ||
415 | return 0; | |
416 | } | |
417 | ||
418 | static const struct pinctrl_ops rk805_pinctrl_ops = { | |
419 | .get_groups_count = rk805_pinctrl_get_groups_count, | |
420 | .get_group_name = rk805_pinctrl_get_group_name, | |
421 | .get_group_pins = rk805_pinctrl_get_group_pins, | |
422 | .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, | |
423 | .dt_free_map = pinctrl_utils_free_map, | |
424 | }; | |
425 | ||
426 | static int rk805_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev) | |
427 | { | |
428 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
429 | ||
430 | return pci->num_functions; | |
431 | } | |
432 | ||
433 | static const char *rk805_pinctrl_get_func_name(struct pinctrl_dev *pctldev, | |
434 | unsigned int function) | |
435 | { | |
436 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
437 | ||
438 | return pci->functions[function].name; | |
439 | } | |
440 | ||
441 | static int rk805_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, | |
442 | unsigned int function, | |
443 | const char *const **groups, | |
444 | unsigned int *const num_groups) | |
445 | { | |
446 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
447 | ||
448 | *groups = pci->functions[function].groups; | |
449 | *num_groups = pci->functions[function].ngroups; | |
450 | ||
451 | return 0; | |
452 | } | |
453 | ||
454 | static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev, | |
455 | unsigned int offset, | |
456 | int mux) | |
457 | { | |
458 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
459 | int ret; | |
460 | ||
461 | if (!pci->pin_cfg[offset].fun_msk) | |
462 | return 0; | |
463 | ||
924764aa SR |
464 | mux <<= ffs(pci->pin_cfg[offset].fun_msk) - 1; |
465 | ret = regmap_update_bits(pci->rk808->regmap, | |
466 | pci->pin_cfg[offset].fun_reg, | |
467 | pci->pin_cfg[offset].fun_msk, mux); | |
468 | ||
469 | if (ret) | |
470 | dev_err(pci->dev, "set gpio%d func%d failed\n", offset, mux); | |
ea479996 JC |
471 | |
472 | return 0; | |
473 | } | |
474 | ||
475 | static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev, | |
476 | unsigned int function, | |
477 | unsigned int group) | |
478 | { | |
479 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
480 | int mux = pci->functions[function].mux_option; | |
481 | int offset = group; | |
482 | ||
483 | return _rk805_pinctrl_set_mux(pctldev, offset, mux); | |
484 | } | |
485 | ||
924764aa SR |
486 | static int rk805_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev, |
487 | struct pinctrl_gpio_range *range, | |
488 | unsigned int offset) | |
489 | { | |
490 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
491 | ||
492 | switch (pci->rk808->variant) { | |
493 | case RK805_ID: | |
494 | return _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO); | |
495 | case RK806_ID: | |
496 | return _rk805_pinctrl_set_mux(pctldev, offset, RK806_PINMUX_FUN5); | |
1bd97d64 AB |
497 | case RK816_ID: |
498 | return _rk805_pinctrl_set_mux(pctldev, offset, RK816_PINMUX_GPIO); | |
924764aa SR |
499 | } |
500 | ||
501 | return -ENOTSUPP; | |
502 | } | |
503 | ||
ea479996 JC |
504 | static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, |
505 | struct pinctrl_gpio_range *range, | |
506 | unsigned int offset, bool input) | |
507 | { | |
508 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
509 | int ret; | |
510 | ||
ea479996 JC |
511 | /* set direction */ |
512 | if (!pci->pin_cfg[offset].dir_msk) | |
513 | return 0; | |
514 | ||
515 | ret = regmap_update_bits(pci->rk808->regmap, | |
516 | pci->pin_cfg[offset].reg, | |
517 | pci->pin_cfg[offset].dir_msk, | |
518 | input ? 0 : pci->pin_cfg[offset].dir_msk); | |
519 | if (ret) { | |
520 | dev_err(pci->dev, "set gpio%d direction failed\n", offset); | |
521 | return ret; | |
522 | } | |
523 | ||
524 | return ret; | |
525 | } | |
526 | ||
527 | static const struct pinmux_ops rk805_pinmux_ops = { | |
528 | .get_functions_count = rk805_pinctrl_get_funcs_count, | |
529 | .get_function_name = rk805_pinctrl_get_func_name, | |
530 | .get_function_groups = rk805_pinctrl_get_func_groups, | |
531 | .set_mux = rk805_pinctrl_set_mux, | |
924764aa | 532 | .gpio_request_enable = rk805_pinctrl_gpio_request_enable, |
ea479996 JC |
533 | .gpio_set_direction = rk805_pmx_gpio_set_direction, |
534 | }; | |
535 | ||
536 | static int rk805_pinconf_get(struct pinctrl_dev *pctldev, | |
537 | unsigned int pin, unsigned long *config) | |
538 | { | |
539 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
540 | enum pin_config_param param = pinconf_to_config_param(*config); | |
541 | u32 arg = 0; | |
542 | ||
543 | switch (param) { | |
544 | case PIN_CONFIG_OUTPUT: | |
924764aa | 545 | case PIN_CONFIG_INPUT_ENABLE: |
ea479996 JC |
546 | arg = rk805_gpio_get(&pci->gpio_chip, pin); |
547 | break; | |
548 | default: | |
549 | dev_err(pci->dev, "Properties not supported\n"); | |
550 | return -ENOTSUPP; | |
551 | } | |
552 | ||
553 | *config = pinconf_to_config_packed(param, (u16)arg); | |
554 | ||
555 | return 0; | |
556 | } | |
557 | ||
558 | static int rk805_pinconf_set(struct pinctrl_dev *pctldev, | |
559 | unsigned int pin, unsigned long *configs, | |
560 | unsigned int num_configs) | |
561 | { | |
562 | struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); | |
563 | enum pin_config_param param; | |
564 | u32 i, arg = 0; | |
565 | ||
566 | for (i = 0; i < num_configs; i++) { | |
567 | param = pinconf_to_config_param(configs[i]); | |
568 | arg = pinconf_to_config_argument(configs[i]); | |
569 | ||
570 | switch (param) { | |
571 | case PIN_CONFIG_OUTPUT: | |
572 | rk805_gpio_set(&pci->gpio_chip, pin, arg); | |
573 | rk805_pmx_gpio_set_direction(pctldev, NULL, pin, false); | |
574 | break; | |
924764aa SR |
575 | case PIN_CONFIG_INPUT_ENABLE: |
576 | if (pci->rk808->variant != RK805_ID && arg) { | |
577 | rk805_pmx_gpio_set_direction(pctldev, NULL, pin, true); | |
578 | break; | |
579 | } | |
580 | fallthrough; | |
ea479996 JC |
581 | default: |
582 | dev_err(pci->dev, "Properties not supported\n"); | |
583 | return -ENOTSUPP; | |
584 | } | |
585 | } | |
586 | ||
587 | return 0; | |
588 | } | |
589 | ||
590 | static const struct pinconf_ops rk805_pinconf_ops = { | |
591 | .pin_config_get = rk805_pinconf_get, | |
592 | .pin_config_set = rk805_pinconf_set, | |
593 | }; | |
594 | ||
6e28aaab | 595 | static const struct pinctrl_desc rk805_pinctrl_desc = { |
ea479996 JC |
596 | .name = "rk805-pinctrl", |
597 | .pctlops = &rk805_pinctrl_ops, | |
598 | .pmxops = &rk805_pinmux_ops, | |
599 | .confops = &rk805_pinconf_ops, | |
600 | .owner = THIS_MODULE, | |
601 | }; | |
602 | ||
603 | static int rk805_pinctrl_probe(struct platform_device *pdev) | |
604 | { | |
605 | struct rk805_pctrl_info *pci; | |
606 | int ret; | |
607 | ||
ce852837 AS |
608 | device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent)); |
609 | ||
ea479996 JC |
610 | pci = devm_kzalloc(&pdev->dev, sizeof(*pci), GFP_KERNEL); |
611 | if (!pci) | |
612 | return -ENOMEM; | |
613 | ||
614 | pci->dev = &pdev->dev; | |
ea479996 JC |
615 | pci->rk808 = dev_get_drvdata(pdev->dev.parent); |
616 | ||
617 | pci->pinctrl_desc = rk805_pinctrl_desc; | |
618 | pci->gpio_chip = rk805_gpio_chip; | |
619 | pci->gpio_chip.parent = &pdev->dev; | |
ea479996 JC |
620 | |
621 | platform_set_drvdata(pdev, pci); | |
622 | ||
623 | switch (pci->rk808->variant) { | |
624 | case RK805_ID: | |
625 | pci->pins = rk805_pins_desc; | |
626 | pci->num_pins = ARRAY_SIZE(rk805_pins_desc); | |
627 | pci->functions = rk805_pin_functions; | |
628 | pci->num_functions = ARRAY_SIZE(rk805_pin_functions); | |
629 | pci->groups = rk805_pin_groups; | |
630 | pci->num_pin_groups = ARRAY_SIZE(rk805_pin_groups); | |
631 | pci->pinctrl_desc.pins = rk805_pins_desc; | |
632 | pci->pinctrl_desc.npins = ARRAY_SIZE(rk805_pins_desc); | |
633 | pci->pin_cfg = rk805_gpio_cfgs; | |
634 | pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs); | |
635 | break; | |
924764aa SR |
636 | case RK806_ID: |
637 | pci->pins = rk806_pins_desc; | |
638 | pci->num_pins = ARRAY_SIZE(rk806_pins_desc); | |
639 | pci->functions = rk806_pin_functions; | |
640 | pci->num_functions = ARRAY_SIZE(rk806_pin_functions); | |
641 | pci->groups = rk806_pin_groups; | |
642 | pci->num_pin_groups = ARRAY_SIZE(rk806_pin_groups); | |
643 | pci->pinctrl_desc.pins = rk806_pins_desc; | |
644 | pci->pinctrl_desc.npins = ARRAY_SIZE(rk806_pins_desc); | |
645 | pci->pin_cfg = rk806_gpio_cfgs; | |
646 | pci->gpio_chip.ngpio = ARRAY_SIZE(rk806_gpio_cfgs); | |
647 | break; | |
1bd97d64 AB |
648 | case RK816_ID: |
649 | pci->pins = rk816_pins_desc; | |
650 | pci->num_pins = ARRAY_SIZE(rk816_pins_desc); | |
651 | pci->functions = rk816_pin_functions; | |
652 | pci->num_functions = ARRAY_SIZE(rk816_pin_functions); | |
653 | pci->groups = rk816_pin_groups; | |
654 | pci->num_pin_groups = ARRAY_SIZE(rk816_pin_groups); | |
655 | pci->pinctrl_desc.pins = rk816_pins_desc; | |
656 | pci->pinctrl_desc.npins = ARRAY_SIZE(rk816_pins_desc); | |
657 | pci->pin_cfg = rk816_gpio_cfgs; | |
658 | pci->gpio_chip.ngpio = ARRAY_SIZE(rk816_gpio_cfgs); | |
659 | break; | |
ea479996 JC |
660 | default: |
661 | dev_err(&pdev->dev, "unsupported RK805 ID %lu\n", | |
662 | pci->rk808->variant); | |
663 | return -EINVAL; | |
664 | } | |
665 | ||
666 | /* Add gpio chip */ | |
667 | ret = devm_gpiochip_add_data(&pdev->dev, &pci->gpio_chip, pci); | |
668 | if (ret < 0) { | |
669 | dev_err(&pdev->dev, "Couldn't add gpiochip\n"); | |
670 | return ret; | |
671 | } | |
672 | ||
673 | /* Add pinctrl */ | |
674 | pci->pctl = devm_pinctrl_register(&pdev->dev, &pci->pinctrl_desc, pci); | |
675 | if (IS_ERR(pci->pctl)) { | |
676 | dev_err(&pdev->dev, "Couldn't add pinctrl\n"); | |
677 | return PTR_ERR(pci->pctl); | |
678 | } | |
679 | ||
680 | /* Add pin range */ | |
681 | ret = gpiochip_add_pin_range(&pci->gpio_chip, dev_name(&pdev->dev), | |
682 | 0, 0, pci->gpio_chip.ngpio); | |
683 | if (ret < 0) { | |
684 | dev_err(&pdev->dev, "Couldn't add gpiochip pin range\n"); | |
685 | return ret; | |
686 | } | |
687 | ||
688 | return 0; | |
689 | } | |
690 | ||
691 | static struct platform_driver rk805_pinctrl_driver = { | |
692 | .probe = rk805_pinctrl_probe, | |
693 | .driver = { | |
694 | .name = "rk805-pinctrl", | |
695 | }, | |
696 | }; | |
697 | module_platform_driver(rk805_pinctrl_driver); | |
698 | ||
699 | MODULE_DESCRIPTION("RK805 pin control and GPIO driver"); | |
924764aa | 700 | MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>"); |
ea479996 JC |
701 | MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>"); |
702 | MODULE_LICENSE("GPL v2"); |