diff options
author | Sean Wang <sean.wang@mediatek.com> | 2018-09-08 07:07:22 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2018-09-18 17:52:49 -0400 |
commit | c28321979ba86bade51246faea13c7ce4ffb6ef5 (patch) | |
tree | df7e204da50f37d70847a69629e2e0ae9da9538d /drivers/pinctrl/mediatek | |
parent | 1dc5e53691596832991e6550fdbaeb1f9bd82383 (diff) |
pinctrl: mediatek: add driving strength related support to pinctrl-mtk-common-v2.c
Put driving strength support related functions to pinctrl-mtk-common-v2.c
as these operations might be different by chips and allow different type
of driver to reuse them.
Signed-off-by: Ryder.Lee <ryder.lee@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/mediatek')
-rw-r--r-- | drivers/pinctrl/mediatek/pinctrl-moore.c | 48 | ||||
-rw-r--r-- | drivers/pinctrl/mediatek/pinctrl-mt7622.c | 2 | ||||
-rw-r--r-- | drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 79 | ||||
-rw-r--r-- | drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 14 |
4 files changed, 112 insertions, 31 deletions
diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c index b412b65d0441..1f0cd306a940 100644 --- a/drivers/pinctrl/mediatek/pinctrl-moore.c +++ b/drivers/pinctrl/mediatek/pinctrl-moore.c | |||
@@ -82,6 +82,9 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, | |||
82 | struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); | 82 | struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); |
83 | u32 param = pinconf_to_config_param(*config); | 83 | u32 param = pinconf_to_config_param(*config); |
84 | int val, val2, err, reg, ret = 1; | 84 | int val, val2, err, reg, ret = 1; |
85 | const struct mtk_pin_desc *desc; | ||
86 | |||
87 | desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; | ||
85 | 88 | ||
86 | switch (param) { | 89 | switch (param) { |
87 | case PIN_CONFIG_BIAS_DISABLE: | 90 | case PIN_CONFIG_BIAS_DISABLE: |
@@ -139,19 +142,13 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, | |||
139 | 142 | ||
140 | break; | 143 | break; |
141 | case PIN_CONFIG_DRIVE_STRENGTH: | 144 | case PIN_CONFIG_DRIVE_STRENGTH: |
142 | err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_E4, &val); | 145 | if (hw->soc->drive_get) { |
143 | if (err) | 146 | err = hw->soc->drive_get(hw, desc, &ret); |
144 | return err; | 147 | if (err) |
145 | 148 | return err; | |
146 | err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_E8, &val2); | 149 | } else { |
147 | if (err) | 150 | err = -ENOTSUPP; |
148 | return err; | 151 | } |
149 | |||
150 | /* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1) | ||
151 | * 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1) | ||
152 | */ | ||
153 | ret = ((val2 << 1) + val + 1) * 4; | ||
154 | |||
155 | break; | 152 | break; |
156 | case MTK_PIN_CONFIG_TDSEL: | 153 | case MTK_PIN_CONFIG_TDSEL: |
157 | case MTK_PIN_CONFIG_RDSEL: | 154 | case MTK_PIN_CONFIG_RDSEL: |
@@ -178,9 +175,12 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, | |||
178 | unsigned long *configs, unsigned int num_configs) | 175 | unsigned long *configs, unsigned int num_configs) |
179 | { | 176 | { |
180 | struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); | 177 | struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); |
178 | const struct mtk_pin_desc *desc; | ||
181 | u32 reg, param, arg; | 179 | u32 reg, param, arg; |
182 | int cfg, err = 0; | 180 | int cfg, err = 0; |
183 | 181 | ||
182 | desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; | ||
183 | |||
184 | for (cfg = 0; cfg < num_configs; cfg++) { | 184 | for (cfg = 0; cfg < num_configs; cfg++) { |
185 | param = pinconf_to_config_param(configs[cfg]); | 185 | param = pinconf_to_config_param(configs[cfg]); |
186 | arg = pinconf_to_config_argument(configs[cfg]); | 186 | arg = pinconf_to_config_argument(configs[cfg]); |
@@ -247,24 +247,10 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, | |||
247 | goto err; | 247 | goto err; |
248 | break; | 248 | break; |
249 | case PIN_CONFIG_DRIVE_STRENGTH: | 249 | case PIN_CONFIG_DRIVE_STRENGTH: |
250 | /* 4mA when (e8, e4) = (0, 0); | 250 | if (hw->soc->drive_set) { |
251 | * 8mA when (e8, e4) = (0, 1); | 251 | err = hw->soc->drive_set(hw, desc, arg); |
252 | * 12mA when (e8, e4) = (1, 0); | 252 | if (err) |
253 | * 16mA when (e8, e4) = (1, 1) | 253 | return err; |
254 | */ | ||
255 | if (!(arg % 4) && (arg >= 4 && arg <= 16)) { | ||
256 | arg = arg / 4 - 1; | ||
257 | err = mtk_hw_set_value(hw, pin, | ||
258 | PINCTRL_PIN_REG_E4, | ||
259 | arg & 0x1); | ||
260 | if (err) | ||
261 | goto err; | ||
262 | |||
263 | err = mtk_hw_set_value(hw, pin, | ||
264 | PINCTRL_PIN_REG_E8, | ||
265 | (arg & 0x2) >> 1); | ||
266 | if (err) | ||
267 | goto err; | ||
268 | } else { | 254 | } else { |
269 | err = -ENOTSUPP; | 255 | err = -ENOTSUPP; |
270 | } | 256 | } |
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7622.c b/drivers/pinctrl/mediatek/pinctrl-mt7622.c index 2fe1f27e21bc..f6904a925755 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt7622.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt7622.c | |||
@@ -767,6 +767,8 @@ static const struct mtk_pin_soc mt7622_data = { | |||
767 | .eint_hw = &mt7622_eint_hw, | 767 | .eint_hw = &mt7622_eint_hw, |
768 | .gpio_m = 1, | 768 | .gpio_m = 1, |
769 | .eint_m = 1, | 769 | .eint_m = 1, |
770 | .drive_set = mtk_pinconf_drive_set, | ||
771 | .drive_get = mtk_pinconf_drive_get, | ||
770 | }; | 772 | }; |
771 | 773 | ||
772 | static const struct of_device_id mt7622_pinctrl_of_match[] = { | 774 | static const struct of_device_id mt7622_pinctrl_of_match[] = { |
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index 2a168043a6f0..886b40ec3b3f 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | |||
@@ -13,6 +13,32 @@ | |||
13 | 13 | ||
14 | #include "pinctrl-mtk-common-v2.h" | 14 | #include "pinctrl-mtk-common-v2.h" |
15 | 15 | ||
16 | /** | ||
17 | * struct mtk_drive_desc - the structure that holds the information | ||
18 | * of the driving current | ||
19 | * @min: the minimum current of this group | ||
20 | * @max: the maximum current of this group | ||
21 | * @step: the step current of this group | ||
22 | * @scal: the weight factor | ||
23 | * | ||
24 | * formula: output = ((input) / step - 1) * scal | ||
25 | */ | ||
26 | struct mtk_drive_desc { | ||
27 | u8 min; | ||
28 | u8 max; | ||
29 | u8 step; | ||
30 | u8 scal; | ||
31 | }; | ||
32 | |||
33 | /* The groups of drive strength */ | ||
34 | const struct mtk_drive_desc mtk_drive[] = { | ||
35 | [DRV_GRP0] = { 4, 16, 4, 1 }, | ||
36 | [DRV_GRP1] = { 4, 16, 4, 2 }, | ||
37 | [DRV_GRP2] = { 2, 8, 2, 1 }, | ||
38 | [DRV_GRP3] = { 2, 8, 2, 2 }, | ||
39 | [DRV_GRP4] = { 2, 16, 2, 1 }, | ||
40 | }; | ||
41 | |||
16 | static void mtk_w32(struct mtk_pinctrl *pctl, u32 reg, u32 val) | 42 | static void mtk_w32(struct mtk_pinctrl *pctl, u32 reg, u32 val) |
17 | { | 43 | { |
18 | writel_relaxed(val, pctl->base + reg); | 44 | writel_relaxed(val, pctl->base + reg); |
@@ -163,3 +189,56 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, int pin, int field, int *value) | |||
163 | 189 | ||
164 | return 0; | 190 | return 0; |
165 | } | 191 | } |
192 | |||
193 | /* Revision 0 */ | ||
194 | int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, | ||
195 | const struct mtk_pin_desc *desc, u32 arg) | ||
196 | { | ||
197 | const struct mtk_drive_desc *tb; | ||
198 | int err = -ENOTSUPP; | ||
199 | |||
200 | tb = &mtk_drive[desc->drv_n]; | ||
201 | /* 4mA when (e8, e4) = (0, 0) | ||
202 | * 8mA when (e8, e4) = (0, 1) | ||
203 | * 12mA when (e8, e4) = (1, 0) | ||
204 | * 16mA when (e8, e4) = (1, 1) | ||
205 | */ | ||
206 | if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) { | ||
207 | arg = (arg / tb->step - 1) * tb->scal; | ||
208 | err = mtk_hw_set_value(hw, desc->number, PINCTRL_PIN_REG_E4, | ||
209 | arg & 0x1); | ||
210 | if (err) | ||
211 | return err; | ||
212 | |||
213 | err = mtk_hw_set_value(hw, desc->number, PINCTRL_PIN_REG_E8, | ||
214 | (arg & 0x2) >> 1); | ||
215 | if (err) | ||
216 | return err; | ||
217 | } | ||
218 | |||
219 | return err; | ||
220 | } | ||
221 | |||
222 | int mtk_pinconf_drive_get(struct mtk_pinctrl *hw, | ||
223 | const struct mtk_pin_desc *desc, int *val) | ||
224 | { | ||
225 | const struct mtk_drive_desc *tb; | ||
226 | int err, val1, val2; | ||
227 | |||
228 | tb = &mtk_drive[desc->drv_n]; | ||
229 | |||
230 | err = mtk_hw_get_value(hw, desc->number, PINCTRL_PIN_REG_E4, &val1); | ||
231 | if (err) | ||
232 | return err; | ||
233 | |||
234 | err = mtk_hw_get_value(hw, desc->number, PINCTRL_PIN_REG_E8, &val2); | ||
235 | if (err) | ||
236 | return err; | ||
237 | |||
238 | /* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1) | ||
239 | * 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1) | ||
240 | */ | ||
241 | *val = (((val2 << 1) + val1) / tb->scal + 1) * tb->step; | ||
242 | |||
243 | return 0; | ||
244 | } | ||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index 6041024a438f..727e5aaca52f 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | |||
@@ -50,6 +50,7 @@ enum { | |||
50 | PINCTRL_PIN_REG_E8, | 50 | PINCTRL_PIN_REG_E8, |
51 | PINCTRL_PIN_REG_TDSEL, | 51 | PINCTRL_PIN_REG_TDSEL, |
52 | PINCTRL_PIN_REG_RDSEL, | 52 | PINCTRL_PIN_REG_RDSEL, |
53 | PINCTRL_PIN_REG_DRV, | ||
53 | PINCTRL_PIN_REG_MAX, | 54 | PINCTRL_PIN_REG_MAX, |
54 | }; | 55 | }; |
55 | 56 | ||
@@ -130,6 +131,8 @@ struct mtk_pin_desc { | |||
130 | u8 drv_n; | 131 | u8 drv_n; |
131 | }; | 132 | }; |
132 | 133 | ||
134 | struct mtk_pinctrl; | ||
135 | |||
133 | /* struct mtk_pin_soc - the structure that holds SoC-specific data */ | 136 | /* struct mtk_pin_soc - the structure that holds SoC-specific data */ |
134 | struct mtk_pin_soc { | 137 | struct mtk_pin_soc { |
135 | const struct mtk_pin_reg_calc *reg_cal; | 138 | const struct mtk_pin_reg_calc *reg_cal; |
@@ -145,6 +148,12 @@ struct mtk_pin_soc { | |||
145 | /* Specific parameters per SoC */ | 148 | /* Specific parameters per SoC */ |
146 | u8 gpio_m; | 149 | u8 gpio_m; |
147 | u8 eint_m; | 150 | u8 eint_m; |
151 | |||
152 | /* Specific pinconfig operations */ | ||
153 | int (*drive_set)(struct mtk_pinctrl *hw, | ||
154 | const struct mtk_pin_desc *desc, u32 arg); | ||
155 | int (*drive_get)(struct mtk_pinctrl *hw, | ||
156 | const struct mtk_pin_desc *desc, int *val); | ||
148 | }; | 157 | }; |
149 | 158 | ||
150 | struct mtk_pinctrl { | 159 | struct mtk_pinctrl { |
@@ -161,4 +170,9 @@ void mtk_rmw(struct mtk_pinctrl *pctl, u32 reg, u32 mask, u32 set); | |||
161 | int mtk_hw_set_value(struct mtk_pinctrl *hw, int pin, int field, int value); | 170 | int mtk_hw_set_value(struct mtk_pinctrl *hw, int pin, int field, int value); |
162 | int mtk_hw_get_value(struct mtk_pinctrl *hw, int pin, int field, int *value); | 171 | int mtk_hw_get_value(struct mtk_pinctrl *hw, int pin, int field, int *value); |
163 | 172 | ||
173 | int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, | ||
174 | const struct mtk_pin_desc *desc, u32 arg); | ||
175 | int mtk_pinconf_drive_get(struct mtk_pinctrl *hw, | ||
176 | const struct mtk_pin_desc *desc, int *val); | ||
177 | |||
164 | #endif /* __PINCTRL_MTK_COMMON_V2_H */ | 178 | #endif /* __PINCTRL_MTK_COMMON_V2_H */ |