diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c index 943475636f88..99e39f0b8ed0 100644 --- a/drivers/mfd/rk808.c +++ b/drivers/mfd/rk808.c @@ -241,7 +241,7 @@ static const struct mfd_cell rk808s[] = { static const struct mfd_cell rk816s[] = { { .name = "rk808-clkout", }, { .name = "rk808-regulator", }, - { .name = "rk8xx-gpio", }, + { .name = "rk805-pinctrl", }, { .name = "rk816-battery", .of_compatible = "rk816-battery", }, { .name = "rk805-pwrkey", diff --git a/drivers/pinctrl/pinctrl-rk805.c b/drivers/pinctrl/pinctrl-rk805.c index 8810aabb7555..204032931ad2 100644 --- a/drivers/pinctrl/pinctrl-rk805.c +++ b/drivers/pinctrl/pinctrl-rk805.c @@ -82,6 +82,7 @@ struct rk805_pctrl_info { enum rk805_pinmux_option { RK805_PINMUX_GPIO, + RK805_PINMUX_TS, }; enum { @@ -136,6 +137,55 @@ static struct rk805_pin_config rk805_gpio_cfgs[] = { }, }; +#define RK816_FUN_MASK BIT(2) +#define RK816_VAL_MASK BIT(3) +#define RK816_DIR_MASK BIT(4) + +enum { + RK816_GPIO0, +}; + +/* RK816: gpio/ts */ +static const char *const rk816_gpio_groups[] = { + "gpio0", +}; + +static const struct pinctrl_pin_desc rk816_pins_desc[] = { + PINCTRL_PIN(RK816_GPIO0, "gpio0"), +}; + +static const struct rk805_pin_function rk816_pin_functions[] = { + { + .name = "gpio", + .groups = rk816_gpio_groups, + .ngroups = ARRAY_SIZE(rk816_gpio_groups), + .mux_option = RK805_PINMUX_GPIO, + }, + { + .name = "ts", + .groups = rk816_gpio_groups, + .ngroups = ARRAY_SIZE(rk816_gpio_groups), + .mux_option = RK805_PINMUX_TS, + }, +}; + +static const struct rk805_pin_group rk816_pin_groups[] = { + { + .name = "gpio0", + .pins = { RK816_GPIO0 }, + .npins = 1, + }, +}; + +static struct rk805_pin_config rk816_gpio_cfgs[] = { + { + .reg = RK816_GPIO_IO_POL_REG, + .val_msk = RK816_VAL_MASK, + .fun_msk = RK816_FUN_MASK, + .dir_msk = RK816_DIR_MASK, + }, +}; + enum rk817_pinmux_option { RK817_PINMUX_FUN0 = 0, RK817_PINMUX_FUN1, @@ -324,6 +374,20 @@ static struct gpio_chip rk805_gpio_chip = { .owner = THIS_MODULE, }; +static struct gpio_chip rk816_gpio_chip = { + .label = "rk816-gpio", + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .get_direction = rk805_gpio_get_direction, + .get = rk805_gpio_get, + .set = rk805_gpio_set, + .direction_input = rk805_gpio_direction_input, + .direction_output = rk805_gpio_direction_output, + .can_sleep = true, + .base = -1, + .owner = THIS_MODULE, +}; + static struct gpio_chip rk817_gpio_chip = { .label = "rk817-gpio", .request = gpiochip_generic_request, @@ -422,6 +486,15 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev, dev_err(pci->dev, "set gpio%d GPIO failed\n", offset); return ret; } + } else if (mux == RK805_PINMUX_TS) { + ret = regmap_update_bits(pci->rk808->regmap, + pci->pin_cfg[offset].reg, + pci->pin_cfg[offset].fun_msk, + 0); + if (ret) { + dev_err(pci->dev, "set gpio%d TS failed\n", offset); + return ret; + } } else { dev_err(pci->dev, "Couldn't find function mux %d\n", mux); return -EINVAL; @@ -461,6 +534,7 @@ static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev, switch (pci->rk808->variant) { case RK805_ID: + case RK816_ID: return _rk805_pinctrl_set_mux(pctldev, offset, mux); case RK809_ID: @@ -495,7 +569,25 @@ static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, return ret; } +static int rk805_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); + + /* switch to gpio function */ + switch (pci->rk808->variant) { + case RK805_ID: + case RK816_ID: + return _rk805_pinctrl_set_mux(pctldev, offset, + RK805_PINMUX_GPIO); + default: + return 0; + } +} + static const struct pinmux_ops rk805_pinmux_ops = { + .gpio_request_enable = rk805_pinctrl_gpio_request_enable, .get_functions_count = rk805_pinctrl_get_funcs_count, .get_function_name = rk805_pinctrl_get_func_name, .get_function_groups = rk805_pinctrl_get_func_groups, @@ -512,6 +604,7 @@ static int rk805_pinconf_get(struct pinctrl_dev *pctldev, switch (param) { case PIN_CONFIG_OUTPUT: + case PIN_CONFIG_INPUT_ENABLE: arg = rk805_gpio_get(&pci->gpio_chip, pin); break; default: @@ -568,6 +661,14 @@ static struct pinctrl_desc rk805_pinctrl_desc = { .owner = THIS_MODULE, }; +static struct pinctrl_desc rk816_pinctrl_desc = { + .name = "rk816-pinctrl", + .pctlops = &rk805_pinctrl_ops, + .pmxops = &rk805_pinmux_ops, + .confops = &rk805_pinconf_ops, + .owner = THIS_MODULE, +}; + static struct pinctrl_desc rk817_pinctrl_desc = { .name = "rk817-pinctrl", .pctlops = &rk805_pinctrl_ops, @@ -611,6 +712,22 @@ static int rk805_pinctrl_probe(struct platform_device *pdev) pci->pin_cfg = rk805_gpio_cfgs; pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs); break; + + case RK816_ID: + pci->pinctrl_desc = rk816_pinctrl_desc; + pci->gpio_chip = rk816_gpio_chip; + pci->pins = rk816_pins_desc; + pci->num_pins = ARRAY_SIZE(rk816_pins_desc); + pci->functions = rk816_pin_functions; + pci->num_functions = ARRAY_SIZE(rk816_pin_functions); + pci->groups = rk816_pin_groups; + pci->num_pin_groups = ARRAY_SIZE(rk816_pin_groups); + pci->pinctrl_desc.pins = rk816_pins_desc; + pci->pinctrl_desc.npins = ARRAY_SIZE(rk816_pins_desc); + pci->pin_cfg = rk816_gpio_cfgs; + pci->gpio_chip.ngpio = ARRAY_SIZE(rk816_gpio_cfgs); + break; + case RK809_ID: case RK817_ID: pci->pinctrl_desc = rk817_pinctrl_desc; @@ -633,6 +750,7 @@ static int rk805_pinctrl_probe(struct platform_device *pdev) pci->gpio_chip.ngpio = 1; } break; + default: dev_err(&pdev->dev, "unsupported RK805 ID %lu\n", pci->rk808->variant); diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h index ffce15322722..7be8dfd42d13 100644 --- a/include/linux/mfd/rk808.h +++ b/include/linux/mfd/rk808.h @@ -181,6 +181,7 @@ enum rk816_reg { #define RK816_LDO5_SLP_VSEL_REG 0x44 #define RK816_LDO6_ON_VSEL_REG 0x45 #define RK816_LDO6_SLP_VSEL_REG 0x46 +#define RK816_GPIO_IO_POL_REG 0x50 /*CHARGER BOOST AND OTG REGISTER*/ #define RK816_OTG_BUCK_LDO_CONFIG_REG 0x2A