1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2012-2014, 2016-2021 The Linux Foundation. All rights reserved. |
4 | * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. |
5 | */ |
6 | |
7 | #include <linux/gpio/driver.h> |
8 | #include <linux/interrupt.h> |
9 | #include <linux/module.h> |
10 | #include <linux/of.h> |
11 | #include <linux/of_irq.h> |
12 | #include <linux/platform_device.h> |
13 | #include <linux/regmap.h> |
14 | #include <linux/seq_file.h> |
15 | #include <linux/slab.h> |
16 | #include <linux/spmi.h> |
17 | #include <linux/types.h> |
18 | |
19 | #include <linux/pinctrl/pinconf-generic.h> |
20 | #include <linux/pinctrl/pinconf.h> |
21 | #include <linux/pinctrl/pinmux.h> |
22 | |
23 | #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> |
24 | |
25 | #include "../core.h" |
26 | #include "../pinctrl-utils.h" |
27 | |
28 | #define PMIC_GPIO_ADDRESS_RANGE 0x100 |
29 | |
30 | /* type and subtype registers base address offsets */ |
31 | #define PMIC_GPIO_REG_TYPE 0x4 |
32 | #define PMIC_GPIO_REG_SUBTYPE 0x5 |
33 | |
34 | /* GPIO peripheral type and subtype out_values */ |
35 | #define PMIC_GPIO_TYPE 0x10 |
36 | #define PMIC_GPIO_SUBTYPE_GPIO_4CH 0x1 |
37 | #define PMIC_GPIO_SUBTYPE_GPIOC_4CH 0x5 |
38 | #define PMIC_GPIO_SUBTYPE_GPIO_8CH 0x9 |
39 | #define PMIC_GPIO_SUBTYPE_GPIOC_8CH 0xd |
40 | #define PMIC_GPIO_SUBTYPE_GPIO_LV 0x10 |
41 | #define PMIC_GPIO_SUBTYPE_GPIO_MV 0x11 |
42 | #define PMIC_GPIO_SUBTYPE_GPIO_LV_VIN2 0x12 |
43 | #define PMIC_GPIO_SUBTYPE_GPIO_MV_VIN3 0x13 |
44 | |
45 | #define PMIC_MPP_REG_RT_STS 0x10 |
46 | #define PMIC_MPP_REG_RT_STS_VAL_MASK 0x1 |
47 | |
48 | /* control register base address offsets */ |
49 | #define PMIC_GPIO_REG_MODE_CTL 0x40 |
50 | #define PMIC_GPIO_REG_DIG_VIN_CTL 0x41 |
51 | #define PMIC_GPIO_REG_DIG_PULL_CTL 0x42 |
52 | #define PMIC_GPIO_REG_LV_MV_DIG_OUT_SOURCE_CTL 0x44 |
53 | #define PMIC_GPIO_REG_DIG_IN_CTL 0x43 |
54 | #define PMIC_GPIO_REG_DIG_OUT_CTL 0x45 |
55 | #define PMIC_GPIO_REG_EN_CTL 0x46 |
56 | #define PMIC_GPIO_REG_LV_MV_ANA_PASS_THRU_SEL 0x4A |
57 | |
58 | /* PMIC_GPIO_REG_MODE_CTL */ |
59 | #define PMIC_GPIO_REG_MODE_VALUE_SHIFT 0x1 |
60 | #define PMIC_GPIO_REG_MODE_FUNCTION_SHIFT 1 |
61 | #define PMIC_GPIO_REG_MODE_FUNCTION_MASK 0x7 |
62 | #define PMIC_GPIO_REG_MODE_DIR_SHIFT 4 |
63 | #define PMIC_GPIO_REG_MODE_DIR_MASK 0x7 |
64 | |
65 | #define PMIC_GPIO_MODE_DIGITAL_INPUT 0 |
66 | #define PMIC_GPIO_MODE_DIGITAL_OUTPUT 1 |
67 | #define PMIC_GPIO_MODE_DIGITAL_INPUT_OUTPUT 2 |
68 | #define PMIC_GPIO_MODE_ANALOG_PASS_THRU 3 |
69 | #define PMIC_GPIO_REG_LV_MV_MODE_DIR_MASK 0x3 |
70 | |
71 | /* PMIC_GPIO_REG_DIG_VIN_CTL */ |
72 | #define PMIC_GPIO_REG_VIN_SHIFT 0 |
73 | #define PMIC_GPIO_REG_VIN_MASK 0x7 |
74 | |
75 | /* PMIC_GPIO_REG_DIG_PULL_CTL */ |
76 | #define PMIC_GPIO_REG_PULL_SHIFT 0 |
77 | #define PMIC_GPIO_REG_PULL_MASK 0x7 |
78 | |
79 | #define PMIC_GPIO_PULL_DOWN 4 |
80 | #define PMIC_GPIO_PULL_DISABLE 5 |
81 | |
82 | /* PMIC_GPIO_REG_LV_MV_DIG_OUT_SOURCE_CTL for LV/MV */ |
83 | #define PMIC_GPIO_LV_MV_OUTPUT_INVERT 0x80 |
84 | #define PMIC_GPIO_LV_MV_OUTPUT_INVERT_SHIFT 7 |
85 | #define PMIC_GPIO_LV_MV_OUTPUT_SOURCE_SEL_MASK 0xF |
86 | |
87 | /* PMIC_GPIO_REG_DIG_IN_CTL */ |
88 | #define PMIC_GPIO_LV_MV_DIG_IN_DTEST_EN 0x80 |
89 | #define PMIC_GPIO_LV_MV_DIG_IN_DTEST_SEL_MASK 0x7 |
90 | #define PMIC_GPIO_DIG_IN_DTEST_SEL_MASK 0xf |
91 | |
92 | /* PMIC_GPIO_REG_DIG_OUT_CTL */ |
93 | #define PMIC_GPIO_REG_OUT_STRENGTH_SHIFT 0 |
94 | #define PMIC_GPIO_REG_OUT_STRENGTH_MASK 0x3 |
95 | #define PMIC_GPIO_REG_OUT_TYPE_SHIFT 4 |
96 | #define PMIC_GPIO_REG_OUT_TYPE_MASK 0x3 |
97 | |
98 | /* |
99 | * Output type - indicates pin should be configured as push-pull, |
100 | * open drain or open source. |
101 | */ |
102 | #define PMIC_GPIO_OUT_BUF_CMOS 0 |
103 | #define PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS 1 |
104 | #define PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS 2 |
105 | |
106 | #define PMIC_GPIO_OUT_STRENGTH_LOW 1 |
107 | #define PMIC_GPIO_OUT_STRENGTH_HIGH 3 |
108 | |
109 | /* PMIC_GPIO_REG_EN_CTL */ |
110 | #define PMIC_GPIO_REG_MASTER_EN_SHIFT 7 |
111 | |
112 | #define PMIC_GPIO_PHYSICAL_OFFSET 1 |
113 | |
114 | /* PMIC_GPIO_REG_LV_MV_ANA_PASS_THRU_SEL */ |
115 | #define PMIC_GPIO_LV_MV_ANA_MUX_SEL_MASK 0x3 |
116 | |
117 | /* Qualcomm specific pin configurations */ |
118 | #define PMIC_GPIO_CONF_PULL_UP (PIN_CONFIG_END + 1) |
119 | #define PMIC_GPIO_CONF_STRENGTH (PIN_CONFIG_END + 2) |
120 | #define PMIC_GPIO_CONF_ATEST (PIN_CONFIG_END + 3) |
121 | #define PMIC_GPIO_CONF_ANALOG_PASS (PIN_CONFIG_END + 4) |
122 | #define PMIC_GPIO_CONF_DTEST_BUFFER (PIN_CONFIG_END + 5) |
123 | |
124 | /* The index of each function in pmic_gpio_functions[] array */ |
125 | enum pmic_gpio_func_index { |
126 | PMIC_GPIO_FUNC_INDEX_NORMAL, |
127 | PMIC_GPIO_FUNC_INDEX_PAIRED, |
128 | PMIC_GPIO_FUNC_INDEX_FUNC1, |
129 | PMIC_GPIO_FUNC_INDEX_FUNC2, |
130 | PMIC_GPIO_FUNC_INDEX_FUNC3, |
131 | PMIC_GPIO_FUNC_INDEX_FUNC4, |
132 | PMIC_GPIO_FUNC_INDEX_DTEST1, |
133 | PMIC_GPIO_FUNC_INDEX_DTEST2, |
134 | PMIC_GPIO_FUNC_INDEX_DTEST3, |
135 | PMIC_GPIO_FUNC_INDEX_DTEST4, |
136 | }; |
137 | |
138 | /** |
139 | * struct pmic_gpio_pad - keep current GPIO settings |
140 | * @base: Address base in SPMI device. |
141 | * @is_enabled: Set to false when GPIO should be put in high Z state. |
142 | * @out_value: Cached pin output value |
143 | * @have_buffer: Set to true if GPIO output could be configured in push-pull, |
144 | * open-drain or open-source mode. |
145 | * @output_enabled: Set to true if GPIO output logic is enabled. |
146 | * @input_enabled: Set to true if GPIO input buffer logic is enabled. |
147 | * @analog_pass: Set to true if GPIO is in analog-pass-through mode. |
148 | * @lv_mv_type: Set to true if GPIO subtype is GPIO_LV(0x10) or GPIO_MV(0x11). |
149 | * @num_sources: Number of power-sources supported by this GPIO. |
150 | * @power_source: Current power-source used. |
151 | * @buffer_type: Push-pull, open-drain or open-source. |
152 | * @pullup: Constant current which flow trough GPIO output buffer. |
153 | * @strength: No, Low, Medium, High |
154 | * @function: See pmic_gpio_functions[] |
155 | * @atest: the ATEST selection for GPIO analog-pass-through mode |
156 | * @dtest_buffer: the DTEST buffer selection for digital input mode. |
157 | */ |
158 | struct pmic_gpio_pad { |
159 | u16 base; |
160 | bool is_enabled; |
161 | bool out_value; |
162 | bool have_buffer; |
163 | bool output_enabled; |
164 | bool input_enabled; |
165 | bool analog_pass; |
166 | bool lv_mv_type; |
167 | unsigned int num_sources; |
168 | unsigned int power_source; |
169 | unsigned int buffer_type; |
170 | unsigned int pullup; |
171 | unsigned int strength; |
172 | unsigned int function; |
173 | unsigned int atest; |
174 | unsigned int dtest_buffer; |
175 | }; |
176 | |
177 | struct pmic_gpio_state { |
178 | struct device *dev; |
179 | struct regmap *map; |
180 | struct pinctrl_dev *ctrl; |
181 | struct gpio_chip chip; |
182 | u8 usid; |
183 | u8 pid_base; |
184 | }; |
185 | |
186 | static const struct pinconf_generic_params pmic_gpio_bindings[] = { |
187 | {"qcom,pull-up-strength" , PMIC_GPIO_CONF_PULL_UP, 0}, |
188 | {"qcom,drive-strength" , PMIC_GPIO_CONF_STRENGTH, 0}, |
189 | {"qcom,atest" , PMIC_GPIO_CONF_ATEST, 0}, |
190 | {"qcom,analog-pass" , PMIC_GPIO_CONF_ANALOG_PASS, 0}, |
191 | {"qcom,dtest-buffer" , PMIC_GPIO_CONF_DTEST_BUFFER, 0}, |
192 | }; |
193 | |
194 | #ifdef CONFIG_DEBUG_FS |
195 | static const struct pin_config_item pmic_conf_items[ARRAY_SIZE(pmic_gpio_bindings)] = { |
196 | PCONFDUMP(PMIC_GPIO_CONF_PULL_UP, "pull up strength" , NULL, true), |
197 | PCONFDUMP(PMIC_GPIO_CONF_STRENGTH, "drive-strength" , NULL, true), |
198 | PCONFDUMP(PMIC_GPIO_CONF_ATEST, "atest" , NULL, true), |
199 | PCONFDUMP(PMIC_GPIO_CONF_ANALOG_PASS, "analog-pass" , NULL, true), |
200 | PCONFDUMP(PMIC_GPIO_CONF_DTEST_BUFFER, "dtest-buffer" , NULL, true), |
201 | }; |
202 | #endif |
203 | |
204 | static const char *const pmic_gpio_groups[] = { |
205 | "gpio1" , "gpio2" , "gpio3" , "gpio4" , "gpio5" , "gpio6" , "gpio7" , "gpio8" , |
206 | "gpio9" , "gpio10" , "gpio11" , "gpio12" , "gpio13" , "gpio14" , "gpio15" , |
207 | "gpio16" , "gpio17" , "gpio18" , "gpio19" , "gpio20" , "gpio21" , "gpio22" , |
208 | "gpio23" , "gpio24" , "gpio25" , "gpio26" , "gpio27" , "gpio28" , "gpio29" , |
209 | "gpio30" , "gpio31" , "gpio32" , "gpio33" , "gpio34" , "gpio35" , "gpio36" , |
210 | }; |
211 | |
212 | static const char *const pmic_gpio_functions[] = { |
213 | [PMIC_GPIO_FUNC_INDEX_NORMAL] = PMIC_GPIO_FUNC_NORMAL, |
214 | [PMIC_GPIO_FUNC_INDEX_PAIRED] = PMIC_GPIO_FUNC_PAIRED, |
215 | [PMIC_GPIO_FUNC_INDEX_FUNC1] = PMIC_GPIO_FUNC_FUNC1, |
216 | [PMIC_GPIO_FUNC_INDEX_FUNC2] = PMIC_GPIO_FUNC_FUNC2, |
217 | [PMIC_GPIO_FUNC_INDEX_FUNC3] = PMIC_GPIO_FUNC_FUNC3, |
218 | [PMIC_GPIO_FUNC_INDEX_FUNC4] = PMIC_GPIO_FUNC_FUNC4, |
219 | [PMIC_GPIO_FUNC_INDEX_DTEST1] = PMIC_GPIO_FUNC_DTEST1, |
220 | [PMIC_GPIO_FUNC_INDEX_DTEST2] = PMIC_GPIO_FUNC_DTEST2, |
221 | [PMIC_GPIO_FUNC_INDEX_DTEST3] = PMIC_GPIO_FUNC_DTEST3, |
222 | [PMIC_GPIO_FUNC_INDEX_DTEST4] = PMIC_GPIO_FUNC_DTEST4, |
223 | }; |
224 | |
225 | static int pmic_gpio_read(struct pmic_gpio_state *state, |
226 | struct pmic_gpio_pad *pad, unsigned int addr) |
227 | { |
228 | unsigned int val; |
229 | int ret; |
230 | |
231 | ret = regmap_read(map: state->map, reg: pad->base + addr, val: &val); |
232 | if (ret < 0) |
233 | dev_err(state->dev, "read 0x%x failed\n" , addr); |
234 | else |
235 | ret = val; |
236 | |
237 | return ret; |
238 | } |
239 | |
240 | static int pmic_gpio_write(struct pmic_gpio_state *state, |
241 | struct pmic_gpio_pad *pad, unsigned int addr, |
242 | unsigned int val) |
243 | { |
244 | int ret; |
245 | |
246 | ret = regmap_write(map: state->map, reg: pad->base + addr, val); |
247 | if (ret < 0) |
248 | dev_err(state->dev, "write 0x%x failed\n" , addr); |
249 | |
250 | return ret; |
251 | } |
252 | |
253 | static int pmic_gpio_get_groups_count(struct pinctrl_dev *pctldev) |
254 | { |
255 | /* Every PIN is a group */ |
256 | return pctldev->desc->npins; |
257 | } |
258 | |
259 | static const char *pmic_gpio_get_group_name(struct pinctrl_dev *pctldev, |
260 | unsigned pin) |
261 | { |
262 | return pctldev->desc->pins[pin].name; |
263 | } |
264 | |
265 | static int pmic_gpio_get_group_pins(struct pinctrl_dev *pctldev, unsigned pin, |
266 | const unsigned **pins, unsigned *num_pins) |
267 | { |
268 | *pins = &pctldev->desc->pins[pin].number; |
269 | *num_pins = 1; |
270 | return 0; |
271 | } |
272 | |
273 | static const struct pinctrl_ops pmic_gpio_pinctrl_ops = { |
274 | .get_groups_count = pmic_gpio_get_groups_count, |
275 | .get_group_name = pmic_gpio_get_group_name, |
276 | .get_group_pins = pmic_gpio_get_group_pins, |
277 | .dt_node_to_map = pinconf_generic_dt_node_to_map_group, |
278 | .dt_free_map = pinctrl_utils_free_map, |
279 | }; |
280 | |
281 | static int pmic_gpio_get_functions_count(struct pinctrl_dev *pctldev) |
282 | { |
283 | return ARRAY_SIZE(pmic_gpio_functions); |
284 | } |
285 | |
286 | static const char *pmic_gpio_get_function_name(struct pinctrl_dev *pctldev, |
287 | unsigned function) |
288 | { |
289 | return pmic_gpio_functions[function]; |
290 | } |
291 | |
292 | static int pmic_gpio_get_function_groups(struct pinctrl_dev *pctldev, |
293 | unsigned function, |
294 | const char *const **groups, |
295 | unsigned *const num_qgroups) |
296 | { |
297 | *groups = pmic_gpio_groups; |
298 | *num_qgroups = pctldev->desc->npins; |
299 | return 0; |
300 | } |
301 | |
302 | static int pmic_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned function, |
303 | unsigned pin) |
304 | { |
305 | struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev); |
306 | struct pmic_gpio_pad *pad; |
307 | unsigned int val; |
308 | int ret; |
309 | |
310 | if (function > PMIC_GPIO_FUNC_INDEX_DTEST4) { |
311 | pr_err("function: %d is not defined\n" , function); |
312 | return -EINVAL; |
313 | } |
314 | |
315 | pad = pctldev->desc->pins[pin].drv_data; |
316 | /* |
317 | * Non-LV/MV subtypes only support 2 special functions, |
318 | * offsetting the dtestx function values by 2 |
319 | */ |
320 | if (!pad->lv_mv_type) { |
321 | if (function == PMIC_GPIO_FUNC_INDEX_FUNC3 || |
322 | function == PMIC_GPIO_FUNC_INDEX_FUNC4) { |
323 | pr_err("LV/MV subtype doesn't have func3/func4\n" ); |
324 | return -EINVAL; |
325 | } |
326 | if (function >= PMIC_GPIO_FUNC_INDEX_DTEST1) |
327 | function -= (PMIC_GPIO_FUNC_INDEX_DTEST1 - |
328 | PMIC_GPIO_FUNC_INDEX_FUNC3); |
329 | } |
330 | |
331 | pad->function = function; |
332 | |
333 | if (pad->analog_pass) |
334 | val = PMIC_GPIO_MODE_ANALOG_PASS_THRU; |
335 | else if (pad->output_enabled && pad->input_enabled) |
336 | val = PMIC_GPIO_MODE_DIGITAL_INPUT_OUTPUT; |
337 | else if (pad->output_enabled) |
338 | val = PMIC_GPIO_MODE_DIGITAL_OUTPUT; |
339 | else |
340 | val = PMIC_GPIO_MODE_DIGITAL_INPUT; |
341 | |
342 | if (pad->lv_mv_type) { |
343 | ret = pmic_gpio_write(state, pad, |
344 | PMIC_GPIO_REG_MODE_CTL, val); |
345 | if (ret < 0) |
346 | return ret; |
347 | |
348 | val = pad->atest - 1; |
349 | ret = pmic_gpio_write(state, pad, |
350 | PMIC_GPIO_REG_LV_MV_ANA_PASS_THRU_SEL, val); |
351 | if (ret < 0) |
352 | return ret; |
353 | |
354 | val = pad->out_value |
355 | << PMIC_GPIO_LV_MV_OUTPUT_INVERT_SHIFT; |
356 | val |= pad->function |
357 | & PMIC_GPIO_LV_MV_OUTPUT_SOURCE_SEL_MASK; |
358 | ret = pmic_gpio_write(state, pad, |
359 | PMIC_GPIO_REG_LV_MV_DIG_OUT_SOURCE_CTL, val); |
360 | if (ret < 0) |
361 | return ret; |
362 | } else { |
363 | val = val << PMIC_GPIO_REG_MODE_DIR_SHIFT; |
364 | val |= pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; |
365 | val |= pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT; |
366 | |
367 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_MODE_CTL, val); |
368 | if (ret < 0) |
369 | return ret; |
370 | } |
371 | |
372 | val = pad->is_enabled << PMIC_GPIO_REG_MASTER_EN_SHIFT; |
373 | |
374 | return pmic_gpio_write(state, pad, PMIC_GPIO_REG_EN_CTL, val); |
375 | } |
376 | |
377 | static const struct pinmux_ops pmic_gpio_pinmux_ops = { |
378 | .get_functions_count = pmic_gpio_get_functions_count, |
379 | .get_function_name = pmic_gpio_get_function_name, |
380 | .get_function_groups = pmic_gpio_get_function_groups, |
381 | .set_mux = pmic_gpio_set_mux, |
382 | }; |
383 | |
384 | static int pmic_gpio_config_get(struct pinctrl_dev *pctldev, |
385 | unsigned int pin, unsigned long *config) |
386 | { |
387 | unsigned param = pinconf_to_config_param(config: *config); |
388 | struct pmic_gpio_pad *pad; |
389 | unsigned arg; |
390 | |
391 | pad = pctldev->desc->pins[pin].drv_data; |
392 | |
393 | switch (param) { |
394 | case PIN_CONFIG_DRIVE_PUSH_PULL: |
395 | if (pad->buffer_type != PMIC_GPIO_OUT_BUF_CMOS) |
396 | return -EINVAL; |
397 | arg = 1; |
398 | break; |
399 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: |
400 | if (pad->buffer_type != PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS) |
401 | return -EINVAL; |
402 | arg = 1; |
403 | break; |
404 | case PIN_CONFIG_DRIVE_OPEN_SOURCE: |
405 | if (pad->buffer_type != PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS) |
406 | return -EINVAL; |
407 | arg = 1; |
408 | break; |
409 | case PIN_CONFIG_BIAS_PULL_DOWN: |
410 | if (pad->pullup != PMIC_GPIO_PULL_DOWN) |
411 | return -EINVAL; |
412 | arg = 1; |
413 | break; |
414 | case PIN_CONFIG_BIAS_DISABLE: |
415 | if (pad->pullup != PMIC_GPIO_PULL_DISABLE) |
416 | return -EINVAL; |
417 | arg = 1; |
418 | break; |
419 | case PIN_CONFIG_BIAS_PULL_UP: |
420 | if (pad->pullup != PMIC_GPIO_PULL_UP_30) |
421 | return -EINVAL; |
422 | arg = 1; |
423 | break; |
424 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: |
425 | if (pad->is_enabled) |
426 | return -EINVAL; |
427 | arg = 1; |
428 | break; |
429 | case PIN_CONFIG_POWER_SOURCE: |
430 | arg = pad->power_source; |
431 | break; |
432 | case PIN_CONFIG_INPUT_ENABLE: |
433 | if (!pad->input_enabled) |
434 | return -EINVAL; |
435 | arg = 1; |
436 | break; |
437 | case PIN_CONFIG_OUTPUT_ENABLE: |
438 | arg = pad->output_enabled; |
439 | break; |
440 | case PIN_CONFIG_OUTPUT: |
441 | arg = pad->out_value; |
442 | break; |
443 | case PMIC_GPIO_CONF_PULL_UP: |
444 | arg = pad->pullup; |
445 | break; |
446 | case PMIC_GPIO_CONF_STRENGTH: |
447 | switch (pad->strength) { |
448 | case PMIC_GPIO_OUT_STRENGTH_HIGH: |
449 | arg = PMIC_GPIO_STRENGTH_HIGH; |
450 | break; |
451 | case PMIC_GPIO_OUT_STRENGTH_LOW: |
452 | arg = PMIC_GPIO_STRENGTH_LOW; |
453 | break; |
454 | default: |
455 | arg = pad->strength; |
456 | break; |
457 | } |
458 | break; |
459 | case PMIC_GPIO_CONF_ATEST: |
460 | arg = pad->atest; |
461 | break; |
462 | case PMIC_GPIO_CONF_ANALOG_PASS: |
463 | arg = pad->analog_pass; |
464 | break; |
465 | case PMIC_GPIO_CONF_DTEST_BUFFER: |
466 | arg = pad->dtest_buffer; |
467 | break; |
468 | default: |
469 | return -EINVAL; |
470 | } |
471 | |
472 | *config = pinconf_to_config_packed(param, argument: arg); |
473 | return 0; |
474 | } |
475 | |
476 | static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int pin, |
477 | unsigned long *configs, unsigned nconfs) |
478 | { |
479 | struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev); |
480 | struct pmic_gpio_pad *pad; |
481 | unsigned param, arg; |
482 | unsigned int val; |
483 | int i, ret; |
484 | |
485 | pad = pctldev->desc->pins[pin].drv_data; |
486 | |
487 | pad->is_enabled = true; |
488 | for (i = 0; i < nconfs; i++) { |
489 | param = pinconf_to_config_param(config: configs[i]); |
490 | arg = pinconf_to_config_argument(config: configs[i]); |
491 | |
492 | switch (param) { |
493 | case PIN_CONFIG_DRIVE_PUSH_PULL: |
494 | pad->buffer_type = PMIC_GPIO_OUT_BUF_CMOS; |
495 | break; |
496 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: |
497 | if (!pad->have_buffer) |
498 | return -EINVAL; |
499 | pad->buffer_type = PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS; |
500 | break; |
501 | case PIN_CONFIG_DRIVE_OPEN_SOURCE: |
502 | if (!pad->have_buffer) |
503 | return -EINVAL; |
504 | pad->buffer_type = PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS; |
505 | break; |
506 | case PIN_CONFIG_BIAS_DISABLE: |
507 | pad->pullup = PMIC_GPIO_PULL_DISABLE; |
508 | break; |
509 | case PIN_CONFIG_BIAS_PULL_UP: |
510 | pad->pullup = PMIC_GPIO_PULL_UP_30; |
511 | break; |
512 | case PIN_CONFIG_BIAS_PULL_DOWN: |
513 | if (arg) |
514 | pad->pullup = PMIC_GPIO_PULL_DOWN; |
515 | else |
516 | pad->pullup = PMIC_GPIO_PULL_DISABLE; |
517 | break; |
518 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: |
519 | pad->is_enabled = false; |
520 | break; |
521 | case PIN_CONFIG_POWER_SOURCE: |
522 | if (arg >= pad->num_sources) |
523 | return -EINVAL; |
524 | pad->power_source = arg; |
525 | break; |
526 | case PIN_CONFIG_INPUT_ENABLE: |
527 | pad->input_enabled = arg ? true : false; |
528 | break; |
529 | case PIN_CONFIG_OUTPUT_ENABLE: |
530 | pad->output_enabled = arg ? true : false; |
531 | break; |
532 | case PIN_CONFIG_OUTPUT: |
533 | pad->output_enabled = true; |
534 | pad->out_value = arg; |
535 | break; |
536 | case PMIC_GPIO_CONF_PULL_UP: |
537 | if (arg > PMIC_GPIO_PULL_UP_1P5_30) |
538 | return -EINVAL; |
539 | pad->pullup = arg; |
540 | break; |
541 | case PMIC_GPIO_CONF_STRENGTH: |
542 | if (arg > PMIC_GPIO_STRENGTH_LOW) |
543 | return -EINVAL; |
544 | switch (arg) { |
545 | case PMIC_GPIO_STRENGTH_HIGH: |
546 | pad->strength = PMIC_GPIO_OUT_STRENGTH_HIGH; |
547 | break; |
548 | case PMIC_GPIO_STRENGTH_LOW: |
549 | pad->strength = PMIC_GPIO_OUT_STRENGTH_LOW; |
550 | break; |
551 | default: |
552 | pad->strength = arg; |
553 | break; |
554 | } |
555 | break; |
556 | case PMIC_GPIO_CONF_ATEST: |
557 | if (!pad->lv_mv_type || arg > 4) |
558 | return -EINVAL; |
559 | pad->atest = arg; |
560 | break; |
561 | case PMIC_GPIO_CONF_ANALOG_PASS: |
562 | if (!pad->lv_mv_type) |
563 | return -EINVAL; |
564 | pad->analog_pass = true; |
565 | break; |
566 | case PMIC_GPIO_CONF_DTEST_BUFFER: |
567 | if (arg > 4) |
568 | return -EINVAL; |
569 | pad->dtest_buffer = arg; |
570 | break; |
571 | default: |
572 | return -EINVAL; |
573 | } |
574 | } |
575 | |
576 | val = pad->power_source << PMIC_GPIO_REG_VIN_SHIFT; |
577 | |
578 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_VIN_CTL, val); |
579 | if (ret < 0) |
580 | return ret; |
581 | |
582 | val = pad->pullup << PMIC_GPIO_REG_PULL_SHIFT; |
583 | |
584 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_PULL_CTL, val); |
585 | if (ret < 0) |
586 | return ret; |
587 | |
588 | val = pad->buffer_type << PMIC_GPIO_REG_OUT_TYPE_SHIFT; |
589 | val |= pad->strength << PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; |
590 | |
591 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL, val); |
592 | if (ret < 0) |
593 | return ret; |
594 | |
595 | if (pad->dtest_buffer == 0) { |
596 | val = 0; |
597 | } else { |
598 | if (pad->lv_mv_type) { |
599 | val = pad->dtest_buffer - 1; |
600 | val |= PMIC_GPIO_LV_MV_DIG_IN_DTEST_EN; |
601 | } else { |
602 | val = BIT(pad->dtest_buffer - 1); |
603 | } |
604 | } |
605 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_DIG_IN_CTL, val); |
606 | if (ret < 0) |
607 | return ret; |
608 | |
609 | if (pad->analog_pass) |
610 | val = PMIC_GPIO_MODE_ANALOG_PASS_THRU; |
611 | else if (pad->output_enabled && pad->input_enabled) |
612 | val = PMIC_GPIO_MODE_DIGITAL_INPUT_OUTPUT; |
613 | else if (pad->output_enabled) |
614 | val = PMIC_GPIO_MODE_DIGITAL_OUTPUT; |
615 | else |
616 | val = PMIC_GPIO_MODE_DIGITAL_INPUT; |
617 | |
618 | if (pad->lv_mv_type) { |
619 | ret = pmic_gpio_write(state, pad, |
620 | PMIC_GPIO_REG_MODE_CTL, val); |
621 | if (ret < 0) |
622 | return ret; |
623 | |
624 | val = pad->atest - 1; |
625 | ret = pmic_gpio_write(state, pad, |
626 | PMIC_GPIO_REG_LV_MV_ANA_PASS_THRU_SEL, val); |
627 | if (ret < 0) |
628 | return ret; |
629 | |
630 | val = pad->out_value |
631 | << PMIC_GPIO_LV_MV_OUTPUT_INVERT_SHIFT; |
632 | val |= pad->function |
633 | & PMIC_GPIO_LV_MV_OUTPUT_SOURCE_SEL_MASK; |
634 | ret = pmic_gpio_write(state, pad, |
635 | PMIC_GPIO_REG_LV_MV_DIG_OUT_SOURCE_CTL, val); |
636 | if (ret < 0) |
637 | return ret; |
638 | } else { |
639 | val = val << PMIC_GPIO_REG_MODE_DIR_SHIFT; |
640 | val |= pad->function << PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; |
641 | val |= pad->out_value & PMIC_GPIO_REG_MODE_VALUE_SHIFT; |
642 | |
643 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_MODE_CTL, val); |
644 | if (ret < 0) |
645 | return ret; |
646 | } |
647 | |
648 | val = pad->is_enabled << PMIC_GPIO_REG_MASTER_EN_SHIFT; |
649 | |
650 | ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_EN_CTL, val); |
651 | |
652 | return ret; |
653 | } |
654 | |
655 | static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev, |
656 | struct seq_file *s, unsigned pin) |
657 | { |
658 | struct pmic_gpio_state *state = pinctrl_dev_get_drvdata(pctldev); |
659 | struct pmic_gpio_pad *pad; |
660 | int ret, val, function; |
661 | |
662 | static const char *const biases[] = { |
663 | "pull-up 30uA" , "pull-up 1.5uA" , "pull-up 31.5uA" , |
664 | "pull-up 1.5uA + 30uA boost" , "pull-down 10uA" , "no pull" |
665 | }; |
666 | static const char *const buffer_types[] = { |
667 | "push-pull" , "open-drain" , "open-source" |
668 | }; |
669 | static const char *const strengths[] = { |
670 | "no" , "high" , "medium" , "low" |
671 | }; |
672 | |
673 | pad = pctldev->desc->pins[pin].drv_data; |
674 | |
675 | seq_printf(m: s, fmt: " gpio%-2d:" , pin + PMIC_GPIO_PHYSICAL_OFFSET); |
676 | |
677 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_EN_CTL); |
678 | |
679 | if (val < 0 || !(val >> PMIC_GPIO_REG_MASTER_EN_SHIFT)) { |
680 | seq_puts(m: s, s: " ---" ); |
681 | } else { |
682 | if (pad->input_enabled) { |
683 | ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS); |
684 | if (ret < 0) |
685 | return; |
686 | |
687 | ret &= PMIC_MPP_REG_RT_STS_VAL_MASK; |
688 | pad->out_value = ret; |
689 | } |
690 | /* |
691 | * For the non-LV/MV subtypes only 2 special functions are |
692 | * available, offsetting the dtest function values by 2. |
693 | */ |
694 | function = pad->function; |
695 | if (!pad->lv_mv_type && |
696 | pad->function >= PMIC_GPIO_FUNC_INDEX_FUNC3) |
697 | function += PMIC_GPIO_FUNC_INDEX_DTEST1 - |
698 | PMIC_GPIO_FUNC_INDEX_FUNC3; |
699 | |
700 | if (pad->analog_pass) |
701 | seq_puts(m: s, s: " analog-pass" ); |
702 | else |
703 | seq_printf(m: s, fmt: " %-4s" , |
704 | pad->output_enabled ? "out" : "in" ); |
705 | seq_printf(m: s, fmt: " %-4s" , pad->out_value ? "high" : "low" ); |
706 | seq_printf(m: s, fmt: " %-7s" , pmic_gpio_functions[function]); |
707 | seq_printf(m: s, fmt: " vin-%d" , pad->power_source); |
708 | seq_printf(m: s, fmt: " %-27s" , biases[pad->pullup]); |
709 | seq_printf(m: s, fmt: " %-10s" , buffer_types[pad->buffer_type]); |
710 | seq_printf(m: s, fmt: " %-7s" , strengths[pad->strength]); |
711 | seq_printf(m: s, fmt: " atest-%d" , pad->atest); |
712 | seq_printf(m: s, fmt: " dtest-%d" , pad->dtest_buffer); |
713 | } |
714 | } |
715 | |
716 | static const struct pinconf_ops pmic_gpio_pinconf_ops = { |
717 | .is_generic = true, |
718 | .pin_config_group_get = pmic_gpio_config_get, |
719 | .pin_config_group_set = pmic_gpio_config_set, |
720 | .pin_config_group_dbg_show = pmic_gpio_config_dbg_show, |
721 | }; |
722 | |
723 | static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned pin) |
724 | { |
725 | struct pmic_gpio_state *state = gpiochip_get_data(gc: chip); |
726 | unsigned long config; |
727 | |
728 | config = pinconf_to_config_packed(param: PIN_CONFIG_INPUT_ENABLE, argument: 1); |
729 | |
730 | return pmic_gpio_config_set(pctldev: state->ctrl, pin, configs: &config, nconfs: 1); |
731 | } |
732 | |
733 | static int pmic_gpio_direction_output(struct gpio_chip *chip, |
734 | unsigned pin, int val) |
735 | { |
736 | struct pmic_gpio_state *state = gpiochip_get_data(gc: chip); |
737 | unsigned long config; |
738 | |
739 | config = pinconf_to_config_packed(param: PIN_CONFIG_OUTPUT, argument: val); |
740 | |
741 | return pmic_gpio_config_set(pctldev: state->ctrl, pin, configs: &config, nconfs: 1); |
742 | } |
743 | |
744 | static int pmic_gpio_get(struct gpio_chip *chip, unsigned pin) |
745 | { |
746 | struct pmic_gpio_state *state = gpiochip_get_data(gc: chip); |
747 | struct pmic_gpio_pad *pad; |
748 | int ret; |
749 | |
750 | pad = state->ctrl->desc->pins[pin].drv_data; |
751 | |
752 | if (!pad->is_enabled) |
753 | return -EINVAL; |
754 | |
755 | if (pad->input_enabled) { |
756 | ret = pmic_gpio_read(state, pad, PMIC_MPP_REG_RT_STS); |
757 | if (ret < 0) |
758 | return ret; |
759 | |
760 | pad->out_value = ret & PMIC_MPP_REG_RT_STS_VAL_MASK; |
761 | } |
762 | |
763 | return !!pad->out_value; |
764 | } |
765 | |
766 | static void pmic_gpio_set(struct gpio_chip *chip, unsigned pin, int value) |
767 | { |
768 | struct pmic_gpio_state *state = gpiochip_get_data(gc: chip); |
769 | unsigned long config; |
770 | |
771 | config = pinconf_to_config_packed(param: PIN_CONFIG_OUTPUT, argument: value); |
772 | |
773 | pmic_gpio_config_set(pctldev: state->ctrl, pin, configs: &config, nconfs: 1); |
774 | } |
775 | |
776 | static int pmic_gpio_of_xlate(struct gpio_chip *chip, |
777 | const struct of_phandle_args *gpio_desc, |
778 | u32 *flags) |
779 | { |
780 | if (chip->of_gpio_n_cells < 2) |
781 | return -EINVAL; |
782 | |
783 | if (flags) |
784 | *flags = gpio_desc->args[1]; |
785 | |
786 | return gpio_desc->args[0] - PMIC_GPIO_PHYSICAL_OFFSET; |
787 | } |
788 | |
789 | static void pmic_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) |
790 | { |
791 | struct pmic_gpio_state *state = gpiochip_get_data(gc: chip); |
792 | unsigned i; |
793 | |
794 | for (i = 0; i < chip->ngpio; i++) { |
795 | pmic_gpio_config_dbg_show(pctldev: state->ctrl, s, pin: i); |
796 | seq_puts(m: s, s: "\n" ); |
797 | } |
798 | } |
799 | |
800 | static const struct gpio_chip pmic_gpio_gpio_template = { |
801 | .direction_input = pmic_gpio_direction_input, |
802 | .direction_output = pmic_gpio_direction_output, |
803 | .get = pmic_gpio_get, |
804 | .set = pmic_gpio_set, |
805 | .request = gpiochip_generic_request, |
806 | .free = gpiochip_generic_free, |
807 | .of_xlate = pmic_gpio_of_xlate, |
808 | .dbg_show = pmic_gpio_dbg_show, |
809 | }; |
810 | |
811 | static int pmic_gpio_populate(struct pmic_gpio_state *state, |
812 | struct pmic_gpio_pad *pad) |
813 | { |
814 | int type, subtype, val, dir; |
815 | |
816 | type = pmic_gpio_read(state, pad, PMIC_GPIO_REG_TYPE); |
817 | if (type < 0) |
818 | return type; |
819 | |
820 | if (type != PMIC_GPIO_TYPE) { |
821 | dev_err(state->dev, "incorrect block type 0x%x at 0x%x\n" , |
822 | type, pad->base); |
823 | return -ENODEV; |
824 | } |
825 | |
826 | subtype = pmic_gpio_read(state, pad, PMIC_GPIO_REG_SUBTYPE); |
827 | if (subtype < 0) |
828 | return subtype; |
829 | |
830 | switch (subtype) { |
831 | case PMIC_GPIO_SUBTYPE_GPIO_4CH: |
832 | pad->have_buffer = true; |
833 | fallthrough; |
834 | case PMIC_GPIO_SUBTYPE_GPIOC_4CH: |
835 | pad->num_sources = 4; |
836 | break; |
837 | case PMIC_GPIO_SUBTYPE_GPIO_8CH: |
838 | pad->have_buffer = true; |
839 | fallthrough; |
840 | case PMIC_GPIO_SUBTYPE_GPIOC_8CH: |
841 | pad->num_sources = 8; |
842 | break; |
843 | case PMIC_GPIO_SUBTYPE_GPIO_LV: |
844 | pad->num_sources = 1; |
845 | pad->have_buffer = true; |
846 | pad->lv_mv_type = true; |
847 | break; |
848 | case PMIC_GPIO_SUBTYPE_GPIO_MV: |
849 | pad->num_sources = 2; |
850 | pad->have_buffer = true; |
851 | pad->lv_mv_type = true; |
852 | break; |
853 | case PMIC_GPIO_SUBTYPE_GPIO_LV_VIN2: |
854 | pad->num_sources = 2; |
855 | pad->have_buffer = true; |
856 | pad->lv_mv_type = true; |
857 | break; |
858 | case PMIC_GPIO_SUBTYPE_GPIO_MV_VIN3: |
859 | pad->num_sources = 3; |
860 | pad->have_buffer = true; |
861 | pad->lv_mv_type = true; |
862 | break; |
863 | default: |
864 | dev_err(state->dev, "unknown GPIO type 0x%x\n" , subtype); |
865 | return -ENODEV; |
866 | } |
867 | |
868 | if (pad->lv_mv_type) { |
869 | val = pmic_gpio_read(state, pad, |
870 | PMIC_GPIO_REG_LV_MV_DIG_OUT_SOURCE_CTL); |
871 | if (val < 0) |
872 | return val; |
873 | |
874 | pad->out_value = !!(val & PMIC_GPIO_LV_MV_OUTPUT_INVERT); |
875 | pad->function = val & PMIC_GPIO_LV_MV_OUTPUT_SOURCE_SEL_MASK; |
876 | |
877 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_MODE_CTL); |
878 | if (val < 0) |
879 | return val; |
880 | |
881 | dir = val & PMIC_GPIO_REG_LV_MV_MODE_DIR_MASK; |
882 | } else { |
883 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_MODE_CTL); |
884 | if (val < 0) |
885 | return val; |
886 | |
887 | pad->out_value = val & PMIC_GPIO_REG_MODE_VALUE_SHIFT; |
888 | |
889 | dir = val >> PMIC_GPIO_REG_MODE_DIR_SHIFT; |
890 | dir &= PMIC_GPIO_REG_MODE_DIR_MASK; |
891 | pad->function = val >> PMIC_GPIO_REG_MODE_FUNCTION_SHIFT; |
892 | pad->function &= PMIC_GPIO_REG_MODE_FUNCTION_MASK; |
893 | } |
894 | |
895 | switch (dir) { |
896 | case PMIC_GPIO_MODE_DIGITAL_INPUT: |
897 | pad->input_enabled = true; |
898 | pad->output_enabled = false; |
899 | break; |
900 | case PMIC_GPIO_MODE_DIGITAL_OUTPUT: |
901 | pad->input_enabled = false; |
902 | pad->output_enabled = true; |
903 | break; |
904 | case PMIC_GPIO_MODE_DIGITAL_INPUT_OUTPUT: |
905 | pad->input_enabled = true; |
906 | pad->output_enabled = true; |
907 | break; |
908 | case PMIC_GPIO_MODE_ANALOG_PASS_THRU: |
909 | if (!pad->lv_mv_type) |
910 | return -ENODEV; |
911 | pad->analog_pass = true; |
912 | break; |
913 | default: |
914 | dev_err(state->dev, "unknown GPIO direction\n" ); |
915 | return -ENODEV; |
916 | } |
917 | |
918 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_VIN_CTL); |
919 | if (val < 0) |
920 | return val; |
921 | |
922 | pad->power_source = val >> PMIC_GPIO_REG_VIN_SHIFT; |
923 | pad->power_source &= PMIC_GPIO_REG_VIN_MASK; |
924 | |
925 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_PULL_CTL); |
926 | if (val < 0) |
927 | return val; |
928 | |
929 | pad->pullup = val >> PMIC_GPIO_REG_PULL_SHIFT; |
930 | pad->pullup &= PMIC_GPIO_REG_PULL_MASK; |
931 | |
932 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_IN_CTL); |
933 | if (val < 0) |
934 | return val; |
935 | |
936 | if (pad->lv_mv_type && (val & PMIC_GPIO_LV_MV_DIG_IN_DTEST_EN)) |
937 | pad->dtest_buffer = |
938 | (val & PMIC_GPIO_LV_MV_DIG_IN_DTEST_SEL_MASK) + 1; |
939 | else if (!pad->lv_mv_type) |
940 | pad->dtest_buffer = ffs(val); |
941 | else |
942 | pad->dtest_buffer = 0; |
943 | |
944 | val = pmic_gpio_read(state, pad, PMIC_GPIO_REG_DIG_OUT_CTL); |
945 | if (val < 0) |
946 | return val; |
947 | |
948 | pad->strength = val >> PMIC_GPIO_REG_OUT_STRENGTH_SHIFT; |
949 | pad->strength &= PMIC_GPIO_REG_OUT_STRENGTH_MASK; |
950 | |
951 | pad->buffer_type = val >> PMIC_GPIO_REG_OUT_TYPE_SHIFT; |
952 | pad->buffer_type &= PMIC_GPIO_REG_OUT_TYPE_MASK; |
953 | |
954 | if (pad->lv_mv_type) { |
955 | val = pmic_gpio_read(state, pad, |
956 | PMIC_GPIO_REG_LV_MV_ANA_PASS_THRU_SEL); |
957 | if (val < 0) |
958 | return val; |
959 | pad->atest = (val & PMIC_GPIO_LV_MV_ANA_MUX_SEL_MASK) + 1; |
960 | } |
961 | |
962 | /* Pin could be disabled with PIN_CONFIG_BIAS_HIGH_IMPEDANCE */ |
963 | pad->is_enabled = true; |
964 | return 0; |
965 | } |
966 | |
967 | static int pmic_gpio_domain_translate(struct irq_domain *domain, |
968 | struct irq_fwspec *fwspec, |
969 | unsigned long *hwirq, |
970 | unsigned int *type) |
971 | { |
972 | struct pmic_gpio_state *state = container_of(domain->host_data, |
973 | struct pmic_gpio_state, |
974 | chip); |
975 | |
976 | if (fwspec->param_count != 2 || |
977 | fwspec->param[0] < 1 || fwspec->param[0] > state->chip.ngpio) |
978 | return -EINVAL; |
979 | |
980 | *hwirq = fwspec->param[0] - PMIC_GPIO_PHYSICAL_OFFSET; |
981 | *type = fwspec->param[1]; |
982 | |
983 | return 0; |
984 | } |
985 | |
986 | static unsigned int pmic_gpio_child_offset_to_irq(struct gpio_chip *chip, |
987 | unsigned int offset) |
988 | { |
989 | return offset + PMIC_GPIO_PHYSICAL_OFFSET; |
990 | } |
991 | |
992 | static int pmic_gpio_child_to_parent_hwirq(struct gpio_chip *chip, |
993 | unsigned int child_hwirq, |
994 | unsigned int child_type, |
995 | unsigned int *parent_hwirq, |
996 | unsigned int *parent_type) |
997 | { |
998 | struct pmic_gpio_state *state = gpiochip_get_data(gc: chip); |
999 | |
1000 | *parent_hwirq = child_hwirq + state->pid_base; |
1001 | *parent_type = child_type; |
1002 | |
1003 | return 0; |
1004 | } |
1005 | |
1006 | static int pmic_gpio_populate_parent_fwspec(struct gpio_chip *chip, |
1007 | union gpio_irq_fwspec *gfwspec, |
1008 | unsigned int parent_hwirq, |
1009 | unsigned int parent_type) |
1010 | { |
1011 | struct pmic_gpio_state *state = gpiochip_get_data(gc: chip); |
1012 | struct irq_fwspec *fwspec = &gfwspec->fwspec; |
1013 | |
1014 | fwspec->fwnode = chip->irq.parent_domain->fwnode; |
1015 | |
1016 | fwspec->param_count = 4; |
1017 | fwspec->param[0] = state->usid; |
1018 | fwspec->param[1] = parent_hwirq; |
1019 | /* param[2] must be left as 0 */ |
1020 | fwspec->param[3] = parent_type; |
1021 | |
1022 | return 0; |
1023 | } |
1024 | |
1025 | static void pmic_gpio_irq_mask(struct irq_data *data) |
1026 | { |
1027 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d: data); |
1028 | |
1029 | irq_chip_mask_parent(data); |
1030 | gpiochip_disable_irq(gc, offset: data->hwirq); |
1031 | } |
1032 | |
1033 | static void pmic_gpio_irq_unmask(struct irq_data *data) |
1034 | { |
1035 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d: data); |
1036 | |
1037 | gpiochip_enable_irq(gc, offset: data->hwirq); |
1038 | irq_chip_unmask_parent(data); |
1039 | } |
1040 | |
1041 | static const struct irq_chip spmi_gpio_irq_chip = { |
1042 | .name = "spmi-gpio" , |
1043 | .irq_ack = irq_chip_ack_parent, |
1044 | .irq_mask = pmic_gpio_irq_mask, |
1045 | .irq_unmask = pmic_gpio_irq_unmask, |
1046 | .irq_set_type = irq_chip_set_type_parent, |
1047 | .irq_set_wake = irq_chip_set_wake_parent, |
1048 | .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND, |
1049 | GPIOCHIP_IRQ_RESOURCE_HELPERS, |
1050 | }; |
1051 | |
1052 | static int pmic_gpio_probe(struct platform_device *pdev) |
1053 | { |
1054 | struct irq_domain *parent_domain; |
1055 | struct device_node *parent_node; |
1056 | struct device *dev = &pdev->dev; |
1057 | struct pinctrl_pin_desc *pindesc; |
1058 | struct pinctrl_desc *pctrldesc; |
1059 | struct pmic_gpio_pad *pad, *pads; |
1060 | struct pmic_gpio_state *state; |
1061 | struct gpio_irq_chip *girq; |
1062 | const struct spmi_device *parent_spmi_dev; |
1063 | int ret, npins, i; |
1064 | u32 reg; |
1065 | |
1066 | ret = of_property_read_u32(np: dev->of_node, propname: "reg" , out_value: ®); |
1067 | if (ret < 0) { |
1068 | dev_err(dev, "missing base address" ); |
1069 | return ret; |
1070 | } |
1071 | |
1072 | npins = (uintptr_t) device_get_match_data(dev: &pdev->dev); |
1073 | |
1074 | state = devm_kzalloc(dev, size: sizeof(*state), GFP_KERNEL); |
1075 | if (!state) |
1076 | return -ENOMEM; |
1077 | |
1078 | platform_set_drvdata(pdev, data: state); |
1079 | |
1080 | state->dev = &pdev->dev; |
1081 | state->map = dev_get_regmap(dev: dev->parent, NULL); |
1082 | parent_spmi_dev = to_spmi_device(d: dev->parent); |
1083 | state->usid = parent_spmi_dev->usid; |
1084 | state->pid_base = reg >> 8; |
1085 | |
1086 | pindesc = devm_kcalloc(dev, n: npins, size: sizeof(*pindesc), GFP_KERNEL); |
1087 | if (!pindesc) |
1088 | return -ENOMEM; |
1089 | |
1090 | pads = devm_kcalloc(dev, n: npins, size: sizeof(*pads), GFP_KERNEL); |
1091 | if (!pads) |
1092 | return -ENOMEM; |
1093 | |
1094 | pctrldesc = devm_kzalloc(dev, size: sizeof(*pctrldesc), GFP_KERNEL); |
1095 | if (!pctrldesc) |
1096 | return -ENOMEM; |
1097 | |
1098 | pctrldesc->pctlops = &pmic_gpio_pinctrl_ops; |
1099 | pctrldesc->pmxops = &pmic_gpio_pinmux_ops; |
1100 | pctrldesc->confops = &pmic_gpio_pinconf_ops; |
1101 | pctrldesc->owner = THIS_MODULE; |
1102 | pctrldesc->name = dev_name(dev); |
1103 | pctrldesc->pins = pindesc; |
1104 | pctrldesc->npins = npins; |
1105 | pctrldesc->num_custom_params = ARRAY_SIZE(pmic_gpio_bindings); |
1106 | pctrldesc->custom_params = pmic_gpio_bindings; |
1107 | #ifdef CONFIG_DEBUG_FS |
1108 | pctrldesc->custom_conf_items = pmic_conf_items; |
1109 | #endif |
1110 | |
1111 | for (i = 0; i < npins; i++, pindesc++) { |
1112 | pad = &pads[i]; |
1113 | pindesc->drv_data = pad; |
1114 | pindesc->number = i; |
1115 | pindesc->name = pmic_gpio_groups[i]; |
1116 | |
1117 | pad->base = reg + i * PMIC_GPIO_ADDRESS_RANGE; |
1118 | |
1119 | ret = pmic_gpio_populate(state, pad); |
1120 | if (ret < 0) |
1121 | return ret; |
1122 | } |
1123 | |
1124 | state->chip = pmic_gpio_gpio_template; |
1125 | state->chip.parent = dev; |
1126 | state->chip.base = -1; |
1127 | state->chip.ngpio = npins; |
1128 | state->chip.label = dev_name(dev); |
1129 | state->chip.of_gpio_n_cells = 2; |
1130 | state->chip.can_sleep = false; |
1131 | |
1132 | state->ctrl = devm_pinctrl_register(dev, pctldesc: pctrldesc, driver_data: state); |
1133 | if (IS_ERR(ptr: state->ctrl)) |
1134 | return PTR_ERR(ptr: state->ctrl); |
1135 | |
1136 | parent_node = of_irq_find_parent(child: state->dev->of_node); |
1137 | if (!parent_node) |
1138 | return -ENXIO; |
1139 | |
1140 | parent_domain = irq_find_host(node: parent_node); |
1141 | of_node_put(node: parent_node); |
1142 | if (!parent_domain) |
1143 | return -ENXIO; |
1144 | |
1145 | girq = &state->chip.irq; |
1146 | gpio_irq_chip_set_chip(girq, chip: &spmi_gpio_irq_chip); |
1147 | girq->default_type = IRQ_TYPE_NONE; |
1148 | girq->handler = handle_level_irq; |
1149 | girq->fwnode = dev_fwnode(state->dev); |
1150 | girq->parent_domain = parent_domain; |
1151 | girq->child_to_parent_hwirq = pmic_gpio_child_to_parent_hwirq; |
1152 | girq->populate_parent_alloc_arg = pmic_gpio_populate_parent_fwspec; |
1153 | girq->child_offset_to_irq = pmic_gpio_child_offset_to_irq; |
1154 | girq->child_irq_domain_ops.translate = pmic_gpio_domain_translate; |
1155 | |
1156 | ret = gpiochip_add_data(&state->chip, state); |
1157 | if (ret) { |
1158 | dev_err(state->dev, "can't add gpio chip\n" ); |
1159 | return ret; |
1160 | } |
1161 | |
1162 | /* |
1163 | * For DeviceTree-supported systems, the gpio core checks the |
1164 | * pinctrl's device node for the "gpio-ranges" property. |
1165 | * If it is present, it takes care of adding the pin ranges |
1166 | * for the driver. In this case the driver can skip ahead. |
1167 | * |
1168 | * In order to remain compatible with older, existing DeviceTree |
1169 | * files which don't set the "gpio-ranges" property or systems that |
1170 | * utilize ACPI the driver has to call gpiochip_add_pin_range(). |
1171 | */ |
1172 | if (!of_property_read_bool(np: dev->of_node, propname: "gpio-ranges" )) { |
1173 | ret = gpiochip_add_pin_range(gc: &state->chip, pinctl_name: dev_name(dev), gpio_offset: 0, pin_offset: 0, |
1174 | npins); |
1175 | if (ret) { |
1176 | dev_err(dev, "failed to add pin range\n" ); |
1177 | goto err_range; |
1178 | } |
1179 | } |
1180 | |
1181 | return 0; |
1182 | |
1183 | err_range: |
1184 | gpiochip_remove(gc: &state->chip); |
1185 | return ret; |
1186 | } |
1187 | |
1188 | static void pmic_gpio_remove(struct platform_device *pdev) |
1189 | { |
1190 | struct pmic_gpio_state *state = platform_get_drvdata(pdev); |
1191 | |
1192 | gpiochip_remove(gc: &state->chip); |
1193 | } |
1194 | |
1195 | static const struct of_device_id pmic_gpio_of_match[] = { |
1196 | { .compatible = "qcom,pm2250-gpio" , .data = (void *) 10 }, |
1197 | /* pm660 has 13 GPIOs with holes on 1, 5, 6, 7, 8 and 10 */ |
1198 | { .compatible = "qcom,pm660-gpio" , .data = (void *) 13 }, |
1199 | /* pm660l has 12 GPIOs with holes on 1, 2, 10, 11 and 12 */ |
1200 | { .compatible = "qcom,pm660l-gpio" , .data = (void *) 12 }, |
1201 | { .compatible = "qcom,pm6125-gpio" , .data = (void *) 9 }, |
1202 | { .compatible = "qcom,pm6150-gpio" , .data = (void *) 10 }, |
1203 | { .compatible = "qcom,pm6150l-gpio" , .data = (void *) 12 }, |
1204 | { .compatible = "qcom,pm6350-gpio" , .data = (void *) 9 }, |
1205 | { .compatible = "qcom,pm7250b-gpio" , .data = (void *) 12 }, |
1206 | { .compatible = "qcom,pm7325-gpio" , .data = (void *) 10 }, |
1207 | { .compatible = "qcom,pm7550ba-gpio" , .data = (void *) 8}, |
1208 | { .compatible = "qcom,pm8005-gpio" , .data = (void *) 4 }, |
1209 | { .compatible = "qcom,pm8008-gpio" , .data = (void *) 2 }, |
1210 | { .compatible = "qcom,pm8019-gpio" , .data = (void *) 6 }, |
1211 | /* pm8150 has 10 GPIOs with holes on 2, 5, 7 and 8 */ |
1212 | { .compatible = "qcom,pm8150-gpio" , .data = (void *) 10 }, |
1213 | { .compatible = "qcom,pmc8180-gpio" , .data = (void *) 10 }, |
1214 | /* pm8150b has 12 GPIOs with holes on 3, r and 7 */ |
1215 | { .compatible = "qcom,pm8150b-gpio" , .data = (void *) 12 }, |
1216 | /* pm8150l has 12 GPIOs with holes on 7 */ |
1217 | { .compatible = "qcom,pm8150l-gpio" , .data = (void *) 12 }, |
1218 | { .compatible = "qcom,pmc8180c-gpio" , .data = (void *) 12 }, |
1219 | { .compatible = "qcom,pm8226-gpio" , .data = (void *) 8 }, |
1220 | { .compatible = "qcom,pm8350-gpio" , .data = (void *) 10 }, |
1221 | { .compatible = "qcom,pm8350b-gpio" , .data = (void *) 8 }, |
1222 | { .compatible = "qcom,pm8350c-gpio" , .data = (void *) 9 }, |
1223 | { .compatible = "qcom,pm8450-gpio" , .data = (void *) 4 }, |
1224 | { .compatible = "qcom,pm8550-gpio" , .data = (void *) 12 }, |
1225 | { .compatible = "qcom,pm8550b-gpio" , .data = (void *) 12 }, |
1226 | { .compatible = "qcom,pm8550ve-gpio" , .data = (void *) 8 }, |
1227 | { .compatible = "qcom,pm8550vs-gpio" , .data = (void *) 6 }, |
1228 | { .compatible = "qcom,pm8916-gpio" , .data = (void *) 4 }, |
1229 | { .compatible = "qcom,pm8941-gpio" , .data = (void *) 36 }, |
1230 | /* pm8950 has 8 GPIOs with holes on 3 */ |
1231 | { .compatible = "qcom,pm8950-gpio" , .data = (void *) 8 }, |
1232 | /* pm8953 has 8 GPIOs with holes on 3 and 6 */ |
1233 | { .compatible = "qcom,pm8953-gpio" , .data = (void *) 8 }, |
1234 | { .compatible = "qcom,pm8994-gpio" , .data = (void *) 22 }, |
1235 | { .compatible = "qcom,pm8998-gpio" , .data = (void *) 26 }, |
1236 | { .compatible = "qcom,pma8084-gpio" , .data = (void *) 22 }, |
1237 | { .compatible = "qcom,pmi632-gpio" , .data = (void *) 8 }, |
1238 | { .compatible = "qcom,pmi8950-gpio" , .data = (void *) 2 }, |
1239 | { .compatible = "qcom,pmi8994-gpio" , .data = (void *) 10 }, |
1240 | { .compatible = "qcom,pmi8998-gpio" , .data = (void *) 14 }, |
1241 | { .compatible = "qcom,pmk8350-gpio" , .data = (void *) 4 }, |
1242 | { .compatible = "qcom,pmk8550-gpio" , .data = (void *) 6 }, |
1243 | { .compatible = "qcom,pmm8155au-gpio" , .data = (void *) 10 }, |
1244 | { .compatible = "qcom,pmm8654au-gpio" , .data = (void *) 12 }, |
1245 | /* pmp8074 has 12 GPIOs with holes on 1 and 12 */ |
1246 | { .compatible = "qcom,pmp8074-gpio" , .data = (void *) 12 }, |
1247 | { .compatible = "qcom,pmr735a-gpio" , .data = (void *) 4 }, |
1248 | { .compatible = "qcom,pmr735b-gpio" , .data = (void *) 4 }, |
1249 | { .compatible = "qcom,pmr735d-gpio" , .data = (void *) 2 }, |
1250 | /* pms405 has 12 GPIOs with holes on 1, 9, and 10 */ |
1251 | { .compatible = "qcom,pms405-gpio" , .data = (void *) 12 }, |
1252 | /* pmx55 has 11 GPIOs with holes on 3, 7, 10, 11 */ |
1253 | { .compatible = "qcom,pmx55-gpio" , .data = (void *) 11 }, |
1254 | { .compatible = "qcom,pmx65-gpio" , .data = (void *) 16 }, |
1255 | { .compatible = "qcom,pmx75-gpio" , .data = (void *) 16 }, |
1256 | { }, |
1257 | }; |
1258 | |
1259 | MODULE_DEVICE_TABLE(of, pmic_gpio_of_match); |
1260 | |
1261 | static struct platform_driver pmic_gpio_driver = { |
1262 | .driver = { |
1263 | .name = "qcom-spmi-gpio" , |
1264 | .of_match_table = pmic_gpio_of_match, |
1265 | }, |
1266 | .probe = pmic_gpio_probe, |
1267 | .remove_new = pmic_gpio_remove, |
1268 | }; |
1269 | |
1270 | module_platform_driver(pmic_gpio_driver); |
1271 | |
1272 | MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>" ); |
1273 | MODULE_DESCRIPTION("Qualcomm SPMI PMIC GPIO pin control driver" ); |
1274 | MODULE_ALIAS("platform:qcom-spmi-gpio" ); |
1275 | MODULE_LICENSE("GPL v2" ); |
1276 | |