mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
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>
This commit is contained in:
parent
1dc5e53691
commit
c28321979b
4 changed files with 112 additions and 31 deletions
|
@ -82,6 +82,9 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
|
||||||
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
|
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
|
||||||
u32 param = pinconf_to_config_param(*config);
|
u32 param = pinconf_to_config_param(*config);
|
||||||
int val, val2, err, reg, ret = 1;
|
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) {
|
switch (param) {
|
||||||
case PIN_CONFIG_BIAS_DISABLE:
|
case PIN_CONFIG_BIAS_DISABLE:
|
||||||
|
@ -139,19 +142,13 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||||
err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_E4, &val);
|
if (hw->soc->drive_get) {
|
||||||
if (err)
|
err = hw->soc->drive_get(hw, desc, &ret);
|
||||||
return err;
|
if (err)
|
||||||
|
return err;
|
||||||
err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_E8, &val2);
|
} else {
|
||||||
if (err)
|
err = -ENOTSUPP;
|
||||||
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;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MTK_PIN_CONFIG_TDSEL:
|
case MTK_PIN_CONFIG_TDSEL:
|
||||||
case MTK_PIN_CONFIG_RDSEL:
|
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)
|
unsigned long *configs, unsigned int num_configs)
|
||||||
{
|
{
|
||||||
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
|
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
|
||||||
|
const struct mtk_pin_desc *desc;
|
||||||
u32 reg, param, arg;
|
u32 reg, param, arg;
|
||||||
int cfg, err = 0;
|
int cfg, err = 0;
|
||||||
|
|
||||||
|
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
|
||||||
|
|
||||||
for (cfg = 0; cfg < num_configs; cfg++) {
|
for (cfg = 0; cfg < num_configs; cfg++) {
|
||||||
param = pinconf_to_config_param(configs[cfg]);
|
param = pinconf_to_config_param(configs[cfg]);
|
||||||
arg = pinconf_to_config_argument(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;
|
goto err;
|
||||||
break;
|
break;
|
||||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||||
/* 4mA when (e8, e4) = (0, 0);
|
if (hw->soc->drive_set) {
|
||||||
* 8mA when (e8, e4) = (0, 1);
|
err = hw->soc->drive_set(hw, desc, arg);
|
||||||
* 12mA when (e8, e4) = (1, 0);
|
if (err)
|
||||||
* 16mA when (e8, e4) = (1, 1)
|
return err;
|
||||||
*/
|
|
||||||
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;
|
|
||||||
} else {
|
} else {
|
||||||
err = -ENOTSUPP;
|
err = -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -767,6 +767,8 @@ static const struct mtk_pin_soc mt7622_data = {
|
||||||
.eint_hw = &mt7622_eint_hw,
|
.eint_hw = &mt7622_eint_hw,
|
||||||
.gpio_m = 1,
|
.gpio_m = 1,
|
||||||
.eint_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[] = {
|
static const struct of_device_id mt7622_pinctrl_of_match[] = {
|
||||||
|
|
|
@ -13,6 +13,32 @@
|
||||||
|
|
||||||
#include "pinctrl-mtk-common-v2.h"
|
#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)
|
static void mtk_w32(struct mtk_pinctrl *pctl, u32 reg, u32 val)
|
||||||
{
|
{
|
||||||
writel_relaxed(val, pctl->base + reg);
|
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;
|
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_E8,
|
||||||
PINCTRL_PIN_REG_TDSEL,
|
PINCTRL_PIN_REG_TDSEL,
|
||||||
PINCTRL_PIN_REG_RDSEL,
|
PINCTRL_PIN_REG_RDSEL,
|
||||||
|
PINCTRL_PIN_REG_DRV,
|
||||||
PINCTRL_PIN_REG_MAX,
|
PINCTRL_PIN_REG_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,6 +131,8 @@ struct mtk_pin_desc {
|
||||||
u8 drv_n;
|
u8 drv_n;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mtk_pinctrl;
|
||||||
|
|
||||||
/* struct mtk_pin_soc - the structure that holds SoC-specific data */
|
/* struct mtk_pin_soc - the structure that holds SoC-specific data */
|
||||||
struct mtk_pin_soc {
|
struct mtk_pin_soc {
|
||||||
const struct mtk_pin_reg_calc *reg_cal;
|
const struct mtk_pin_reg_calc *reg_cal;
|
||||||
|
@ -145,6 +148,12 @@ struct mtk_pin_soc {
|
||||||
/* Specific parameters per SoC */
|
/* Specific parameters per SoC */
|
||||||
u8 gpio_m;
|
u8 gpio_m;
|
||||||
u8 eint_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 {
|
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_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_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 */
|
#endif /* __PINCTRL_MTK_COMMON_V2_H */
|
||||||
|
|
Loading…
Add table
Reference in a new issue