mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 07:31:15 +00:00
pinctrl: mediatek: add support for different types of IO pins
There are many pins in an SoC, and register usage may vary by pins. This patch introduces a concept of "io type" and "io type group" to mediatek pinctrl drivers. This can provide different pinconf handlers implementation (eg: "bias-pull-up/down", "driving" and "input-enable") for IO pins that belong to different types. Signed-off-by: Sam Shih <sam.shih@mediatek.com>
This commit is contained in:
parent
10334e0bc8
commit
1a80ef5520
2 changed files with 81 additions and 5 deletions
|
@ -219,6 +219,25 @@ static int mtk_hw_get_value(struct udevice *dev, int pin, int field,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINCONF)
|
||||
static int mtk_get_pin_io_type(struct udevice *dev, int pin,
|
||||
struct mtk_io_type_desc *io_type)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
u8 io_n = priv->soc->pins[pin].io_n;
|
||||
|
||||
if (io_n >= priv->soc->ntype)
|
||||
return -EINVAL;
|
||||
|
||||
io_type->name = priv->soc->io_type[io_n].name;
|
||||
io_type->bias_set = priv->soc->io_type[io_n].bias_set;
|
||||
io_type->drive_set = priv->soc->io_type[io_n].drive_set;
|
||||
io_type->input_enable = priv->soc->io_type[io_n].input_enable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mtk_get_groups_count(struct udevice *dev)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
@ -416,16 +435,25 @@ int mtk_pinconf_bias_set(struct udevice *dev, u32 pin, u32 arg, u32 val)
|
|||
{
|
||||
int err;
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
struct mtk_io_type_desc io_type;
|
||||
int rev = priv->soc->rev;
|
||||
bool disable, pullup;
|
||||
|
||||
disable = (arg == PIN_CONFIG_BIAS_DISABLE);
|
||||
pullup = (arg == PIN_CONFIG_BIAS_PULL_UP);
|
||||
|
||||
if (rev == MTK_PINCTRL_V0)
|
||||
if (!mtk_get_pin_io_type(dev, pin, &io_type)) {
|
||||
if (io_type.bias_set)
|
||||
err = io_type.bias_set(dev, pin, disable, pullup,
|
||||
val);
|
||||
else
|
||||
err = -EINVAL;
|
||||
|
||||
} else if (rev == MTK_PINCTRL_V0) {
|
||||
err = mtk_pinconf_bias_set_v0(dev, pin, disable, pullup, val);
|
||||
else
|
||||
} else {
|
||||
err = mtk_pinconf_bias_set_v1(dev, pin, disable, pullup, val);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -447,8 +475,13 @@ int mtk_pinconf_input_enable_v1(struct udevice *dev, u32 pin, u32 arg)
|
|||
int mtk_pinconf_input_enable(struct udevice *dev, u32 pin, u32 arg)
|
||||
{
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
struct mtk_io_type_desc io_type;
|
||||
|
||||
int rev = priv->soc->rev;
|
||||
|
||||
if (!mtk_get_pin_io_type(dev, pin, &io_type))
|
||||
if (io_type.input_enable)
|
||||
return io_type.input_enable(dev, pin, arg);
|
||||
if (rev == MTK_PINCTRL_V1)
|
||||
return mtk_pinconf_input_enable_v1(dev, pin, arg);
|
||||
|
||||
|
@ -505,12 +538,19 @@ int mtk_pinconf_drive_set(struct udevice *dev, u32 pin, u32 arg)
|
|||
{
|
||||
int err;
|
||||
struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
struct mtk_io_type_desc io_type;
|
||||
int rev = priv->soc->rev;
|
||||
|
||||
if (rev == MTK_PINCTRL_V0)
|
||||
if (!mtk_get_pin_io_type(dev, pin, &io_type)) {
|
||||
if (io_type.drive_set)
|
||||
err = io_type.drive_set(dev, pin, arg);
|
||||
else
|
||||
err = -EINVAL;
|
||||
} else if (rev == MTK_PINCTRL_V0) {
|
||||
err = mtk_pinconf_drive_set_v0(dev, pin, arg);
|
||||
else
|
||||
} else {
|
||||
err = mtk_pinconf_drive_set_v1(dev, pin, arg);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -12,10 +12,15 @@
|
|||
#define MAX_BASE_CALC 10
|
||||
|
||||
#define MTK_RANGE(_a) { .range = (_a), .nranges = ARRAY_SIZE(_a), }
|
||||
#define MTK_PIN(_number, _name, _drv_n) { \
|
||||
|
||||
#define MTK_PIN(_number, _name, _drv_n) \
|
||||
MTK_TYPED_PIN(_number, _name, _drv_n, IO_TYPE_DEFAULT)
|
||||
|
||||
#define MTK_TYPED_PIN(_number, _name, _drv_n, _io_n) { \
|
||||
.number = _number, \
|
||||
.name = _name, \
|
||||
.drv_n = _drv_n, \
|
||||
.io_n = _io_n, \
|
||||
}
|
||||
|
||||
#define PINCTRL_PIN_GROUP(name, id) \
|
||||
|
@ -75,6 +80,18 @@ enum {
|
|||
DRV_GRP4,
|
||||
};
|
||||
|
||||
/* Group the pins by the io type */
|
||||
enum {
|
||||
IO_TYPE_DEFAULT,
|
||||
IO_TYPE_GRP0,
|
||||
IO_TYPE_GRP1,
|
||||
IO_TYPE_GRP2,
|
||||
IO_TYPE_GRP3,
|
||||
IO_TYPE_GRP4,
|
||||
IO_TYPE_GRP5,
|
||||
IO_TYPE_GRP6,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_pin_field - the structure that holds the information of the field
|
||||
* used to describe the attribute for the pin
|
||||
|
@ -139,11 +156,13 @@ struct mtk_pin_reg_calc {
|
|||
* @number: unique pin number from the global pin number space
|
||||
* @name: name for this pin
|
||||
* @drv_n: the index with the driving group
|
||||
* @io_n: the index with the io type
|
||||
*/
|
||||
struct mtk_pin_desc {
|
||||
unsigned int number;
|
||||
const char *name;
|
||||
u8 drv_n;
|
||||
u8 io_n;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -172,6 +191,21 @@ struct mtk_function_desc {
|
|||
int num_group_names;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_io_type_desc - io class descriptor for specific pins
|
||||
* @name: name of the io class
|
||||
*/
|
||||
struct mtk_io_type_desc {
|
||||
const char *name;
|
||||
#if CONFIG_IS_ENABLED(PINCONF)
|
||||
/* Specific pinconfig operations */
|
||||
int (*bias_set)(struct udevice *dev, u32 pin, bool disable,
|
||||
bool pullup, u32 val);
|
||||
int (*drive_set)(struct udevice *dev, u32 pin, u32 arg);
|
||||
int (*input_enable)(struct udevice *dev, u32 pin, u32 arg);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* struct mtk_pin_soc - the structure that holds SoC-specific data */
|
||||
struct mtk_pinctrl_soc {
|
||||
const char *name;
|
||||
|
@ -182,6 +216,8 @@ struct mtk_pinctrl_soc {
|
|||
int ngrps;
|
||||
const struct mtk_function_desc *funcs;
|
||||
int nfuncs;
|
||||
const struct mtk_io_type_desc *io_type;
|
||||
u8 ntype;
|
||||
int gpio_mode;
|
||||
const char * const *base_names;
|
||||
unsigned int nbase_names;
|
||||
|
|
Loading…
Reference in a new issue