1d3e51161SHeiko Stübner /* 2d3e51161SHeiko Stübner * Pinctrl driver for Rockchip SoCs 3d3e51161SHeiko Stübner * 4d3e51161SHeiko Stübner * Copyright (c) 2013 MundoReader S.L. 5d3e51161SHeiko Stübner * Author: Heiko Stuebner <heiko@sntech.de> 6d3e51161SHeiko Stübner * 7d3e51161SHeiko Stübner * With some ideas taken from pinctrl-samsung: 8d3e51161SHeiko Stübner * Copyright (c) 2012 Samsung Electronics Co., Ltd. 9d3e51161SHeiko Stübner * http://www.samsung.com 10d3e51161SHeiko Stübner * Copyright (c) 2012 Linaro Ltd 11d3e51161SHeiko Stübner * http://www.linaro.org 12d3e51161SHeiko Stübner * 13d3e51161SHeiko Stübner * and pinctrl-at91: 14d3e51161SHeiko Stübner * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> 15d3e51161SHeiko Stübner * 16d3e51161SHeiko Stübner * This program is free software; you can redistribute it and/or modify 17d3e51161SHeiko Stübner * it under the terms of the GNU General Public License version 2 as published 18d3e51161SHeiko Stübner * by the Free Software Foundation. 19d3e51161SHeiko Stübner * 20d3e51161SHeiko Stübner * This program is distributed in the hope that it will be useful, 21d3e51161SHeiko Stübner * but WITHOUT ANY WARRANTY; without even the implied warranty of 22d3e51161SHeiko Stübner * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23d3e51161SHeiko Stübner * GNU General Public License for more details. 24d3e51161SHeiko Stübner */ 25d3e51161SHeiko Stübner 26d3e51161SHeiko Stübner #include <linux/module.h> 27d3e51161SHeiko Stübner #include <linux/platform_device.h> 28d3e51161SHeiko Stübner #include <linux/io.h> 29d3e51161SHeiko Stübner #include <linux/bitops.h> 30d3e51161SHeiko Stübner #include <linux/gpio.h> 31d3e51161SHeiko Stübner #include <linux/of_address.h> 32d3e51161SHeiko Stübner #include <linux/of_irq.h> 33d3e51161SHeiko Stübner #include <linux/pinctrl/machine.h> 34d3e51161SHeiko Stübner #include <linux/pinctrl/pinconf.h> 35d3e51161SHeiko Stübner #include <linux/pinctrl/pinctrl.h> 36d3e51161SHeiko Stübner #include <linux/pinctrl/pinmux.h> 37d3e51161SHeiko Stübner #include <linux/pinctrl/pinconf-generic.h> 38d3e51161SHeiko Stübner #include <linux/irqchip/chained_irq.h> 397e865abbSHeiko Stübner #include <linux/clk.h> 40d3e51161SHeiko Stübner #include <dt-bindings/pinctrl/rockchip.h> 41d3e51161SHeiko Stübner 42d3e51161SHeiko Stübner #include "core.h" 43d3e51161SHeiko Stübner #include "pinconf.h" 44d3e51161SHeiko Stübner 45d3e51161SHeiko Stübner /* GPIO control registers */ 46d3e51161SHeiko Stübner #define GPIO_SWPORT_DR 0x00 47d3e51161SHeiko Stübner #define GPIO_SWPORT_DDR 0x04 48d3e51161SHeiko Stübner #define GPIO_INTEN 0x30 49d3e51161SHeiko Stübner #define GPIO_INTMASK 0x34 50d3e51161SHeiko Stübner #define GPIO_INTTYPE_LEVEL 0x38 51d3e51161SHeiko Stübner #define GPIO_INT_POLARITY 0x3c 52d3e51161SHeiko Stübner #define GPIO_INT_STATUS 0x40 53d3e51161SHeiko Stübner #define GPIO_INT_RAWSTATUS 0x44 54d3e51161SHeiko Stübner #define GPIO_DEBOUNCE 0x48 55d3e51161SHeiko Stübner #define GPIO_PORTS_EOI 0x4c 56d3e51161SHeiko Stübner #define GPIO_EXT_PORT 0x50 57d3e51161SHeiko Stübner #define GPIO_LS_SYNC 0x60 58d3e51161SHeiko Stübner 59a282926dSHeiko Stübner enum rockchip_pinctrl_type { 60a282926dSHeiko Stübner RK2928, 61a282926dSHeiko Stübner RK3066B, 62a282926dSHeiko Stübner RK3188, 63a282926dSHeiko Stübner }; 64a282926dSHeiko Stübner 6565fca613SHeiko Stübner enum rockchip_pin_bank_type { 6665fca613SHeiko Stübner COMMON_BANK, 676ca5274dSHeiko Stübner RK3188_BANK0, 6865fca613SHeiko Stübner }; 6965fca613SHeiko Stübner 70d3e51161SHeiko Stübner /** 71d3e51161SHeiko Stübner * @reg_base: register base of the gpio bank 726ca5274dSHeiko Stübner * @reg_pull: optional separate register for additional pull settings 73d3e51161SHeiko Stübner * @clk: clock of the gpio bank 74d3e51161SHeiko Stübner * @irq: interrupt of the gpio bank 75d3e51161SHeiko Stübner * @pin_base: first pin number 76d3e51161SHeiko Stübner * @nr_pins: number of pins in this bank 77d3e51161SHeiko Stübner * @name: name of the bank 78d3e51161SHeiko Stübner * @bank_num: number of the bank, to account for holes 79d3e51161SHeiko Stübner * @valid: are all necessary informations present 80d3e51161SHeiko Stübner * @of_node: dt node of this bank 81d3e51161SHeiko Stübner * @drvdata: common pinctrl basedata 82d3e51161SHeiko Stübner * @domain: irqdomain of the gpio bank 83d3e51161SHeiko Stübner * @gpio_chip: gpiolib chip 84d3e51161SHeiko Stübner * @grange: gpio range 85d3e51161SHeiko Stübner * @slock: spinlock for the gpio bank 86d3e51161SHeiko Stübner */ 87d3e51161SHeiko Stübner struct rockchip_pin_bank { 88d3e51161SHeiko Stübner void __iomem *reg_base; 896ca5274dSHeiko Stübner void __iomem *reg_pull; 90d3e51161SHeiko Stübner struct clk *clk; 91d3e51161SHeiko Stübner int irq; 92d3e51161SHeiko Stübner u32 pin_base; 93d3e51161SHeiko Stübner u8 nr_pins; 94d3e51161SHeiko Stübner char *name; 95d3e51161SHeiko Stübner u8 bank_num; 9665fca613SHeiko Stübner enum rockchip_pin_bank_type bank_type; 97d3e51161SHeiko Stübner bool valid; 98d3e51161SHeiko Stübner struct device_node *of_node; 99d3e51161SHeiko Stübner struct rockchip_pinctrl *drvdata; 100d3e51161SHeiko Stübner struct irq_domain *domain; 101d3e51161SHeiko Stübner struct gpio_chip gpio_chip; 102d3e51161SHeiko Stübner struct pinctrl_gpio_range grange; 103d3e51161SHeiko Stübner spinlock_t slock; 1045a927501SHeiko Stübner u32 toggle_edge_mode; 105d3e51161SHeiko Stübner }; 106d3e51161SHeiko Stübner 107d3e51161SHeiko Stübner #define PIN_BANK(id, pins, label) \ 108d3e51161SHeiko Stübner { \ 109d3e51161SHeiko Stübner .bank_num = id, \ 110d3e51161SHeiko Stübner .nr_pins = pins, \ 111d3e51161SHeiko Stübner .name = label, \ 112d3e51161SHeiko Stübner } 113d3e51161SHeiko Stübner 114d3e51161SHeiko Stübner /** 115d3e51161SHeiko Stübner */ 116d3e51161SHeiko Stübner struct rockchip_pin_ctrl { 117d3e51161SHeiko Stübner struct rockchip_pin_bank *pin_banks; 118d3e51161SHeiko Stübner u32 nr_banks; 119d3e51161SHeiko Stübner u32 nr_pins; 120d3e51161SHeiko Stübner char *label; 121a282926dSHeiko Stübner enum rockchip_pinctrl_type type; 122d3e51161SHeiko Stübner int mux_offset; 123a282926dSHeiko Stübner void (*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num, 124a282926dSHeiko Stübner void __iomem **reg, u8 *bit); 125d3e51161SHeiko Stübner }; 126d3e51161SHeiko Stübner 127d3e51161SHeiko Stübner struct rockchip_pin_config { 128d3e51161SHeiko Stübner unsigned int func; 129d3e51161SHeiko Stübner unsigned long *configs; 130d3e51161SHeiko Stübner unsigned int nconfigs; 131d3e51161SHeiko Stübner }; 132d3e51161SHeiko Stübner 133d3e51161SHeiko Stübner /** 134d3e51161SHeiko Stübner * struct rockchip_pin_group: represent group of pins of a pinmux function. 135d3e51161SHeiko Stübner * @name: name of the pin group, used to lookup the group. 136d3e51161SHeiko Stübner * @pins: the pins included in this group. 137d3e51161SHeiko Stübner * @npins: number of pins included in this group. 138d3e51161SHeiko Stübner * @func: the mux function number to be programmed when selected. 139d3e51161SHeiko Stübner * @configs: the config values to be set for each pin 140d3e51161SHeiko Stübner * @nconfigs: number of configs for each pin 141d3e51161SHeiko Stübner */ 142d3e51161SHeiko Stübner struct rockchip_pin_group { 143d3e51161SHeiko Stübner const char *name; 144d3e51161SHeiko Stübner unsigned int npins; 145d3e51161SHeiko Stübner unsigned int *pins; 146d3e51161SHeiko Stübner struct rockchip_pin_config *data; 147d3e51161SHeiko Stübner }; 148d3e51161SHeiko Stübner 149d3e51161SHeiko Stübner /** 150d3e51161SHeiko Stübner * struct rockchip_pmx_func: represent a pin function. 151d3e51161SHeiko Stübner * @name: name of the pin function, used to lookup the function. 152d3e51161SHeiko Stübner * @groups: one or more names of pin groups that provide this function. 153d3e51161SHeiko Stübner * @num_groups: number of groups included in @groups. 154d3e51161SHeiko Stübner */ 155d3e51161SHeiko Stübner struct rockchip_pmx_func { 156d3e51161SHeiko Stübner const char *name; 157d3e51161SHeiko Stübner const char **groups; 158d3e51161SHeiko Stübner u8 ngroups; 159d3e51161SHeiko Stübner }; 160d3e51161SHeiko Stübner 161d3e51161SHeiko Stübner struct rockchip_pinctrl { 162d3e51161SHeiko Stübner void __iomem *reg_base; 163*bfc7a42aSHeiko Stübner int reg_size; 1646ca5274dSHeiko Stübner void __iomem *reg_pull; 165d3e51161SHeiko Stübner struct device *dev; 166d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 167d3e51161SHeiko Stübner struct pinctrl_desc pctl; 168d3e51161SHeiko Stübner struct pinctrl_dev *pctl_dev; 169d3e51161SHeiko Stübner struct rockchip_pin_group *groups; 170d3e51161SHeiko Stübner unsigned int ngroups; 171d3e51161SHeiko Stübner struct rockchip_pmx_func *functions; 172d3e51161SHeiko Stübner unsigned int nfunctions; 173d3e51161SHeiko Stübner }; 174d3e51161SHeiko Stübner 175d3e51161SHeiko Stübner static inline struct rockchip_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) 176d3e51161SHeiko Stübner { 177d3e51161SHeiko Stübner return container_of(gc, struct rockchip_pin_bank, gpio_chip); 178d3e51161SHeiko Stübner } 179d3e51161SHeiko Stübner 180d3e51161SHeiko Stübner static const inline struct rockchip_pin_group *pinctrl_name_to_group( 181d3e51161SHeiko Stübner const struct rockchip_pinctrl *info, 182d3e51161SHeiko Stübner const char *name) 183d3e51161SHeiko Stübner { 184d3e51161SHeiko Stübner int i; 185d3e51161SHeiko Stübner 186d3e51161SHeiko Stübner for (i = 0; i < info->ngroups; i++) { 1871cb95395SAxel Lin if (!strcmp(info->groups[i].name, name)) 1881cb95395SAxel Lin return &info->groups[i]; 189d3e51161SHeiko Stübner } 190d3e51161SHeiko Stübner 1911cb95395SAxel Lin return NULL; 192d3e51161SHeiko Stübner } 193d3e51161SHeiko Stübner 194d3e51161SHeiko Stübner /* 195d3e51161SHeiko Stübner * given a pin number that is local to a pin controller, find out the pin bank 196d3e51161SHeiko Stübner * and the register base of the pin bank. 197d3e51161SHeiko Stübner */ 198d3e51161SHeiko Stübner static struct rockchip_pin_bank *pin_to_bank(struct rockchip_pinctrl *info, 199d3e51161SHeiko Stübner unsigned pin) 200d3e51161SHeiko Stübner { 201d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 202d3e51161SHeiko Stübner 20351578b9bSAxel Lin while (pin >= (b->pin_base + b->nr_pins)) 204d3e51161SHeiko Stübner b++; 205d3e51161SHeiko Stübner 206d3e51161SHeiko Stübner return b; 207d3e51161SHeiko Stübner } 208d3e51161SHeiko Stübner 209d3e51161SHeiko Stübner static struct rockchip_pin_bank *bank_num_to_bank( 210d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 211d3e51161SHeiko Stübner unsigned num) 212d3e51161SHeiko Stübner { 213d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 214d3e51161SHeiko Stübner int i; 215d3e51161SHeiko Stübner 2161cb95395SAxel Lin for (i = 0; i < info->ctrl->nr_banks; i++, b++) { 217d3e51161SHeiko Stübner if (b->bank_num == num) 2181cb95395SAxel Lin return b; 219d3e51161SHeiko Stübner } 220d3e51161SHeiko Stübner 221d3e51161SHeiko Stübner return ERR_PTR(-EINVAL); 222d3e51161SHeiko Stübner } 223d3e51161SHeiko Stübner 224d3e51161SHeiko Stübner /* 225d3e51161SHeiko Stübner * Pinctrl_ops handling 226d3e51161SHeiko Stübner */ 227d3e51161SHeiko Stübner 228d3e51161SHeiko Stübner static int rockchip_get_groups_count(struct pinctrl_dev *pctldev) 229d3e51161SHeiko Stübner { 230d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 231d3e51161SHeiko Stübner 232d3e51161SHeiko Stübner return info->ngroups; 233d3e51161SHeiko Stübner } 234d3e51161SHeiko Stübner 235d3e51161SHeiko Stübner static const char *rockchip_get_group_name(struct pinctrl_dev *pctldev, 236d3e51161SHeiko Stübner unsigned selector) 237d3e51161SHeiko Stübner { 238d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 239d3e51161SHeiko Stübner 240d3e51161SHeiko Stübner return info->groups[selector].name; 241d3e51161SHeiko Stübner } 242d3e51161SHeiko Stübner 243d3e51161SHeiko Stübner static int rockchip_get_group_pins(struct pinctrl_dev *pctldev, 244d3e51161SHeiko Stübner unsigned selector, const unsigned **pins, 245d3e51161SHeiko Stübner unsigned *npins) 246d3e51161SHeiko Stübner { 247d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 248d3e51161SHeiko Stübner 249d3e51161SHeiko Stübner if (selector >= info->ngroups) 250d3e51161SHeiko Stübner return -EINVAL; 251d3e51161SHeiko Stübner 252d3e51161SHeiko Stübner *pins = info->groups[selector].pins; 253d3e51161SHeiko Stübner *npins = info->groups[selector].npins; 254d3e51161SHeiko Stübner 255d3e51161SHeiko Stübner return 0; 256d3e51161SHeiko Stübner } 257d3e51161SHeiko Stübner 258d3e51161SHeiko Stübner static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev, 259d3e51161SHeiko Stübner struct device_node *np, 260d3e51161SHeiko Stübner struct pinctrl_map **map, unsigned *num_maps) 261d3e51161SHeiko Stübner { 262d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 263d3e51161SHeiko Stübner const struct rockchip_pin_group *grp; 264d3e51161SHeiko Stübner struct pinctrl_map *new_map; 265d3e51161SHeiko Stübner struct device_node *parent; 266d3e51161SHeiko Stübner int map_num = 1; 267d3e51161SHeiko Stübner int i; 268d3e51161SHeiko Stübner 269d3e51161SHeiko Stübner /* 270d3e51161SHeiko Stübner * first find the group of this node and check if we need to create 271d3e51161SHeiko Stübner * config maps for pins 272d3e51161SHeiko Stübner */ 273d3e51161SHeiko Stübner grp = pinctrl_name_to_group(info, np->name); 274d3e51161SHeiko Stübner if (!grp) { 275d3e51161SHeiko Stübner dev_err(info->dev, "unable to find group for node %s\n", 276d3e51161SHeiko Stübner np->name); 277d3e51161SHeiko Stübner return -EINVAL; 278d3e51161SHeiko Stübner } 279d3e51161SHeiko Stübner 280d3e51161SHeiko Stübner map_num += grp->npins; 281d3e51161SHeiko Stübner new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num, 282d3e51161SHeiko Stübner GFP_KERNEL); 283d3e51161SHeiko Stübner if (!new_map) 284d3e51161SHeiko Stübner return -ENOMEM; 285d3e51161SHeiko Stübner 286d3e51161SHeiko Stübner *map = new_map; 287d3e51161SHeiko Stübner *num_maps = map_num; 288d3e51161SHeiko Stübner 289d3e51161SHeiko Stübner /* create mux map */ 290d3e51161SHeiko Stübner parent = of_get_parent(np); 291d3e51161SHeiko Stübner if (!parent) { 292d3e51161SHeiko Stübner devm_kfree(pctldev->dev, new_map); 293d3e51161SHeiko Stübner return -EINVAL; 294d3e51161SHeiko Stübner } 295d3e51161SHeiko Stübner new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; 296d3e51161SHeiko Stübner new_map[0].data.mux.function = parent->name; 297d3e51161SHeiko Stübner new_map[0].data.mux.group = np->name; 298d3e51161SHeiko Stübner of_node_put(parent); 299d3e51161SHeiko Stübner 300d3e51161SHeiko Stübner /* create config map */ 301d3e51161SHeiko Stübner new_map++; 302d3e51161SHeiko Stübner for (i = 0; i < grp->npins; i++) { 303d3e51161SHeiko Stübner new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; 304d3e51161SHeiko Stübner new_map[i].data.configs.group_or_pin = 305d3e51161SHeiko Stübner pin_get_name(pctldev, grp->pins[i]); 306d3e51161SHeiko Stübner new_map[i].data.configs.configs = grp->data[i].configs; 307d3e51161SHeiko Stübner new_map[i].data.configs.num_configs = grp->data[i].nconfigs; 308d3e51161SHeiko Stübner } 309d3e51161SHeiko Stübner 310d3e51161SHeiko Stübner dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", 311d3e51161SHeiko Stübner (*map)->data.mux.function, (*map)->data.mux.group, map_num); 312d3e51161SHeiko Stübner 313d3e51161SHeiko Stübner return 0; 314d3e51161SHeiko Stübner } 315d3e51161SHeiko Stübner 316d3e51161SHeiko Stübner static void rockchip_dt_free_map(struct pinctrl_dev *pctldev, 317d3e51161SHeiko Stübner struct pinctrl_map *map, unsigned num_maps) 318d3e51161SHeiko Stübner { 319d3e51161SHeiko Stübner } 320d3e51161SHeiko Stübner 321d3e51161SHeiko Stübner static const struct pinctrl_ops rockchip_pctrl_ops = { 322d3e51161SHeiko Stübner .get_groups_count = rockchip_get_groups_count, 323d3e51161SHeiko Stübner .get_group_name = rockchip_get_group_name, 324d3e51161SHeiko Stübner .get_group_pins = rockchip_get_group_pins, 325d3e51161SHeiko Stübner .dt_node_to_map = rockchip_dt_node_to_map, 326d3e51161SHeiko Stübner .dt_free_map = rockchip_dt_free_map, 327d3e51161SHeiko Stübner }; 328d3e51161SHeiko Stübner 329d3e51161SHeiko Stübner /* 330d3e51161SHeiko Stübner * Hardware access 331d3e51161SHeiko Stübner */ 332d3e51161SHeiko Stübner 333a076e2edSHeiko Stübner static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) 334a076e2edSHeiko Stübner { 335a076e2edSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 336a076e2edSHeiko Stübner void __iomem *reg = info->reg_base + info->ctrl->mux_offset; 337a076e2edSHeiko Stübner u8 bit; 338a076e2edSHeiko Stübner 339a076e2edSHeiko Stübner if (bank->bank_type == RK3188_BANK0 && pin < 16) 340a076e2edSHeiko Stübner return RK_FUNC_GPIO; 341a076e2edSHeiko Stübner 342a076e2edSHeiko Stübner /* get basic quadrupel of mux registers and the correct reg inside */ 343a076e2edSHeiko Stübner reg += bank->bank_num * 0x10; 344a076e2edSHeiko Stübner reg += (pin / 8) * 4; 345a076e2edSHeiko Stübner bit = (pin % 8) * 2; 346a076e2edSHeiko Stübner 347a076e2edSHeiko Stübner return ((readl(reg) >> bit) & 3); 348a076e2edSHeiko Stübner } 349a076e2edSHeiko Stübner 350d3e51161SHeiko Stübner /* 351d3e51161SHeiko Stübner * Set a new mux function for a pin. 352d3e51161SHeiko Stübner * 353d3e51161SHeiko Stübner * The register is divided into the upper and lower 16 bit. When changing 354d3e51161SHeiko Stübner * a value, the previous register value is not read and changed. Instead 355d3e51161SHeiko Stübner * it seems the changed bits are marked in the upper 16 bit, while the 356d3e51161SHeiko Stübner * changed value gets set in the same offset in the lower 16 bit. 357d3e51161SHeiko Stübner * All pin settings seem to be 2 bit wide in both the upper and lower 358d3e51161SHeiko Stübner * parts. 359d3e51161SHeiko Stübner * @bank: pin bank to change 360d3e51161SHeiko Stübner * @pin: pin to change 361d3e51161SHeiko Stübner * @mux: new mux function to set 362d3e51161SHeiko Stübner */ 36314797189SHeiko Stübner static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 364d3e51161SHeiko Stübner { 365d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 366d3e51161SHeiko Stübner void __iomem *reg = info->reg_base + info->ctrl->mux_offset; 367d3e51161SHeiko Stübner unsigned long flags; 368d3e51161SHeiko Stübner u8 bit; 369d3e51161SHeiko Stübner u32 data; 370d3e51161SHeiko Stübner 371c4a532deSHeiko Stübner /* 372c4a532deSHeiko Stübner * The first 16 pins of rk3188_bank0 are always gpios and do not have 373c4a532deSHeiko Stübner * a mux register at all. 374c4a532deSHeiko Stübner */ 375c4a532deSHeiko Stübner if (bank->bank_type == RK3188_BANK0 && pin < 16) { 376c4a532deSHeiko Stübner if (mux != RK_FUNC_GPIO) { 377c4a532deSHeiko Stübner dev_err(info->dev, 378c4a532deSHeiko Stübner "pin %d only supports a gpio mux\n", pin); 379c4a532deSHeiko Stübner return -ENOTSUPP; 380c4a532deSHeiko Stübner } else { 381c4a532deSHeiko Stübner return 0; 382c4a532deSHeiko Stübner } 383c4a532deSHeiko Stübner } 384c4a532deSHeiko Stübner 385d3e51161SHeiko Stübner dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n", 386d3e51161SHeiko Stübner bank->bank_num, pin, mux); 387d3e51161SHeiko Stübner 388d3e51161SHeiko Stübner /* get basic quadrupel of mux registers and the correct reg inside */ 389d3e51161SHeiko Stübner reg += bank->bank_num * 0x10; 390d3e51161SHeiko Stübner reg += (pin / 8) * 4; 391d3e51161SHeiko Stübner bit = (pin % 8) * 2; 392d3e51161SHeiko Stübner 393d3e51161SHeiko Stübner spin_lock_irqsave(&bank->slock, flags); 394d3e51161SHeiko Stübner 395d3e51161SHeiko Stübner data = (3 << (bit + 16)); 396d3e51161SHeiko Stübner data |= (mux & 3) << bit; 397d3e51161SHeiko Stübner writel(data, reg); 398d3e51161SHeiko Stübner 399d3e51161SHeiko Stübner spin_unlock_irqrestore(&bank->slock, flags); 40014797189SHeiko Stübner 40114797189SHeiko Stübner return 0; 402d3e51161SHeiko Stübner } 403d3e51161SHeiko Stübner 404a282926dSHeiko Stübner #define RK2928_PULL_OFFSET 0x118 405a282926dSHeiko Stübner #define RK2928_PULL_PINS_PER_REG 16 406a282926dSHeiko Stübner #define RK2928_PULL_BANK_STRIDE 8 407a282926dSHeiko Stübner 408a282926dSHeiko Stübner static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 409a282926dSHeiko Stübner int pin_num, void __iomem **reg, u8 *bit) 410a282926dSHeiko Stübner { 411a282926dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 412a282926dSHeiko Stübner 413a282926dSHeiko Stübner *reg = info->reg_base + RK2928_PULL_OFFSET; 414a282926dSHeiko Stübner *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 415a282926dSHeiko Stübner *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4; 416a282926dSHeiko Stübner 417a282926dSHeiko Stübner *bit = pin_num % RK2928_PULL_PINS_PER_REG; 418a282926dSHeiko Stübner }; 419a282926dSHeiko Stübner 420*bfc7a42aSHeiko Stübner #define RK3188_PULL_OFFSET 0x164 4216ca5274dSHeiko Stübner #define RK3188_PULL_BITS_PER_PIN 2 4226ca5274dSHeiko Stübner #define RK3188_PULL_PINS_PER_REG 8 4236ca5274dSHeiko Stübner #define RK3188_PULL_BANK_STRIDE 16 4246ca5274dSHeiko Stübner 4256ca5274dSHeiko Stübner static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 4266ca5274dSHeiko Stübner int pin_num, void __iomem **reg, u8 *bit) 4276ca5274dSHeiko Stübner { 4286ca5274dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 4296ca5274dSHeiko Stübner 4306ca5274dSHeiko Stübner /* The first 12 pins of the first bank are located elsewhere */ 4316ca5274dSHeiko Stübner if (bank->bank_type == RK3188_BANK0 && pin_num < 12) { 4326ca5274dSHeiko Stübner *reg = bank->reg_pull + 4336ca5274dSHeiko Stübner ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 4346ca5274dSHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 4356ca5274dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 4366ca5274dSHeiko Stübner } else { 437*bfc7a42aSHeiko Stübner *reg = info->reg_pull ? info->reg_pull 438*bfc7a42aSHeiko Stübner : info->reg_base + RK3188_PULL_OFFSET; 439*bfc7a42aSHeiko Stübner /* correct the offset, as it is the 2nd pull register */ 440*bfc7a42aSHeiko Stübner *reg -= 4; 4416ca5274dSHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 4426ca5274dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 4436ca5274dSHeiko Stübner 4446ca5274dSHeiko Stübner /* 4456ca5274dSHeiko Stübner * The bits in these registers have an inverse ordering 4466ca5274dSHeiko Stübner * with the lowest pin being in bits 15:14 and the highest 4476ca5274dSHeiko Stübner * pin in bits 1:0 4486ca5274dSHeiko Stübner */ 4496ca5274dSHeiko Stübner *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG); 4506ca5274dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 4516ca5274dSHeiko Stübner } 4526ca5274dSHeiko Stübner } 4536ca5274dSHeiko Stübner 454d3e51161SHeiko Stübner static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) 455d3e51161SHeiko Stübner { 456d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 457d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 458d3e51161SHeiko Stübner void __iomem *reg; 459d3e51161SHeiko Stübner u8 bit; 4606ca5274dSHeiko Stübner u32 data; 461d3e51161SHeiko Stübner 462d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 463a282926dSHeiko Stübner if (ctrl->type == RK3066B) 464d3e51161SHeiko Stübner return PIN_CONFIG_BIAS_DISABLE; 465d3e51161SHeiko Stübner 4666ca5274dSHeiko Stübner ctrl->pull_calc_reg(bank, pin_num, ®, &bit); 4676ca5274dSHeiko Stübner 468a282926dSHeiko Stübner switch (ctrl->type) { 469a282926dSHeiko Stübner case RK2928: 470d3e51161SHeiko Stübner return !(readl_relaxed(reg) & BIT(bit)) 471d3e51161SHeiko Stübner ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT 472d3e51161SHeiko Stübner : PIN_CONFIG_BIAS_DISABLE; 473a282926dSHeiko Stübner case RK3188: 4746ca5274dSHeiko Stübner data = readl_relaxed(reg) >> bit; 4756ca5274dSHeiko Stübner data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; 4766ca5274dSHeiko Stübner 4776ca5274dSHeiko Stübner switch (data) { 4786ca5274dSHeiko Stübner case 0: 4796ca5274dSHeiko Stübner return PIN_CONFIG_BIAS_DISABLE; 4806ca5274dSHeiko Stübner case 1: 4816ca5274dSHeiko Stübner return PIN_CONFIG_BIAS_PULL_UP; 4826ca5274dSHeiko Stübner case 2: 4836ca5274dSHeiko Stübner return PIN_CONFIG_BIAS_PULL_DOWN; 4846ca5274dSHeiko Stübner case 3: 4856ca5274dSHeiko Stübner return PIN_CONFIG_BIAS_BUS_HOLD; 4866ca5274dSHeiko Stübner } 4876ca5274dSHeiko Stübner 4886ca5274dSHeiko Stübner dev_err(info->dev, "unknown pull setting\n"); 489d3e51161SHeiko Stübner return -EIO; 490a282926dSHeiko Stübner default: 491a282926dSHeiko Stübner dev_err(info->dev, "unsupported pinctrl type\n"); 492a282926dSHeiko Stübner return -EINVAL; 493a282926dSHeiko Stübner }; 494d3e51161SHeiko Stübner } 495d3e51161SHeiko Stübner 496d3e51161SHeiko Stübner static int rockchip_set_pull(struct rockchip_pin_bank *bank, 497d3e51161SHeiko Stübner int pin_num, int pull) 498d3e51161SHeiko Stübner { 499d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 500d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 501d3e51161SHeiko Stübner void __iomem *reg; 502d3e51161SHeiko Stübner unsigned long flags; 503d3e51161SHeiko Stübner u8 bit; 504d3e51161SHeiko Stübner u32 data; 505d3e51161SHeiko Stübner 506d3e51161SHeiko Stübner dev_dbg(info->dev, "setting pull of GPIO%d-%d to %d\n", 507d3e51161SHeiko Stübner bank->bank_num, pin_num, pull); 508d3e51161SHeiko Stübner 509d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 510a282926dSHeiko Stübner if (ctrl->type == RK3066B) 511d3e51161SHeiko Stübner return pull ? -EINVAL : 0; 512d3e51161SHeiko Stübner 513a282926dSHeiko Stübner ctrl->pull_calc_reg(bank, pin_num, ®, &bit); 514d3e51161SHeiko Stübner 5156ca5274dSHeiko Stübner switch (ctrl->type) { 5166ca5274dSHeiko Stübner case RK2928: 517d3e51161SHeiko Stübner spin_lock_irqsave(&bank->slock, flags); 518d3e51161SHeiko Stübner 519d3e51161SHeiko Stübner data = BIT(bit + 16); 520d3e51161SHeiko Stübner if (pull == PIN_CONFIG_BIAS_DISABLE) 521d3e51161SHeiko Stübner data |= BIT(bit); 522d3e51161SHeiko Stübner writel(data, reg); 523d3e51161SHeiko Stübner 524d3e51161SHeiko Stübner spin_unlock_irqrestore(&bank->slock, flags); 525a282926dSHeiko Stübner break; 526a282926dSHeiko Stübner case RK3188: 5276ca5274dSHeiko Stübner spin_lock_irqsave(&bank->slock, flags); 5286ca5274dSHeiko Stübner 5296ca5274dSHeiko Stübner /* enable the write to the equivalent lower bits */ 5306ca5274dSHeiko Stübner data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); 5316ca5274dSHeiko Stübner 5326ca5274dSHeiko Stübner switch (pull) { 5336ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 5346ca5274dSHeiko Stübner break; 5356ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 5366ca5274dSHeiko Stübner data |= (1 << bit); 5376ca5274dSHeiko Stübner break; 5386ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 5396ca5274dSHeiko Stübner data |= (2 << bit); 5406ca5274dSHeiko Stübner break; 5416ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 5426ca5274dSHeiko Stübner data |= (3 << bit); 5436ca5274dSHeiko Stübner break; 5446ca5274dSHeiko Stübner default: 545d32c3e26SDan Carpenter spin_unlock_irqrestore(&bank->slock, flags); 5466ca5274dSHeiko Stübner dev_err(info->dev, "unsupported pull setting %d\n", 5476ca5274dSHeiko Stübner pull); 5486ca5274dSHeiko Stübner return -EINVAL; 5496ca5274dSHeiko Stübner } 5506ca5274dSHeiko Stübner 5516ca5274dSHeiko Stübner writel(data, reg); 5526ca5274dSHeiko Stübner 5536ca5274dSHeiko Stübner spin_unlock_irqrestore(&bank->slock, flags); 5546ca5274dSHeiko Stübner break; 555a282926dSHeiko Stübner default: 556a282926dSHeiko Stübner dev_err(info->dev, "unsupported pinctrl type\n"); 557a282926dSHeiko Stübner return -EINVAL; 558d3e51161SHeiko Stübner } 559d3e51161SHeiko Stübner 560d3e51161SHeiko Stübner return 0; 561d3e51161SHeiko Stübner } 562d3e51161SHeiko Stübner 563d3e51161SHeiko Stübner /* 564d3e51161SHeiko Stübner * Pinmux_ops handling 565d3e51161SHeiko Stübner */ 566d3e51161SHeiko Stübner 567d3e51161SHeiko Stübner static int rockchip_pmx_get_funcs_count(struct pinctrl_dev *pctldev) 568d3e51161SHeiko Stübner { 569d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 570d3e51161SHeiko Stübner 571d3e51161SHeiko Stübner return info->nfunctions; 572d3e51161SHeiko Stübner } 573d3e51161SHeiko Stübner 574d3e51161SHeiko Stübner static const char *rockchip_pmx_get_func_name(struct pinctrl_dev *pctldev, 575d3e51161SHeiko Stübner unsigned selector) 576d3e51161SHeiko Stübner { 577d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 578d3e51161SHeiko Stübner 579d3e51161SHeiko Stübner return info->functions[selector].name; 580d3e51161SHeiko Stübner } 581d3e51161SHeiko Stübner 582d3e51161SHeiko Stübner static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev, 583d3e51161SHeiko Stübner unsigned selector, const char * const **groups, 584d3e51161SHeiko Stübner unsigned * const num_groups) 585d3e51161SHeiko Stübner { 586d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 587d3e51161SHeiko Stübner 588d3e51161SHeiko Stübner *groups = info->functions[selector].groups; 589d3e51161SHeiko Stübner *num_groups = info->functions[selector].ngroups; 590d3e51161SHeiko Stübner 591d3e51161SHeiko Stübner return 0; 592d3e51161SHeiko Stübner } 593d3e51161SHeiko Stübner 594d3e51161SHeiko Stübner static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, 595d3e51161SHeiko Stübner unsigned group) 596d3e51161SHeiko Stübner { 597d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 598d3e51161SHeiko Stübner const unsigned int *pins = info->groups[group].pins; 599d3e51161SHeiko Stübner const struct rockchip_pin_config *data = info->groups[group].data; 600d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 60114797189SHeiko Stübner int cnt, ret = 0; 602d3e51161SHeiko Stübner 603d3e51161SHeiko Stübner dev_dbg(info->dev, "enable function %s group %s\n", 604d3e51161SHeiko Stübner info->functions[selector].name, info->groups[group].name); 605d3e51161SHeiko Stübner 606d3e51161SHeiko Stübner /* 607d3e51161SHeiko Stübner * for each pin in the pin group selected, program the correspoding pin 608d3e51161SHeiko Stübner * pin function number in the config register. 609d3e51161SHeiko Stübner */ 610d3e51161SHeiko Stübner for (cnt = 0; cnt < info->groups[group].npins; cnt++) { 611d3e51161SHeiko Stübner bank = pin_to_bank(info, pins[cnt]); 61214797189SHeiko Stübner ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 613d3e51161SHeiko Stübner data[cnt].func); 61414797189SHeiko Stübner if (ret) 61514797189SHeiko Stübner break; 61614797189SHeiko Stübner } 61714797189SHeiko Stübner 61814797189SHeiko Stübner if (ret) { 61914797189SHeiko Stübner /* revert the already done pin settings */ 62014797189SHeiko Stübner for (cnt--; cnt >= 0; cnt--) 62114797189SHeiko Stübner rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); 62214797189SHeiko Stübner 62314797189SHeiko Stübner return ret; 624d3e51161SHeiko Stübner } 625d3e51161SHeiko Stübner 626d3e51161SHeiko Stübner return 0; 627d3e51161SHeiko Stübner } 628d3e51161SHeiko Stübner 629d3e51161SHeiko Stübner static void rockchip_pmx_disable(struct pinctrl_dev *pctldev, 630d3e51161SHeiko Stübner unsigned selector, unsigned group) 631d3e51161SHeiko Stübner { 632d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 633d3e51161SHeiko Stübner const unsigned int *pins = info->groups[group].pins; 634d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 635d3e51161SHeiko Stübner int cnt; 636d3e51161SHeiko Stübner 637d3e51161SHeiko Stübner dev_dbg(info->dev, "disable function %s group %s\n", 638d3e51161SHeiko Stübner info->functions[selector].name, info->groups[group].name); 639d3e51161SHeiko Stübner 640d3e51161SHeiko Stübner for (cnt = 0; cnt < info->groups[group].npins; cnt++) { 641d3e51161SHeiko Stübner bank = pin_to_bank(info, pins[cnt]); 642d3e51161SHeiko Stübner rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); 643d3e51161SHeiko Stübner } 644d3e51161SHeiko Stübner } 645d3e51161SHeiko Stübner 646d3e51161SHeiko Stübner /* 647d3e51161SHeiko Stübner * The calls to gpio_direction_output() and gpio_direction_input() 648d3e51161SHeiko Stübner * leads to this function call (via the pinctrl_gpio_direction_{input|output}() 649d3e51161SHeiko Stübner * function called from the gpiolib interface). 650d3e51161SHeiko Stübner */ 651d3e51161SHeiko Stübner static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, 652d3e51161SHeiko Stübner struct pinctrl_gpio_range *range, 653d3e51161SHeiko Stübner unsigned offset, bool input) 654d3e51161SHeiko Stübner { 655d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 656d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 657d3e51161SHeiko Stübner struct gpio_chip *chip; 65814797189SHeiko Stübner int pin, ret; 659d3e51161SHeiko Stübner u32 data; 660d3e51161SHeiko Stübner 661d3e51161SHeiko Stübner chip = range->gc; 662d3e51161SHeiko Stübner bank = gc_to_pin_bank(chip); 663d3e51161SHeiko Stübner pin = offset - chip->base; 664d3e51161SHeiko Stübner 665d3e51161SHeiko Stübner dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", 666d3e51161SHeiko Stübner offset, range->name, pin, input ? "input" : "output"); 667d3e51161SHeiko Stübner 66814797189SHeiko Stübner ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); 66914797189SHeiko Stübner if (ret < 0) 67014797189SHeiko Stübner return ret; 671d3e51161SHeiko Stübner 672d3e51161SHeiko Stübner data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); 673d3e51161SHeiko Stübner /* set bit to 1 for output, 0 for input */ 674d3e51161SHeiko Stübner if (!input) 675d3e51161SHeiko Stübner data |= BIT(pin); 676d3e51161SHeiko Stübner else 677d3e51161SHeiko Stübner data &= ~BIT(pin); 678d3e51161SHeiko Stübner writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); 679d3e51161SHeiko Stübner 680d3e51161SHeiko Stübner return 0; 681d3e51161SHeiko Stübner } 682d3e51161SHeiko Stübner 683d3e51161SHeiko Stübner static const struct pinmux_ops rockchip_pmx_ops = { 684d3e51161SHeiko Stübner .get_functions_count = rockchip_pmx_get_funcs_count, 685d3e51161SHeiko Stübner .get_function_name = rockchip_pmx_get_func_name, 686d3e51161SHeiko Stübner .get_function_groups = rockchip_pmx_get_groups, 687d3e51161SHeiko Stübner .enable = rockchip_pmx_enable, 688d3e51161SHeiko Stübner .disable = rockchip_pmx_disable, 689d3e51161SHeiko Stübner .gpio_set_direction = rockchip_pmx_gpio_set_direction, 690d3e51161SHeiko Stübner }; 691d3e51161SHeiko Stübner 692d3e51161SHeiko Stübner /* 693d3e51161SHeiko Stübner * Pinconf_ops handling 694d3e51161SHeiko Stübner */ 695d3e51161SHeiko Stübner 69644b6d930SHeiko Stübner static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, 69744b6d930SHeiko Stübner enum pin_config_param pull) 69844b6d930SHeiko Stübner { 699a282926dSHeiko Stübner switch (ctrl->type) { 700a282926dSHeiko Stübner case RK2928: 701a282926dSHeiko Stübner return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT || 702a282926dSHeiko Stübner pull == PIN_CONFIG_BIAS_DISABLE); 703a282926dSHeiko Stübner case RK3066B: 70444b6d930SHeiko Stübner return pull ? false : true; 705a282926dSHeiko Stübner case RK3188: 706a282926dSHeiko Stübner return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); 70744b6d930SHeiko Stübner } 70844b6d930SHeiko Stübner 709a282926dSHeiko Stübner return false; 71044b6d930SHeiko Stübner } 71144b6d930SHeiko Stübner 712a076e2edSHeiko Stübner static int rockchip_gpio_direction_output(struct gpio_chip *gc, 713a076e2edSHeiko Stübner unsigned offset, int value); 714a076e2edSHeiko Stübner static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); 715a076e2edSHeiko Stübner 716d3e51161SHeiko Stübner /* set the pin config settings for a specified pin */ 717d3e51161SHeiko Stübner static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, 71803b054e9SSherman Yin unsigned long *configs, unsigned num_configs) 719d3e51161SHeiko Stübner { 720d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 721d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 72203b054e9SSherman Yin enum pin_config_param param; 72303b054e9SSherman Yin u16 arg; 72403b054e9SSherman Yin int i; 72503b054e9SSherman Yin int rc; 72603b054e9SSherman Yin 72703b054e9SSherman Yin for (i = 0; i < num_configs; i++) { 72803b054e9SSherman Yin param = pinconf_to_config_param(configs[i]); 72903b054e9SSherman Yin arg = pinconf_to_config_argument(configs[i]); 730d3e51161SHeiko Stübner 731d3e51161SHeiko Stübner switch (param) { 732d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 73303b054e9SSherman Yin rc = rockchip_set_pull(bank, pin - bank->pin_base, 73403b054e9SSherman Yin param); 73503b054e9SSherman Yin if (rc) 73603b054e9SSherman Yin return rc; 73744b6d930SHeiko Stübner break; 738d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 739d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 740d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 7416ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 74244b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 74344b6d930SHeiko Stübner return -ENOTSUPP; 74444b6d930SHeiko Stübner 74544b6d930SHeiko Stübner if (!arg) 74644b6d930SHeiko Stübner return -EINVAL; 74744b6d930SHeiko Stübner 74803b054e9SSherman Yin rc = rockchip_set_pull(bank, pin - bank->pin_base, 74903b054e9SSherman Yin param); 75003b054e9SSherman Yin if (rc) 75103b054e9SSherman Yin return rc; 752d3e51161SHeiko Stübner break; 753a076e2edSHeiko Stübner case PIN_CONFIG_OUTPUT: 754a076e2edSHeiko Stübner rc = rockchip_gpio_direction_output(&bank->gpio_chip, 755a076e2edSHeiko Stübner pin - bank->pin_base, 756a076e2edSHeiko Stübner arg); 757a076e2edSHeiko Stübner if (rc) 758a076e2edSHeiko Stübner return rc; 759a076e2edSHeiko Stübner break; 760d3e51161SHeiko Stübner default: 761d3e51161SHeiko Stübner return -ENOTSUPP; 762d3e51161SHeiko Stübner break; 763d3e51161SHeiko Stübner } 76403b054e9SSherman Yin } /* for each config */ 765d3e51161SHeiko Stübner 766d3e51161SHeiko Stübner return 0; 767d3e51161SHeiko Stübner } 768d3e51161SHeiko Stübner 769d3e51161SHeiko Stübner /* get the pin config settings for a specified pin */ 770d3e51161SHeiko Stübner static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, 771d3e51161SHeiko Stübner unsigned long *config) 772d3e51161SHeiko Stübner { 773d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 774d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 775d3e51161SHeiko Stübner enum pin_config_param param = pinconf_to_config_param(*config); 776dab3eba7SHeiko Stübner u16 arg; 777a076e2edSHeiko Stübner int rc; 778d3e51161SHeiko Stübner 779d3e51161SHeiko Stübner switch (param) { 780d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 78144b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 782d3e51161SHeiko Stübner return -EINVAL; 783d3e51161SHeiko Stübner 784dab3eba7SHeiko Stübner arg = 0; 785d3e51161SHeiko Stübner break; 78644b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 78744b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 78844b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 7896ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 79044b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 79144b6d930SHeiko Stübner return -ENOTSUPP; 79244b6d930SHeiko Stübner 79344b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 79444b6d930SHeiko Stübner return -EINVAL; 79544b6d930SHeiko Stübner 796dab3eba7SHeiko Stübner arg = 1; 79744b6d930SHeiko Stübner break; 798a076e2edSHeiko Stübner case PIN_CONFIG_OUTPUT: 799a076e2edSHeiko Stübner rc = rockchip_get_mux(bank, pin - bank->pin_base); 800a076e2edSHeiko Stübner if (rc != RK_FUNC_GPIO) 801a076e2edSHeiko Stübner return -EINVAL; 802a076e2edSHeiko Stübner 803a076e2edSHeiko Stübner rc = rockchip_gpio_get(&bank->gpio_chip, pin - bank->pin_base); 804a076e2edSHeiko Stübner if (rc < 0) 805a076e2edSHeiko Stübner return rc; 806a076e2edSHeiko Stübner 807a076e2edSHeiko Stübner arg = rc ? 1 : 0; 808a076e2edSHeiko Stübner break; 809d3e51161SHeiko Stübner default: 810d3e51161SHeiko Stübner return -ENOTSUPP; 811d3e51161SHeiko Stübner break; 812d3e51161SHeiko Stübner } 813d3e51161SHeiko Stübner 814dab3eba7SHeiko Stübner *config = pinconf_to_config_packed(param, arg); 815dab3eba7SHeiko Stübner 816d3e51161SHeiko Stübner return 0; 817d3e51161SHeiko Stübner } 818d3e51161SHeiko Stübner 819d3e51161SHeiko Stübner static const struct pinconf_ops rockchip_pinconf_ops = { 820d3e51161SHeiko Stübner .pin_config_get = rockchip_pinconf_get, 821d3e51161SHeiko Stübner .pin_config_set = rockchip_pinconf_set, 822d3e51161SHeiko Stübner }; 823d3e51161SHeiko Stübner 82465fca613SHeiko Stübner static const struct of_device_id rockchip_bank_match[] = { 82565fca613SHeiko Stübner { .compatible = "rockchip,gpio-bank" }, 8266ca5274dSHeiko Stübner { .compatible = "rockchip,rk3188-gpio-bank0" }, 82765fca613SHeiko Stübner {}, 82865fca613SHeiko Stübner }; 829d3e51161SHeiko Stübner 830d3e51161SHeiko Stübner static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info, 831d3e51161SHeiko Stübner struct device_node *np) 832d3e51161SHeiko Stübner { 833d3e51161SHeiko Stübner struct device_node *child; 834d3e51161SHeiko Stübner 835d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 83665fca613SHeiko Stübner if (of_match_node(rockchip_bank_match, child)) 837d3e51161SHeiko Stübner continue; 838d3e51161SHeiko Stübner 839d3e51161SHeiko Stübner info->nfunctions++; 840d3e51161SHeiko Stübner info->ngroups += of_get_child_count(child); 841d3e51161SHeiko Stübner } 842d3e51161SHeiko Stübner } 843d3e51161SHeiko Stübner 844d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_groups(struct device_node *np, 845d3e51161SHeiko Stübner struct rockchip_pin_group *grp, 846d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 847d3e51161SHeiko Stübner u32 index) 848d3e51161SHeiko Stübner { 849d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 850d3e51161SHeiko Stübner int size; 851d3e51161SHeiko Stübner const __be32 *list; 852d3e51161SHeiko Stübner int num; 853d3e51161SHeiko Stübner int i, j; 854d3e51161SHeiko Stübner int ret; 855d3e51161SHeiko Stübner 856d3e51161SHeiko Stübner dev_dbg(info->dev, "group(%d): %s\n", index, np->name); 857d3e51161SHeiko Stübner 858d3e51161SHeiko Stübner /* Initialise group */ 859d3e51161SHeiko Stübner grp->name = np->name; 860d3e51161SHeiko Stübner 861d3e51161SHeiko Stübner /* 862d3e51161SHeiko Stübner * the binding format is rockchip,pins = <bank pin mux CONFIG>, 863d3e51161SHeiko Stübner * do sanity check and calculate pins number 864d3e51161SHeiko Stübner */ 865d3e51161SHeiko Stübner list = of_get_property(np, "rockchip,pins", &size); 866d3e51161SHeiko Stübner /* we do not check return since it's safe node passed down */ 867d3e51161SHeiko Stübner size /= sizeof(*list); 868d3e51161SHeiko Stübner if (!size || size % 4) { 869d3e51161SHeiko Stübner dev_err(info->dev, "wrong pins number or pins and configs should be by 4\n"); 870d3e51161SHeiko Stübner return -EINVAL; 871d3e51161SHeiko Stübner } 872d3e51161SHeiko Stübner 873d3e51161SHeiko Stübner grp->npins = size / 4; 874d3e51161SHeiko Stübner 875d3e51161SHeiko Stübner grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), 876d3e51161SHeiko Stübner GFP_KERNEL); 877d3e51161SHeiko Stübner grp->data = devm_kzalloc(info->dev, grp->npins * 878d3e51161SHeiko Stübner sizeof(struct rockchip_pin_config), 879d3e51161SHeiko Stübner GFP_KERNEL); 880d3e51161SHeiko Stübner if (!grp->pins || !grp->data) 881d3e51161SHeiko Stübner return -ENOMEM; 882d3e51161SHeiko Stübner 883d3e51161SHeiko Stübner for (i = 0, j = 0; i < size; i += 4, j++) { 884d3e51161SHeiko Stübner const __be32 *phandle; 885d3e51161SHeiko Stübner struct device_node *np_config; 886d3e51161SHeiko Stübner 887d3e51161SHeiko Stübner num = be32_to_cpu(*list++); 888d3e51161SHeiko Stübner bank = bank_num_to_bank(info, num); 889d3e51161SHeiko Stübner if (IS_ERR(bank)) 890d3e51161SHeiko Stübner return PTR_ERR(bank); 891d3e51161SHeiko Stübner 892d3e51161SHeiko Stübner grp->pins[j] = bank->pin_base + be32_to_cpu(*list++); 893d3e51161SHeiko Stübner grp->data[j].func = be32_to_cpu(*list++); 894d3e51161SHeiko Stübner 895d3e51161SHeiko Stübner phandle = list++; 896d3e51161SHeiko Stübner if (!phandle) 897d3e51161SHeiko Stübner return -EINVAL; 898d3e51161SHeiko Stübner 899d3e51161SHeiko Stübner np_config = of_find_node_by_phandle(be32_to_cpup(phandle)); 900d3e51161SHeiko Stübner ret = pinconf_generic_parse_dt_config(np_config, 901d3e51161SHeiko Stübner &grp->data[j].configs, &grp->data[j].nconfigs); 902d3e51161SHeiko Stübner if (ret) 903d3e51161SHeiko Stübner return ret; 904d3e51161SHeiko Stübner } 905d3e51161SHeiko Stübner 906d3e51161SHeiko Stübner return 0; 907d3e51161SHeiko Stübner } 908d3e51161SHeiko Stübner 909d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_functions(struct device_node *np, 910d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 911d3e51161SHeiko Stübner u32 index) 912d3e51161SHeiko Stübner { 913d3e51161SHeiko Stübner struct device_node *child; 914d3e51161SHeiko Stübner struct rockchip_pmx_func *func; 915d3e51161SHeiko Stübner struct rockchip_pin_group *grp; 916d3e51161SHeiko Stübner int ret; 917d3e51161SHeiko Stübner static u32 grp_index; 918d3e51161SHeiko Stübner u32 i = 0; 919d3e51161SHeiko Stübner 920d3e51161SHeiko Stübner dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name); 921d3e51161SHeiko Stübner 922d3e51161SHeiko Stübner func = &info->functions[index]; 923d3e51161SHeiko Stübner 924d3e51161SHeiko Stübner /* Initialise function */ 925d3e51161SHeiko Stübner func->name = np->name; 926d3e51161SHeiko Stübner func->ngroups = of_get_child_count(np); 927d3e51161SHeiko Stübner if (func->ngroups <= 0) 928d3e51161SHeiko Stübner return 0; 929d3e51161SHeiko Stübner 930d3e51161SHeiko Stübner func->groups = devm_kzalloc(info->dev, 931d3e51161SHeiko Stübner func->ngroups * sizeof(char *), GFP_KERNEL); 932d3e51161SHeiko Stübner if (!func->groups) 933d3e51161SHeiko Stübner return -ENOMEM; 934d3e51161SHeiko Stübner 935d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 936d3e51161SHeiko Stübner func->groups[i] = child->name; 937d3e51161SHeiko Stübner grp = &info->groups[grp_index++]; 938d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_groups(child, grp, info, i++); 939d3e51161SHeiko Stübner if (ret) 940d3e51161SHeiko Stübner return ret; 941d3e51161SHeiko Stübner } 942d3e51161SHeiko Stübner 943d3e51161SHeiko Stübner return 0; 944d3e51161SHeiko Stübner } 945d3e51161SHeiko Stübner 946d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_dt(struct platform_device *pdev, 947d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 948d3e51161SHeiko Stübner { 949d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 950d3e51161SHeiko Stübner struct device_node *np = dev->of_node; 951d3e51161SHeiko Stübner struct device_node *child; 952d3e51161SHeiko Stübner int ret; 953d3e51161SHeiko Stübner int i; 954d3e51161SHeiko Stübner 955d3e51161SHeiko Stübner rockchip_pinctrl_child_count(info, np); 956d3e51161SHeiko Stübner 957d3e51161SHeiko Stübner dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); 958d3e51161SHeiko Stübner dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); 959d3e51161SHeiko Stübner 960d3e51161SHeiko Stübner info->functions = devm_kzalloc(dev, info->nfunctions * 961d3e51161SHeiko Stübner sizeof(struct rockchip_pmx_func), 962d3e51161SHeiko Stübner GFP_KERNEL); 963d3e51161SHeiko Stübner if (!info->functions) { 964d3e51161SHeiko Stübner dev_err(dev, "failed to allocate memory for function list\n"); 965d3e51161SHeiko Stübner return -EINVAL; 966d3e51161SHeiko Stübner } 967d3e51161SHeiko Stübner 968d3e51161SHeiko Stübner info->groups = devm_kzalloc(dev, info->ngroups * 969d3e51161SHeiko Stübner sizeof(struct rockchip_pin_group), 970d3e51161SHeiko Stübner GFP_KERNEL); 971d3e51161SHeiko Stübner if (!info->groups) { 972d3e51161SHeiko Stübner dev_err(dev, "failed allocate memory for ping group list\n"); 973d3e51161SHeiko Stübner return -EINVAL; 974d3e51161SHeiko Stübner } 975d3e51161SHeiko Stübner 976d3e51161SHeiko Stübner i = 0; 977d3e51161SHeiko Stübner 978d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 97965fca613SHeiko Stübner if (of_match_node(rockchip_bank_match, child)) 980d3e51161SHeiko Stübner continue; 98165fca613SHeiko Stübner 982d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_functions(child, info, i++); 983d3e51161SHeiko Stübner if (ret) { 984d3e51161SHeiko Stübner dev_err(&pdev->dev, "failed to parse function\n"); 985d3e51161SHeiko Stübner return ret; 986d3e51161SHeiko Stübner } 987d3e51161SHeiko Stübner } 988d3e51161SHeiko Stübner 989d3e51161SHeiko Stübner return 0; 990d3e51161SHeiko Stübner } 991d3e51161SHeiko Stübner 992d3e51161SHeiko Stübner static int rockchip_pinctrl_register(struct platform_device *pdev, 993d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 994d3e51161SHeiko Stübner { 995d3e51161SHeiko Stübner struct pinctrl_desc *ctrldesc = &info->pctl; 996d3e51161SHeiko Stübner struct pinctrl_pin_desc *pindesc, *pdesc; 997d3e51161SHeiko Stübner struct rockchip_pin_bank *pin_bank; 998d3e51161SHeiko Stübner int pin, bank, ret; 999d3e51161SHeiko Stübner int k; 1000d3e51161SHeiko Stübner 1001d3e51161SHeiko Stübner ctrldesc->name = "rockchip-pinctrl"; 1002d3e51161SHeiko Stübner ctrldesc->owner = THIS_MODULE; 1003d3e51161SHeiko Stübner ctrldesc->pctlops = &rockchip_pctrl_ops; 1004d3e51161SHeiko Stübner ctrldesc->pmxops = &rockchip_pmx_ops; 1005d3e51161SHeiko Stübner ctrldesc->confops = &rockchip_pinconf_ops; 1006d3e51161SHeiko Stübner 1007d3e51161SHeiko Stübner pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * 1008d3e51161SHeiko Stübner info->ctrl->nr_pins, GFP_KERNEL); 1009d3e51161SHeiko Stübner if (!pindesc) { 1010d3e51161SHeiko Stübner dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n"); 1011d3e51161SHeiko Stübner return -ENOMEM; 1012d3e51161SHeiko Stübner } 1013d3e51161SHeiko Stübner ctrldesc->pins = pindesc; 1014d3e51161SHeiko Stübner ctrldesc->npins = info->ctrl->nr_pins; 1015d3e51161SHeiko Stübner 1016d3e51161SHeiko Stübner pdesc = pindesc; 1017d3e51161SHeiko Stübner for (bank = 0 , k = 0; bank < info->ctrl->nr_banks; bank++) { 1018d3e51161SHeiko Stübner pin_bank = &info->ctrl->pin_banks[bank]; 1019d3e51161SHeiko Stübner for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) { 1020d3e51161SHeiko Stübner pdesc->number = k; 1021d3e51161SHeiko Stübner pdesc->name = kasprintf(GFP_KERNEL, "%s-%d", 1022d3e51161SHeiko Stübner pin_bank->name, pin); 1023d3e51161SHeiko Stübner pdesc++; 1024d3e51161SHeiko Stübner } 1025d3e51161SHeiko Stübner } 1026d3e51161SHeiko Stübner 1027d3e51161SHeiko Stübner info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info); 1028d3e51161SHeiko Stübner if (!info->pctl_dev) { 1029d3e51161SHeiko Stübner dev_err(&pdev->dev, "could not register pinctrl driver\n"); 1030d3e51161SHeiko Stübner return -EINVAL; 1031d3e51161SHeiko Stübner } 1032d3e51161SHeiko Stübner 1033d3e51161SHeiko Stübner for (bank = 0; bank < info->ctrl->nr_banks; ++bank) { 1034d3e51161SHeiko Stübner pin_bank = &info->ctrl->pin_banks[bank]; 1035d3e51161SHeiko Stübner pin_bank->grange.name = pin_bank->name; 1036d3e51161SHeiko Stübner pin_bank->grange.id = bank; 1037d3e51161SHeiko Stübner pin_bank->grange.pin_base = pin_bank->pin_base; 1038d3e51161SHeiko Stübner pin_bank->grange.base = pin_bank->gpio_chip.base; 1039d3e51161SHeiko Stübner pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; 1040d3e51161SHeiko Stübner pin_bank->grange.gc = &pin_bank->gpio_chip; 1041d3e51161SHeiko Stübner pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange); 1042d3e51161SHeiko Stübner } 1043d3e51161SHeiko Stübner 1044d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_dt(pdev, info); 1045d3e51161SHeiko Stübner if (ret) { 1046d3e51161SHeiko Stübner pinctrl_unregister(info->pctl_dev); 1047d3e51161SHeiko Stübner return ret; 1048d3e51161SHeiko Stübner } 1049d3e51161SHeiko Stübner 1050d3e51161SHeiko Stübner return 0; 1051d3e51161SHeiko Stübner } 1052d3e51161SHeiko Stübner 1053d3e51161SHeiko Stübner /* 1054d3e51161SHeiko Stübner * GPIO handling 1055d3e51161SHeiko Stübner */ 1056d3e51161SHeiko Stübner 10570351c287SAxel Lin static int rockchip_gpio_request(struct gpio_chip *chip, unsigned offset) 10580351c287SAxel Lin { 10590351c287SAxel Lin return pinctrl_request_gpio(chip->base + offset); 10600351c287SAxel Lin } 10610351c287SAxel Lin 10620351c287SAxel Lin static void rockchip_gpio_free(struct gpio_chip *chip, unsigned offset) 10630351c287SAxel Lin { 10640351c287SAxel Lin pinctrl_free_gpio(chip->base + offset); 10650351c287SAxel Lin } 10660351c287SAxel Lin 1067d3e51161SHeiko Stübner static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value) 1068d3e51161SHeiko Stübner { 1069d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); 1070d3e51161SHeiko Stübner void __iomem *reg = bank->reg_base + GPIO_SWPORT_DR; 1071d3e51161SHeiko Stübner unsigned long flags; 1072d3e51161SHeiko Stübner u32 data; 1073d3e51161SHeiko Stübner 1074d3e51161SHeiko Stübner spin_lock_irqsave(&bank->slock, flags); 1075d3e51161SHeiko Stübner 1076d3e51161SHeiko Stübner data = readl(reg); 1077d3e51161SHeiko Stübner data &= ~BIT(offset); 1078d3e51161SHeiko Stübner if (value) 1079d3e51161SHeiko Stübner data |= BIT(offset); 1080d3e51161SHeiko Stübner writel(data, reg); 1081d3e51161SHeiko Stübner 1082d3e51161SHeiko Stübner spin_unlock_irqrestore(&bank->slock, flags); 1083d3e51161SHeiko Stübner } 1084d3e51161SHeiko Stübner 1085d3e51161SHeiko Stübner /* 1086d3e51161SHeiko Stübner * Returns the level of the pin for input direction and setting of the DR 1087d3e51161SHeiko Stübner * register for output gpios. 1088d3e51161SHeiko Stübner */ 1089d3e51161SHeiko Stübner static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset) 1090d3e51161SHeiko Stübner { 1091d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); 1092d3e51161SHeiko Stübner u32 data; 1093d3e51161SHeiko Stübner 1094d3e51161SHeiko Stübner data = readl(bank->reg_base + GPIO_EXT_PORT); 1095d3e51161SHeiko Stübner data >>= offset; 1096d3e51161SHeiko Stübner data &= 1; 1097d3e51161SHeiko Stübner return data; 1098d3e51161SHeiko Stübner } 1099d3e51161SHeiko Stübner 1100d3e51161SHeiko Stübner /* 1101d3e51161SHeiko Stübner * gpiolib gpio_direction_input callback function. The setting of the pin 1102d3e51161SHeiko Stübner * mux function as 'gpio input' will be handled by the pinctrl susbsystem 1103d3e51161SHeiko Stübner * interface. 1104d3e51161SHeiko Stübner */ 1105d3e51161SHeiko Stübner static int rockchip_gpio_direction_input(struct gpio_chip *gc, unsigned offset) 1106d3e51161SHeiko Stübner { 1107d3e51161SHeiko Stübner return pinctrl_gpio_direction_input(gc->base + offset); 1108d3e51161SHeiko Stübner } 1109d3e51161SHeiko Stübner 1110d3e51161SHeiko Stübner /* 1111d3e51161SHeiko Stübner * gpiolib gpio_direction_output callback function. The setting of the pin 1112d3e51161SHeiko Stübner * mux function as 'gpio output' will be handled by the pinctrl susbsystem 1113d3e51161SHeiko Stübner * interface. 1114d3e51161SHeiko Stübner */ 1115d3e51161SHeiko Stübner static int rockchip_gpio_direction_output(struct gpio_chip *gc, 1116d3e51161SHeiko Stübner unsigned offset, int value) 1117d3e51161SHeiko Stübner { 1118d3e51161SHeiko Stübner rockchip_gpio_set(gc, offset, value); 1119d3e51161SHeiko Stübner return pinctrl_gpio_direction_output(gc->base + offset); 1120d3e51161SHeiko Stübner } 1121d3e51161SHeiko Stübner 1122d3e51161SHeiko Stübner /* 1123d3e51161SHeiko Stübner * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin 1124d3e51161SHeiko Stübner * and a virtual IRQ, if not already present. 1125d3e51161SHeiko Stübner */ 1126d3e51161SHeiko Stübner static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned offset) 1127d3e51161SHeiko Stübner { 1128d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); 1129d3e51161SHeiko Stübner unsigned int virq; 1130d3e51161SHeiko Stübner 1131d3e51161SHeiko Stübner if (!bank->domain) 1132d3e51161SHeiko Stübner return -ENXIO; 1133d3e51161SHeiko Stübner 1134d3e51161SHeiko Stübner virq = irq_create_mapping(bank->domain, offset); 1135d3e51161SHeiko Stübner 1136d3e51161SHeiko Stübner return (virq) ? : -ENXIO; 1137d3e51161SHeiko Stübner } 1138d3e51161SHeiko Stübner 1139d3e51161SHeiko Stübner static const struct gpio_chip rockchip_gpiolib_chip = { 11400351c287SAxel Lin .request = rockchip_gpio_request, 11410351c287SAxel Lin .free = rockchip_gpio_free, 1142d3e51161SHeiko Stübner .set = rockchip_gpio_set, 1143d3e51161SHeiko Stübner .get = rockchip_gpio_get, 1144d3e51161SHeiko Stübner .direction_input = rockchip_gpio_direction_input, 1145d3e51161SHeiko Stübner .direction_output = rockchip_gpio_direction_output, 1146d3e51161SHeiko Stübner .to_irq = rockchip_gpio_to_irq, 1147d3e51161SHeiko Stübner .owner = THIS_MODULE, 1148d3e51161SHeiko Stübner }; 1149d3e51161SHeiko Stübner 1150d3e51161SHeiko Stübner /* 1151d3e51161SHeiko Stübner * Interrupt handling 1152d3e51161SHeiko Stübner */ 1153d3e51161SHeiko Stübner 1154d3e51161SHeiko Stübner static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) 1155d3e51161SHeiko Stübner { 1156d3e51161SHeiko Stübner struct irq_chip *chip = irq_get_chip(irq); 1157d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = irq_get_handler_data(irq); 11585a927501SHeiko Stübner u32 polarity = 0, data = 0; 1159d3e51161SHeiko Stübner u32 pend; 11605a927501SHeiko Stübner bool edge_changed = false; 1161d3e51161SHeiko Stübner 1162d3e51161SHeiko Stübner dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); 1163d3e51161SHeiko Stübner 1164d3e51161SHeiko Stübner chained_irq_enter(chip, desc); 1165d3e51161SHeiko Stübner 1166d3e51161SHeiko Stübner pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); 1167d3e51161SHeiko Stübner 11685a927501SHeiko Stübner if (bank->toggle_edge_mode) { 11695a927501SHeiko Stübner polarity = readl_relaxed(bank->reg_base + 11705a927501SHeiko Stübner GPIO_INT_POLARITY); 11715a927501SHeiko Stübner data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); 11725a927501SHeiko Stübner } 11735a927501SHeiko Stübner 1174d3e51161SHeiko Stübner while (pend) { 1175d3e51161SHeiko Stübner unsigned int virq; 1176d3e51161SHeiko Stübner 1177d3e51161SHeiko Stübner irq = __ffs(pend); 1178d3e51161SHeiko Stübner pend &= ~BIT(irq); 1179d3e51161SHeiko Stübner virq = irq_linear_revmap(bank->domain, irq); 1180d3e51161SHeiko Stübner 1181d3e51161SHeiko Stübner if (!virq) { 1182d3e51161SHeiko Stübner dev_err(bank->drvdata->dev, "unmapped irq %d\n", irq); 1183d3e51161SHeiko Stübner continue; 1184d3e51161SHeiko Stübner } 1185d3e51161SHeiko Stübner 1186d3e51161SHeiko Stübner dev_dbg(bank->drvdata->dev, "handling irq %d\n", irq); 1187d3e51161SHeiko Stübner 11885a927501SHeiko Stübner /* 11895a927501SHeiko Stübner * Triggering IRQ on both rising and falling edge 11905a927501SHeiko Stübner * needs manual intervention. 11915a927501SHeiko Stübner */ 11925a927501SHeiko Stübner if (bank->toggle_edge_mode & BIT(irq)) { 11935a927501SHeiko Stübner if (data & BIT(irq)) 11945a927501SHeiko Stübner polarity &= ~BIT(irq); 11955a927501SHeiko Stübner else 11965a927501SHeiko Stübner polarity |= BIT(irq); 11975a927501SHeiko Stübner 11985a927501SHeiko Stübner edge_changed = true; 11995a927501SHeiko Stübner } 12005a927501SHeiko Stübner 1201d3e51161SHeiko Stübner generic_handle_irq(virq); 1202d3e51161SHeiko Stübner } 1203d3e51161SHeiko Stübner 12045a927501SHeiko Stübner if (bank->toggle_edge_mode && edge_changed) { 12055a927501SHeiko Stübner /* Interrupt params should only be set with ints disabled */ 12065a927501SHeiko Stübner data = readl_relaxed(bank->reg_base + GPIO_INTEN); 12075a927501SHeiko Stübner writel_relaxed(0, bank->reg_base + GPIO_INTEN); 12085a927501SHeiko Stübner writel(polarity, bank->reg_base + GPIO_INT_POLARITY); 12095a927501SHeiko Stübner writel(data, bank->reg_base + GPIO_INTEN); 12105a927501SHeiko Stübner } 12115a927501SHeiko Stübner 1212d3e51161SHeiko Stübner chained_irq_exit(chip, desc); 1213d3e51161SHeiko Stübner } 1214d3e51161SHeiko Stübner 1215d3e51161SHeiko Stübner static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) 1216d3e51161SHeiko Stübner { 1217d3e51161SHeiko Stübner struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 1218d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc->private; 1219d3e51161SHeiko Stübner u32 mask = BIT(d->hwirq); 1220d3e51161SHeiko Stübner u32 polarity; 1221d3e51161SHeiko Stübner u32 level; 1222d3e51161SHeiko Stübner u32 data; 122314797189SHeiko Stübner int ret; 1224d3e51161SHeiko Stübner 12255a927501SHeiko Stübner /* make sure the pin is configured as gpio input */ 122614797189SHeiko Stübner ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO); 122714797189SHeiko Stübner if (ret < 0) 122814797189SHeiko Stübner return ret; 122914797189SHeiko Stübner 12305a927501SHeiko Stübner data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); 12315a927501SHeiko Stübner data &= ~mask; 12325a927501SHeiko Stübner writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); 12335a927501SHeiko Stübner 1234d3e51161SHeiko Stübner if (type & IRQ_TYPE_EDGE_BOTH) 1235d3e51161SHeiko Stübner __irq_set_handler_locked(d->irq, handle_edge_irq); 1236d3e51161SHeiko Stübner else 1237d3e51161SHeiko Stübner __irq_set_handler_locked(d->irq, handle_level_irq); 1238d3e51161SHeiko Stübner 1239d3e51161SHeiko Stübner irq_gc_lock(gc); 1240d3e51161SHeiko Stübner 1241d3e51161SHeiko Stübner level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL); 1242d3e51161SHeiko Stübner polarity = readl_relaxed(gc->reg_base + GPIO_INT_POLARITY); 1243d3e51161SHeiko Stübner 1244d3e51161SHeiko Stübner switch (type) { 12455a927501SHeiko Stübner case IRQ_TYPE_EDGE_BOTH: 12465a927501SHeiko Stübner bank->toggle_edge_mode |= mask; 12475a927501SHeiko Stübner level |= mask; 12485a927501SHeiko Stübner 12495a927501SHeiko Stübner /* 12505a927501SHeiko Stübner * Determine gpio state. If 1 next interrupt should be falling 12515a927501SHeiko Stübner * otherwise rising. 12525a927501SHeiko Stübner */ 12535a927501SHeiko Stübner data = readl(bank->reg_base + GPIO_EXT_PORT); 12545a927501SHeiko Stübner if (data & mask) 12555a927501SHeiko Stübner polarity &= ~mask; 12565a927501SHeiko Stübner else 12575a927501SHeiko Stübner polarity |= mask; 12585a927501SHeiko Stübner break; 1259d3e51161SHeiko Stübner case IRQ_TYPE_EDGE_RISING: 12605a927501SHeiko Stübner bank->toggle_edge_mode &= ~mask; 1261d3e51161SHeiko Stübner level |= mask; 1262d3e51161SHeiko Stübner polarity |= mask; 1263d3e51161SHeiko Stübner break; 1264d3e51161SHeiko Stübner case IRQ_TYPE_EDGE_FALLING: 12655a927501SHeiko Stübner bank->toggle_edge_mode &= ~mask; 1266d3e51161SHeiko Stübner level |= mask; 1267d3e51161SHeiko Stübner polarity &= ~mask; 1268d3e51161SHeiko Stübner break; 1269d3e51161SHeiko Stübner case IRQ_TYPE_LEVEL_HIGH: 12705a927501SHeiko Stübner bank->toggle_edge_mode &= ~mask; 1271d3e51161SHeiko Stübner level &= ~mask; 1272d3e51161SHeiko Stübner polarity |= mask; 1273d3e51161SHeiko Stübner break; 1274d3e51161SHeiko Stübner case IRQ_TYPE_LEVEL_LOW: 12755a927501SHeiko Stübner bank->toggle_edge_mode &= ~mask; 1276d3e51161SHeiko Stübner level &= ~mask; 1277d3e51161SHeiko Stübner polarity &= ~mask; 1278d3e51161SHeiko Stübner break; 1279d3e51161SHeiko Stübner default: 12807cc5f970SAxel Lin irq_gc_unlock(gc); 1281d3e51161SHeiko Stübner return -EINVAL; 1282d3e51161SHeiko Stübner } 1283d3e51161SHeiko Stübner 1284d3e51161SHeiko Stübner writel_relaxed(level, gc->reg_base + GPIO_INTTYPE_LEVEL); 1285d3e51161SHeiko Stübner writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY); 1286d3e51161SHeiko Stübner 1287d3e51161SHeiko Stübner irq_gc_unlock(gc); 1288d3e51161SHeiko Stübner 1289d3e51161SHeiko Stübner return 0; 1290d3e51161SHeiko Stübner } 1291d3e51161SHeiko Stübner 1292d3e51161SHeiko Stübner static int rockchip_interrupts_register(struct platform_device *pdev, 1293d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 1294d3e51161SHeiko Stübner { 1295d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1296d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = ctrl->pin_banks; 1297d3e51161SHeiko Stübner unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; 1298d3e51161SHeiko Stübner struct irq_chip_generic *gc; 1299d3e51161SHeiko Stübner int ret; 1300d3e51161SHeiko Stübner int i; 1301d3e51161SHeiko Stübner 1302d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1303d3e51161SHeiko Stübner if (!bank->valid) { 1304d3e51161SHeiko Stübner dev_warn(&pdev->dev, "bank %s is not valid\n", 1305d3e51161SHeiko Stübner bank->name); 1306d3e51161SHeiko Stübner continue; 1307d3e51161SHeiko Stübner } 1308d3e51161SHeiko Stübner 1309d3e51161SHeiko Stübner bank->domain = irq_domain_add_linear(bank->of_node, 32, 1310d3e51161SHeiko Stübner &irq_generic_chip_ops, NULL); 1311d3e51161SHeiko Stübner if (!bank->domain) { 1312d3e51161SHeiko Stübner dev_warn(&pdev->dev, "could not initialize irq domain for bank %s\n", 1313d3e51161SHeiko Stübner bank->name); 1314d3e51161SHeiko Stübner continue; 1315d3e51161SHeiko Stübner } 1316d3e51161SHeiko Stübner 1317d3e51161SHeiko Stübner ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1, 1318d3e51161SHeiko Stübner "rockchip_gpio_irq", handle_level_irq, 1319d3e51161SHeiko Stübner clr, 0, IRQ_GC_INIT_MASK_CACHE); 1320d3e51161SHeiko Stübner if (ret) { 1321d3e51161SHeiko Stübner dev_err(&pdev->dev, "could not alloc generic chips for bank %s\n", 1322d3e51161SHeiko Stübner bank->name); 1323d3e51161SHeiko Stübner irq_domain_remove(bank->domain); 1324d3e51161SHeiko Stübner continue; 1325d3e51161SHeiko Stübner } 1326d3e51161SHeiko Stübner 1327d3e51161SHeiko Stübner gc = irq_get_domain_generic_chip(bank->domain, 0); 1328d3e51161SHeiko Stübner gc->reg_base = bank->reg_base; 1329d3e51161SHeiko Stübner gc->private = bank; 1330d3e51161SHeiko Stübner gc->chip_types[0].regs.mask = GPIO_INTEN; 1331d3e51161SHeiko Stübner gc->chip_types[0].regs.ack = GPIO_PORTS_EOI; 1332d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; 1333d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; 1334d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; 1335d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; 1336d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; 1337d3e51161SHeiko Stübner 1338d3e51161SHeiko Stübner irq_set_handler_data(bank->irq, bank); 1339d3e51161SHeiko Stübner irq_set_chained_handler(bank->irq, rockchip_irq_demux); 1340d3e51161SHeiko Stübner } 1341d3e51161SHeiko Stübner 1342d3e51161SHeiko Stübner return 0; 1343d3e51161SHeiko Stübner } 1344d3e51161SHeiko Stübner 1345d3e51161SHeiko Stübner static int rockchip_gpiolib_register(struct platform_device *pdev, 1346d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 1347d3e51161SHeiko Stübner { 1348d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1349d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = ctrl->pin_banks; 1350d3e51161SHeiko Stübner struct gpio_chip *gc; 1351d3e51161SHeiko Stübner int ret; 1352d3e51161SHeiko Stübner int i; 1353d3e51161SHeiko Stübner 1354d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1355d3e51161SHeiko Stübner if (!bank->valid) { 1356d3e51161SHeiko Stübner dev_warn(&pdev->dev, "bank %s is not valid\n", 1357d3e51161SHeiko Stübner bank->name); 1358d3e51161SHeiko Stübner continue; 1359d3e51161SHeiko Stübner } 1360d3e51161SHeiko Stübner 1361d3e51161SHeiko Stübner bank->gpio_chip = rockchip_gpiolib_chip; 1362d3e51161SHeiko Stübner 1363d3e51161SHeiko Stübner gc = &bank->gpio_chip; 1364d3e51161SHeiko Stübner gc->base = bank->pin_base; 1365d3e51161SHeiko Stübner gc->ngpio = bank->nr_pins; 1366d3e51161SHeiko Stübner gc->dev = &pdev->dev; 1367d3e51161SHeiko Stübner gc->of_node = bank->of_node; 1368d3e51161SHeiko Stübner gc->label = bank->name; 1369d3e51161SHeiko Stübner 1370d3e51161SHeiko Stübner ret = gpiochip_add(gc); 1371d3e51161SHeiko Stübner if (ret) { 1372d3e51161SHeiko Stübner dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n", 1373d3e51161SHeiko Stübner gc->label, ret); 1374d3e51161SHeiko Stübner goto fail; 1375d3e51161SHeiko Stübner } 1376d3e51161SHeiko Stübner } 1377d3e51161SHeiko Stübner 1378d3e51161SHeiko Stübner rockchip_interrupts_register(pdev, info); 1379d3e51161SHeiko Stübner 1380d3e51161SHeiko Stübner return 0; 1381d3e51161SHeiko Stübner 1382d3e51161SHeiko Stübner fail: 1383d3e51161SHeiko Stübner for (--i, --bank; i >= 0; --i, --bank) { 1384d3e51161SHeiko Stübner if (!bank->valid) 1385d3e51161SHeiko Stübner continue; 1386d3e51161SHeiko Stübner 1387d3e51161SHeiko Stübner if (gpiochip_remove(&bank->gpio_chip)) 1388d3e51161SHeiko Stübner dev_err(&pdev->dev, "gpio chip %s remove failed\n", 1389d3e51161SHeiko Stübner bank->gpio_chip.label); 1390d3e51161SHeiko Stübner } 1391d3e51161SHeiko Stübner return ret; 1392d3e51161SHeiko Stübner } 1393d3e51161SHeiko Stübner 1394d3e51161SHeiko Stübner static int rockchip_gpiolib_unregister(struct platform_device *pdev, 1395d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 1396d3e51161SHeiko Stübner { 1397d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1398d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = ctrl->pin_banks; 1399d3e51161SHeiko Stübner int ret = 0; 1400d3e51161SHeiko Stübner int i; 1401d3e51161SHeiko Stübner 1402d3e51161SHeiko Stübner for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) { 1403d3e51161SHeiko Stübner if (!bank->valid) 1404d3e51161SHeiko Stübner continue; 1405d3e51161SHeiko Stübner 1406d3e51161SHeiko Stübner ret = gpiochip_remove(&bank->gpio_chip); 1407d3e51161SHeiko Stübner } 1408d3e51161SHeiko Stübner 1409d3e51161SHeiko Stübner if (ret) 1410d3e51161SHeiko Stübner dev_err(&pdev->dev, "gpio chip remove failed\n"); 1411d3e51161SHeiko Stübner 1412d3e51161SHeiko Stübner return ret; 1413d3e51161SHeiko Stübner } 1414d3e51161SHeiko Stübner 1415d3e51161SHeiko Stübner static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, 1416d3e51161SHeiko Stübner struct device *dev) 1417d3e51161SHeiko Stübner { 1418d3e51161SHeiko Stübner struct resource res; 1419d3e51161SHeiko Stübner 1420d3e51161SHeiko Stübner if (of_address_to_resource(bank->of_node, 0, &res)) { 1421d3e51161SHeiko Stübner dev_err(dev, "cannot find IO resource for bank\n"); 1422d3e51161SHeiko Stübner return -ENOENT; 1423d3e51161SHeiko Stübner } 1424d3e51161SHeiko Stübner 1425d3e51161SHeiko Stübner bank->reg_base = devm_ioremap_resource(dev, &res); 1426d3e51161SHeiko Stübner if (IS_ERR(bank->reg_base)) 1427d3e51161SHeiko Stübner return PTR_ERR(bank->reg_base); 1428d3e51161SHeiko Stübner 14296ca5274dSHeiko Stübner /* 14306ca5274dSHeiko Stübner * special case, where parts of the pull setting-registers are 14316ca5274dSHeiko Stübner * part of the PMU register space 14326ca5274dSHeiko Stübner */ 14336ca5274dSHeiko Stübner if (of_device_is_compatible(bank->of_node, 14346ca5274dSHeiko Stübner "rockchip,rk3188-gpio-bank0")) { 1435*bfc7a42aSHeiko Stübner 14366ca5274dSHeiko Stübner bank->bank_type = RK3188_BANK0; 14376ca5274dSHeiko Stübner 14386ca5274dSHeiko Stübner if (of_address_to_resource(bank->of_node, 1, &res)) { 14396ca5274dSHeiko Stübner dev_err(dev, "cannot find IO resource for bank\n"); 14406ca5274dSHeiko Stübner return -ENOENT; 14416ca5274dSHeiko Stübner } 14426ca5274dSHeiko Stübner 14436ca5274dSHeiko Stübner bank->reg_pull = devm_ioremap_resource(dev, &res); 14446ca5274dSHeiko Stübner if (IS_ERR(bank->reg_pull)) 14456ca5274dSHeiko Stübner return PTR_ERR(bank->reg_pull); 14466ca5274dSHeiko Stübner } else { 144765fca613SHeiko Stübner bank->bank_type = COMMON_BANK; 14486ca5274dSHeiko Stübner } 144965fca613SHeiko Stübner 1450d3e51161SHeiko Stübner bank->irq = irq_of_parse_and_map(bank->of_node, 0); 1451d3e51161SHeiko Stübner 1452d3e51161SHeiko Stübner bank->clk = of_clk_get(bank->of_node, 0); 1453d3e51161SHeiko Stübner if (IS_ERR(bank->clk)) 1454d3e51161SHeiko Stübner return PTR_ERR(bank->clk); 1455d3e51161SHeiko Stübner 1456d3e51161SHeiko Stübner return clk_prepare_enable(bank->clk); 1457d3e51161SHeiko Stübner } 1458d3e51161SHeiko Stübner 1459d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[]; 1460d3e51161SHeiko Stübner 1461d3e51161SHeiko Stübner /* retrieve the soc specific data */ 1462d3e51161SHeiko Stübner static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( 1463d3e51161SHeiko Stübner struct rockchip_pinctrl *d, 1464d3e51161SHeiko Stübner struct platform_device *pdev) 1465d3e51161SHeiko Stübner { 1466d3e51161SHeiko Stübner const struct of_device_id *match; 1467d3e51161SHeiko Stübner struct device_node *node = pdev->dev.of_node; 1468d3e51161SHeiko Stübner struct device_node *np; 1469d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 1470d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 1471d3e51161SHeiko Stübner int i; 1472d3e51161SHeiko Stübner 1473d3e51161SHeiko Stübner match = of_match_node(rockchip_pinctrl_dt_match, node); 1474d3e51161SHeiko Stübner ctrl = (struct rockchip_pin_ctrl *)match->data; 1475d3e51161SHeiko Stübner 1476d3e51161SHeiko Stübner for_each_child_of_node(node, np) { 1477d3e51161SHeiko Stübner if (!of_find_property(np, "gpio-controller", NULL)) 1478d3e51161SHeiko Stübner continue; 1479d3e51161SHeiko Stübner 1480d3e51161SHeiko Stübner bank = ctrl->pin_banks; 1481d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1482d3e51161SHeiko Stübner if (!strcmp(bank->name, np->name)) { 1483d3e51161SHeiko Stübner bank->of_node = np; 1484d3e51161SHeiko Stübner 1485d3e51161SHeiko Stübner if (!rockchip_get_bank_data(bank, &pdev->dev)) 1486d3e51161SHeiko Stübner bank->valid = true; 1487d3e51161SHeiko Stübner 1488d3e51161SHeiko Stübner break; 1489d3e51161SHeiko Stübner } 1490d3e51161SHeiko Stübner } 1491d3e51161SHeiko Stübner } 1492d3e51161SHeiko Stübner 1493d3e51161SHeiko Stübner bank = ctrl->pin_banks; 1494d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1495d3e51161SHeiko Stübner spin_lock_init(&bank->slock); 1496d3e51161SHeiko Stübner bank->drvdata = d; 1497d3e51161SHeiko Stübner bank->pin_base = ctrl->nr_pins; 1498d3e51161SHeiko Stübner ctrl->nr_pins += bank->nr_pins; 1499d3e51161SHeiko Stübner } 1500d3e51161SHeiko Stübner 1501d3e51161SHeiko Stübner return ctrl; 1502d3e51161SHeiko Stübner } 1503d3e51161SHeiko Stübner 1504d3e51161SHeiko Stübner static int rockchip_pinctrl_probe(struct platform_device *pdev) 1505d3e51161SHeiko Stübner { 1506d3e51161SHeiko Stübner struct rockchip_pinctrl *info; 1507d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 1508d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 1509d3e51161SHeiko Stübner struct resource *res; 1510d3e51161SHeiko Stübner int ret; 1511d3e51161SHeiko Stübner 1512d3e51161SHeiko Stübner if (!dev->of_node) { 1513d3e51161SHeiko Stübner dev_err(dev, "device tree node not found\n"); 1514d3e51161SHeiko Stübner return -ENODEV; 1515d3e51161SHeiko Stübner } 1516d3e51161SHeiko Stübner 1517d3e51161SHeiko Stübner info = devm_kzalloc(dev, sizeof(struct rockchip_pinctrl), GFP_KERNEL); 1518d3e51161SHeiko Stübner if (!info) 1519d3e51161SHeiko Stübner return -ENOMEM; 1520d3e51161SHeiko Stübner 1521d3e51161SHeiko Stübner ctrl = rockchip_pinctrl_get_soc_data(info, pdev); 1522d3e51161SHeiko Stübner if (!ctrl) { 1523d3e51161SHeiko Stübner dev_err(dev, "driver data not available\n"); 1524d3e51161SHeiko Stübner return -EINVAL; 1525d3e51161SHeiko Stübner } 1526d3e51161SHeiko Stübner info->ctrl = ctrl; 1527d3e51161SHeiko Stübner info->dev = dev; 1528d3e51161SHeiko Stübner 1529d3e51161SHeiko Stübner res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1530d3e51161SHeiko Stübner info->reg_base = devm_ioremap_resource(&pdev->dev, res); 1531d3e51161SHeiko Stübner if (IS_ERR(info->reg_base)) 1532d3e51161SHeiko Stübner return PTR_ERR(info->reg_base); 1533d3e51161SHeiko Stübner 1534*bfc7a42aSHeiko Stübner /* to check for the old dt-bindings */ 1535*bfc7a42aSHeiko Stübner info->reg_size = resource_size(res); 1536*bfc7a42aSHeiko Stübner 1537*bfc7a42aSHeiko Stübner /* Honor the old binding, with pull registers as 2nd resource */ 1538*bfc7a42aSHeiko Stübner if (ctrl->type == RK3188 && info->reg_size < 0x200) { 15396ca5274dSHeiko Stübner res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 15406ca5274dSHeiko Stübner info->reg_pull = devm_ioremap_resource(&pdev->dev, res); 154138d321c8SDan Carpenter if (IS_ERR(info->reg_pull)) 154238d321c8SDan Carpenter return PTR_ERR(info->reg_pull); 15436ca5274dSHeiko Stübner } 15446ca5274dSHeiko Stübner 1545d3e51161SHeiko Stübner ret = rockchip_gpiolib_register(pdev, info); 1546d3e51161SHeiko Stübner if (ret) 1547d3e51161SHeiko Stübner return ret; 1548d3e51161SHeiko Stübner 1549d3e51161SHeiko Stübner ret = rockchip_pinctrl_register(pdev, info); 1550d3e51161SHeiko Stübner if (ret) { 1551d3e51161SHeiko Stübner rockchip_gpiolib_unregister(pdev, info); 1552d3e51161SHeiko Stübner return ret; 1553d3e51161SHeiko Stübner } 1554d3e51161SHeiko Stübner 1555d3e51161SHeiko Stübner platform_set_drvdata(pdev, info); 1556d3e51161SHeiko Stübner 1557d3e51161SHeiko Stübner return 0; 1558d3e51161SHeiko Stübner } 1559d3e51161SHeiko Stübner 1560d3e51161SHeiko Stübner static struct rockchip_pin_bank rk2928_pin_banks[] = { 1561d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 1562d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1563d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1564d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1565d3e51161SHeiko Stübner }; 1566d3e51161SHeiko Stübner 1567d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk2928_pin_ctrl = { 1568d3e51161SHeiko Stübner .pin_banks = rk2928_pin_banks, 1569d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk2928_pin_banks), 1570d3e51161SHeiko Stübner .label = "RK2928-GPIO", 1571a282926dSHeiko Stübner .type = RK2928, 1572d3e51161SHeiko Stübner .mux_offset = 0xa8, 1573a282926dSHeiko Stübner .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 1574d3e51161SHeiko Stübner }; 1575d3e51161SHeiko Stübner 1576d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066a_pin_banks[] = { 1577d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 1578d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1579d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1580d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1581d3e51161SHeiko Stübner PIN_BANK(4, 32, "gpio4"), 1582d3e51161SHeiko Stübner PIN_BANK(6, 16, "gpio6"), 1583d3e51161SHeiko Stübner }; 1584d3e51161SHeiko Stübner 1585d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { 1586d3e51161SHeiko Stübner .pin_banks = rk3066a_pin_banks, 1587d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), 1588d3e51161SHeiko Stübner .label = "RK3066a-GPIO", 1589a282926dSHeiko Stübner .type = RK2928, 1590d3e51161SHeiko Stübner .mux_offset = 0xa8, 1591a282926dSHeiko Stübner .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 1592d3e51161SHeiko Stübner }; 1593d3e51161SHeiko Stübner 1594d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066b_pin_banks[] = { 1595d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 1596d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1597d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1598d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1599d3e51161SHeiko Stübner }; 1600d3e51161SHeiko Stübner 1601d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { 1602d3e51161SHeiko Stübner .pin_banks = rk3066b_pin_banks, 1603d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), 1604d3e51161SHeiko Stübner .label = "RK3066b-GPIO", 1605a282926dSHeiko Stübner .type = RK3066B, 1606d3e51161SHeiko Stübner .mux_offset = 0x60, 1607d3e51161SHeiko Stübner }; 1608d3e51161SHeiko Stübner 1609d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3188_pin_banks[] = { 1610d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 1611d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1612d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1613d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1614d3e51161SHeiko Stübner }; 1615d3e51161SHeiko Stübner 1616d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3188_pin_ctrl = { 1617d3e51161SHeiko Stübner .pin_banks = rk3188_pin_banks, 1618d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3188_pin_banks), 1619d3e51161SHeiko Stübner .label = "RK3188-GPIO", 1620a282926dSHeiko Stübner .type = RK3188, 162122c0d7e3SBeniamino Galvani .mux_offset = 0x60, 16226ca5274dSHeiko Stübner .pull_calc_reg = rk3188_calc_pull_reg_and_bit, 1623d3e51161SHeiko Stübner }; 1624d3e51161SHeiko Stübner 1625d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[] = { 1626d3e51161SHeiko Stübner { .compatible = "rockchip,rk2928-pinctrl", 1627d3e51161SHeiko Stübner .data = (void *)&rk2928_pin_ctrl }, 1628d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066a-pinctrl", 1629d3e51161SHeiko Stübner .data = (void *)&rk3066a_pin_ctrl }, 1630d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066b-pinctrl", 1631d3e51161SHeiko Stübner .data = (void *)&rk3066b_pin_ctrl }, 1632d3e51161SHeiko Stübner { .compatible = "rockchip,rk3188-pinctrl", 1633d3e51161SHeiko Stübner .data = (void *)&rk3188_pin_ctrl }, 1634d3e51161SHeiko Stübner {}, 1635d3e51161SHeiko Stübner }; 1636d3e51161SHeiko Stübner MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); 1637d3e51161SHeiko Stübner 1638d3e51161SHeiko Stübner static struct platform_driver rockchip_pinctrl_driver = { 1639d3e51161SHeiko Stübner .probe = rockchip_pinctrl_probe, 1640d3e51161SHeiko Stübner .driver = { 1641d3e51161SHeiko Stübner .name = "rockchip-pinctrl", 1642d3e51161SHeiko Stübner .owner = THIS_MODULE, 16430be9e70dSAxel Lin .of_match_table = rockchip_pinctrl_dt_match, 1644d3e51161SHeiko Stübner }, 1645d3e51161SHeiko Stübner }; 1646d3e51161SHeiko Stübner 1647d3e51161SHeiko Stübner static int __init rockchip_pinctrl_drv_register(void) 1648d3e51161SHeiko Stübner { 1649d3e51161SHeiko Stübner return platform_driver_register(&rockchip_pinctrl_driver); 1650d3e51161SHeiko Stübner } 1651d3e51161SHeiko Stübner postcore_initcall(rockchip_pinctrl_drv_register); 1652d3e51161SHeiko Stübner 1653d3e51161SHeiko Stübner MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 1654d3e51161SHeiko Stübner MODULE_DESCRIPTION("Rockchip pinctrl driver"); 1655d3e51161SHeiko Stübner MODULE_LICENSE("GPL v2"); 1656