12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2ea479996SJoseph Chen /* 3ea479996SJoseph Chen * Pinctrl driver for Rockchip RK805 PMIC 4ea479996SJoseph Chen * 5ea479996SJoseph Chen * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd 6ea479996SJoseph Chen * 7ea479996SJoseph Chen * Author: Joseph Chen <chenjh@rock-chips.com> 8ea479996SJoseph Chen * 9ea479996SJoseph Chen * Based on the pinctrl-as3722 driver 10ea479996SJoseph Chen */ 11ea479996SJoseph Chen 12ea479996SJoseph Chen #include <linux/gpio/driver.h> 13ea479996SJoseph Chen #include <linux/kernel.h> 14ea479996SJoseph Chen #include <linux/module.h> 15ea479996SJoseph Chen #include <linux/mfd/rk808.h> 16ea479996SJoseph Chen #include <linux/of.h> 17ea479996SJoseph Chen #include <linux/of_device.h> 18ea479996SJoseph Chen #include <linux/platform_device.h> 19ea479996SJoseph Chen #include <linux/pinctrl/consumer.h> 20ea479996SJoseph Chen #include <linux/pinctrl/machine.h> 21ea479996SJoseph Chen #include <linux/pinctrl/pinctrl.h> 22ea479996SJoseph Chen #include <linux/pinctrl/pinconf-generic.h> 23ea479996SJoseph Chen #include <linux/pinctrl/pinconf.h> 24ea479996SJoseph Chen #include <linux/pinctrl/pinmux.h> 25ea479996SJoseph Chen #include <linux/pm.h> 26ea479996SJoseph Chen #include <linux/slab.h> 27ea479996SJoseph Chen 28ea479996SJoseph Chen #include "core.h" 29ea479996SJoseph Chen #include "pinconf.h" 30ea479996SJoseph Chen #include "pinctrl-utils.h" 31ea479996SJoseph Chen 32ea479996SJoseph Chen struct rk805_pin_function { 33ea479996SJoseph Chen const char *name; 34ea479996SJoseph Chen const char *const *groups; 35ea479996SJoseph Chen unsigned int ngroups; 36ea479996SJoseph Chen int mux_option; 37ea479996SJoseph Chen }; 38ea479996SJoseph Chen 39ea479996SJoseph Chen struct rk805_pin_group { 40ea479996SJoseph Chen const char *name; 41ea479996SJoseph Chen const unsigned int pins[1]; 42ea479996SJoseph Chen unsigned int npins; 43ea479996SJoseph Chen }; 44ea479996SJoseph Chen 45ea479996SJoseph Chen /* 46ea479996SJoseph Chen * @reg: gpio setting register; 47ea479996SJoseph Chen * @fun_mask: functions select mask value, when set is gpio; 48ea479996SJoseph Chen * @dir_mask: input or output mask value, when set is output, otherwise input; 49ea479996SJoseph Chen * @val_mask: gpio set value, when set is level high, otherwise low; 50ea479996SJoseph Chen * 51ea479996SJoseph Chen * Different PMIC has different pin features, belowing 3 mask members are not 52ea479996SJoseph Chen * all necessary for every PMIC. For example, RK805 has 2 pins that can be used 53ea479996SJoseph Chen * as output only GPIOs, so func_mask and dir_mask are not needed. RK816 has 1 54ea479996SJoseph Chen * pin that can be used as TS/GPIO, so fun_mask, dir_mask and val_mask are all 55ea479996SJoseph Chen * necessary. 56ea479996SJoseph Chen */ 57ea479996SJoseph Chen struct rk805_pin_config { 58ea479996SJoseph Chen u8 reg; 59ea479996SJoseph Chen u8 fun_msk; 60ea479996SJoseph Chen u8 dir_msk; 61ea479996SJoseph Chen u8 val_msk; 62ea479996SJoseph Chen }; 63ea479996SJoseph Chen 64ea479996SJoseph Chen struct rk805_pctrl_info { 65ea479996SJoseph Chen struct rk808 *rk808; 66ea479996SJoseph Chen struct device *dev; 67ea479996SJoseph Chen struct pinctrl_dev *pctl; 68ea479996SJoseph Chen struct gpio_chip gpio_chip; 69ea479996SJoseph Chen struct pinctrl_desc pinctrl_desc; 70ea479996SJoseph Chen const struct rk805_pin_function *functions; 71ea479996SJoseph Chen unsigned int num_functions; 72ea479996SJoseph Chen const struct rk805_pin_group *groups; 73ea479996SJoseph Chen int num_pin_groups; 74ea479996SJoseph Chen const struct pinctrl_pin_desc *pins; 75ea479996SJoseph Chen unsigned int num_pins; 76ea479996SJoseph Chen struct rk805_pin_config *pin_cfg; 77ea479996SJoseph Chen }; 78ea479996SJoseph Chen 79ea479996SJoseph Chen enum rk805_pinmux_option { 80ea479996SJoseph Chen RK805_PINMUX_GPIO, 81ea479996SJoseph Chen }; 82ea479996SJoseph Chen 83ea479996SJoseph Chen enum { 84ea479996SJoseph Chen RK805_GPIO0, 85ea479996SJoseph Chen RK805_GPIO1, 86ea479996SJoseph Chen }; 87ea479996SJoseph Chen 88ea479996SJoseph Chen static const char *const rk805_gpio_groups[] = { 89ea479996SJoseph Chen "gpio0", 90ea479996SJoseph Chen "gpio1", 91ea479996SJoseph Chen }; 92ea479996SJoseph Chen 93ea479996SJoseph Chen /* RK805: 2 output only GPIOs */ 94ea479996SJoseph Chen static const struct pinctrl_pin_desc rk805_pins_desc[] = { 95ea479996SJoseph Chen PINCTRL_PIN(RK805_GPIO0, "gpio0"), 96ea479996SJoseph Chen PINCTRL_PIN(RK805_GPIO1, "gpio1"), 97ea479996SJoseph Chen }; 98ea479996SJoseph Chen 99ea479996SJoseph Chen static const struct rk805_pin_function rk805_pin_functions[] = { 100ea479996SJoseph Chen { 101ea479996SJoseph Chen .name = "gpio", 102ea479996SJoseph Chen .groups = rk805_gpio_groups, 103ea479996SJoseph Chen .ngroups = ARRAY_SIZE(rk805_gpio_groups), 104ea479996SJoseph Chen .mux_option = RK805_PINMUX_GPIO, 105ea479996SJoseph Chen }, 106ea479996SJoseph Chen }; 107ea479996SJoseph Chen 108ea479996SJoseph Chen static const struct rk805_pin_group rk805_pin_groups[] = { 109ea479996SJoseph Chen { 110ea479996SJoseph Chen .name = "gpio0", 111ea479996SJoseph Chen .pins = { RK805_GPIO0 }, 112ea479996SJoseph Chen .npins = 1, 113ea479996SJoseph Chen }, 114ea479996SJoseph Chen { 115ea479996SJoseph Chen .name = "gpio1", 116ea479996SJoseph Chen .pins = { RK805_GPIO1 }, 117ea479996SJoseph Chen .npins = 1, 118ea479996SJoseph Chen }, 119ea479996SJoseph Chen }; 120ea479996SJoseph Chen 121ea479996SJoseph Chen #define RK805_GPIO0_VAL_MSK BIT(0) 122ea479996SJoseph Chen #define RK805_GPIO1_VAL_MSK BIT(1) 123ea479996SJoseph Chen 124ea479996SJoseph Chen static struct rk805_pin_config rk805_gpio_cfgs[] = { 125ea479996SJoseph Chen { 126ea479996SJoseph Chen .reg = RK805_OUT_REG, 127ea479996SJoseph Chen .val_msk = RK805_GPIO0_VAL_MSK, 128ea479996SJoseph Chen }, 129ea479996SJoseph Chen { 130ea479996SJoseph Chen .reg = RK805_OUT_REG, 131ea479996SJoseph Chen .val_msk = RK805_GPIO1_VAL_MSK, 132ea479996SJoseph Chen }, 133ea479996SJoseph Chen }; 134ea479996SJoseph Chen 135ea479996SJoseph Chen /* generic gpio chip */ 136ea479996SJoseph Chen static int rk805_gpio_get(struct gpio_chip *chip, unsigned int offset) 137ea479996SJoseph Chen { 138ea479996SJoseph Chen struct rk805_pctrl_info *pci = gpiochip_get_data(chip); 139ea479996SJoseph Chen int ret, val; 140ea479996SJoseph Chen 141ea479996SJoseph Chen ret = regmap_read(pci->rk808->regmap, pci->pin_cfg[offset].reg, &val); 142ea479996SJoseph Chen if (ret) { 143ea479996SJoseph Chen dev_err(pci->dev, "get gpio%d value failed\n", offset); 144ea479996SJoseph Chen return ret; 145ea479996SJoseph Chen } 146ea479996SJoseph Chen 147ea479996SJoseph Chen return !!(val & pci->pin_cfg[offset].val_msk); 148ea479996SJoseph Chen } 149ea479996SJoseph Chen 150ea479996SJoseph Chen static void rk805_gpio_set(struct gpio_chip *chip, 151ea479996SJoseph Chen unsigned int offset, 152ea479996SJoseph Chen int value) 153ea479996SJoseph Chen { 154ea479996SJoseph Chen struct rk805_pctrl_info *pci = gpiochip_get_data(chip); 155ea479996SJoseph Chen int ret; 156ea479996SJoseph Chen 157ea479996SJoseph Chen ret = regmap_update_bits(pci->rk808->regmap, 158ea479996SJoseph Chen pci->pin_cfg[offset].reg, 159ea479996SJoseph Chen pci->pin_cfg[offset].val_msk, 160ea479996SJoseph Chen value ? pci->pin_cfg[offset].val_msk : 0); 161ea479996SJoseph Chen if (ret) 162ea479996SJoseph Chen dev_err(pci->dev, "set gpio%d value %d failed\n", 163ea479996SJoseph Chen offset, value); 164ea479996SJoseph Chen } 165ea479996SJoseph Chen 166ea479996SJoseph Chen static int rk805_gpio_direction_input(struct gpio_chip *chip, 167ea479996SJoseph Chen unsigned int offset) 168ea479996SJoseph Chen { 169ea479996SJoseph Chen return pinctrl_gpio_direction_input(chip->base + offset); 170ea479996SJoseph Chen } 171ea479996SJoseph Chen 172ea479996SJoseph Chen static int rk805_gpio_direction_output(struct gpio_chip *chip, 173ea479996SJoseph Chen unsigned int offset, int value) 174ea479996SJoseph Chen { 175ea479996SJoseph Chen rk805_gpio_set(chip, offset, value); 176ea479996SJoseph Chen return pinctrl_gpio_direction_output(chip->base + offset); 177ea479996SJoseph Chen } 178ea479996SJoseph Chen 179ea479996SJoseph Chen static int rk805_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 180ea479996SJoseph Chen { 181ea479996SJoseph Chen struct rk805_pctrl_info *pci = gpiochip_get_data(chip); 182ea479996SJoseph Chen unsigned int val; 183ea479996SJoseph Chen int ret; 184ea479996SJoseph Chen 185ea479996SJoseph Chen /* default output*/ 186ea479996SJoseph Chen if (!pci->pin_cfg[offset].dir_msk) 1873c827873SMatti Vaittinen return GPIO_LINE_DIRECTION_OUT; 188ea479996SJoseph Chen 189ea479996SJoseph Chen ret = regmap_read(pci->rk808->regmap, 190ea479996SJoseph Chen pci->pin_cfg[offset].reg, 191ea479996SJoseph Chen &val); 192ea479996SJoseph Chen if (ret) { 193ea479996SJoseph Chen dev_err(pci->dev, "get gpio%d direction failed\n", offset); 194ea479996SJoseph Chen return ret; 195ea479996SJoseph Chen } 196ea479996SJoseph Chen 1973c827873SMatti Vaittinen if (val & pci->pin_cfg[offset].dir_msk) 1983c827873SMatti Vaittinen return GPIO_LINE_DIRECTION_OUT; 1993c827873SMatti Vaittinen 2003c827873SMatti Vaittinen return GPIO_LINE_DIRECTION_IN; 201ea479996SJoseph Chen } 202ea479996SJoseph Chen 2036e28aaabSNishka Dasgupta static const struct gpio_chip rk805_gpio_chip = { 204ea479996SJoseph Chen .label = "rk805-gpio", 205ea479996SJoseph Chen .request = gpiochip_generic_request, 206ea479996SJoseph Chen .free = gpiochip_generic_free, 207ea479996SJoseph Chen .get_direction = rk805_gpio_get_direction, 208ea479996SJoseph Chen .get = rk805_gpio_get, 209ea479996SJoseph Chen .set = rk805_gpio_set, 210ea479996SJoseph Chen .direction_input = rk805_gpio_direction_input, 211ea479996SJoseph Chen .direction_output = rk805_gpio_direction_output, 212ea479996SJoseph Chen .can_sleep = true, 213ea479996SJoseph Chen .base = -1, 214ea479996SJoseph Chen .owner = THIS_MODULE, 215ea479996SJoseph Chen }; 216ea479996SJoseph Chen 217ea479996SJoseph Chen /* generic pinctrl */ 218ea479996SJoseph Chen static int rk805_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) 219ea479996SJoseph Chen { 220ea479996SJoseph Chen struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 221ea479996SJoseph Chen 222ea479996SJoseph Chen return pci->num_pin_groups; 223ea479996SJoseph Chen } 224ea479996SJoseph Chen 225ea479996SJoseph Chen static const char *rk805_pinctrl_get_group_name(struct pinctrl_dev *pctldev, 226ea479996SJoseph Chen unsigned int group) 227ea479996SJoseph Chen { 228ea479996SJoseph Chen struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 229ea479996SJoseph Chen 230ea479996SJoseph Chen return pci->groups[group].name; 231ea479996SJoseph Chen } 232ea479996SJoseph Chen 233ea479996SJoseph Chen static int rk805_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, 234ea479996SJoseph Chen unsigned int group, 235ea479996SJoseph Chen const unsigned int **pins, 236ea479996SJoseph Chen unsigned int *num_pins) 237ea479996SJoseph Chen { 238ea479996SJoseph Chen struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 239ea479996SJoseph Chen 240ea479996SJoseph Chen *pins = pci->groups[group].pins; 241ea479996SJoseph Chen *num_pins = pci->groups[group].npins; 242ea479996SJoseph Chen 243ea479996SJoseph Chen return 0; 244ea479996SJoseph Chen } 245ea479996SJoseph Chen 246ea479996SJoseph Chen static const struct pinctrl_ops rk805_pinctrl_ops = { 247ea479996SJoseph Chen .get_groups_count = rk805_pinctrl_get_groups_count, 248ea479996SJoseph Chen .get_group_name = rk805_pinctrl_get_group_name, 249ea479996SJoseph Chen .get_group_pins = rk805_pinctrl_get_group_pins, 250ea479996SJoseph Chen .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, 251ea479996SJoseph Chen .dt_free_map = pinctrl_utils_free_map, 252ea479996SJoseph Chen }; 253ea479996SJoseph Chen 254ea479996SJoseph Chen static int rk805_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev) 255ea479996SJoseph Chen { 256ea479996SJoseph Chen struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 257ea479996SJoseph Chen 258ea479996SJoseph Chen return pci->num_functions; 259ea479996SJoseph Chen } 260ea479996SJoseph Chen 261ea479996SJoseph Chen static const char *rk805_pinctrl_get_func_name(struct pinctrl_dev *pctldev, 262ea479996SJoseph Chen unsigned int function) 263ea479996SJoseph Chen { 264ea479996SJoseph Chen struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 265ea479996SJoseph Chen 266ea479996SJoseph Chen return pci->functions[function].name; 267ea479996SJoseph Chen } 268ea479996SJoseph Chen 269ea479996SJoseph Chen static int rk805_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, 270ea479996SJoseph Chen unsigned int function, 271ea479996SJoseph Chen const char *const **groups, 272ea479996SJoseph Chen unsigned int *const num_groups) 273ea479996SJoseph Chen { 274ea479996SJoseph Chen struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 275ea479996SJoseph Chen 276ea479996SJoseph Chen *groups = pci->functions[function].groups; 277ea479996SJoseph Chen *num_groups = pci->functions[function].ngroups; 278ea479996SJoseph Chen 279ea479996SJoseph Chen return 0; 280ea479996SJoseph Chen } 281ea479996SJoseph Chen 282ea479996SJoseph Chen static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev, 283ea479996SJoseph Chen unsigned int offset, 284ea479996SJoseph Chen int mux) 285ea479996SJoseph Chen { 286ea479996SJoseph Chen struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 287ea479996SJoseph Chen int ret; 288ea479996SJoseph Chen 289ea479996SJoseph Chen if (!pci->pin_cfg[offset].fun_msk) 290ea479996SJoseph Chen return 0; 291ea479996SJoseph Chen 292ea479996SJoseph Chen if (mux == RK805_PINMUX_GPIO) { 293ea479996SJoseph Chen ret = regmap_update_bits(pci->rk808->regmap, 294ea479996SJoseph Chen pci->pin_cfg[offset].reg, 295ea479996SJoseph Chen pci->pin_cfg[offset].fun_msk, 296ea479996SJoseph Chen pci->pin_cfg[offset].fun_msk); 297ea479996SJoseph Chen if (ret) { 298ea479996SJoseph Chen dev_err(pci->dev, "set gpio%d GPIO failed\n", offset); 299ea479996SJoseph Chen return ret; 300ea479996SJoseph Chen } 301ea479996SJoseph Chen } else { 302ea479996SJoseph Chen dev_err(pci->dev, "Couldn't find function mux %d\n", mux); 303ea479996SJoseph Chen return -EINVAL; 304ea479996SJoseph Chen } 305ea479996SJoseph Chen 306ea479996SJoseph Chen return 0; 307ea479996SJoseph Chen } 308ea479996SJoseph Chen 309ea479996SJoseph Chen static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev, 310ea479996SJoseph Chen unsigned int function, 311ea479996SJoseph Chen unsigned int group) 312ea479996SJoseph Chen { 313ea479996SJoseph Chen struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 314ea479996SJoseph Chen int mux = pci->functions[function].mux_option; 315ea479996SJoseph Chen int offset = group; 316ea479996SJoseph Chen 317ea479996SJoseph Chen return _rk805_pinctrl_set_mux(pctldev, offset, mux); 318ea479996SJoseph Chen } 319ea479996SJoseph Chen 320ea479996SJoseph Chen static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, 321ea479996SJoseph Chen struct pinctrl_gpio_range *range, 322ea479996SJoseph Chen unsigned int offset, bool input) 323ea479996SJoseph Chen { 324ea479996SJoseph Chen struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 325ea479996SJoseph Chen int ret; 326ea479996SJoseph Chen 327ea479996SJoseph Chen /* switch to gpio function */ 328ea479996SJoseph Chen ret = _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO); 329ea479996SJoseph Chen if (ret) { 330ea479996SJoseph Chen dev_err(pci->dev, "set gpio%d mux failed\n", offset); 331ea479996SJoseph Chen return ret; 332ea479996SJoseph Chen } 333ea479996SJoseph Chen 334ea479996SJoseph Chen /* set direction */ 335ea479996SJoseph Chen if (!pci->pin_cfg[offset].dir_msk) 336ea479996SJoseph Chen return 0; 337ea479996SJoseph Chen 338ea479996SJoseph Chen ret = regmap_update_bits(pci->rk808->regmap, 339ea479996SJoseph Chen pci->pin_cfg[offset].reg, 340ea479996SJoseph Chen pci->pin_cfg[offset].dir_msk, 341ea479996SJoseph Chen input ? 0 : pci->pin_cfg[offset].dir_msk); 342ea479996SJoseph Chen if (ret) { 343ea479996SJoseph Chen dev_err(pci->dev, "set gpio%d direction failed\n", offset); 344ea479996SJoseph Chen return ret; 345ea479996SJoseph Chen } 346ea479996SJoseph Chen 347ea479996SJoseph Chen return ret; 348ea479996SJoseph Chen } 349ea479996SJoseph Chen 350ea479996SJoseph Chen static const struct pinmux_ops rk805_pinmux_ops = { 351ea479996SJoseph Chen .get_functions_count = rk805_pinctrl_get_funcs_count, 352ea479996SJoseph Chen .get_function_name = rk805_pinctrl_get_func_name, 353ea479996SJoseph Chen .get_function_groups = rk805_pinctrl_get_func_groups, 354ea479996SJoseph Chen .set_mux = rk805_pinctrl_set_mux, 355ea479996SJoseph Chen .gpio_set_direction = rk805_pmx_gpio_set_direction, 356ea479996SJoseph Chen }; 357ea479996SJoseph Chen 358ea479996SJoseph Chen static int rk805_pinconf_get(struct pinctrl_dev *pctldev, 359ea479996SJoseph Chen unsigned int pin, unsigned long *config) 360ea479996SJoseph Chen { 361ea479996SJoseph Chen struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 362ea479996SJoseph Chen enum pin_config_param param = pinconf_to_config_param(*config); 363ea479996SJoseph Chen u32 arg = 0; 364ea479996SJoseph Chen 365ea479996SJoseph Chen switch (param) { 366ea479996SJoseph Chen case PIN_CONFIG_OUTPUT: 367ea479996SJoseph Chen arg = rk805_gpio_get(&pci->gpio_chip, pin); 368ea479996SJoseph Chen break; 369ea479996SJoseph Chen default: 370ea479996SJoseph Chen dev_err(pci->dev, "Properties not supported\n"); 371ea479996SJoseph Chen return -ENOTSUPP; 372ea479996SJoseph Chen } 373ea479996SJoseph Chen 374ea479996SJoseph Chen *config = pinconf_to_config_packed(param, (u16)arg); 375ea479996SJoseph Chen 376ea479996SJoseph Chen return 0; 377ea479996SJoseph Chen } 378ea479996SJoseph Chen 379ea479996SJoseph Chen static int rk805_pinconf_set(struct pinctrl_dev *pctldev, 380ea479996SJoseph Chen unsigned int pin, unsigned long *configs, 381ea479996SJoseph Chen unsigned int num_configs) 382ea479996SJoseph Chen { 383ea479996SJoseph Chen struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 384ea479996SJoseph Chen enum pin_config_param param; 385ea479996SJoseph Chen u32 i, arg = 0; 386ea479996SJoseph Chen 387ea479996SJoseph Chen for (i = 0; i < num_configs; i++) { 388ea479996SJoseph Chen param = pinconf_to_config_param(configs[i]); 389ea479996SJoseph Chen arg = pinconf_to_config_argument(configs[i]); 390ea479996SJoseph Chen 391ea479996SJoseph Chen switch (param) { 392ea479996SJoseph Chen case PIN_CONFIG_OUTPUT: 393ea479996SJoseph Chen rk805_gpio_set(&pci->gpio_chip, pin, arg); 394ea479996SJoseph Chen rk805_pmx_gpio_set_direction(pctldev, NULL, pin, false); 395ea479996SJoseph Chen break; 396ea479996SJoseph Chen default: 397ea479996SJoseph Chen dev_err(pci->dev, "Properties not supported\n"); 398ea479996SJoseph Chen return -ENOTSUPP; 399ea479996SJoseph Chen } 400ea479996SJoseph Chen } 401ea479996SJoseph Chen 402ea479996SJoseph Chen return 0; 403ea479996SJoseph Chen } 404ea479996SJoseph Chen 405ea479996SJoseph Chen static const struct pinconf_ops rk805_pinconf_ops = { 406ea479996SJoseph Chen .pin_config_get = rk805_pinconf_get, 407ea479996SJoseph Chen .pin_config_set = rk805_pinconf_set, 408ea479996SJoseph Chen }; 409ea479996SJoseph Chen 4106e28aaabSNishka Dasgupta static const struct pinctrl_desc rk805_pinctrl_desc = { 411ea479996SJoseph Chen .name = "rk805-pinctrl", 412ea479996SJoseph Chen .pctlops = &rk805_pinctrl_ops, 413ea479996SJoseph Chen .pmxops = &rk805_pinmux_ops, 414ea479996SJoseph Chen .confops = &rk805_pinconf_ops, 415ea479996SJoseph Chen .owner = THIS_MODULE, 416ea479996SJoseph Chen }; 417ea479996SJoseph Chen 418ea479996SJoseph Chen static int rk805_pinctrl_probe(struct platform_device *pdev) 419ea479996SJoseph Chen { 420ea479996SJoseph Chen struct rk805_pctrl_info *pci; 421ea479996SJoseph Chen int ret; 422ea479996SJoseph Chen 423ea479996SJoseph Chen pci = devm_kzalloc(&pdev->dev, sizeof(*pci), GFP_KERNEL); 424ea479996SJoseph Chen if (!pci) 425ea479996SJoseph Chen return -ENOMEM; 426ea479996SJoseph Chen 427ea479996SJoseph Chen pci->dev = &pdev->dev; 428ea479996SJoseph Chen pci->dev->of_node = pdev->dev.parent->of_node; 429ea479996SJoseph Chen pci->rk808 = dev_get_drvdata(pdev->dev.parent); 430ea479996SJoseph Chen 431ea479996SJoseph Chen pci->pinctrl_desc = rk805_pinctrl_desc; 432ea479996SJoseph Chen pci->gpio_chip = rk805_gpio_chip; 433ea479996SJoseph Chen pci->gpio_chip.parent = &pdev->dev; 434ea479996SJoseph Chen pci->gpio_chip.of_node = pdev->dev.parent->of_node; 435ea479996SJoseph Chen 436ea479996SJoseph Chen platform_set_drvdata(pdev, pci); 437ea479996SJoseph Chen 438ea479996SJoseph Chen switch (pci->rk808->variant) { 439ea479996SJoseph Chen case RK805_ID: 440ea479996SJoseph Chen pci->pins = rk805_pins_desc; 441ea479996SJoseph Chen pci->num_pins = ARRAY_SIZE(rk805_pins_desc); 442ea479996SJoseph Chen pci->functions = rk805_pin_functions; 443ea479996SJoseph Chen pci->num_functions = ARRAY_SIZE(rk805_pin_functions); 444ea479996SJoseph Chen pci->groups = rk805_pin_groups; 445ea479996SJoseph Chen pci->num_pin_groups = ARRAY_SIZE(rk805_pin_groups); 446ea479996SJoseph Chen pci->pinctrl_desc.pins = rk805_pins_desc; 447ea479996SJoseph Chen pci->pinctrl_desc.npins = ARRAY_SIZE(rk805_pins_desc); 448ea479996SJoseph Chen pci->pin_cfg = rk805_gpio_cfgs; 449ea479996SJoseph Chen pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs); 450ea479996SJoseph Chen break; 451ea479996SJoseph Chen default: 452ea479996SJoseph Chen dev_err(&pdev->dev, "unsupported RK805 ID %lu\n", 453ea479996SJoseph Chen pci->rk808->variant); 454ea479996SJoseph Chen return -EINVAL; 455ea479996SJoseph Chen } 456ea479996SJoseph Chen 457ea479996SJoseph Chen /* Add gpio chip */ 458ea479996SJoseph Chen ret = devm_gpiochip_add_data(&pdev->dev, &pci->gpio_chip, pci); 459ea479996SJoseph Chen if (ret < 0) { 460ea479996SJoseph Chen dev_err(&pdev->dev, "Couldn't add gpiochip\n"); 461ea479996SJoseph Chen return ret; 462ea479996SJoseph Chen } 463ea479996SJoseph Chen 464ea479996SJoseph Chen /* Add pinctrl */ 465ea479996SJoseph Chen pci->pctl = devm_pinctrl_register(&pdev->dev, &pci->pinctrl_desc, pci); 466ea479996SJoseph Chen if (IS_ERR(pci->pctl)) { 467ea479996SJoseph Chen dev_err(&pdev->dev, "Couldn't add pinctrl\n"); 468ea479996SJoseph Chen return PTR_ERR(pci->pctl); 469ea479996SJoseph Chen } 470ea479996SJoseph Chen 471ea479996SJoseph Chen /* Add pin range */ 472ea479996SJoseph Chen ret = gpiochip_add_pin_range(&pci->gpio_chip, dev_name(&pdev->dev), 473ea479996SJoseph Chen 0, 0, pci->gpio_chip.ngpio); 474ea479996SJoseph Chen if (ret < 0) { 475ea479996SJoseph Chen dev_err(&pdev->dev, "Couldn't add gpiochip pin range\n"); 476ea479996SJoseph Chen return ret; 477ea479996SJoseph Chen } 478ea479996SJoseph Chen 479ea479996SJoseph Chen return 0; 480ea479996SJoseph Chen } 481ea479996SJoseph Chen 482ea479996SJoseph Chen static struct platform_driver rk805_pinctrl_driver = { 483ea479996SJoseph Chen .probe = rk805_pinctrl_probe, 484ea479996SJoseph Chen .driver = { 485ea479996SJoseph Chen .name = "rk805-pinctrl", 486ea479996SJoseph Chen }, 487ea479996SJoseph Chen }; 488ea479996SJoseph Chen module_platform_driver(rk805_pinctrl_driver); 489ea479996SJoseph Chen 490ea479996SJoseph Chen MODULE_DESCRIPTION("RK805 pin control and GPIO driver"); 491ea479996SJoseph Chen MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>"); 492ea479996SJoseph Chen MODULE_LICENSE("GPL v2"); 493