Commit 8919ffbb authored by Linus Walleij's avatar Linus Walleij

Merge branch 'devel-mt2701' into devel

parents 4afe2684 59ee9c96
This diff is collapsed.
...@@ -9,6 +9,12 @@ config PINCTRL_MTK_COMMON ...@@ -9,6 +9,12 @@ config PINCTRL_MTK_COMMON
select OF_GPIO select OF_GPIO
# For ARMv7 SoCs # 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 config PINCTRL_MT8135
bool "Mediatek MT8135 pin control" if COMPILE_TEST && !MACH_MT8135 bool "Mediatek MT8135 pin control" if COMPILE_TEST && !MACH_MT8135
depends on OF depends on OF
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinctrl-mtk-common.o obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinctrl-mtk-common.o
# SoC Drivers # SoC Drivers
obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o
obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
......
This diff is collapsed.
...@@ -43,10 +43,13 @@ ...@@ -43,10 +43,13 @@
#define MAX_GPIO_MODE_PER_REG 5 #define MAX_GPIO_MODE_PER_REG 5
#define GPIO_MODE_BITS 3 #define GPIO_MODE_BITS 3
#define GPIO_MODE_PREFIX "GPIO"
static const char * const mtk_gpio_functions[] = { static const char * const mtk_gpio_functions[] = {
"func0", "func1", "func2", "func3", "func0", "func1", "func2", "func3",
"func4", "func5", "func6", "func7", "func4", "func5", "func6", "func7",
"func8", "func9", "func10", "func11",
"func12", "func13", "func14", "func15",
}; };
/* /*
...@@ -81,6 +84,9 @@ static int mtk_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, ...@@ -81,6 +84,9 @@ static int mtk_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset; reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset;
bit = BIT(offset & 0xf); bit = BIT(offset & 0xf);
if (pctl->devdata->spec_dir_set)
pctl->devdata->spec_dir_set(&reg_addr, offset);
if (input) if (input)
/* Different SoC has different alignment offset. */ /* Different SoC has different alignment offset. */
reg_addr = CLR_ADDR(reg_addr, pctl); reg_addr = CLR_ADDR(reg_addr, pctl);
...@@ -675,9 +681,14 @@ static int mtk_pmx_set_mode(struct pinctrl_dev *pctldev, ...@@ -675,9 +681,14 @@ static int mtk_pmx_set_mode(struct pinctrl_dev *pctldev,
unsigned int mask = (1L << GPIO_MODE_BITS) - 1; unsigned int mask = (1L << GPIO_MODE_BITS) - 1;
struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); 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) reg_addr = ((pin / MAX_GPIO_MODE_PER_REG) << pctl->devdata->port_shf)
+ pctl->devdata->pinmux_offset; + pctl->devdata->pinmux_offset;
mode &= mask;
bit = pin % MAX_GPIO_MODE_PER_REG; bit = pin % MAX_GPIO_MODE_PER_REG;
mask <<= (GPIO_MODE_BITS * bit); mask <<= (GPIO_MODE_BITS * bit);
val = (mode << (GPIO_MODE_BITS * bit)); val = (mode << (GPIO_MODE_BITS * bit));
...@@ -723,12 +734,47 @@ static int mtk_pmx_set_mux(struct pinctrl_dev *pctldev, ...@@ -723,12 +734,47 @@ static int mtk_pmx_set_mux(struct pinctrl_dev *pctldev,
return 0; return 0;
} }
static int mtk_pmx_find_gpio_mode(struct mtk_pinctrl *pctl,
unsigned offset)
{
const struct mtk_desc_pin *pin = pctl->devdata->pins + offset;
const struct mtk_desc_function *func = pin->functions;
while (func && func->name) {
if (!strncmp(func->name, GPIO_MODE_PREFIX,
sizeof(GPIO_MODE_PREFIX)-1))
return func->muxval;
func++;
}
return -EINVAL;
}
static int mtk_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
{
unsigned long muxval;
struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
muxval = mtk_pmx_find_gpio_mode(pctl, offset);
if (muxval < 0) {
dev_err(pctl->dev, "invalid gpio pin %d.\n", offset);
return -EINVAL;
}
mtk_pmx_set_mode(pctldev, offset, muxval);
return 0;
}
static const struct pinmux_ops mtk_pmx_ops = { static const struct pinmux_ops mtk_pmx_ops = {
.get_functions_count = mtk_pmx_get_funcs_cnt, .get_functions_count = mtk_pmx_get_funcs_cnt,
.get_function_name = mtk_pmx_get_func_name, .get_function_name = mtk_pmx_get_func_name,
.get_function_groups = mtk_pmx_get_func_groups, .get_function_groups = mtk_pmx_get_func_groups,
.set_mux = mtk_pmx_set_mux, .set_mux = mtk_pmx_set_mux,
.gpio_set_direction = mtk_pmx_gpio_set_direction, .gpio_set_direction = mtk_pmx_gpio_set_direction,
.gpio_request_enable = mtk_pmx_gpio_request_enable,
}; };
static int mtk_gpio_direction_input(struct gpio_chip *chip, static int mtk_gpio_direction_input(struct gpio_chip *chip,
...@@ -754,6 +800,10 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned offset) ...@@ -754,6 +800,10 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset; reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset;
bit = BIT(offset & 0xf); bit = BIT(offset & 0xf);
if (pctl->devdata->spec_dir_set)
pctl->devdata->spec_dir_set(&reg_addr, offset);
regmap_read(pctl->regmap1, reg_addr, &read_val); regmap_read(pctl->regmap1, reg_addr, &read_val);
return !(read_val & bit); return !(read_val & bit);
} }
......
...@@ -209,7 +209,14 @@ struct mtk_eint_offsets { ...@@ -209,7 +209,14 @@ struct mtk_eint_offsets {
* means when user set smt, input enable is set at the same time. So they * 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 * also need special control. If special control is success, this should
* return 0, otherwise return non-zero value. * 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. * @dir_offset: The direction register offset.
* @pullen_offset: The pull-up/pull-down enable register offset. * @pullen_offset: The pull-up/pull-down enable register offset.
* @pinmux_offset: The pinmux register offset. * @pinmux_offset: The pinmux register offset.
...@@ -234,6 +241,9 @@ struct mtk_pinctrl_devdata { ...@@ -234,6 +241,9 @@ struct mtk_pinctrl_devdata {
unsigned char align, bool isup, unsigned int arg); unsigned char align, bool isup, unsigned int arg);
int (*spec_ies_smt_set)(struct regmap *reg, unsigned int pin, int (*spec_ies_smt_set)(struct regmap *reg, unsigned int pin,
unsigned char align, int value, enum pin_config_param arg); 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 dir_offset;
unsigned int ies_offset; unsigned int ies_offset;
unsigned int smt_offset; unsigned int smt_offset;
......
This diff is collapsed.
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