]>
Commit | Line | Data |
---|---|---|
ad97051b RF |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * TLMM driver for Qualcomm APQ8016, APQ8096 | |
4 | * | |
5 | * (C) Copyright 2018 Ramon Fried <[email protected]> | |
6 | * | |
7 | */ | |
8 | ||
9 | #include <common.h> | |
10 | #include <dm.h> | |
11 | #include <errno.h> | |
12 | #include <asm/io.h> | |
13 | #include <dm/pinctrl.h> | |
cd93d625 | 14 | #include <linux/bitops.h> |
ad97051b RF |
15 | #include "pinctrl-snapdragon.h" |
16 | ||
17 | struct msm_pinctrl_priv { | |
18 | phys_addr_t base; | |
19 | struct msm_pinctrl_data *data; | |
20 | }; | |
21 | ||
22 | #define GPIO_CONFIG_OFFSET(x) ((x) * 0x1000) | |
23 | #define TLMM_GPIO_PULL_MASK GENMASK(1, 0) | |
24 | #define TLMM_FUNC_SEL_MASK GENMASK(5, 2) | |
25 | #define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6) | |
ea7bf8fb | 26 | #define TLMM_GPIO_DISABLE BIT(9) |
ad97051b RF |
27 | |
28 | static const struct pinconf_param msm_conf_params[] = { | |
29 | { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 3 }, | |
30 | { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, | |
31 | }; | |
32 | ||
33 | static int msm_get_functions_count(struct udevice *dev) | |
34 | { | |
35 | struct msm_pinctrl_priv *priv = dev_get_priv(dev); | |
36 | ||
37 | return priv->data->functions_count; | |
38 | } | |
39 | ||
40 | static int msm_get_pins_count(struct udevice *dev) | |
41 | { | |
42 | struct msm_pinctrl_priv *priv = dev_get_priv(dev); | |
43 | ||
44 | return priv->data->pin_count; | |
45 | } | |
46 | ||
47 | static const char *msm_get_function_name(struct udevice *dev, | |
48 | unsigned int selector) | |
49 | { | |
50 | struct msm_pinctrl_priv *priv = dev_get_priv(dev); | |
51 | ||
52 | return priv->data->get_function_name(dev, selector); | |
53 | } | |
54 | ||
55 | static int msm_pinctrl_probe(struct udevice *dev) | |
56 | { | |
57 | struct msm_pinctrl_priv *priv = dev_get_priv(dev); | |
58 | ||
59 | priv->base = devfdt_get_addr(dev); | |
60 | priv->data = (struct msm_pinctrl_data *)dev->driver_data; | |
61 | ||
62 | return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0; | |
63 | } | |
64 | ||
65 | static const char *msm_get_pin_name(struct udevice *dev, unsigned int selector) | |
66 | { | |
67 | struct msm_pinctrl_priv *priv = dev_get_priv(dev); | |
68 | ||
69 | return priv->data->get_pin_name(dev, selector); | |
70 | } | |
71 | ||
72 | static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector, | |
73 | unsigned int func_selector) | |
74 | { | |
75 | struct msm_pinctrl_priv *priv = dev_get_priv(dev); | |
76 | ||
77 | clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), | |
ea7bf8fb | 78 | TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE, |
ad97051b RF |
79 | priv->data->get_function_mux(func_selector) << 2); |
80 | return 0; | |
81 | } | |
82 | ||
83 | static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector, | |
84 | unsigned int param, unsigned int argument) | |
85 | { | |
86 | struct msm_pinctrl_priv *priv = dev_get_priv(dev); | |
87 | ||
88 | switch (param) { | |
89 | case PIN_CONFIG_DRIVE_STRENGTH: | |
90 | clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), | |
91 | TLMM_DRV_STRENGTH_MASK, argument << 6); | |
92 | break; | |
93 | case PIN_CONFIG_BIAS_DISABLE: | |
94 | clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), | |
95 | TLMM_GPIO_PULL_MASK); | |
96 | break; | |
97 | default: | |
98 | return 0; | |
99 | } | |
100 | ||
101 | return 0; | |
102 | } | |
103 | ||
104 | static struct pinctrl_ops msm_pinctrl_ops = { | |
105 | .get_pins_count = msm_get_pins_count, | |
106 | .get_pin_name = msm_get_pin_name, | |
107 | .set_state = pinctrl_generic_set_state, | |
108 | .pinmux_set = msm_pinmux_set, | |
109 | .pinconf_num_params = ARRAY_SIZE(msm_conf_params), | |
110 | .pinconf_params = msm_conf_params, | |
111 | .pinconf_set = msm_pinconf_set, | |
112 | .get_functions_count = msm_get_functions_count, | |
113 | .get_function_name = msm_get_function_name, | |
114 | }; | |
115 | ||
116 | static const struct udevice_id msm_pinctrl_ids[] = { | |
ad97051b | 117 | { .compatible = "qcom,tlmm-apq8016", .data = (ulong)&apq8016_data }, |
94268f1a | 118 | { .compatible = "qcom,tlmm-apq8096", .data = (ulong)&apq8096_data }, |
ad97051b RF |
119 | { } |
120 | }; | |
121 | ||
122 | U_BOOT_DRIVER(pinctrl_snapdraon) = { | |
123 | .name = "pinctrl_msm", | |
124 | .id = UCLASS_PINCTRL, | |
125 | .of_match = msm_pinctrl_ids, | |
126 | .priv_auto_alloc_size = sizeof(struct msm_pinctrl_priv), | |
127 | .ops = &msm_pinctrl_ops, | |
128 | .probe = msm_pinctrl_probe, | |
129 | }; |