Commit c2832197 authored by Sean Wang's avatar Sean Wang Committed by Linus Walleij

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: default avatarRyder.Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarSean Wang <sean.wang@mediatek.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 1dc5e536
......@@ -82,6 +82,9 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
int val, val2, err, reg, ret = 1;
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
......@@ -139,19 +142,13 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
break;
case PIN_CONFIG_DRIVE_STRENGTH:
err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_E4, &val);
if (err)
return err;
err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_E8, &val2);
if (err)
return err;
/* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1)
* 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1)
*/
ret = ((val2 << 1) + val + 1) * 4;
if (hw->soc->drive_get) {
err = hw->soc->drive_get(hw, desc, &ret);
if (err)
return err;
} else {
err = -ENOTSUPP;
}
break;
case MTK_PIN_CONFIG_TDSEL:
case MTK_PIN_CONFIG_RDSEL:
......@@ -178,9 +175,12 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
const struct mtk_pin_desc *desc;
u32 reg, param, arg;
int cfg, err = 0;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
for (cfg = 0; cfg < num_configs; cfg++) {
param = pinconf_to_config_param(configs[cfg]);
arg = pinconf_to_config_argument(configs[cfg]);
......@@ -247,24 +247,10 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
goto err;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
/* 4mA when (e8, e4) = (0, 0);
* 8mA when (e8, e4) = (0, 1);
* 12mA when (e8, e4) = (1, 0);
* 16mA when (e8, e4) = (1, 1)
*/
if (!(arg % 4) && (arg >= 4 && arg <= 16)) {
arg = arg / 4 - 1;
err = mtk_hw_set_value(hw, pin,
PINCTRL_PIN_REG_E4,
arg & 0x1);
if (err)
goto err;
err = mtk_hw_set_value(hw, pin,
PINCTRL_PIN_REG_E8,
(arg & 0x2) >> 1);
if (err)
goto err;
if (hw->soc->drive_set) {
err = hw->soc->drive_set(hw, desc, arg);
if (err)
return err;
} else {
err = -ENOTSUPP;
}
......
......@@ -767,6 +767,8 @@ static const struct mtk_pin_soc mt7622_data = {
.eint_hw = &mt7622_eint_hw,
.gpio_m = 1,
.eint_m = 1,
.drive_set = mtk_pinconf_drive_set,
.drive_get = mtk_pinconf_drive_get,
};
static const struct of_device_id mt7622_pinctrl_of_match[] = {
......
......@@ -13,6 +13,32 @@
#include "pinctrl-mtk-common-v2.h"
/**
* struct mtk_drive_desc - the structure that holds the information
* of the driving current
* @min: the minimum current of this group
* @max: the maximum current of this group
* @step: the step current of this group
* @scal: the weight factor
*
* formula: output = ((input) / step - 1) * scal
*/
struct mtk_drive_desc {
u8 min;
u8 max;
u8 step;
u8 scal;
};
/* The groups of drive strength */
const struct mtk_drive_desc mtk_drive[] = {
[DRV_GRP0] = { 4, 16, 4, 1 },
[DRV_GRP1] = { 4, 16, 4, 2 },
[DRV_GRP2] = { 2, 8, 2, 1 },
[DRV_GRP3] = { 2, 8, 2, 2 },
[DRV_GRP4] = { 2, 16, 2, 1 },
};
static void mtk_w32(struct mtk_pinctrl *pctl, u32 reg, u32 val)
{
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)
return 0;
}
/* Revision 0 */
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg)
{
const struct mtk_drive_desc *tb;
int err = -ENOTSUPP;
tb = &mtk_drive[desc->drv_n];
/* 4mA when (e8, e4) = (0, 0)
* 8mA when (e8, e4) = (0, 1)
* 12mA when (e8, e4) = (1, 0)
* 16mA when (e8, e4) = (1, 1)
*/
if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
arg = (arg / tb->step - 1) * tb->scal;
err = mtk_hw_set_value(hw, desc->number, PINCTRL_PIN_REG_E4,
arg & 0x1);
if (err)
return err;
err = mtk_hw_set_value(hw, desc->number, PINCTRL_PIN_REG_E8,
(arg & 0x2) >> 1);
if (err)
return err;
}
return err;
}
int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val)
{
const struct mtk_drive_desc *tb;
int err, val1, val2;
tb = &mtk_drive[desc->drv_n];
err = mtk_hw_get_value(hw, desc->number, PINCTRL_PIN_REG_E4, &val1);
if (err)
return err;
err = mtk_hw_get_value(hw, desc->number, PINCTRL_PIN_REG_E8, &val2);
if (err)
return err;
/* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1)
* 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1)
*/
*val = (((val2 << 1) + val1) / tb->scal + 1) * tb->step;
return 0;
}
......@@ -50,6 +50,7 @@ enum {
PINCTRL_PIN_REG_E8,
PINCTRL_PIN_REG_TDSEL,
PINCTRL_PIN_REG_RDSEL,
PINCTRL_PIN_REG_DRV,
PINCTRL_PIN_REG_MAX,
};
......@@ -130,6 +131,8 @@ struct mtk_pin_desc {
u8 drv_n;
};
struct mtk_pinctrl;
/* struct mtk_pin_soc - the structure that holds SoC-specific data */
struct mtk_pin_soc {
const struct mtk_pin_reg_calc *reg_cal;
......@@ -145,6 +148,12 @@ struct mtk_pin_soc {
/* Specific parameters per SoC */
u8 gpio_m;
u8 eint_m;
/* Specific pinconfig operations */
int (*drive_set)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
int (*drive_get)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val);
};
struct mtk_pinctrl {
......@@ -161,4 +170,9 @@ void mtk_rmw(struct mtk_pinctrl *pctl, u32 reg, u32 mask, u32 set);
int mtk_hw_set_value(struct mtk_pinctrl *hw, int pin, int field, int value);
int mtk_hw_get_value(struct mtk_pinctrl *hw, int pin, int field, int *value);
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val);
#endif /* __PINCTRL_MTK_COMMON_V2_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment