mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
pinctrl: mediatek: Add Pinctrl/GPIO/EINT driver for mt2701
Add mt2701 support using mediatek common pinctrl driver. MT2701 have some special pins need an extra setting register than other ICs, so adding this support to common code. Signed-off-by: Biao Huang <biao.huang@mediatek.com> Acked-by: Yingjoe Chen <yingjoe.chen@mediatek.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
committed by
Linus Walleij
parent
5372381587
commit
148b95eea0
@@ -9,6 +9,12 @@ config PINCTRL_MTK_COMMON
|
||||
select OF_GPIO
|
||||
|
||||
# For ARMv7 SoCs
|
||||
config PINCTRL_MT2701
|
||||
bool "Mediatek MT2701 pin control" if COMPILE_TEST && !MACH_MT2701
|
||||
depends on OF
|
||||
default MACH_MT2701
|
||||
select PINCTRL_MTK_COMMON
|
||||
|
||||
config PINCTRL_MT8135
|
||||
bool "Mediatek MT8135 pin control" if COMPILE_TEST && !MACH_MT8135
|
||||
depends on OF
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinctrl-mtk-common.o
|
||||
|
||||
# SoC Drivers
|
||||
obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o
|
||||
obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
|
||||
obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o
|
||||
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -47,6 +47,8 @@
|
||||
static const char * const mtk_gpio_functions[] = {
|
||||
"func0", "func1", "func2", "func3",
|
||||
"func4", "func5", "func6", "func7",
|
||||
"func8", "func9", "func10", "func11",
|
||||
"func12", "func13", "func14", "func15",
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -81,6 +83,9 @@ static int mtk_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset;
|
||||
bit = BIT(offset & 0xf);
|
||||
|
||||
if (pctl->devdata->spec_dir_set)
|
||||
pctl->devdata->spec_dir_set(®_addr, offset);
|
||||
|
||||
if (input)
|
||||
/* Different SoC has different alignment offset. */
|
||||
reg_addr = CLR_ADDR(reg_addr, pctl);
|
||||
@@ -675,9 +680,14 @@ static int mtk_pmx_set_mode(struct pinctrl_dev *pctldev,
|
||||
unsigned int mask = (1L << GPIO_MODE_BITS) - 1;
|
||||
struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
if (pctl->devdata->spec_pinmux_set)
|
||||
pctl->devdata->spec_pinmux_set(mtk_get_regmap(pctl, pin),
|
||||
pin, mode);
|
||||
|
||||
reg_addr = ((pin / MAX_GPIO_MODE_PER_REG) << pctl->devdata->port_shf)
|
||||
+ pctl->devdata->pinmux_offset;
|
||||
|
||||
mode &= mask;
|
||||
bit = pin % MAX_GPIO_MODE_PER_REG;
|
||||
mask <<= (GPIO_MODE_BITS * bit);
|
||||
val = (mode << (GPIO_MODE_BITS * bit));
|
||||
@@ -754,6 +764,10 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
||||
|
||||
reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset;
|
||||
bit = BIT(offset & 0xf);
|
||||
|
||||
if (pctl->devdata->spec_dir_set)
|
||||
pctl->devdata->spec_dir_set(®_addr, offset);
|
||||
|
||||
regmap_read(pctl->regmap1, reg_addr, &read_val);
|
||||
return !(read_val & bit);
|
||||
}
|
||||
|
||||
@@ -209,7 +209,14 @@ struct mtk_eint_offsets {
|
||||
* means when user set smt, input enable is set at the same time. So they
|
||||
* also need special control. If special control is success, this should
|
||||
* return 0, otherwise return non-zero value.
|
||||
*
|
||||
* @spec_pinmux_set: In some cases, there are two pinmux functions share
|
||||
* the same value in the same segment of pinmux control register. If user
|
||||
* want to use one of the two functions, they need an extra bit setting to
|
||||
* select the right one.
|
||||
* @spec_dir_set: In very few SoCs, direction control registers are not
|
||||
* arranged continuously, they may be cut to parts. So they need special
|
||||
* dir setting.
|
||||
|
||||
* @dir_offset: The direction register offset.
|
||||
* @pullen_offset: The pull-up/pull-down enable register offset.
|
||||
* @pinmux_offset: The pinmux register offset.
|
||||
@@ -234,6 +241,9 @@ struct mtk_pinctrl_devdata {
|
||||
unsigned char align, bool isup, unsigned int arg);
|
||||
int (*spec_ies_smt_set)(struct regmap *reg, unsigned int pin,
|
||||
unsigned char align, int value, enum pin_config_param arg);
|
||||
void (*spec_pinmux_set)(struct regmap *reg, unsigned int pin,
|
||||
unsigned int mode);
|
||||
void (*spec_dir_set)(unsigned int *reg_addr, unsigned int pin);
|
||||
unsigned int dir_offset;
|
||||
unsigned int ies_offset;
|
||||
unsigned int smt_offset;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user