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> 39*7e865abbSHeiko 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 59d3e51161SHeiko Stübner /** 60d3e51161SHeiko Stübner * @reg_base: register base of the gpio bank 61d3e51161SHeiko Stübner * @clk: clock of the gpio bank 62d3e51161SHeiko Stübner * @irq: interrupt of the gpio bank 63d3e51161SHeiko Stübner * @pin_base: first pin number 64d3e51161SHeiko Stübner * @nr_pins: number of pins in this bank 65d3e51161SHeiko Stübner * @name: name of the bank 66d3e51161SHeiko Stübner * @bank_num: number of the bank, to account for holes 67d3e51161SHeiko Stübner * @valid: are all necessary informations present 68d3e51161SHeiko Stübner * @of_node: dt node of this bank 69d3e51161SHeiko Stübner * @drvdata: common pinctrl basedata 70d3e51161SHeiko Stübner * @domain: irqdomain of the gpio bank 71d3e51161SHeiko Stübner * @gpio_chip: gpiolib chip 72d3e51161SHeiko Stübner * @grange: gpio range 73d3e51161SHeiko Stübner * @slock: spinlock for the gpio bank 74d3e51161SHeiko Stübner */ 75d3e51161SHeiko Stübner struct rockchip_pin_bank { 76d3e51161SHeiko Stübner void __iomem *reg_base; 77d3e51161SHeiko Stübner struct clk *clk; 78d3e51161SHeiko Stübner int irq; 79d3e51161SHeiko Stübner u32 pin_base; 80d3e51161SHeiko Stübner u8 nr_pins; 81d3e51161SHeiko Stübner char *name; 82d3e51161SHeiko Stübner u8 bank_num; 83d3e51161SHeiko Stübner bool valid; 84d3e51161SHeiko Stübner struct device_node *of_node; 85d3e51161SHeiko Stübner struct rockchip_pinctrl *drvdata; 86d3e51161SHeiko Stübner struct irq_domain *domain; 87d3e51161SHeiko Stübner struct gpio_chip gpio_chip; 88d3e51161SHeiko Stübner struct pinctrl_gpio_range grange; 89d3e51161SHeiko Stübner spinlock_t slock; 90d3e51161SHeiko Stübner 91d3e51161SHeiko Stübner }; 92d3e51161SHeiko Stübner 93d3e51161SHeiko Stübner #define PIN_BANK(id, pins, label) \ 94d3e51161SHeiko Stübner { \ 95d3e51161SHeiko Stübner .bank_num = id, \ 96d3e51161SHeiko Stübner .nr_pins = pins, \ 97d3e51161SHeiko Stübner .name = label, \ 98d3e51161SHeiko Stübner } 99d3e51161SHeiko Stübner 100d3e51161SHeiko Stübner /** 101d3e51161SHeiko Stübner * @pull_auto: some SoCs don't allow pulls to be specified as up or down, but 102d3e51161SHeiko Stübner * instead decide this automatically based on the pad-type. 103d3e51161SHeiko Stübner */ 104d3e51161SHeiko Stübner struct rockchip_pin_ctrl { 105d3e51161SHeiko Stübner struct rockchip_pin_bank *pin_banks; 106d3e51161SHeiko Stübner u32 nr_banks; 107d3e51161SHeiko Stübner u32 nr_pins; 108d3e51161SHeiko Stübner char *label; 109d3e51161SHeiko Stübner int mux_offset; 110d3e51161SHeiko Stübner int pull_offset; 111d3e51161SHeiko Stübner bool pull_auto; 112d3e51161SHeiko Stübner int pull_bank_stride; 113d3e51161SHeiko Stübner }; 114d3e51161SHeiko Stübner 115d3e51161SHeiko Stübner struct rockchip_pin_config { 116d3e51161SHeiko Stübner unsigned int func; 117d3e51161SHeiko Stübner unsigned long *configs; 118d3e51161SHeiko Stübner unsigned int nconfigs; 119d3e51161SHeiko Stübner }; 120d3e51161SHeiko Stübner 121d3e51161SHeiko Stübner /** 122d3e51161SHeiko Stübner * struct rockchip_pin_group: represent group of pins of a pinmux function. 123d3e51161SHeiko Stübner * @name: name of the pin group, used to lookup the group. 124d3e51161SHeiko Stübner * @pins: the pins included in this group. 125d3e51161SHeiko Stübner * @npins: number of pins included in this group. 126d3e51161SHeiko Stübner * @func: the mux function number to be programmed when selected. 127d3e51161SHeiko Stübner * @configs: the config values to be set for each pin 128d3e51161SHeiko Stübner * @nconfigs: number of configs for each pin 129d3e51161SHeiko Stübner */ 130d3e51161SHeiko Stübner struct rockchip_pin_group { 131d3e51161SHeiko Stübner const char *name; 132d3e51161SHeiko Stübner unsigned int npins; 133d3e51161SHeiko Stübner unsigned int *pins; 134d3e51161SHeiko Stübner struct rockchip_pin_config *data; 135d3e51161SHeiko Stübner }; 136d3e51161SHeiko Stübner 137d3e51161SHeiko Stübner /** 138d3e51161SHeiko Stübner * struct rockchip_pmx_func: represent a pin function. 139d3e51161SHeiko Stübner * @name: name of the pin function, used to lookup the function. 140d3e51161SHeiko Stübner * @groups: one or more names of pin groups that provide this function. 141d3e51161SHeiko Stübner * @num_groups: number of groups included in @groups. 142d3e51161SHeiko Stübner */ 143d3e51161SHeiko Stübner struct rockchip_pmx_func { 144d3e51161SHeiko Stübner const char *name; 145d3e51161SHeiko Stübner const char **groups; 146d3e51161SHeiko Stübner u8 ngroups; 147d3e51161SHeiko Stübner }; 148d3e51161SHeiko Stübner 149d3e51161SHeiko Stübner struct rockchip_pinctrl { 150d3e51161SHeiko Stübner void __iomem *reg_base; 151d3e51161SHeiko Stübner struct device *dev; 152d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 153d3e51161SHeiko Stübner struct pinctrl_desc pctl; 154d3e51161SHeiko Stübner struct pinctrl_dev *pctl_dev; 155d3e51161SHeiko Stübner struct rockchip_pin_group *groups; 156d3e51161SHeiko Stübner unsigned int ngroups; 157d3e51161SHeiko Stübner struct rockchip_pmx_func *functions; 158d3e51161SHeiko Stübner unsigned int nfunctions; 159d3e51161SHeiko Stübner }; 160d3e51161SHeiko Stübner 161d3e51161SHeiko Stübner static inline struct rockchip_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) 162d3e51161SHeiko Stübner { 163d3e51161SHeiko Stübner return container_of(gc, struct rockchip_pin_bank, gpio_chip); 164d3e51161SHeiko Stübner } 165d3e51161SHeiko Stübner 166d3e51161SHeiko Stübner static const inline struct rockchip_pin_group *pinctrl_name_to_group( 167d3e51161SHeiko Stübner const struct rockchip_pinctrl *info, 168d3e51161SHeiko Stübner const char *name) 169d3e51161SHeiko Stübner { 170d3e51161SHeiko Stübner const struct rockchip_pin_group *grp = NULL; 171d3e51161SHeiko Stübner int i; 172d3e51161SHeiko Stübner 173d3e51161SHeiko Stübner for (i = 0; i < info->ngroups; i++) { 174d3e51161SHeiko Stübner if (strcmp(info->groups[i].name, name)) 175d3e51161SHeiko Stübner continue; 176d3e51161SHeiko Stübner 177d3e51161SHeiko Stübner grp = &info->groups[i]; 178d3e51161SHeiko Stübner break; 179d3e51161SHeiko Stübner } 180d3e51161SHeiko Stübner 181d3e51161SHeiko Stübner return grp; 182d3e51161SHeiko Stübner } 183d3e51161SHeiko Stübner 184d3e51161SHeiko Stübner /* 185d3e51161SHeiko Stübner * given a pin number that is local to a pin controller, find out the pin bank 186d3e51161SHeiko Stübner * and the register base of the pin bank. 187d3e51161SHeiko Stübner */ 188d3e51161SHeiko Stübner static struct rockchip_pin_bank *pin_to_bank(struct rockchip_pinctrl *info, 189d3e51161SHeiko Stübner unsigned pin) 190d3e51161SHeiko Stübner { 191d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 192d3e51161SHeiko Stübner 193d3e51161SHeiko Stübner while ((pin >= b->pin_base) && 194d3e51161SHeiko Stübner ((b->pin_base + b->nr_pins - 1) < pin)) 195d3e51161SHeiko Stübner b++; 196d3e51161SHeiko Stübner 197d3e51161SHeiko Stübner return b; 198d3e51161SHeiko Stübner } 199d3e51161SHeiko Stübner 200d3e51161SHeiko Stübner static struct rockchip_pin_bank *bank_num_to_bank( 201d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 202d3e51161SHeiko Stübner unsigned num) 203d3e51161SHeiko Stübner { 204d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 205d3e51161SHeiko Stübner int i; 206d3e51161SHeiko Stübner 207d3e51161SHeiko Stübner for (i = 0; i < info->ctrl->nr_banks; i++) { 208d3e51161SHeiko Stübner if (b->bank_num == num) 209d3e51161SHeiko Stübner break; 210d3e51161SHeiko Stübner 211d3e51161SHeiko Stübner b++; 212d3e51161SHeiko Stübner } 213d3e51161SHeiko Stübner 214d3e51161SHeiko Stübner if (b->bank_num != num) 215d3e51161SHeiko Stübner return ERR_PTR(-EINVAL); 216d3e51161SHeiko Stübner 217d3e51161SHeiko Stübner return b; 218d3e51161SHeiko Stübner } 219d3e51161SHeiko Stübner 220d3e51161SHeiko Stübner /* 221d3e51161SHeiko Stübner * Pinctrl_ops handling 222d3e51161SHeiko Stübner */ 223d3e51161SHeiko Stübner 224d3e51161SHeiko Stübner static int rockchip_get_groups_count(struct pinctrl_dev *pctldev) 225d3e51161SHeiko Stübner { 226d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 227d3e51161SHeiko Stübner 228d3e51161SHeiko Stübner return info->ngroups; 229d3e51161SHeiko Stübner } 230d3e51161SHeiko Stübner 231d3e51161SHeiko Stübner static const char *rockchip_get_group_name(struct pinctrl_dev *pctldev, 232d3e51161SHeiko Stübner unsigned selector) 233d3e51161SHeiko Stübner { 234d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 235d3e51161SHeiko Stübner 236d3e51161SHeiko Stübner return info->groups[selector].name; 237d3e51161SHeiko Stübner } 238d3e51161SHeiko Stübner 239d3e51161SHeiko Stübner static int rockchip_get_group_pins(struct pinctrl_dev *pctldev, 240d3e51161SHeiko Stübner unsigned selector, const unsigned **pins, 241d3e51161SHeiko Stübner unsigned *npins) 242d3e51161SHeiko Stübner { 243d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 244d3e51161SHeiko Stübner 245d3e51161SHeiko Stübner if (selector >= info->ngroups) 246d3e51161SHeiko Stübner return -EINVAL; 247d3e51161SHeiko Stübner 248d3e51161SHeiko Stübner *pins = info->groups[selector].pins; 249d3e51161SHeiko Stübner *npins = info->groups[selector].npins; 250d3e51161SHeiko Stübner 251d3e51161SHeiko Stübner return 0; 252d3e51161SHeiko Stübner } 253d3e51161SHeiko Stübner 254d3e51161SHeiko Stübner static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev, 255d3e51161SHeiko Stübner struct device_node *np, 256d3e51161SHeiko Stübner struct pinctrl_map **map, unsigned *num_maps) 257d3e51161SHeiko Stübner { 258d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 259d3e51161SHeiko Stübner const struct rockchip_pin_group *grp; 260d3e51161SHeiko Stübner struct pinctrl_map *new_map; 261d3e51161SHeiko Stübner struct device_node *parent; 262d3e51161SHeiko Stübner int map_num = 1; 263d3e51161SHeiko Stübner int i; 264d3e51161SHeiko Stübner 265d3e51161SHeiko Stübner /* 266d3e51161SHeiko Stübner * first find the group of this node and check if we need to create 267d3e51161SHeiko Stübner * config maps for pins 268d3e51161SHeiko Stübner */ 269d3e51161SHeiko Stübner grp = pinctrl_name_to_group(info, np->name); 270d3e51161SHeiko Stübner if (!grp) { 271d3e51161SHeiko Stübner dev_err(info->dev, "unable to find group for node %s\n", 272d3e51161SHeiko Stübner np->name); 273d3e51161SHeiko Stübner return -EINVAL; 274d3e51161SHeiko Stübner } 275d3e51161SHeiko Stübner 276d3e51161SHeiko Stübner map_num += grp->npins; 277d3e51161SHeiko Stübner new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num, 278d3e51161SHeiko Stübner GFP_KERNEL); 279d3e51161SHeiko Stübner if (!new_map) 280d3e51161SHeiko Stübner return -ENOMEM; 281d3e51161SHeiko Stübner 282d3e51161SHeiko Stübner *map = new_map; 283d3e51161SHeiko Stübner *num_maps = map_num; 284d3e51161SHeiko Stübner 285d3e51161SHeiko Stübner /* create mux map */ 286d3e51161SHeiko Stübner parent = of_get_parent(np); 287d3e51161SHeiko Stübner if (!parent) { 288d3e51161SHeiko Stübner devm_kfree(pctldev->dev, new_map); 289d3e51161SHeiko Stübner return -EINVAL; 290d3e51161SHeiko Stübner } 291d3e51161SHeiko Stübner new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; 292d3e51161SHeiko Stübner new_map[0].data.mux.function = parent->name; 293d3e51161SHeiko Stübner new_map[0].data.mux.group = np->name; 294d3e51161SHeiko Stübner of_node_put(parent); 295d3e51161SHeiko Stübner 296d3e51161SHeiko Stübner /* create config map */ 297d3e51161SHeiko Stübner new_map++; 298d3e51161SHeiko Stübner for (i = 0; i < grp->npins; i++) { 299d3e51161SHeiko Stübner new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; 300d3e51161SHeiko Stübner new_map[i].data.configs.group_or_pin = 301d3e51161SHeiko Stübner pin_get_name(pctldev, grp->pins[i]); 302d3e51161SHeiko Stübner new_map[i].data.configs.configs = grp->data[i].configs; 303d3e51161SHeiko Stübner new_map[i].data.configs.num_configs = grp->data[i].nconfigs; 304d3e51161SHeiko Stübner } 305d3e51161SHeiko Stübner 306d3e51161SHeiko Stübner dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", 307d3e51161SHeiko Stübner (*map)->data.mux.function, (*map)->data.mux.group, map_num); 308d3e51161SHeiko Stübner 309d3e51161SHeiko Stübner return 0; 310d3e51161SHeiko Stübner } 311d3e51161SHeiko Stübner 312d3e51161SHeiko Stübner static void rockchip_dt_free_map(struct pinctrl_dev *pctldev, 313d3e51161SHeiko Stübner struct pinctrl_map *map, unsigned num_maps) 314d3e51161SHeiko Stübner { 315d3e51161SHeiko Stübner } 316d3e51161SHeiko Stübner 317d3e51161SHeiko Stübner static const struct pinctrl_ops rockchip_pctrl_ops = { 318d3e51161SHeiko Stübner .get_groups_count = rockchip_get_groups_count, 319d3e51161SHeiko Stübner .get_group_name = rockchip_get_group_name, 320d3e51161SHeiko Stübner .get_group_pins = rockchip_get_group_pins, 321d3e51161SHeiko Stübner .dt_node_to_map = rockchip_dt_node_to_map, 322d3e51161SHeiko Stübner .dt_free_map = rockchip_dt_free_map, 323d3e51161SHeiko Stübner }; 324d3e51161SHeiko Stübner 325d3e51161SHeiko Stübner /* 326d3e51161SHeiko Stübner * Hardware access 327d3e51161SHeiko Stübner */ 328d3e51161SHeiko Stübner 329d3e51161SHeiko Stübner /* 330d3e51161SHeiko Stübner * Set a new mux function for a pin. 331d3e51161SHeiko Stübner * 332d3e51161SHeiko Stübner * The register is divided into the upper and lower 16 bit. When changing 333d3e51161SHeiko Stübner * a value, the previous register value is not read and changed. Instead 334d3e51161SHeiko Stübner * it seems the changed bits are marked in the upper 16 bit, while the 335d3e51161SHeiko Stübner * changed value gets set in the same offset in the lower 16 bit. 336d3e51161SHeiko Stübner * All pin settings seem to be 2 bit wide in both the upper and lower 337d3e51161SHeiko Stübner * parts. 338d3e51161SHeiko Stübner * @bank: pin bank to change 339d3e51161SHeiko Stübner * @pin: pin to change 340d3e51161SHeiko Stübner * @mux: new mux function to set 341d3e51161SHeiko Stübner */ 342d3e51161SHeiko Stübner static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 343d3e51161SHeiko Stübner { 344d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 345d3e51161SHeiko Stübner void __iomem *reg = info->reg_base + info->ctrl->mux_offset; 346d3e51161SHeiko Stübner unsigned long flags; 347d3e51161SHeiko Stübner u8 bit; 348d3e51161SHeiko Stübner u32 data; 349d3e51161SHeiko Stübner 350d3e51161SHeiko Stübner dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n", 351d3e51161SHeiko Stübner bank->bank_num, pin, mux); 352d3e51161SHeiko Stübner 353d3e51161SHeiko Stübner /* get basic quadrupel of mux registers and the correct reg inside */ 354d3e51161SHeiko Stübner reg += bank->bank_num * 0x10; 355d3e51161SHeiko Stübner reg += (pin / 8) * 4; 356d3e51161SHeiko Stübner bit = (pin % 8) * 2; 357d3e51161SHeiko Stübner 358d3e51161SHeiko Stübner spin_lock_irqsave(&bank->slock, flags); 359d3e51161SHeiko Stübner 360d3e51161SHeiko Stübner data = (3 << (bit + 16)); 361d3e51161SHeiko Stübner data |= (mux & 3) << bit; 362d3e51161SHeiko Stübner writel(data, reg); 363d3e51161SHeiko Stübner 364d3e51161SHeiko Stübner spin_unlock_irqrestore(&bank->slock, flags); 365d3e51161SHeiko Stübner } 366d3e51161SHeiko Stübner 367d3e51161SHeiko Stübner static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) 368d3e51161SHeiko Stübner { 369d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 370d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 371d3e51161SHeiko Stübner void __iomem *reg; 372d3e51161SHeiko Stübner u8 bit; 373d3e51161SHeiko Stübner 374d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 375d3e51161SHeiko Stübner if (!ctrl->pull_offset) 376d3e51161SHeiko Stübner return PIN_CONFIG_BIAS_DISABLE; 377d3e51161SHeiko Stübner 378d3e51161SHeiko Stübner reg = info->reg_base + ctrl->pull_offset; 379d3e51161SHeiko Stübner 380d3e51161SHeiko Stübner if (ctrl->pull_auto) { 381d3e51161SHeiko Stübner reg += bank->bank_num * ctrl->pull_bank_stride; 382d3e51161SHeiko Stübner reg += (pin_num / 16) * 4; 383d3e51161SHeiko Stübner bit = pin_num % 16; 384d3e51161SHeiko Stübner 385d3e51161SHeiko Stübner return !(readl_relaxed(reg) & BIT(bit)) 386d3e51161SHeiko Stübner ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT 387d3e51161SHeiko Stübner : PIN_CONFIG_BIAS_DISABLE; 388d3e51161SHeiko Stübner } else { 389d3e51161SHeiko Stübner dev_err(info->dev, "pull support for rk31xx not implemented\n"); 390d3e51161SHeiko Stübner return -EIO; 391d3e51161SHeiko Stübner } 392d3e51161SHeiko Stübner } 393d3e51161SHeiko Stübner 394d3e51161SHeiko Stübner static int rockchip_set_pull(struct rockchip_pin_bank *bank, 395d3e51161SHeiko Stübner int pin_num, int pull) 396d3e51161SHeiko Stübner { 397d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 398d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 399d3e51161SHeiko Stübner void __iomem *reg; 400d3e51161SHeiko Stübner unsigned long flags; 401d3e51161SHeiko Stübner u8 bit; 402d3e51161SHeiko Stübner u32 data; 403d3e51161SHeiko Stübner 404d3e51161SHeiko Stübner dev_dbg(info->dev, "setting pull of GPIO%d-%d to %d\n", 405d3e51161SHeiko Stübner bank->bank_num, pin_num, pull); 406d3e51161SHeiko Stübner 407d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 408d3e51161SHeiko Stübner if (!ctrl->pull_offset) 409d3e51161SHeiko Stübner return pull ? -EINVAL : 0; 410d3e51161SHeiko Stübner 411d3e51161SHeiko Stübner reg = info->reg_base + ctrl->pull_offset; 412d3e51161SHeiko Stübner 413d3e51161SHeiko Stübner if (ctrl->pull_auto) { 414d3e51161SHeiko Stübner if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT && 415d3e51161SHeiko Stübner pull != PIN_CONFIG_BIAS_DISABLE) { 416d3e51161SHeiko Stübner dev_err(info->dev, "only PIN_DEFAULT and DISABLE allowed\n"); 417d3e51161SHeiko Stübner return -EINVAL; 418d3e51161SHeiko Stübner } 419d3e51161SHeiko Stübner 420d3e51161SHeiko Stübner reg += bank->bank_num * ctrl->pull_bank_stride; 421d3e51161SHeiko Stübner reg += (pin_num / 16) * 4; 422d3e51161SHeiko Stübner bit = pin_num % 16; 423d3e51161SHeiko Stübner 424d3e51161SHeiko Stübner spin_lock_irqsave(&bank->slock, flags); 425d3e51161SHeiko Stübner 426d3e51161SHeiko Stübner data = BIT(bit + 16); 427d3e51161SHeiko Stübner if (pull == PIN_CONFIG_BIAS_DISABLE) 428d3e51161SHeiko Stübner data |= BIT(bit); 429d3e51161SHeiko Stübner writel(data, reg); 430d3e51161SHeiko Stübner 431d3e51161SHeiko Stübner spin_unlock_irqrestore(&bank->slock, flags); 432d3e51161SHeiko Stübner } else { 433d3e51161SHeiko Stübner if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) { 434d3e51161SHeiko Stübner dev_err(info->dev, "pull direction (up/down) needs to be specified\n"); 435d3e51161SHeiko Stübner return -EINVAL; 436d3e51161SHeiko Stübner } 437d3e51161SHeiko Stübner 438d3e51161SHeiko Stübner dev_err(info->dev, "pull support for rk31xx not implemented\n"); 439d3e51161SHeiko Stübner return -EIO; 440d3e51161SHeiko Stübner } 441d3e51161SHeiko Stübner 442d3e51161SHeiko Stübner return 0; 443d3e51161SHeiko Stübner } 444d3e51161SHeiko Stübner 445d3e51161SHeiko Stübner /* 446d3e51161SHeiko Stübner * Pinmux_ops handling 447d3e51161SHeiko Stübner */ 448d3e51161SHeiko Stübner 449d3e51161SHeiko Stübner static int rockchip_pmx_get_funcs_count(struct pinctrl_dev *pctldev) 450d3e51161SHeiko Stübner { 451d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 452d3e51161SHeiko Stübner 453d3e51161SHeiko Stübner return info->nfunctions; 454d3e51161SHeiko Stübner } 455d3e51161SHeiko Stübner 456d3e51161SHeiko Stübner static const char *rockchip_pmx_get_func_name(struct pinctrl_dev *pctldev, 457d3e51161SHeiko Stübner unsigned selector) 458d3e51161SHeiko Stübner { 459d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 460d3e51161SHeiko Stübner 461d3e51161SHeiko Stübner return info->functions[selector].name; 462d3e51161SHeiko Stübner } 463d3e51161SHeiko Stübner 464d3e51161SHeiko Stübner static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev, 465d3e51161SHeiko Stübner unsigned selector, const char * const **groups, 466d3e51161SHeiko Stübner unsigned * const num_groups) 467d3e51161SHeiko Stübner { 468d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 469d3e51161SHeiko Stübner 470d3e51161SHeiko Stübner *groups = info->functions[selector].groups; 471d3e51161SHeiko Stübner *num_groups = info->functions[selector].ngroups; 472d3e51161SHeiko Stübner 473d3e51161SHeiko Stübner return 0; 474d3e51161SHeiko Stübner } 475d3e51161SHeiko Stübner 476d3e51161SHeiko Stübner static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, 477d3e51161SHeiko Stübner unsigned group) 478d3e51161SHeiko Stübner { 479d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 480d3e51161SHeiko Stübner const unsigned int *pins = info->groups[group].pins; 481d3e51161SHeiko Stübner const struct rockchip_pin_config *data = info->groups[group].data; 482d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 483d3e51161SHeiko Stübner int cnt; 484d3e51161SHeiko Stübner 485d3e51161SHeiko Stübner dev_dbg(info->dev, "enable function %s group %s\n", 486d3e51161SHeiko Stübner info->functions[selector].name, info->groups[group].name); 487d3e51161SHeiko Stübner 488d3e51161SHeiko Stübner /* 489d3e51161SHeiko Stübner * for each pin in the pin group selected, program the correspoding pin 490d3e51161SHeiko Stübner * pin function number in the config register. 491d3e51161SHeiko Stübner */ 492d3e51161SHeiko Stübner for (cnt = 0; cnt < info->groups[group].npins; cnt++) { 493d3e51161SHeiko Stübner bank = pin_to_bank(info, pins[cnt]); 494d3e51161SHeiko Stübner rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 495d3e51161SHeiko Stübner data[cnt].func); 496d3e51161SHeiko Stübner } 497d3e51161SHeiko Stübner 498d3e51161SHeiko Stübner return 0; 499d3e51161SHeiko Stübner } 500d3e51161SHeiko Stübner 501d3e51161SHeiko Stübner static void rockchip_pmx_disable(struct pinctrl_dev *pctldev, 502d3e51161SHeiko Stübner unsigned selector, unsigned group) 503d3e51161SHeiko Stübner { 504d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 505d3e51161SHeiko Stübner const unsigned int *pins = info->groups[group].pins; 506d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 507d3e51161SHeiko Stübner int cnt; 508d3e51161SHeiko Stübner 509d3e51161SHeiko Stübner dev_dbg(info->dev, "disable function %s group %s\n", 510d3e51161SHeiko Stübner info->functions[selector].name, info->groups[group].name); 511d3e51161SHeiko Stübner 512d3e51161SHeiko Stübner for (cnt = 0; cnt < info->groups[group].npins; cnt++) { 513d3e51161SHeiko Stübner bank = pin_to_bank(info, pins[cnt]); 514d3e51161SHeiko Stübner rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); 515d3e51161SHeiko Stübner } 516d3e51161SHeiko Stübner } 517d3e51161SHeiko Stübner 518d3e51161SHeiko Stübner /* 519d3e51161SHeiko Stübner * The calls to gpio_direction_output() and gpio_direction_input() 520d3e51161SHeiko Stübner * leads to this function call (via the pinctrl_gpio_direction_{input|output}() 521d3e51161SHeiko Stübner * function called from the gpiolib interface). 522d3e51161SHeiko Stübner */ 523d3e51161SHeiko Stübner static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, 524d3e51161SHeiko Stübner struct pinctrl_gpio_range *range, 525d3e51161SHeiko Stübner unsigned offset, bool input) 526d3e51161SHeiko Stübner { 527d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 528d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 529d3e51161SHeiko Stübner struct gpio_chip *chip; 530d3e51161SHeiko Stübner int pin; 531d3e51161SHeiko Stübner u32 data; 532d3e51161SHeiko Stübner 533d3e51161SHeiko Stübner chip = range->gc; 534d3e51161SHeiko Stübner bank = gc_to_pin_bank(chip); 535d3e51161SHeiko Stübner pin = offset - chip->base; 536d3e51161SHeiko Stübner 537d3e51161SHeiko Stübner dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", 538d3e51161SHeiko Stübner offset, range->name, pin, input ? "input" : "output"); 539d3e51161SHeiko Stübner 540d3e51161SHeiko Stübner rockchip_set_mux(bank, pin, RK_FUNC_GPIO); 541d3e51161SHeiko Stübner 542d3e51161SHeiko Stübner data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); 543d3e51161SHeiko Stübner /* set bit to 1 for output, 0 for input */ 544d3e51161SHeiko Stübner if (!input) 545d3e51161SHeiko Stübner data |= BIT(pin); 546d3e51161SHeiko Stübner else 547d3e51161SHeiko Stübner data &= ~BIT(pin); 548d3e51161SHeiko Stübner writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); 549d3e51161SHeiko Stübner 550d3e51161SHeiko Stübner return 0; 551d3e51161SHeiko Stübner } 552d3e51161SHeiko Stübner 553d3e51161SHeiko Stübner static const struct pinmux_ops rockchip_pmx_ops = { 554d3e51161SHeiko Stübner .get_functions_count = rockchip_pmx_get_funcs_count, 555d3e51161SHeiko Stübner .get_function_name = rockchip_pmx_get_func_name, 556d3e51161SHeiko Stübner .get_function_groups = rockchip_pmx_get_groups, 557d3e51161SHeiko Stübner .enable = rockchip_pmx_enable, 558d3e51161SHeiko Stübner .disable = rockchip_pmx_disable, 559d3e51161SHeiko Stübner .gpio_set_direction = rockchip_pmx_gpio_set_direction, 560d3e51161SHeiko Stübner }; 561d3e51161SHeiko Stübner 562d3e51161SHeiko Stübner /* 563d3e51161SHeiko Stübner * Pinconf_ops handling 564d3e51161SHeiko Stübner */ 565d3e51161SHeiko Stübner 56644b6d930SHeiko Stübner static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, 56744b6d930SHeiko Stübner enum pin_config_param pull) 56844b6d930SHeiko Stübner { 56944b6d930SHeiko Stübner /* rk3066b does support any pulls */ 57044b6d930SHeiko Stübner if (!ctrl->pull_offset) 57144b6d930SHeiko Stübner return pull ? false : true; 57244b6d930SHeiko Stübner 57344b6d930SHeiko Stübner if (ctrl->pull_auto) { 57444b6d930SHeiko Stübner if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT && 57544b6d930SHeiko Stübner pull != PIN_CONFIG_BIAS_DISABLE) 57644b6d930SHeiko Stübner return false; 57744b6d930SHeiko Stübner } else { 57844b6d930SHeiko Stübner if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 57944b6d930SHeiko Stübner return false; 58044b6d930SHeiko Stübner } 58144b6d930SHeiko Stübner 58244b6d930SHeiko Stübner return true; 58344b6d930SHeiko Stübner } 58444b6d930SHeiko Stübner 585d3e51161SHeiko Stübner /* set the pin config settings for a specified pin */ 586d3e51161SHeiko Stübner static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, 587d3e51161SHeiko Stübner unsigned long config) 588d3e51161SHeiko Stübner { 589d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 590d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 591d3e51161SHeiko Stübner enum pin_config_param param = pinconf_to_config_param(config); 59244b6d930SHeiko Stübner u16 arg = pinconf_to_config_argument(config); 593d3e51161SHeiko Stübner 594d3e51161SHeiko Stübner switch (param) { 595d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 59644b6d930SHeiko Stübner return rockchip_set_pull(bank, pin - bank->pin_base, param); 59744b6d930SHeiko Stübner break; 598d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 599d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 600d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 60144b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 60244b6d930SHeiko Stübner return -ENOTSUPP; 60344b6d930SHeiko Stübner 60444b6d930SHeiko Stübner if (!arg) 60544b6d930SHeiko Stübner return -EINVAL; 60644b6d930SHeiko Stübner 607d3e51161SHeiko Stübner return rockchip_set_pull(bank, pin - bank->pin_base, param); 608d3e51161SHeiko Stübner break; 609d3e51161SHeiko Stübner default: 610d3e51161SHeiko Stübner return -ENOTSUPP; 611d3e51161SHeiko Stübner break; 612d3e51161SHeiko Stübner } 613d3e51161SHeiko Stübner 614d3e51161SHeiko Stübner return 0; 615d3e51161SHeiko Stübner } 616d3e51161SHeiko Stübner 617d3e51161SHeiko Stübner /* get the pin config settings for a specified pin */ 618d3e51161SHeiko Stübner static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, 619d3e51161SHeiko Stübner unsigned long *config) 620d3e51161SHeiko Stübner { 621d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 622d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 623d3e51161SHeiko Stübner enum pin_config_param param = pinconf_to_config_param(*config); 624d3e51161SHeiko Stübner 625d3e51161SHeiko Stübner switch (param) { 626d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 62744b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 628d3e51161SHeiko Stübner return -EINVAL; 629d3e51161SHeiko Stübner 630d3e51161SHeiko Stübner *config = 0; 631d3e51161SHeiko Stübner break; 63244b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 63344b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 63444b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 63544b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 63644b6d930SHeiko Stübner return -ENOTSUPP; 63744b6d930SHeiko Stübner 63844b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 63944b6d930SHeiko Stübner return -EINVAL; 64044b6d930SHeiko Stübner 64144b6d930SHeiko Stübner *config = 1; 64244b6d930SHeiko Stübner break; 643d3e51161SHeiko Stübner default: 644d3e51161SHeiko Stübner return -ENOTSUPP; 645d3e51161SHeiko Stübner break; 646d3e51161SHeiko Stübner } 647d3e51161SHeiko Stübner 648d3e51161SHeiko Stübner return 0; 649d3e51161SHeiko Stübner } 650d3e51161SHeiko Stübner 651d3e51161SHeiko Stübner static const struct pinconf_ops rockchip_pinconf_ops = { 652d3e51161SHeiko Stübner .pin_config_get = rockchip_pinconf_get, 653d3e51161SHeiko Stübner .pin_config_set = rockchip_pinconf_set, 654d3e51161SHeiko Stübner }; 655d3e51161SHeiko Stübner 656d3e51161SHeiko Stübner static const char *gpio_compat = "rockchip,gpio-bank"; 657d3e51161SHeiko Stübner 658d3e51161SHeiko Stübner static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info, 659d3e51161SHeiko Stübner struct device_node *np) 660d3e51161SHeiko Stübner { 661d3e51161SHeiko Stübner struct device_node *child; 662d3e51161SHeiko Stübner 663d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 664d3e51161SHeiko Stübner if (of_device_is_compatible(child, gpio_compat)) 665d3e51161SHeiko Stübner continue; 666d3e51161SHeiko Stübner 667d3e51161SHeiko Stübner info->nfunctions++; 668d3e51161SHeiko Stübner info->ngroups += of_get_child_count(child); 669d3e51161SHeiko Stübner } 670d3e51161SHeiko Stübner } 671d3e51161SHeiko Stübner 672d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_groups(struct device_node *np, 673d3e51161SHeiko Stübner struct rockchip_pin_group *grp, 674d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 675d3e51161SHeiko Stübner u32 index) 676d3e51161SHeiko Stübner { 677d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 678d3e51161SHeiko Stübner int size; 679d3e51161SHeiko Stübner const __be32 *list; 680d3e51161SHeiko Stübner int num; 681d3e51161SHeiko Stübner int i, j; 682d3e51161SHeiko Stübner int ret; 683d3e51161SHeiko Stübner 684d3e51161SHeiko Stübner dev_dbg(info->dev, "group(%d): %s\n", index, np->name); 685d3e51161SHeiko Stübner 686d3e51161SHeiko Stübner /* Initialise group */ 687d3e51161SHeiko Stübner grp->name = np->name; 688d3e51161SHeiko Stübner 689d3e51161SHeiko Stübner /* 690d3e51161SHeiko Stübner * the binding format is rockchip,pins = <bank pin mux CONFIG>, 691d3e51161SHeiko Stübner * do sanity check and calculate pins number 692d3e51161SHeiko Stübner */ 693d3e51161SHeiko Stübner list = of_get_property(np, "rockchip,pins", &size); 694d3e51161SHeiko Stübner /* we do not check return since it's safe node passed down */ 695d3e51161SHeiko Stübner size /= sizeof(*list); 696d3e51161SHeiko Stübner if (!size || size % 4) { 697d3e51161SHeiko Stübner dev_err(info->dev, "wrong pins number or pins and configs should be by 4\n"); 698d3e51161SHeiko Stübner return -EINVAL; 699d3e51161SHeiko Stübner } 700d3e51161SHeiko Stübner 701d3e51161SHeiko Stübner grp->npins = size / 4; 702d3e51161SHeiko Stübner 703d3e51161SHeiko Stübner grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), 704d3e51161SHeiko Stübner GFP_KERNEL); 705d3e51161SHeiko Stübner grp->data = devm_kzalloc(info->dev, grp->npins * 706d3e51161SHeiko Stübner sizeof(struct rockchip_pin_config), 707d3e51161SHeiko Stübner GFP_KERNEL); 708d3e51161SHeiko Stübner if (!grp->pins || !grp->data) 709d3e51161SHeiko Stübner return -ENOMEM; 710d3e51161SHeiko Stübner 711d3e51161SHeiko Stübner for (i = 0, j = 0; i < size; i += 4, j++) { 712d3e51161SHeiko Stübner const __be32 *phandle; 713d3e51161SHeiko Stübner struct device_node *np_config; 714d3e51161SHeiko Stübner 715d3e51161SHeiko Stübner num = be32_to_cpu(*list++); 716d3e51161SHeiko Stübner bank = bank_num_to_bank(info, num); 717d3e51161SHeiko Stübner if (IS_ERR(bank)) 718d3e51161SHeiko Stübner return PTR_ERR(bank); 719d3e51161SHeiko Stübner 720d3e51161SHeiko Stübner grp->pins[j] = bank->pin_base + be32_to_cpu(*list++); 721d3e51161SHeiko Stübner grp->data[j].func = be32_to_cpu(*list++); 722d3e51161SHeiko Stübner 723d3e51161SHeiko Stübner phandle = list++; 724d3e51161SHeiko Stübner if (!phandle) 725d3e51161SHeiko Stübner return -EINVAL; 726d3e51161SHeiko Stübner 727d3e51161SHeiko Stübner np_config = of_find_node_by_phandle(be32_to_cpup(phandle)); 728d3e51161SHeiko Stübner ret = pinconf_generic_parse_dt_config(np_config, 729d3e51161SHeiko Stübner &grp->data[j].configs, &grp->data[j].nconfigs); 730d3e51161SHeiko Stübner if (ret) 731d3e51161SHeiko Stübner return ret; 732d3e51161SHeiko Stübner } 733d3e51161SHeiko Stübner 734d3e51161SHeiko Stübner return 0; 735d3e51161SHeiko Stübner } 736d3e51161SHeiko Stübner 737d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_functions(struct device_node *np, 738d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 739d3e51161SHeiko Stübner u32 index) 740d3e51161SHeiko Stübner { 741d3e51161SHeiko Stübner struct device_node *child; 742d3e51161SHeiko Stübner struct rockchip_pmx_func *func; 743d3e51161SHeiko Stübner struct rockchip_pin_group *grp; 744d3e51161SHeiko Stübner int ret; 745d3e51161SHeiko Stübner static u32 grp_index; 746d3e51161SHeiko Stübner u32 i = 0; 747d3e51161SHeiko Stübner 748d3e51161SHeiko Stübner dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name); 749d3e51161SHeiko Stübner 750d3e51161SHeiko Stübner func = &info->functions[index]; 751d3e51161SHeiko Stübner 752d3e51161SHeiko Stübner /* Initialise function */ 753d3e51161SHeiko Stübner func->name = np->name; 754d3e51161SHeiko Stübner func->ngroups = of_get_child_count(np); 755d3e51161SHeiko Stübner if (func->ngroups <= 0) 756d3e51161SHeiko Stübner return 0; 757d3e51161SHeiko Stübner 758d3e51161SHeiko Stübner func->groups = devm_kzalloc(info->dev, 759d3e51161SHeiko Stübner func->ngroups * sizeof(char *), GFP_KERNEL); 760d3e51161SHeiko Stübner if (!func->groups) 761d3e51161SHeiko Stübner return -ENOMEM; 762d3e51161SHeiko Stübner 763d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 764d3e51161SHeiko Stübner func->groups[i] = child->name; 765d3e51161SHeiko Stübner grp = &info->groups[grp_index++]; 766d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_groups(child, grp, info, i++); 767d3e51161SHeiko Stübner if (ret) 768d3e51161SHeiko Stübner return ret; 769d3e51161SHeiko Stübner } 770d3e51161SHeiko Stübner 771d3e51161SHeiko Stübner return 0; 772d3e51161SHeiko Stübner } 773d3e51161SHeiko Stübner 774d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_dt(struct platform_device *pdev, 775d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 776d3e51161SHeiko Stübner { 777d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 778d3e51161SHeiko Stübner struct device_node *np = dev->of_node; 779d3e51161SHeiko Stübner struct device_node *child; 780d3e51161SHeiko Stübner int ret; 781d3e51161SHeiko Stübner int i; 782d3e51161SHeiko Stübner 783d3e51161SHeiko Stübner rockchip_pinctrl_child_count(info, np); 784d3e51161SHeiko Stübner 785d3e51161SHeiko Stübner dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); 786d3e51161SHeiko Stübner dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); 787d3e51161SHeiko Stübner 788d3e51161SHeiko Stübner info->functions = devm_kzalloc(dev, info->nfunctions * 789d3e51161SHeiko Stübner sizeof(struct rockchip_pmx_func), 790d3e51161SHeiko Stübner GFP_KERNEL); 791d3e51161SHeiko Stübner if (!info->functions) { 792d3e51161SHeiko Stübner dev_err(dev, "failed to allocate memory for function list\n"); 793d3e51161SHeiko Stübner return -EINVAL; 794d3e51161SHeiko Stübner } 795d3e51161SHeiko Stübner 796d3e51161SHeiko Stübner info->groups = devm_kzalloc(dev, info->ngroups * 797d3e51161SHeiko Stübner sizeof(struct rockchip_pin_group), 798d3e51161SHeiko Stübner GFP_KERNEL); 799d3e51161SHeiko Stübner if (!info->groups) { 800d3e51161SHeiko Stübner dev_err(dev, "failed allocate memory for ping group list\n"); 801d3e51161SHeiko Stübner return -EINVAL; 802d3e51161SHeiko Stübner } 803d3e51161SHeiko Stübner 804d3e51161SHeiko Stübner i = 0; 805d3e51161SHeiko Stübner 806d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 807d3e51161SHeiko Stübner if (of_device_is_compatible(child, gpio_compat)) 808d3e51161SHeiko Stübner continue; 809d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_functions(child, info, i++); 810d3e51161SHeiko Stübner if (ret) { 811d3e51161SHeiko Stübner dev_err(&pdev->dev, "failed to parse function\n"); 812d3e51161SHeiko Stübner return ret; 813d3e51161SHeiko Stübner } 814d3e51161SHeiko Stübner } 815d3e51161SHeiko Stübner 816d3e51161SHeiko Stübner return 0; 817d3e51161SHeiko Stübner } 818d3e51161SHeiko Stübner 819d3e51161SHeiko Stübner static int rockchip_pinctrl_register(struct platform_device *pdev, 820d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 821d3e51161SHeiko Stübner { 822d3e51161SHeiko Stübner struct pinctrl_desc *ctrldesc = &info->pctl; 823d3e51161SHeiko Stübner struct pinctrl_pin_desc *pindesc, *pdesc; 824d3e51161SHeiko Stübner struct rockchip_pin_bank *pin_bank; 825d3e51161SHeiko Stübner int pin, bank, ret; 826d3e51161SHeiko Stübner int k; 827d3e51161SHeiko Stübner 828d3e51161SHeiko Stübner ctrldesc->name = "rockchip-pinctrl"; 829d3e51161SHeiko Stübner ctrldesc->owner = THIS_MODULE; 830d3e51161SHeiko Stübner ctrldesc->pctlops = &rockchip_pctrl_ops; 831d3e51161SHeiko Stübner ctrldesc->pmxops = &rockchip_pmx_ops; 832d3e51161SHeiko Stübner ctrldesc->confops = &rockchip_pinconf_ops; 833d3e51161SHeiko Stübner 834d3e51161SHeiko Stübner pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * 835d3e51161SHeiko Stübner info->ctrl->nr_pins, GFP_KERNEL); 836d3e51161SHeiko Stübner if (!pindesc) { 837d3e51161SHeiko Stübner dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n"); 838d3e51161SHeiko Stübner return -ENOMEM; 839d3e51161SHeiko Stübner } 840d3e51161SHeiko Stübner ctrldesc->pins = pindesc; 841d3e51161SHeiko Stübner ctrldesc->npins = info->ctrl->nr_pins; 842d3e51161SHeiko Stübner 843d3e51161SHeiko Stübner pdesc = pindesc; 844d3e51161SHeiko Stübner for (bank = 0 , k = 0; bank < info->ctrl->nr_banks; bank++) { 845d3e51161SHeiko Stübner pin_bank = &info->ctrl->pin_banks[bank]; 846d3e51161SHeiko Stübner for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) { 847d3e51161SHeiko Stübner pdesc->number = k; 848d3e51161SHeiko Stübner pdesc->name = kasprintf(GFP_KERNEL, "%s-%d", 849d3e51161SHeiko Stübner pin_bank->name, pin); 850d3e51161SHeiko Stübner pdesc++; 851d3e51161SHeiko Stübner } 852d3e51161SHeiko Stübner } 853d3e51161SHeiko Stübner 854d3e51161SHeiko Stübner info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info); 855d3e51161SHeiko Stübner if (!info->pctl_dev) { 856d3e51161SHeiko Stübner dev_err(&pdev->dev, "could not register pinctrl driver\n"); 857d3e51161SHeiko Stübner return -EINVAL; 858d3e51161SHeiko Stübner } 859d3e51161SHeiko Stübner 860d3e51161SHeiko Stübner for (bank = 0; bank < info->ctrl->nr_banks; ++bank) { 861d3e51161SHeiko Stübner pin_bank = &info->ctrl->pin_banks[bank]; 862d3e51161SHeiko Stübner pin_bank->grange.name = pin_bank->name; 863d3e51161SHeiko Stübner pin_bank->grange.id = bank; 864d3e51161SHeiko Stübner pin_bank->grange.pin_base = pin_bank->pin_base; 865d3e51161SHeiko Stübner pin_bank->grange.base = pin_bank->gpio_chip.base; 866d3e51161SHeiko Stübner pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; 867d3e51161SHeiko Stübner pin_bank->grange.gc = &pin_bank->gpio_chip; 868d3e51161SHeiko Stübner pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange); 869d3e51161SHeiko Stübner } 870d3e51161SHeiko Stübner 871d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_dt(pdev, info); 872d3e51161SHeiko Stübner if (ret) { 873d3e51161SHeiko Stübner pinctrl_unregister(info->pctl_dev); 874d3e51161SHeiko Stübner return ret; 875d3e51161SHeiko Stübner } 876d3e51161SHeiko Stübner 877d3e51161SHeiko Stübner return 0; 878d3e51161SHeiko Stübner } 879d3e51161SHeiko Stübner 880d3e51161SHeiko Stübner /* 881d3e51161SHeiko Stübner * GPIO handling 882d3e51161SHeiko Stübner */ 883d3e51161SHeiko Stübner 884d3e51161SHeiko Stübner static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value) 885d3e51161SHeiko Stübner { 886d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); 887d3e51161SHeiko Stübner void __iomem *reg = bank->reg_base + GPIO_SWPORT_DR; 888d3e51161SHeiko Stübner unsigned long flags; 889d3e51161SHeiko Stübner u32 data; 890d3e51161SHeiko Stübner 891d3e51161SHeiko Stübner spin_lock_irqsave(&bank->slock, flags); 892d3e51161SHeiko Stübner 893d3e51161SHeiko Stübner data = readl(reg); 894d3e51161SHeiko Stübner data &= ~BIT(offset); 895d3e51161SHeiko Stübner if (value) 896d3e51161SHeiko Stübner data |= BIT(offset); 897d3e51161SHeiko Stübner writel(data, reg); 898d3e51161SHeiko Stübner 899d3e51161SHeiko Stübner spin_unlock_irqrestore(&bank->slock, flags); 900d3e51161SHeiko Stübner } 901d3e51161SHeiko Stübner 902d3e51161SHeiko Stübner /* 903d3e51161SHeiko Stübner * Returns the level of the pin for input direction and setting of the DR 904d3e51161SHeiko Stübner * register for output gpios. 905d3e51161SHeiko Stübner */ 906d3e51161SHeiko Stübner static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset) 907d3e51161SHeiko Stübner { 908d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); 909d3e51161SHeiko Stübner u32 data; 910d3e51161SHeiko Stübner 911d3e51161SHeiko Stübner data = readl(bank->reg_base + GPIO_EXT_PORT); 912d3e51161SHeiko Stübner data >>= offset; 913d3e51161SHeiko Stübner data &= 1; 914d3e51161SHeiko Stübner return data; 915d3e51161SHeiko Stübner } 916d3e51161SHeiko Stübner 917d3e51161SHeiko Stübner /* 918d3e51161SHeiko Stübner * gpiolib gpio_direction_input callback function. The setting of the pin 919d3e51161SHeiko Stübner * mux function as 'gpio input' will be handled by the pinctrl susbsystem 920d3e51161SHeiko Stübner * interface. 921d3e51161SHeiko Stübner */ 922d3e51161SHeiko Stübner static int rockchip_gpio_direction_input(struct gpio_chip *gc, unsigned offset) 923d3e51161SHeiko Stübner { 924d3e51161SHeiko Stübner return pinctrl_gpio_direction_input(gc->base + offset); 925d3e51161SHeiko Stübner } 926d3e51161SHeiko Stübner 927d3e51161SHeiko Stübner /* 928d3e51161SHeiko Stübner * gpiolib gpio_direction_output callback function. The setting of the pin 929d3e51161SHeiko Stübner * mux function as 'gpio output' will be handled by the pinctrl susbsystem 930d3e51161SHeiko Stübner * interface. 931d3e51161SHeiko Stübner */ 932d3e51161SHeiko Stübner static int rockchip_gpio_direction_output(struct gpio_chip *gc, 933d3e51161SHeiko Stübner unsigned offset, int value) 934d3e51161SHeiko Stübner { 935d3e51161SHeiko Stübner rockchip_gpio_set(gc, offset, value); 936d3e51161SHeiko Stübner return pinctrl_gpio_direction_output(gc->base + offset); 937d3e51161SHeiko Stübner } 938d3e51161SHeiko Stübner 939d3e51161SHeiko Stübner /* 940d3e51161SHeiko Stübner * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin 941d3e51161SHeiko Stübner * and a virtual IRQ, if not already present. 942d3e51161SHeiko Stübner */ 943d3e51161SHeiko Stübner static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned offset) 944d3e51161SHeiko Stübner { 945d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); 946d3e51161SHeiko Stübner unsigned int virq; 947d3e51161SHeiko Stübner 948d3e51161SHeiko Stübner if (!bank->domain) 949d3e51161SHeiko Stübner return -ENXIO; 950d3e51161SHeiko Stübner 951d3e51161SHeiko Stübner virq = irq_create_mapping(bank->domain, offset); 952d3e51161SHeiko Stübner 953d3e51161SHeiko Stübner return (virq) ? : -ENXIO; 954d3e51161SHeiko Stübner } 955d3e51161SHeiko Stübner 956d3e51161SHeiko Stübner static const struct gpio_chip rockchip_gpiolib_chip = { 957d3e51161SHeiko Stübner .set = rockchip_gpio_set, 958d3e51161SHeiko Stübner .get = rockchip_gpio_get, 959d3e51161SHeiko Stübner .direction_input = rockchip_gpio_direction_input, 960d3e51161SHeiko Stübner .direction_output = rockchip_gpio_direction_output, 961d3e51161SHeiko Stübner .to_irq = rockchip_gpio_to_irq, 962d3e51161SHeiko Stübner .owner = THIS_MODULE, 963d3e51161SHeiko Stübner }; 964d3e51161SHeiko Stübner 965d3e51161SHeiko Stübner /* 966d3e51161SHeiko Stübner * Interrupt handling 967d3e51161SHeiko Stübner */ 968d3e51161SHeiko Stübner 969d3e51161SHeiko Stübner static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) 970d3e51161SHeiko Stübner { 971d3e51161SHeiko Stübner struct irq_chip *chip = irq_get_chip(irq); 972d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = irq_get_handler_data(irq); 973d3e51161SHeiko Stübner u32 pend; 974d3e51161SHeiko Stübner 975d3e51161SHeiko Stübner dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); 976d3e51161SHeiko Stübner 977d3e51161SHeiko Stübner chained_irq_enter(chip, desc); 978d3e51161SHeiko Stübner 979d3e51161SHeiko Stübner pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); 980d3e51161SHeiko Stübner 981d3e51161SHeiko Stübner while (pend) { 982d3e51161SHeiko Stübner unsigned int virq; 983d3e51161SHeiko Stübner 984d3e51161SHeiko Stübner irq = __ffs(pend); 985d3e51161SHeiko Stübner pend &= ~BIT(irq); 986d3e51161SHeiko Stübner virq = irq_linear_revmap(bank->domain, irq); 987d3e51161SHeiko Stübner 988d3e51161SHeiko Stübner if (!virq) { 989d3e51161SHeiko Stübner dev_err(bank->drvdata->dev, "unmapped irq %d\n", irq); 990d3e51161SHeiko Stübner continue; 991d3e51161SHeiko Stübner } 992d3e51161SHeiko Stübner 993d3e51161SHeiko Stübner dev_dbg(bank->drvdata->dev, "handling irq %d\n", irq); 994d3e51161SHeiko Stübner 995d3e51161SHeiko Stübner generic_handle_irq(virq); 996d3e51161SHeiko Stübner } 997d3e51161SHeiko Stübner 998d3e51161SHeiko Stübner chained_irq_exit(chip, desc); 999d3e51161SHeiko Stübner } 1000d3e51161SHeiko Stübner 1001d3e51161SHeiko Stübner static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) 1002d3e51161SHeiko Stübner { 1003d3e51161SHeiko Stübner struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 1004d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc->private; 1005d3e51161SHeiko Stübner u32 mask = BIT(d->hwirq); 1006d3e51161SHeiko Stübner u32 polarity; 1007d3e51161SHeiko Stübner u32 level; 1008d3e51161SHeiko Stübner u32 data; 1009d3e51161SHeiko Stübner 1010d3e51161SHeiko Stübner if (type & IRQ_TYPE_EDGE_BOTH) 1011d3e51161SHeiko Stübner __irq_set_handler_locked(d->irq, handle_edge_irq); 1012d3e51161SHeiko Stübner else 1013d3e51161SHeiko Stübner __irq_set_handler_locked(d->irq, handle_level_irq); 1014d3e51161SHeiko Stübner 1015d3e51161SHeiko Stübner irq_gc_lock(gc); 1016d3e51161SHeiko Stübner 1017d3e51161SHeiko Stübner level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL); 1018d3e51161SHeiko Stübner polarity = readl_relaxed(gc->reg_base + GPIO_INT_POLARITY); 1019d3e51161SHeiko Stübner 1020d3e51161SHeiko Stübner switch (type) { 1021d3e51161SHeiko Stübner case IRQ_TYPE_EDGE_RISING: 1022d3e51161SHeiko Stübner level |= mask; 1023d3e51161SHeiko Stübner polarity |= mask; 1024d3e51161SHeiko Stübner break; 1025d3e51161SHeiko Stübner case IRQ_TYPE_EDGE_FALLING: 1026d3e51161SHeiko Stübner level |= mask; 1027d3e51161SHeiko Stübner polarity &= ~mask; 1028d3e51161SHeiko Stübner break; 1029d3e51161SHeiko Stübner case IRQ_TYPE_LEVEL_HIGH: 1030d3e51161SHeiko Stübner level &= ~mask; 1031d3e51161SHeiko Stübner polarity |= mask; 1032d3e51161SHeiko Stübner break; 1033d3e51161SHeiko Stübner case IRQ_TYPE_LEVEL_LOW: 1034d3e51161SHeiko Stübner level &= ~mask; 1035d3e51161SHeiko Stübner polarity &= ~mask; 1036d3e51161SHeiko Stübner break; 1037d3e51161SHeiko Stübner default: 10387cc5f970SAxel Lin irq_gc_unlock(gc); 1039d3e51161SHeiko Stübner return -EINVAL; 1040d3e51161SHeiko Stübner } 1041d3e51161SHeiko Stübner 1042d3e51161SHeiko Stübner writel_relaxed(level, gc->reg_base + GPIO_INTTYPE_LEVEL); 1043d3e51161SHeiko Stübner writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY); 1044d3e51161SHeiko Stübner 1045d3e51161SHeiko Stübner irq_gc_unlock(gc); 1046d3e51161SHeiko Stübner 1047d3e51161SHeiko Stübner /* make sure the pin is configured as gpio input */ 1048d3e51161SHeiko Stübner rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO); 1049d3e51161SHeiko Stübner data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); 1050d3e51161SHeiko Stübner data &= ~mask; 1051d3e51161SHeiko Stübner writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); 1052d3e51161SHeiko Stübner 1053d3e51161SHeiko Stübner return 0; 1054d3e51161SHeiko Stübner } 1055d3e51161SHeiko Stübner 1056d3e51161SHeiko Stübner static int rockchip_interrupts_register(struct platform_device *pdev, 1057d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 1058d3e51161SHeiko Stübner { 1059d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1060d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = ctrl->pin_banks; 1061d3e51161SHeiko Stübner unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; 1062d3e51161SHeiko Stübner struct irq_chip_generic *gc; 1063d3e51161SHeiko Stübner int ret; 1064d3e51161SHeiko Stübner int i; 1065d3e51161SHeiko Stübner 1066d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1067d3e51161SHeiko Stübner if (!bank->valid) { 1068d3e51161SHeiko Stübner dev_warn(&pdev->dev, "bank %s is not valid\n", 1069d3e51161SHeiko Stübner bank->name); 1070d3e51161SHeiko Stübner continue; 1071d3e51161SHeiko Stübner } 1072d3e51161SHeiko Stübner 1073d3e51161SHeiko Stübner bank->domain = irq_domain_add_linear(bank->of_node, 32, 1074d3e51161SHeiko Stübner &irq_generic_chip_ops, NULL); 1075d3e51161SHeiko Stübner if (!bank->domain) { 1076d3e51161SHeiko Stübner dev_warn(&pdev->dev, "could not initialize irq domain for bank %s\n", 1077d3e51161SHeiko Stübner bank->name); 1078d3e51161SHeiko Stübner continue; 1079d3e51161SHeiko Stübner } 1080d3e51161SHeiko Stübner 1081d3e51161SHeiko Stübner ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1, 1082d3e51161SHeiko Stübner "rockchip_gpio_irq", handle_level_irq, 1083d3e51161SHeiko Stübner clr, 0, IRQ_GC_INIT_MASK_CACHE); 1084d3e51161SHeiko Stübner if (ret) { 1085d3e51161SHeiko Stübner dev_err(&pdev->dev, "could not alloc generic chips for bank %s\n", 1086d3e51161SHeiko Stübner bank->name); 1087d3e51161SHeiko Stübner irq_domain_remove(bank->domain); 1088d3e51161SHeiko Stübner continue; 1089d3e51161SHeiko Stübner } 1090d3e51161SHeiko Stübner 1091d3e51161SHeiko Stübner gc = irq_get_domain_generic_chip(bank->domain, 0); 1092d3e51161SHeiko Stübner gc->reg_base = bank->reg_base; 1093d3e51161SHeiko Stübner gc->private = bank; 1094d3e51161SHeiko Stübner gc->chip_types[0].regs.mask = GPIO_INTEN; 1095d3e51161SHeiko Stübner gc->chip_types[0].regs.ack = GPIO_PORTS_EOI; 1096d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; 1097d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; 1098d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; 1099d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; 1100d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; 1101d3e51161SHeiko Stübner 1102d3e51161SHeiko Stübner irq_set_handler_data(bank->irq, bank); 1103d3e51161SHeiko Stübner irq_set_chained_handler(bank->irq, rockchip_irq_demux); 1104d3e51161SHeiko Stübner } 1105d3e51161SHeiko Stübner 1106d3e51161SHeiko Stübner return 0; 1107d3e51161SHeiko Stübner } 1108d3e51161SHeiko Stübner 1109d3e51161SHeiko Stübner static int rockchip_gpiolib_register(struct platform_device *pdev, 1110d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 1111d3e51161SHeiko Stübner { 1112d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1113d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = ctrl->pin_banks; 1114d3e51161SHeiko Stübner struct gpio_chip *gc; 1115d3e51161SHeiko Stübner int ret; 1116d3e51161SHeiko Stübner int i; 1117d3e51161SHeiko Stübner 1118d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1119d3e51161SHeiko Stübner if (!bank->valid) { 1120d3e51161SHeiko Stübner dev_warn(&pdev->dev, "bank %s is not valid\n", 1121d3e51161SHeiko Stübner bank->name); 1122d3e51161SHeiko Stübner continue; 1123d3e51161SHeiko Stübner } 1124d3e51161SHeiko Stübner 1125d3e51161SHeiko Stübner bank->gpio_chip = rockchip_gpiolib_chip; 1126d3e51161SHeiko Stübner 1127d3e51161SHeiko Stübner gc = &bank->gpio_chip; 1128d3e51161SHeiko Stübner gc->base = bank->pin_base; 1129d3e51161SHeiko Stübner gc->ngpio = bank->nr_pins; 1130d3e51161SHeiko Stübner gc->dev = &pdev->dev; 1131d3e51161SHeiko Stübner gc->of_node = bank->of_node; 1132d3e51161SHeiko Stübner gc->label = bank->name; 1133d3e51161SHeiko Stübner 1134d3e51161SHeiko Stübner ret = gpiochip_add(gc); 1135d3e51161SHeiko Stübner if (ret) { 1136d3e51161SHeiko Stübner dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n", 1137d3e51161SHeiko Stübner gc->label, ret); 1138d3e51161SHeiko Stübner goto fail; 1139d3e51161SHeiko Stübner } 1140d3e51161SHeiko Stübner } 1141d3e51161SHeiko Stübner 1142d3e51161SHeiko Stübner rockchip_interrupts_register(pdev, info); 1143d3e51161SHeiko Stübner 1144d3e51161SHeiko Stübner return 0; 1145d3e51161SHeiko Stübner 1146d3e51161SHeiko Stübner fail: 1147d3e51161SHeiko Stübner for (--i, --bank; i >= 0; --i, --bank) { 1148d3e51161SHeiko Stübner if (!bank->valid) 1149d3e51161SHeiko Stübner continue; 1150d3e51161SHeiko Stübner 1151d3e51161SHeiko Stübner if (gpiochip_remove(&bank->gpio_chip)) 1152d3e51161SHeiko Stübner dev_err(&pdev->dev, "gpio chip %s remove failed\n", 1153d3e51161SHeiko Stübner bank->gpio_chip.label); 1154d3e51161SHeiko Stübner } 1155d3e51161SHeiko Stübner return ret; 1156d3e51161SHeiko Stübner } 1157d3e51161SHeiko Stübner 1158d3e51161SHeiko Stübner static int rockchip_gpiolib_unregister(struct platform_device *pdev, 1159d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 1160d3e51161SHeiko Stübner { 1161d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1162d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = ctrl->pin_banks; 1163d3e51161SHeiko Stübner int ret = 0; 1164d3e51161SHeiko Stübner int i; 1165d3e51161SHeiko Stübner 1166d3e51161SHeiko Stübner for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) { 1167d3e51161SHeiko Stübner if (!bank->valid) 1168d3e51161SHeiko Stübner continue; 1169d3e51161SHeiko Stübner 1170d3e51161SHeiko Stübner ret = gpiochip_remove(&bank->gpio_chip); 1171d3e51161SHeiko Stübner } 1172d3e51161SHeiko Stübner 1173d3e51161SHeiko Stübner if (ret) 1174d3e51161SHeiko Stübner dev_err(&pdev->dev, "gpio chip remove failed\n"); 1175d3e51161SHeiko Stübner 1176d3e51161SHeiko Stübner return ret; 1177d3e51161SHeiko Stübner } 1178d3e51161SHeiko Stübner 1179d3e51161SHeiko Stübner static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, 1180d3e51161SHeiko Stübner struct device *dev) 1181d3e51161SHeiko Stübner { 1182d3e51161SHeiko Stübner struct resource res; 1183d3e51161SHeiko Stübner 1184d3e51161SHeiko Stübner if (of_address_to_resource(bank->of_node, 0, &res)) { 1185d3e51161SHeiko Stübner dev_err(dev, "cannot find IO resource for bank\n"); 1186d3e51161SHeiko Stübner return -ENOENT; 1187d3e51161SHeiko Stübner } 1188d3e51161SHeiko Stübner 1189d3e51161SHeiko Stübner bank->reg_base = devm_ioremap_resource(dev, &res); 1190d3e51161SHeiko Stübner if (IS_ERR(bank->reg_base)) 1191d3e51161SHeiko Stübner return PTR_ERR(bank->reg_base); 1192d3e51161SHeiko Stübner 1193d3e51161SHeiko Stübner bank->irq = irq_of_parse_and_map(bank->of_node, 0); 1194d3e51161SHeiko Stübner 1195d3e51161SHeiko Stübner bank->clk = of_clk_get(bank->of_node, 0); 1196d3e51161SHeiko Stübner if (IS_ERR(bank->clk)) 1197d3e51161SHeiko Stübner return PTR_ERR(bank->clk); 1198d3e51161SHeiko Stübner 1199d3e51161SHeiko Stübner return clk_prepare_enable(bank->clk); 1200d3e51161SHeiko Stübner } 1201d3e51161SHeiko Stübner 1202d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[]; 1203d3e51161SHeiko Stübner 1204d3e51161SHeiko Stübner /* retrieve the soc specific data */ 1205d3e51161SHeiko Stübner static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( 1206d3e51161SHeiko Stübner struct rockchip_pinctrl *d, 1207d3e51161SHeiko Stübner struct platform_device *pdev) 1208d3e51161SHeiko Stübner { 1209d3e51161SHeiko Stübner const struct of_device_id *match; 1210d3e51161SHeiko Stübner struct device_node *node = pdev->dev.of_node; 1211d3e51161SHeiko Stübner struct device_node *np; 1212d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 1213d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 1214d3e51161SHeiko Stübner int i; 1215d3e51161SHeiko Stübner 1216d3e51161SHeiko Stübner match = of_match_node(rockchip_pinctrl_dt_match, node); 1217d3e51161SHeiko Stübner ctrl = (struct rockchip_pin_ctrl *)match->data; 1218d3e51161SHeiko Stübner 1219d3e51161SHeiko Stübner for_each_child_of_node(node, np) { 1220d3e51161SHeiko Stübner if (!of_find_property(np, "gpio-controller", NULL)) 1221d3e51161SHeiko Stübner continue; 1222d3e51161SHeiko Stübner 1223d3e51161SHeiko Stübner bank = ctrl->pin_banks; 1224d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1225d3e51161SHeiko Stübner if (!strcmp(bank->name, np->name)) { 1226d3e51161SHeiko Stübner bank->of_node = np; 1227d3e51161SHeiko Stübner 1228d3e51161SHeiko Stübner if (!rockchip_get_bank_data(bank, &pdev->dev)) 1229d3e51161SHeiko Stübner bank->valid = true; 1230d3e51161SHeiko Stübner 1231d3e51161SHeiko Stübner break; 1232d3e51161SHeiko Stübner } 1233d3e51161SHeiko Stübner } 1234d3e51161SHeiko Stübner } 1235d3e51161SHeiko Stübner 1236d3e51161SHeiko Stübner bank = ctrl->pin_banks; 1237d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1238d3e51161SHeiko Stübner spin_lock_init(&bank->slock); 1239d3e51161SHeiko Stübner bank->drvdata = d; 1240d3e51161SHeiko Stübner bank->pin_base = ctrl->nr_pins; 1241d3e51161SHeiko Stübner ctrl->nr_pins += bank->nr_pins; 1242d3e51161SHeiko Stübner } 1243d3e51161SHeiko Stübner 1244d3e51161SHeiko Stübner return ctrl; 1245d3e51161SHeiko Stübner } 1246d3e51161SHeiko Stübner 1247d3e51161SHeiko Stübner static int rockchip_pinctrl_probe(struct platform_device *pdev) 1248d3e51161SHeiko Stübner { 1249d3e51161SHeiko Stübner struct rockchip_pinctrl *info; 1250d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 1251d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 1252d3e51161SHeiko Stübner struct resource *res; 1253d3e51161SHeiko Stübner int ret; 1254d3e51161SHeiko Stübner 1255d3e51161SHeiko Stübner if (!dev->of_node) { 1256d3e51161SHeiko Stübner dev_err(dev, "device tree node not found\n"); 1257d3e51161SHeiko Stübner return -ENODEV; 1258d3e51161SHeiko Stübner } 1259d3e51161SHeiko Stübner 1260d3e51161SHeiko Stübner info = devm_kzalloc(dev, sizeof(struct rockchip_pinctrl), GFP_KERNEL); 1261d3e51161SHeiko Stübner if (!info) 1262d3e51161SHeiko Stübner return -ENOMEM; 1263d3e51161SHeiko Stübner 1264d3e51161SHeiko Stübner ctrl = rockchip_pinctrl_get_soc_data(info, pdev); 1265d3e51161SHeiko Stübner if (!ctrl) { 1266d3e51161SHeiko Stübner dev_err(dev, "driver data not available\n"); 1267d3e51161SHeiko Stübner return -EINVAL; 1268d3e51161SHeiko Stübner } 1269d3e51161SHeiko Stübner info->ctrl = ctrl; 1270d3e51161SHeiko Stübner info->dev = dev; 1271d3e51161SHeiko Stübner 1272d3e51161SHeiko Stübner res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1273d3e51161SHeiko Stübner if (!res) { 1274d3e51161SHeiko Stübner dev_err(dev, "cannot find IO resource\n"); 1275d3e51161SHeiko Stübner return -ENOENT; 1276d3e51161SHeiko Stübner } 1277d3e51161SHeiko Stübner 1278d3e51161SHeiko Stübner info->reg_base = devm_ioremap_resource(&pdev->dev, res); 1279d3e51161SHeiko Stübner if (IS_ERR(info->reg_base)) 1280d3e51161SHeiko Stübner return PTR_ERR(info->reg_base); 1281d3e51161SHeiko Stübner 1282d3e51161SHeiko Stübner ret = rockchip_gpiolib_register(pdev, info); 1283d3e51161SHeiko Stübner if (ret) 1284d3e51161SHeiko Stübner return ret; 1285d3e51161SHeiko Stübner 1286d3e51161SHeiko Stübner ret = rockchip_pinctrl_register(pdev, info); 1287d3e51161SHeiko Stübner if (ret) { 1288d3e51161SHeiko Stübner rockchip_gpiolib_unregister(pdev, info); 1289d3e51161SHeiko Stübner return ret; 1290d3e51161SHeiko Stübner } 1291d3e51161SHeiko Stübner 1292d3e51161SHeiko Stübner platform_set_drvdata(pdev, info); 1293d3e51161SHeiko Stübner 1294d3e51161SHeiko Stübner return 0; 1295d3e51161SHeiko Stübner } 1296d3e51161SHeiko Stübner 1297d3e51161SHeiko Stübner static struct rockchip_pin_bank rk2928_pin_banks[] = { 1298d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 1299d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1300d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1301d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1302d3e51161SHeiko Stübner }; 1303d3e51161SHeiko Stübner 1304d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk2928_pin_ctrl = { 1305d3e51161SHeiko Stübner .pin_banks = rk2928_pin_banks, 1306d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk2928_pin_banks), 1307d3e51161SHeiko Stübner .label = "RK2928-GPIO", 1308d3e51161SHeiko Stübner .mux_offset = 0xa8, 1309d3e51161SHeiko Stübner .pull_offset = 0x118, 1310d3e51161SHeiko Stübner .pull_auto = 1, 1311d3e51161SHeiko Stübner .pull_bank_stride = 8, 1312d3e51161SHeiko Stübner }; 1313d3e51161SHeiko Stübner 1314d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066a_pin_banks[] = { 1315d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 1316d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1317d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1318d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1319d3e51161SHeiko Stübner PIN_BANK(4, 32, "gpio4"), 1320d3e51161SHeiko Stübner PIN_BANK(6, 16, "gpio6"), 1321d3e51161SHeiko Stübner }; 1322d3e51161SHeiko Stübner 1323d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { 1324d3e51161SHeiko Stübner .pin_banks = rk3066a_pin_banks, 1325d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), 1326d3e51161SHeiko Stübner .label = "RK3066a-GPIO", 1327d3e51161SHeiko Stübner .mux_offset = 0xa8, 1328d3e51161SHeiko Stübner .pull_offset = 0x118, 1329d3e51161SHeiko Stübner .pull_auto = 1, 1330d3e51161SHeiko Stübner .pull_bank_stride = 8, 1331d3e51161SHeiko Stübner }; 1332d3e51161SHeiko Stübner 1333d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066b_pin_banks[] = { 1334d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 1335d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1336d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1337d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1338d3e51161SHeiko Stübner }; 1339d3e51161SHeiko Stübner 1340d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { 1341d3e51161SHeiko Stübner .pin_banks = rk3066b_pin_banks, 1342d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), 1343d3e51161SHeiko Stübner .label = "RK3066b-GPIO", 1344d3e51161SHeiko Stübner .mux_offset = 0x60, 1345d3e51161SHeiko Stübner .pull_offset = -EINVAL, 1346d3e51161SHeiko Stübner }; 1347d3e51161SHeiko Stübner 1348d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3188_pin_banks[] = { 1349d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 1350d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1351d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1352d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1353d3e51161SHeiko Stübner }; 1354d3e51161SHeiko Stübner 1355d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3188_pin_ctrl = { 1356d3e51161SHeiko Stübner .pin_banks = rk3188_pin_banks, 1357d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3188_pin_banks), 1358d3e51161SHeiko Stübner .label = "RK3188-GPIO", 1359d3e51161SHeiko Stübner .mux_offset = 0x68, 1360d3e51161SHeiko Stübner .pull_offset = 0x164, 1361d3e51161SHeiko Stübner .pull_bank_stride = 16, 1362d3e51161SHeiko Stübner }; 1363d3e51161SHeiko Stübner 1364d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[] = { 1365d3e51161SHeiko Stübner { .compatible = "rockchip,rk2928-pinctrl", 1366d3e51161SHeiko Stübner .data = (void *)&rk2928_pin_ctrl }, 1367d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066a-pinctrl", 1368d3e51161SHeiko Stübner .data = (void *)&rk3066a_pin_ctrl }, 1369d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066b-pinctrl", 1370d3e51161SHeiko Stübner .data = (void *)&rk3066b_pin_ctrl }, 1371d3e51161SHeiko Stübner { .compatible = "rockchip,rk3188-pinctrl", 1372d3e51161SHeiko Stübner .data = (void *)&rk3188_pin_ctrl }, 1373d3e51161SHeiko Stübner {}, 1374d3e51161SHeiko Stübner }; 1375d3e51161SHeiko Stübner MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); 1376d3e51161SHeiko Stübner 1377d3e51161SHeiko Stübner static struct platform_driver rockchip_pinctrl_driver = { 1378d3e51161SHeiko Stübner .probe = rockchip_pinctrl_probe, 1379d3e51161SHeiko Stübner .driver = { 1380d3e51161SHeiko Stübner .name = "rockchip-pinctrl", 1381d3e51161SHeiko Stübner .owner = THIS_MODULE, 1382d3e51161SHeiko Stübner .of_match_table = of_match_ptr(rockchip_pinctrl_dt_match), 1383d3e51161SHeiko Stübner }, 1384d3e51161SHeiko Stübner }; 1385d3e51161SHeiko Stübner 1386d3e51161SHeiko Stübner static int __init rockchip_pinctrl_drv_register(void) 1387d3e51161SHeiko Stübner { 1388d3e51161SHeiko Stübner return platform_driver_register(&rockchip_pinctrl_driver); 1389d3e51161SHeiko Stübner } 1390d3e51161SHeiko Stübner postcore_initcall(rockchip_pinctrl_drv_register); 1391d3e51161SHeiko Stübner 1392d3e51161SHeiko Stübner MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 1393d3e51161SHeiko Stübner MODULE_DESCRIPTION("Rockchip pinctrl driver"); 1394d3e51161SHeiko Stübner MODULE_LICENSE("GPL v2"); 1395