summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/mediatek
diff options
context:
space:
mode:
authorSean Wang <sean.wang@mediatek.com>2018-09-08 07:07:22 -0400
committerLinus Walleij <linus.walleij@linaro.org>2018-09-18 17:52:49 -0400
commitc28321979ba86bade51246faea13c7ce4ffb6ef5 (patch)
treedf7e204da50f37d70847a69629e2e0ae9da9538d /drivers/pinctrl/mediatek
parent1dc5e53691596832991e6550fdbaeb1f9bd82383 (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.c48
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mt7622.c2
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c79
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h14
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
772static const struct of_device_id mt7622_pinctrl_of_match[] = { 774static 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 */
26struct mtk_drive_desc {
27 u8 min;
28 u8 max;
29 u8 step;
30 u8 scal;
31};
32
33/* The groups of drive strength */
34const 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
16static void mtk_w32(struct mtk_pinctrl *pctl, u32 reg, u32 val) 42static 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 */
194int 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
222int 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
134struct 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 */
134struct mtk_pin_soc { 137struct 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
150struct mtk_pinctrl { 159struct mtk_pinctrl {
@@ -161,4 +170,9 @@ void mtk_rmw(struct mtk_pinctrl *pctl, u32 reg, u32 mask, u32 set);
161int mtk_hw_set_value(struct mtk_pinctrl *hw, int pin, int field, int value); 170int mtk_hw_set_value(struct mtk_pinctrl *hw, int pin, int field, int value);
162int mtk_hw_get_value(struct mtk_pinctrl *hw, int pin, int field, int *value); 171int mtk_hw_get_value(struct mtk_pinctrl *hw, int pin, int field, int *value);
163 172
173int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
174 const struct mtk_pin_desc *desc, u32 arg);
175int 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 */