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> 40751a99abSHeiko Stübner #include <linux/regmap.h> 4114dee867SHeiko Stübner #include <linux/mfd/syscon.h> 42d3e51161SHeiko Stübner #include <dt-bindings/pinctrl/rockchip.h> 43d3e51161SHeiko Stübner 44d3e51161SHeiko Stübner #include "core.h" 45d3e51161SHeiko Stübner #include "pinconf.h" 46d3e51161SHeiko Stübner 47d3e51161SHeiko Stübner /* GPIO control registers */ 48d3e51161SHeiko Stübner #define GPIO_SWPORT_DR 0x00 49d3e51161SHeiko Stübner #define GPIO_SWPORT_DDR 0x04 50d3e51161SHeiko Stübner #define GPIO_INTEN 0x30 51d3e51161SHeiko Stübner #define GPIO_INTMASK 0x34 52d3e51161SHeiko Stübner #define GPIO_INTTYPE_LEVEL 0x38 53d3e51161SHeiko Stübner #define GPIO_INT_POLARITY 0x3c 54d3e51161SHeiko Stübner #define GPIO_INT_STATUS 0x40 55d3e51161SHeiko Stübner #define GPIO_INT_RAWSTATUS 0x44 56d3e51161SHeiko Stübner #define GPIO_DEBOUNCE 0x48 57d3e51161SHeiko Stübner #define GPIO_PORTS_EOI 0x4c 58d3e51161SHeiko Stübner #define GPIO_EXT_PORT 0x50 59d3e51161SHeiko Stübner #define GPIO_LS_SYNC 0x60 60d3e51161SHeiko Stübner 61a282926dSHeiko Stübner enum rockchip_pinctrl_type { 62a282926dSHeiko Stübner RK2928, 63a282926dSHeiko Stübner RK3066B, 64a282926dSHeiko Stübner RK3188, 65*66d750e1SHeiko Stübner RK3288, 66a282926dSHeiko Stübner }; 67a282926dSHeiko Stübner 68fc72c923SHeiko Stübner /** 69fc72c923SHeiko Stübner * Encode variants of iomux registers into a type variable 70fc72c923SHeiko Stübner */ 71fc72c923SHeiko Stübner #define IOMUX_GPIO_ONLY BIT(0) 7203716e1dSHeiko Stübner #define IOMUX_WIDTH_4BIT BIT(1) 7395ec8ae4SHeiko Stübner #define IOMUX_SOURCE_PMU BIT(2) 7462f49226SHeiko Stübner #define IOMUX_UNROUTED BIT(3) 75fc72c923SHeiko Stübner 76fc72c923SHeiko Stübner /** 77fc72c923SHeiko Stübner * @type: iomux variant using IOMUX_* constants 786bc0d121SHeiko Stübner * @offset: if initialized to -1 it will be autocalculated, by specifying 796bc0d121SHeiko Stübner * an initial offset value the relevant source offset can be reset 806bc0d121SHeiko Stübner * to a new value for autocalculating the following iomux registers. 81fc72c923SHeiko Stübner */ 82fc72c923SHeiko Stübner struct rockchip_iomux { 83fc72c923SHeiko Stübner int type; 846bc0d121SHeiko Stübner int offset; 8565fca613SHeiko Stübner }; 8665fca613SHeiko Stübner 87d3e51161SHeiko Stübner /** 88d3e51161SHeiko Stübner * @reg_base: register base of the gpio bank 896ca5274dSHeiko Stübner * @reg_pull: optional separate register for additional pull settings 90d3e51161SHeiko Stübner * @clk: clock of the gpio bank 91d3e51161SHeiko Stübner * @irq: interrupt of the gpio bank 92d3e51161SHeiko Stübner * @pin_base: first pin number 93d3e51161SHeiko Stübner * @nr_pins: number of pins in this bank 94d3e51161SHeiko Stübner * @name: name of the bank 95d3e51161SHeiko Stübner * @bank_num: number of the bank, to account for holes 96fc72c923SHeiko Stübner * @iomux: array describing the 4 iomux sources of the bank 97d3e51161SHeiko Stübner * @valid: are all necessary informations present 98d3e51161SHeiko Stübner * @of_node: dt node of this bank 99d3e51161SHeiko Stübner * @drvdata: common pinctrl basedata 100d3e51161SHeiko Stübner * @domain: irqdomain of the gpio bank 101d3e51161SHeiko Stübner * @gpio_chip: gpiolib chip 102d3e51161SHeiko Stübner * @grange: gpio range 103d3e51161SHeiko Stübner * @slock: spinlock for the gpio bank 104d3e51161SHeiko Stübner */ 105d3e51161SHeiko Stübner struct rockchip_pin_bank { 106d3e51161SHeiko Stübner void __iomem *reg_base; 107751a99abSHeiko Stübner struct regmap *regmap_pull; 108d3e51161SHeiko Stübner struct clk *clk; 109d3e51161SHeiko Stübner int irq; 110d3e51161SHeiko Stübner u32 pin_base; 111d3e51161SHeiko Stübner u8 nr_pins; 112d3e51161SHeiko Stübner char *name; 113d3e51161SHeiko Stübner u8 bank_num; 114fc72c923SHeiko Stübner struct rockchip_iomux iomux[4]; 115d3e51161SHeiko Stübner bool valid; 116d3e51161SHeiko Stübner struct device_node *of_node; 117d3e51161SHeiko Stübner struct rockchip_pinctrl *drvdata; 118d3e51161SHeiko Stübner struct irq_domain *domain; 119d3e51161SHeiko Stübner struct gpio_chip gpio_chip; 120d3e51161SHeiko Stübner struct pinctrl_gpio_range grange; 121d3e51161SHeiko Stübner spinlock_t slock; 1225a927501SHeiko Stübner u32 toggle_edge_mode; 123d3e51161SHeiko Stübner }; 124d3e51161SHeiko Stübner 125d3e51161SHeiko Stübner #define PIN_BANK(id, pins, label) \ 126d3e51161SHeiko Stübner { \ 127d3e51161SHeiko Stübner .bank_num = id, \ 128d3e51161SHeiko Stübner .nr_pins = pins, \ 129d3e51161SHeiko Stübner .name = label, \ 1306bc0d121SHeiko Stübner .iomux = { \ 1316bc0d121SHeiko Stübner { .offset = -1 }, \ 1326bc0d121SHeiko Stübner { .offset = -1 }, \ 1336bc0d121SHeiko Stübner { .offset = -1 }, \ 1346bc0d121SHeiko Stübner { .offset = -1 }, \ 1356bc0d121SHeiko Stübner }, \ 136d3e51161SHeiko Stübner } 137d3e51161SHeiko Stübner 138fc72c923SHeiko Stübner #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ 139fc72c923SHeiko Stübner { \ 140fc72c923SHeiko Stübner .bank_num = id, \ 141fc72c923SHeiko Stübner .nr_pins = pins, \ 142fc72c923SHeiko Stübner .name = label, \ 143fc72c923SHeiko Stübner .iomux = { \ 1446bc0d121SHeiko Stübner { .type = iom0, .offset = -1 }, \ 1456bc0d121SHeiko Stübner { .type = iom1, .offset = -1 }, \ 1466bc0d121SHeiko Stübner { .type = iom2, .offset = -1 }, \ 1476bc0d121SHeiko Stübner { .type = iom3, .offset = -1 }, \ 148fc72c923SHeiko Stübner }, \ 149fc72c923SHeiko Stübner } 150fc72c923SHeiko Stübner 151d3e51161SHeiko Stübner /** 152d3e51161SHeiko Stübner */ 153d3e51161SHeiko Stübner struct rockchip_pin_ctrl { 154d3e51161SHeiko Stübner struct rockchip_pin_bank *pin_banks; 155d3e51161SHeiko Stübner u32 nr_banks; 156d3e51161SHeiko Stübner u32 nr_pins; 157d3e51161SHeiko Stübner char *label; 158a282926dSHeiko Stübner enum rockchip_pinctrl_type type; 15995ec8ae4SHeiko Stübner int grf_mux_offset; 16095ec8ae4SHeiko Stübner int pmu_mux_offset; 161751a99abSHeiko Stübner void (*pull_calc_reg)(struct rockchip_pin_bank *bank, 162751a99abSHeiko Stübner int pin_num, struct regmap **regmap, 163751a99abSHeiko Stübner int *reg, u8 *bit); 164d3e51161SHeiko Stübner }; 165d3e51161SHeiko Stübner 166d3e51161SHeiko Stübner struct rockchip_pin_config { 167d3e51161SHeiko Stübner unsigned int func; 168d3e51161SHeiko Stübner unsigned long *configs; 169d3e51161SHeiko Stübner unsigned int nconfigs; 170d3e51161SHeiko Stübner }; 171d3e51161SHeiko Stübner 172d3e51161SHeiko Stübner /** 173d3e51161SHeiko Stübner * struct rockchip_pin_group: represent group of pins of a pinmux function. 174d3e51161SHeiko Stübner * @name: name of the pin group, used to lookup the group. 175d3e51161SHeiko Stübner * @pins: the pins included in this group. 176d3e51161SHeiko Stübner * @npins: number of pins included in this group. 177d3e51161SHeiko Stübner * @func: the mux function number to be programmed when selected. 178d3e51161SHeiko Stübner * @configs: the config values to be set for each pin 179d3e51161SHeiko Stübner * @nconfigs: number of configs for each pin 180d3e51161SHeiko Stübner */ 181d3e51161SHeiko Stübner struct rockchip_pin_group { 182d3e51161SHeiko Stübner const char *name; 183d3e51161SHeiko Stübner unsigned int npins; 184d3e51161SHeiko Stübner unsigned int *pins; 185d3e51161SHeiko Stübner struct rockchip_pin_config *data; 186d3e51161SHeiko Stübner }; 187d3e51161SHeiko Stübner 188d3e51161SHeiko Stübner /** 189d3e51161SHeiko Stübner * struct rockchip_pmx_func: represent a pin function. 190d3e51161SHeiko Stübner * @name: name of the pin function, used to lookup the function. 191d3e51161SHeiko Stübner * @groups: one or more names of pin groups that provide this function. 192d3e51161SHeiko Stübner * @num_groups: number of groups included in @groups. 193d3e51161SHeiko Stübner */ 194d3e51161SHeiko Stübner struct rockchip_pmx_func { 195d3e51161SHeiko Stübner const char *name; 196d3e51161SHeiko Stübner const char **groups; 197d3e51161SHeiko Stübner u8 ngroups; 198d3e51161SHeiko Stübner }; 199d3e51161SHeiko Stübner 200d3e51161SHeiko Stübner struct rockchip_pinctrl { 201751a99abSHeiko Stübner struct regmap *regmap_base; 202bfc7a42aSHeiko Stübner int reg_size; 203751a99abSHeiko Stübner struct regmap *regmap_pull; 20414dee867SHeiko Stübner struct regmap *regmap_pmu; 205d3e51161SHeiko Stübner struct device *dev; 206d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 207d3e51161SHeiko Stübner struct pinctrl_desc pctl; 208d3e51161SHeiko Stübner struct pinctrl_dev *pctl_dev; 209d3e51161SHeiko Stübner struct rockchip_pin_group *groups; 210d3e51161SHeiko Stübner unsigned int ngroups; 211d3e51161SHeiko Stübner struct rockchip_pmx_func *functions; 212d3e51161SHeiko Stübner unsigned int nfunctions; 213d3e51161SHeiko Stübner }; 214d3e51161SHeiko Stübner 215751a99abSHeiko Stübner static struct regmap_config rockchip_regmap_config = { 216751a99abSHeiko Stübner .reg_bits = 32, 217751a99abSHeiko Stübner .val_bits = 32, 218751a99abSHeiko Stübner .reg_stride = 4, 219751a99abSHeiko Stübner }; 220751a99abSHeiko Stübner 221d3e51161SHeiko Stübner static inline struct rockchip_pin_bank *gc_to_pin_bank(struct gpio_chip *gc) 222d3e51161SHeiko Stübner { 223d3e51161SHeiko Stübner return container_of(gc, struct rockchip_pin_bank, gpio_chip); 224d3e51161SHeiko Stübner } 225d3e51161SHeiko Stübner 226d3e51161SHeiko Stübner static const inline struct rockchip_pin_group *pinctrl_name_to_group( 227d3e51161SHeiko Stübner const struct rockchip_pinctrl *info, 228d3e51161SHeiko Stübner const char *name) 229d3e51161SHeiko Stübner { 230d3e51161SHeiko Stübner int i; 231d3e51161SHeiko Stübner 232d3e51161SHeiko Stübner for (i = 0; i < info->ngroups; i++) { 2331cb95395SAxel Lin if (!strcmp(info->groups[i].name, name)) 2341cb95395SAxel Lin return &info->groups[i]; 235d3e51161SHeiko Stübner } 236d3e51161SHeiko Stübner 2371cb95395SAxel Lin return NULL; 238d3e51161SHeiko Stübner } 239d3e51161SHeiko Stübner 240d3e51161SHeiko Stübner /* 241d3e51161SHeiko Stübner * given a pin number that is local to a pin controller, find out the pin bank 242d3e51161SHeiko Stübner * and the register base of the pin bank. 243d3e51161SHeiko Stübner */ 244d3e51161SHeiko Stübner static struct rockchip_pin_bank *pin_to_bank(struct rockchip_pinctrl *info, 245d3e51161SHeiko Stübner unsigned pin) 246d3e51161SHeiko Stübner { 247d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 248d3e51161SHeiko Stübner 24951578b9bSAxel Lin while (pin >= (b->pin_base + b->nr_pins)) 250d3e51161SHeiko Stübner b++; 251d3e51161SHeiko Stübner 252d3e51161SHeiko Stübner return b; 253d3e51161SHeiko Stübner } 254d3e51161SHeiko Stübner 255d3e51161SHeiko Stübner static struct rockchip_pin_bank *bank_num_to_bank( 256d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 257d3e51161SHeiko Stübner unsigned num) 258d3e51161SHeiko Stübner { 259d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 260d3e51161SHeiko Stübner int i; 261d3e51161SHeiko Stübner 2621cb95395SAxel Lin for (i = 0; i < info->ctrl->nr_banks; i++, b++) { 263d3e51161SHeiko Stübner if (b->bank_num == num) 2641cb95395SAxel Lin return b; 265d3e51161SHeiko Stübner } 266d3e51161SHeiko Stübner 267d3e51161SHeiko Stübner return ERR_PTR(-EINVAL); 268d3e51161SHeiko Stübner } 269d3e51161SHeiko Stübner 270d3e51161SHeiko Stübner /* 271d3e51161SHeiko Stübner * Pinctrl_ops handling 272d3e51161SHeiko Stübner */ 273d3e51161SHeiko Stübner 274d3e51161SHeiko Stübner static int rockchip_get_groups_count(struct pinctrl_dev *pctldev) 275d3e51161SHeiko Stübner { 276d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 277d3e51161SHeiko Stübner 278d3e51161SHeiko Stübner return info->ngroups; 279d3e51161SHeiko Stübner } 280d3e51161SHeiko Stübner 281d3e51161SHeiko Stübner static const char *rockchip_get_group_name(struct pinctrl_dev *pctldev, 282d3e51161SHeiko Stübner unsigned selector) 283d3e51161SHeiko Stübner { 284d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 285d3e51161SHeiko Stübner 286d3e51161SHeiko Stübner return info->groups[selector].name; 287d3e51161SHeiko Stübner } 288d3e51161SHeiko Stübner 289d3e51161SHeiko Stübner static int rockchip_get_group_pins(struct pinctrl_dev *pctldev, 290d3e51161SHeiko Stübner unsigned selector, const unsigned **pins, 291d3e51161SHeiko Stübner unsigned *npins) 292d3e51161SHeiko Stübner { 293d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 294d3e51161SHeiko Stübner 295d3e51161SHeiko Stübner if (selector >= info->ngroups) 296d3e51161SHeiko Stübner return -EINVAL; 297d3e51161SHeiko Stübner 298d3e51161SHeiko Stübner *pins = info->groups[selector].pins; 299d3e51161SHeiko Stübner *npins = info->groups[selector].npins; 300d3e51161SHeiko Stübner 301d3e51161SHeiko Stübner return 0; 302d3e51161SHeiko Stübner } 303d3e51161SHeiko Stübner 304d3e51161SHeiko Stübner static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev, 305d3e51161SHeiko Stübner struct device_node *np, 306d3e51161SHeiko Stübner struct pinctrl_map **map, unsigned *num_maps) 307d3e51161SHeiko Stübner { 308d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 309d3e51161SHeiko Stübner const struct rockchip_pin_group *grp; 310d3e51161SHeiko Stübner struct pinctrl_map *new_map; 311d3e51161SHeiko Stübner struct device_node *parent; 312d3e51161SHeiko Stübner int map_num = 1; 313d3e51161SHeiko Stübner int i; 314d3e51161SHeiko Stübner 315d3e51161SHeiko Stübner /* 316d3e51161SHeiko Stübner * first find the group of this node and check if we need to create 317d3e51161SHeiko Stübner * config maps for pins 318d3e51161SHeiko Stübner */ 319d3e51161SHeiko Stübner grp = pinctrl_name_to_group(info, np->name); 320d3e51161SHeiko Stübner if (!grp) { 321d3e51161SHeiko Stübner dev_err(info->dev, "unable to find group for node %s\n", 322d3e51161SHeiko Stübner np->name); 323d3e51161SHeiko Stübner return -EINVAL; 324d3e51161SHeiko Stübner } 325d3e51161SHeiko Stübner 326d3e51161SHeiko Stübner map_num += grp->npins; 327d3e51161SHeiko Stübner new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num, 328d3e51161SHeiko Stübner GFP_KERNEL); 329d3e51161SHeiko Stübner if (!new_map) 330d3e51161SHeiko Stübner return -ENOMEM; 331d3e51161SHeiko Stübner 332d3e51161SHeiko Stübner *map = new_map; 333d3e51161SHeiko Stübner *num_maps = map_num; 334d3e51161SHeiko Stübner 335d3e51161SHeiko Stübner /* create mux map */ 336d3e51161SHeiko Stübner parent = of_get_parent(np); 337d3e51161SHeiko Stübner if (!parent) { 338d3e51161SHeiko Stübner devm_kfree(pctldev->dev, new_map); 339d3e51161SHeiko Stübner return -EINVAL; 340d3e51161SHeiko Stübner } 341d3e51161SHeiko Stübner new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; 342d3e51161SHeiko Stübner new_map[0].data.mux.function = parent->name; 343d3e51161SHeiko Stübner new_map[0].data.mux.group = np->name; 344d3e51161SHeiko Stübner of_node_put(parent); 345d3e51161SHeiko Stübner 346d3e51161SHeiko Stübner /* create config map */ 347d3e51161SHeiko Stübner new_map++; 348d3e51161SHeiko Stübner for (i = 0; i < grp->npins; i++) { 349d3e51161SHeiko Stübner new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; 350d3e51161SHeiko Stübner new_map[i].data.configs.group_or_pin = 351d3e51161SHeiko Stübner pin_get_name(pctldev, grp->pins[i]); 352d3e51161SHeiko Stübner new_map[i].data.configs.configs = grp->data[i].configs; 353d3e51161SHeiko Stübner new_map[i].data.configs.num_configs = grp->data[i].nconfigs; 354d3e51161SHeiko Stübner } 355d3e51161SHeiko Stübner 356d3e51161SHeiko Stübner dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", 357d3e51161SHeiko Stübner (*map)->data.mux.function, (*map)->data.mux.group, map_num); 358d3e51161SHeiko Stübner 359d3e51161SHeiko Stübner return 0; 360d3e51161SHeiko Stübner } 361d3e51161SHeiko Stübner 362d3e51161SHeiko Stübner static void rockchip_dt_free_map(struct pinctrl_dev *pctldev, 363d3e51161SHeiko Stübner struct pinctrl_map *map, unsigned num_maps) 364d3e51161SHeiko Stübner { 365d3e51161SHeiko Stübner } 366d3e51161SHeiko Stübner 367d3e51161SHeiko Stübner static const struct pinctrl_ops rockchip_pctrl_ops = { 368d3e51161SHeiko Stübner .get_groups_count = rockchip_get_groups_count, 369d3e51161SHeiko Stübner .get_group_name = rockchip_get_group_name, 370d3e51161SHeiko Stübner .get_group_pins = rockchip_get_group_pins, 371d3e51161SHeiko Stübner .dt_node_to_map = rockchip_dt_node_to_map, 372d3e51161SHeiko Stübner .dt_free_map = rockchip_dt_free_map, 373d3e51161SHeiko Stübner }; 374d3e51161SHeiko Stübner 375d3e51161SHeiko Stübner /* 376d3e51161SHeiko Stübner * Hardware access 377d3e51161SHeiko Stübner */ 378d3e51161SHeiko Stübner 379a076e2edSHeiko Stübner static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) 380a076e2edSHeiko Stübner { 381a076e2edSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 382fc72c923SHeiko Stübner int iomux_num = (pin / 8); 38395ec8ae4SHeiko Stübner struct regmap *regmap; 384751a99abSHeiko Stübner unsigned int val; 38503716e1dSHeiko Stübner int reg, ret, mask; 386a076e2edSHeiko Stübner u8 bit; 387a076e2edSHeiko Stübner 388fc72c923SHeiko Stübner if (iomux_num > 3) 389fc72c923SHeiko Stübner return -EINVAL; 390fc72c923SHeiko Stübner 39162f49226SHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 39262f49226SHeiko Stübner dev_err(info->dev, "pin %d is unrouted\n", pin); 39362f49226SHeiko Stübner return -EINVAL; 39462f49226SHeiko Stübner } 39562f49226SHeiko Stübner 396fc72c923SHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 397a076e2edSHeiko Stübner return RK_FUNC_GPIO; 398a076e2edSHeiko Stübner 39995ec8ae4SHeiko Stübner regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 40095ec8ae4SHeiko Stübner ? info->regmap_pmu : info->regmap_base; 40195ec8ae4SHeiko Stübner 402a076e2edSHeiko Stübner /* get basic quadrupel of mux registers and the correct reg inside */ 40303716e1dSHeiko Stübner mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3; 4046bc0d121SHeiko Stübner reg = bank->iomux[iomux_num].offset; 40503716e1dSHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) { 40603716e1dSHeiko Stübner if ((pin % 8) >= 4) 40703716e1dSHeiko Stübner reg += 0x4; 40803716e1dSHeiko Stübner bit = (pin % 4) * 4; 40903716e1dSHeiko Stübner } else { 410a076e2edSHeiko Stübner bit = (pin % 8) * 2; 41103716e1dSHeiko Stübner } 412a076e2edSHeiko Stübner 41395ec8ae4SHeiko Stübner ret = regmap_read(regmap, reg, &val); 414751a99abSHeiko Stübner if (ret) 415751a99abSHeiko Stübner return ret; 416751a99abSHeiko Stübner 41703716e1dSHeiko Stübner return ((val >> bit) & mask); 418a076e2edSHeiko Stübner } 419a076e2edSHeiko Stübner 420d3e51161SHeiko Stübner /* 421d3e51161SHeiko Stübner * Set a new mux function for a pin. 422d3e51161SHeiko Stübner * 423d3e51161SHeiko Stübner * The register is divided into the upper and lower 16 bit. When changing 424d3e51161SHeiko Stübner * a value, the previous register value is not read and changed. Instead 425d3e51161SHeiko Stübner * it seems the changed bits are marked in the upper 16 bit, while the 426d3e51161SHeiko Stübner * changed value gets set in the same offset in the lower 16 bit. 427d3e51161SHeiko Stübner * All pin settings seem to be 2 bit wide in both the upper and lower 428d3e51161SHeiko Stübner * parts. 429d3e51161SHeiko Stübner * @bank: pin bank to change 430d3e51161SHeiko Stübner * @pin: pin to change 431d3e51161SHeiko Stübner * @mux: new mux function to set 432d3e51161SHeiko Stübner */ 43314797189SHeiko Stübner static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 434d3e51161SHeiko Stübner { 435d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 436fc72c923SHeiko Stübner int iomux_num = (pin / 8); 43795ec8ae4SHeiko Stübner struct regmap *regmap; 43803716e1dSHeiko Stübner int reg, ret, mask; 439d3e51161SHeiko Stübner unsigned long flags; 440d3e51161SHeiko Stübner u8 bit; 441d3e51161SHeiko Stübner u32 data; 442d3e51161SHeiko Stübner 443fc72c923SHeiko Stübner if (iomux_num > 3) 444fc72c923SHeiko Stübner return -EINVAL; 445fc72c923SHeiko Stübner 44662f49226SHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 44762f49226SHeiko Stübner dev_err(info->dev, "pin %d is unrouted\n", pin); 44862f49226SHeiko Stübner return -EINVAL; 44962f49226SHeiko Stübner } 45062f49226SHeiko Stübner 451fc72c923SHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { 452c4a532deSHeiko Stübner if (mux != RK_FUNC_GPIO) { 453c4a532deSHeiko Stübner dev_err(info->dev, 454c4a532deSHeiko Stübner "pin %d only supports a gpio mux\n", pin); 455c4a532deSHeiko Stübner return -ENOTSUPP; 456c4a532deSHeiko Stübner } else { 457c4a532deSHeiko Stübner return 0; 458c4a532deSHeiko Stübner } 459c4a532deSHeiko Stübner } 460c4a532deSHeiko Stübner 461d3e51161SHeiko Stübner dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n", 462d3e51161SHeiko Stübner bank->bank_num, pin, mux); 463d3e51161SHeiko Stübner 46495ec8ae4SHeiko Stübner regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 46595ec8ae4SHeiko Stübner ? info->regmap_pmu : info->regmap_base; 46695ec8ae4SHeiko Stübner 467d3e51161SHeiko Stübner /* get basic quadrupel of mux registers and the correct reg inside */ 46803716e1dSHeiko Stübner mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3; 4696bc0d121SHeiko Stübner reg = bank->iomux[iomux_num].offset; 47003716e1dSHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) { 47103716e1dSHeiko Stübner if ((pin % 8) >= 4) 47203716e1dSHeiko Stübner reg += 0x4; 47303716e1dSHeiko Stübner bit = (pin % 4) * 4; 47403716e1dSHeiko Stübner } else { 475d3e51161SHeiko Stübner bit = (pin % 8) * 2; 47603716e1dSHeiko Stübner } 477d3e51161SHeiko Stübner 478d3e51161SHeiko Stübner spin_lock_irqsave(&bank->slock, flags); 479d3e51161SHeiko Stübner 48003716e1dSHeiko Stübner data = (mask << (bit + 16)); 48103716e1dSHeiko Stübner data |= (mux & mask) << bit; 48295ec8ae4SHeiko Stübner ret = regmap_write(regmap, reg, data); 483d3e51161SHeiko Stübner 484d3e51161SHeiko Stübner spin_unlock_irqrestore(&bank->slock, flags); 48514797189SHeiko Stübner 486751a99abSHeiko Stübner return ret; 487d3e51161SHeiko Stübner } 488d3e51161SHeiko Stübner 489a282926dSHeiko Stübner #define RK2928_PULL_OFFSET 0x118 490a282926dSHeiko Stübner #define RK2928_PULL_PINS_PER_REG 16 491a282926dSHeiko Stübner #define RK2928_PULL_BANK_STRIDE 8 492a282926dSHeiko Stübner 493a282926dSHeiko Stübner static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 494751a99abSHeiko Stübner int pin_num, struct regmap **regmap, 495751a99abSHeiko Stübner int *reg, u8 *bit) 496a282926dSHeiko Stübner { 497a282926dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 498a282926dSHeiko Stübner 499751a99abSHeiko Stübner *regmap = info->regmap_base; 500751a99abSHeiko Stübner *reg = RK2928_PULL_OFFSET; 501a282926dSHeiko Stübner *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 502a282926dSHeiko Stübner *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4; 503a282926dSHeiko Stübner 504a282926dSHeiko Stübner *bit = pin_num % RK2928_PULL_PINS_PER_REG; 505a282926dSHeiko Stübner }; 506a282926dSHeiko Stübner 507bfc7a42aSHeiko Stübner #define RK3188_PULL_OFFSET 0x164 5086ca5274dSHeiko Stübner #define RK3188_PULL_BITS_PER_PIN 2 5096ca5274dSHeiko Stübner #define RK3188_PULL_PINS_PER_REG 8 5106ca5274dSHeiko Stübner #define RK3188_PULL_BANK_STRIDE 16 51114dee867SHeiko Stübner #define RK3188_PULL_PMU_OFFSET 0x64 5126ca5274dSHeiko Stübner 5136ca5274dSHeiko Stübner static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 514751a99abSHeiko Stübner int pin_num, struct regmap **regmap, 515751a99abSHeiko Stübner int *reg, u8 *bit) 5166ca5274dSHeiko Stübner { 5176ca5274dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 5186ca5274dSHeiko Stübner 5196ca5274dSHeiko Stübner /* The first 12 pins of the first bank are located elsewhere */ 520fc72c923SHeiko Stübner if (bank->bank_num == 0 && pin_num < 12) { 52114dee867SHeiko Stübner *regmap = info->regmap_pmu ? info->regmap_pmu 52214dee867SHeiko Stübner : bank->regmap_pull; 52314dee867SHeiko Stübner *reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0; 524751a99abSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 5256ca5274dSHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 5266ca5274dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 5276ca5274dSHeiko Stübner } else { 528751a99abSHeiko Stübner *regmap = info->regmap_pull ? info->regmap_pull 529751a99abSHeiko Stübner : info->regmap_base; 530751a99abSHeiko Stübner *reg = info->regmap_pull ? 0 : RK3188_PULL_OFFSET; 531751a99abSHeiko Stübner 532bfc7a42aSHeiko Stübner /* correct the offset, as it is the 2nd pull register */ 533bfc7a42aSHeiko Stübner *reg -= 4; 5346ca5274dSHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 5356ca5274dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 5366ca5274dSHeiko Stübner 5376ca5274dSHeiko Stübner /* 5386ca5274dSHeiko Stübner * The bits in these registers have an inverse ordering 5396ca5274dSHeiko Stübner * with the lowest pin being in bits 15:14 and the highest 5406ca5274dSHeiko Stübner * pin in bits 1:0 5416ca5274dSHeiko Stübner */ 5426ca5274dSHeiko Stübner *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG); 5436ca5274dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 5446ca5274dSHeiko Stübner } 5456ca5274dSHeiko Stübner } 5466ca5274dSHeiko Stübner 547304f077dSHeiko Stübner #define RK3288_PULL_OFFSET 0x140 548304f077dSHeiko Stübner static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 549304f077dSHeiko Stübner int pin_num, struct regmap **regmap, 550304f077dSHeiko Stübner int *reg, u8 *bit) 551304f077dSHeiko Stübner { 552304f077dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 553304f077dSHeiko Stübner 554304f077dSHeiko Stübner /* The first 24 pins of the first bank are located in PMU */ 555304f077dSHeiko Stübner if (bank->bank_num == 0) { 556304f077dSHeiko Stübner *regmap = info->regmap_pmu; 557304f077dSHeiko Stübner *reg = RK3188_PULL_PMU_OFFSET; 558304f077dSHeiko Stübner 559304f077dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 560304f077dSHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 561304f077dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 562304f077dSHeiko Stübner } else { 563304f077dSHeiko Stübner *regmap = info->regmap_base; 564304f077dSHeiko Stübner *reg = RK3288_PULL_OFFSET; 565304f077dSHeiko Stübner 566304f077dSHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 567304f077dSHeiko Stübner *reg -= 0x10; 568304f077dSHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 569304f077dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 570304f077dSHeiko Stübner 571304f077dSHeiko Stübner *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 572304f077dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 573304f077dSHeiko Stübner } 574304f077dSHeiko Stübner } 575304f077dSHeiko Stübner 576d3e51161SHeiko Stübner static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) 577d3e51161SHeiko Stübner { 578d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 579d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 580751a99abSHeiko Stübner struct regmap *regmap; 581751a99abSHeiko Stübner int reg, ret; 582d3e51161SHeiko Stübner u8 bit; 5836ca5274dSHeiko Stübner u32 data; 584d3e51161SHeiko Stübner 585d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 586a282926dSHeiko Stübner if (ctrl->type == RK3066B) 587d3e51161SHeiko Stübner return PIN_CONFIG_BIAS_DISABLE; 588d3e51161SHeiko Stübner 589751a99abSHeiko Stübner ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); 590751a99abSHeiko Stübner 591751a99abSHeiko Stübner ret = regmap_read(regmap, reg, &data); 592751a99abSHeiko Stübner if (ret) 593751a99abSHeiko Stübner return ret; 5946ca5274dSHeiko Stübner 595a282926dSHeiko Stübner switch (ctrl->type) { 596a282926dSHeiko Stübner case RK2928: 597751a99abSHeiko Stübner return !(data & BIT(bit)) 598d3e51161SHeiko Stübner ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT 599d3e51161SHeiko Stübner : PIN_CONFIG_BIAS_DISABLE; 600a282926dSHeiko Stübner case RK3188: 601*66d750e1SHeiko Stübner case RK3288: 602751a99abSHeiko Stübner data >>= bit; 6036ca5274dSHeiko Stübner data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; 6046ca5274dSHeiko Stübner 6056ca5274dSHeiko Stübner switch (data) { 6066ca5274dSHeiko Stübner case 0: 6076ca5274dSHeiko Stübner return PIN_CONFIG_BIAS_DISABLE; 6086ca5274dSHeiko Stübner case 1: 6096ca5274dSHeiko Stübner return PIN_CONFIG_BIAS_PULL_UP; 6106ca5274dSHeiko Stübner case 2: 6116ca5274dSHeiko Stübner return PIN_CONFIG_BIAS_PULL_DOWN; 6126ca5274dSHeiko Stübner case 3: 6136ca5274dSHeiko Stübner return PIN_CONFIG_BIAS_BUS_HOLD; 6146ca5274dSHeiko Stübner } 6156ca5274dSHeiko Stübner 6166ca5274dSHeiko Stübner dev_err(info->dev, "unknown pull setting\n"); 617d3e51161SHeiko Stübner return -EIO; 618a282926dSHeiko Stübner default: 619a282926dSHeiko Stübner dev_err(info->dev, "unsupported pinctrl type\n"); 620a282926dSHeiko Stübner return -EINVAL; 621a282926dSHeiko Stübner }; 622d3e51161SHeiko Stübner } 623d3e51161SHeiko Stübner 624d3e51161SHeiko Stübner static int rockchip_set_pull(struct rockchip_pin_bank *bank, 625d3e51161SHeiko Stübner int pin_num, int pull) 626d3e51161SHeiko Stübner { 627d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 628d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 629751a99abSHeiko Stübner struct regmap *regmap; 630751a99abSHeiko Stübner int reg, ret; 631d3e51161SHeiko Stübner unsigned long flags; 632d3e51161SHeiko Stübner u8 bit; 633d3e51161SHeiko Stübner u32 data; 634d3e51161SHeiko Stübner 635d3e51161SHeiko Stübner dev_dbg(info->dev, "setting pull of GPIO%d-%d to %d\n", 636d3e51161SHeiko Stübner bank->bank_num, pin_num, pull); 637d3e51161SHeiko Stübner 638d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 639a282926dSHeiko Stübner if (ctrl->type == RK3066B) 640d3e51161SHeiko Stübner return pull ? -EINVAL : 0; 641d3e51161SHeiko Stübner 642751a99abSHeiko Stübner ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); 643d3e51161SHeiko Stübner 6446ca5274dSHeiko Stübner switch (ctrl->type) { 6456ca5274dSHeiko Stübner case RK2928: 646d3e51161SHeiko Stübner spin_lock_irqsave(&bank->slock, flags); 647d3e51161SHeiko Stübner 648d3e51161SHeiko Stübner data = BIT(bit + 16); 649d3e51161SHeiko Stübner if (pull == PIN_CONFIG_BIAS_DISABLE) 650d3e51161SHeiko Stübner data |= BIT(bit); 651751a99abSHeiko Stübner ret = regmap_write(regmap, reg, data); 652d3e51161SHeiko Stübner 653d3e51161SHeiko Stübner spin_unlock_irqrestore(&bank->slock, flags); 654a282926dSHeiko Stübner break; 655a282926dSHeiko Stübner case RK3188: 656*66d750e1SHeiko Stübner case RK3288: 6576ca5274dSHeiko Stübner spin_lock_irqsave(&bank->slock, flags); 6586ca5274dSHeiko Stübner 6596ca5274dSHeiko Stübner /* enable the write to the equivalent lower bits */ 6606ca5274dSHeiko Stübner data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); 6616ca5274dSHeiko Stübner 6626ca5274dSHeiko Stübner switch (pull) { 6636ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 6646ca5274dSHeiko Stübner break; 6656ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 6666ca5274dSHeiko Stübner data |= (1 << bit); 6676ca5274dSHeiko Stübner break; 6686ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 6696ca5274dSHeiko Stübner data |= (2 << bit); 6706ca5274dSHeiko Stübner break; 6716ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 6726ca5274dSHeiko Stübner data |= (3 << bit); 6736ca5274dSHeiko Stübner break; 6746ca5274dSHeiko Stübner default: 675d32c3e26SDan Carpenter spin_unlock_irqrestore(&bank->slock, flags); 6766ca5274dSHeiko Stübner dev_err(info->dev, "unsupported pull setting %d\n", 6776ca5274dSHeiko Stübner pull); 6786ca5274dSHeiko Stübner return -EINVAL; 6796ca5274dSHeiko Stübner } 6806ca5274dSHeiko Stübner 681751a99abSHeiko Stübner ret = regmap_write(regmap, reg, data); 6826ca5274dSHeiko Stübner 6836ca5274dSHeiko Stübner spin_unlock_irqrestore(&bank->slock, flags); 6846ca5274dSHeiko Stübner break; 685a282926dSHeiko Stübner default: 686a282926dSHeiko Stübner dev_err(info->dev, "unsupported pinctrl type\n"); 687a282926dSHeiko Stübner return -EINVAL; 688d3e51161SHeiko Stübner } 689d3e51161SHeiko Stübner 690751a99abSHeiko Stübner return ret; 691d3e51161SHeiko Stübner } 692d3e51161SHeiko Stübner 693d3e51161SHeiko Stübner /* 694d3e51161SHeiko Stübner * Pinmux_ops handling 695d3e51161SHeiko Stübner */ 696d3e51161SHeiko Stübner 697d3e51161SHeiko Stübner static int rockchip_pmx_get_funcs_count(struct pinctrl_dev *pctldev) 698d3e51161SHeiko Stübner { 699d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 700d3e51161SHeiko Stübner 701d3e51161SHeiko Stübner return info->nfunctions; 702d3e51161SHeiko Stübner } 703d3e51161SHeiko Stübner 704d3e51161SHeiko Stübner static const char *rockchip_pmx_get_func_name(struct pinctrl_dev *pctldev, 705d3e51161SHeiko Stübner unsigned selector) 706d3e51161SHeiko Stübner { 707d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 708d3e51161SHeiko Stübner 709d3e51161SHeiko Stübner return info->functions[selector].name; 710d3e51161SHeiko Stübner } 711d3e51161SHeiko Stübner 712d3e51161SHeiko Stübner static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev, 713d3e51161SHeiko Stübner unsigned selector, const char * const **groups, 714d3e51161SHeiko Stübner unsigned * const num_groups) 715d3e51161SHeiko Stübner { 716d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 717d3e51161SHeiko Stübner 718d3e51161SHeiko Stübner *groups = info->functions[selector].groups; 719d3e51161SHeiko Stübner *num_groups = info->functions[selector].ngroups; 720d3e51161SHeiko Stübner 721d3e51161SHeiko Stübner return 0; 722d3e51161SHeiko Stübner } 723d3e51161SHeiko Stübner 724d3e51161SHeiko Stübner static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, 725d3e51161SHeiko Stübner unsigned group) 726d3e51161SHeiko Stübner { 727d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 728d3e51161SHeiko Stübner const unsigned int *pins = info->groups[group].pins; 729d3e51161SHeiko Stübner const struct rockchip_pin_config *data = info->groups[group].data; 730d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 73114797189SHeiko Stübner int cnt, ret = 0; 732d3e51161SHeiko Stübner 733d3e51161SHeiko Stübner dev_dbg(info->dev, "enable function %s group %s\n", 734d3e51161SHeiko Stübner info->functions[selector].name, info->groups[group].name); 735d3e51161SHeiko Stübner 736d3e51161SHeiko Stübner /* 737d3e51161SHeiko Stübner * for each pin in the pin group selected, program the correspoding pin 738d3e51161SHeiko Stübner * pin function number in the config register. 739d3e51161SHeiko Stübner */ 740d3e51161SHeiko Stübner for (cnt = 0; cnt < info->groups[group].npins; cnt++) { 741d3e51161SHeiko Stübner bank = pin_to_bank(info, pins[cnt]); 74214797189SHeiko Stübner ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 743d3e51161SHeiko Stübner data[cnt].func); 74414797189SHeiko Stübner if (ret) 74514797189SHeiko Stübner break; 74614797189SHeiko Stübner } 74714797189SHeiko Stübner 74814797189SHeiko Stübner if (ret) { 74914797189SHeiko Stübner /* revert the already done pin settings */ 75014797189SHeiko Stübner for (cnt--; cnt >= 0; cnt--) 75114797189SHeiko Stübner rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); 75214797189SHeiko Stübner 75314797189SHeiko Stübner return ret; 754d3e51161SHeiko Stübner } 755d3e51161SHeiko Stübner 756d3e51161SHeiko Stübner return 0; 757d3e51161SHeiko Stübner } 758d3e51161SHeiko Stübner 759d3e51161SHeiko Stübner /* 760d3e51161SHeiko Stübner * The calls to gpio_direction_output() and gpio_direction_input() 761d3e51161SHeiko Stübner * leads to this function call (via the pinctrl_gpio_direction_{input|output}() 762d3e51161SHeiko Stübner * function called from the gpiolib interface). 763d3e51161SHeiko Stübner */ 764d3e51161SHeiko Stübner static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, 765d3e51161SHeiko Stübner struct pinctrl_gpio_range *range, 766d3e51161SHeiko Stübner unsigned offset, bool input) 767d3e51161SHeiko Stübner { 768d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 769d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 770d3e51161SHeiko Stübner struct gpio_chip *chip; 77114797189SHeiko Stübner int pin, ret; 772d3e51161SHeiko Stübner u32 data; 773d3e51161SHeiko Stübner 774d3e51161SHeiko Stübner chip = range->gc; 775d3e51161SHeiko Stübner bank = gc_to_pin_bank(chip); 776d3e51161SHeiko Stübner pin = offset - chip->base; 777d3e51161SHeiko Stübner 778d3e51161SHeiko Stübner dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", 779d3e51161SHeiko Stübner offset, range->name, pin, input ? "input" : "output"); 780d3e51161SHeiko Stübner 78114797189SHeiko Stübner ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); 78214797189SHeiko Stübner if (ret < 0) 78314797189SHeiko Stübner return ret; 784d3e51161SHeiko Stübner 785d3e51161SHeiko Stübner data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); 786d3e51161SHeiko Stübner /* set bit to 1 for output, 0 for input */ 787d3e51161SHeiko Stübner if (!input) 788d3e51161SHeiko Stübner data |= BIT(pin); 789d3e51161SHeiko Stübner else 790d3e51161SHeiko Stübner data &= ~BIT(pin); 791d3e51161SHeiko Stübner writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); 792d3e51161SHeiko Stübner 793d3e51161SHeiko Stübner return 0; 794d3e51161SHeiko Stübner } 795d3e51161SHeiko Stübner 796d3e51161SHeiko Stübner static const struct pinmux_ops rockchip_pmx_ops = { 797d3e51161SHeiko Stübner .get_functions_count = rockchip_pmx_get_funcs_count, 798d3e51161SHeiko Stübner .get_function_name = rockchip_pmx_get_func_name, 799d3e51161SHeiko Stübner .get_function_groups = rockchip_pmx_get_groups, 800d3e51161SHeiko Stübner .enable = rockchip_pmx_enable, 801d3e51161SHeiko Stübner .gpio_set_direction = rockchip_pmx_gpio_set_direction, 802d3e51161SHeiko Stübner }; 803d3e51161SHeiko Stübner 804d3e51161SHeiko Stübner /* 805d3e51161SHeiko Stübner * Pinconf_ops handling 806d3e51161SHeiko Stübner */ 807d3e51161SHeiko Stübner 80844b6d930SHeiko Stübner static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, 80944b6d930SHeiko Stübner enum pin_config_param pull) 81044b6d930SHeiko Stübner { 811a282926dSHeiko Stübner switch (ctrl->type) { 812a282926dSHeiko Stübner case RK2928: 813a282926dSHeiko Stübner return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT || 814a282926dSHeiko Stübner pull == PIN_CONFIG_BIAS_DISABLE); 815a282926dSHeiko Stübner case RK3066B: 81644b6d930SHeiko Stübner return pull ? false : true; 817a282926dSHeiko Stübner case RK3188: 818*66d750e1SHeiko Stübner case RK3288: 819a282926dSHeiko Stübner return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); 82044b6d930SHeiko Stübner } 82144b6d930SHeiko Stübner 822a282926dSHeiko Stübner return false; 82344b6d930SHeiko Stübner } 82444b6d930SHeiko Stübner 825a076e2edSHeiko Stübner static int rockchip_gpio_direction_output(struct gpio_chip *gc, 826a076e2edSHeiko Stübner unsigned offset, int value); 827a076e2edSHeiko Stübner static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); 828a076e2edSHeiko Stübner 829d3e51161SHeiko Stübner /* set the pin config settings for a specified pin */ 830d3e51161SHeiko Stübner static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, 83103b054e9SSherman Yin unsigned long *configs, unsigned num_configs) 832d3e51161SHeiko Stübner { 833d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 834d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 83503b054e9SSherman Yin enum pin_config_param param; 83603b054e9SSherman Yin u16 arg; 83703b054e9SSherman Yin int i; 83803b054e9SSherman Yin int rc; 83903b054e9SSherman Yin 84003b054e9SSherman Yin for (i = 0; i < num_configs; i++) { 84103b054e9SSherman Yin param = pinconf_to_config_param(configs[i]); 84203b054e9SSherman Yin arg = pinconf_to_config_argument(configs[i]); 843d3e51161SHeiko Stübner 844d3e51161SHeiko Stübner switch (param) { 845d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 84603b054e9SSherman Yin rc = rockchip_set_pull(bank, pin - bank->pin_base, 84703b054e9SSherman Yin param); 84803b054e9SSherman Yin if (rc) 84903b054e9SSherman Yin return rc; 85044b6d930SHeiko Stübner break; 851d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 852d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 853d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 8546ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 85544b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 85644b6d930SHeiko Stübner return -ENOTSUPP; 85744b6d930SHeiko Stübner 85844b6d930SHeiko Stübner if (!arg) 85944b6d930SHeiko Stübner return -EINVAL; 86044b6d930SHeiko Stübner 86103b054e9SSherman Yin rc = rockchip_set_pull(bank, pin - bank->pin_base, 86203b054e9SSherman Yin param); 86303b054e9SSherman Yin if (rc) 86403b054e9SSherman Yin return rc; 865d3e51161SHeiko Stübner break; 866a076e2edSHeiko Stübner case PIN_CONFIG_OUTPUT: 867a076e2edSHeiko Stübner rc = rockchip_gpio_direction_output(&bank->gpio_chip, 868a076e2edSHeiko Stübner pin - bank->pin_base, 869a076e2edSHeiko Stübner arg); 870a076e2edSHeiko Stübner if (rc) 871a076e2edSHeiko Stübner return rc; 872a076e2edSHeiko Stübner break; 873d3e51161SHeiko Stübner default: 874d3e51161SHeiko Stübner return -ENOTSUPP; 875d3e51161SHeiko Stübner break; 876d3e51161SHeiko Stübner } 87703b054e9SSherman Yin } /* for each config */ 878d3e51161SHeiko Stübner 879d3e51161SHeiko Stübner return 0; 880d3e51161SHeiko Stübner } 881d3e51161SHeiko Stübner 882d3e51161SHeiko Stübner /* get the pin config settings for a specified pin */ 883d3e51161SHeiko Stübner static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, 884d3e51161SHeiko Stübner unsigned long *config) 885d3e51161SHeiko Stübner { 886d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 887d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 888d3e51161SHeiko Stübner enum pin_config_param param = pinconf_to_config_param(*config); 889dab3eba7SHeiko Stübner u16 arg; 890a076e2edSHeiko Stübner int rc; 891d3e51161SHeiko Stübner 892d3e51161SHeiko Stübner switch (param) { 893d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 89444b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 895d3e51161SHeiko Stübner return -EINVAL; 896d3e51161SHeiko Stübner 897dab3eba7SHeiko Stübner arg = 0; 898d3e51161SHeiko Stübner break; 89944b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 90044b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 90144b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 9026ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 90344b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 90444b6d930SHeiko Stübner return -ENOTSUPP; 90544b6d930SHeiko Stübner 90644b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 90744b6d930SHeiko Stübner return -EINVAL; 90844b6d930SHeiko Stübner 909dab3eba7SHeiko Stübner arg = 1; 91044b6d930SHeiko Stübner break; 911a076e2edSHeiko Stübner case PIN_CONFIG_OUTPUT: 912a076e2edSHeiko Stübner rc = rockchip_get_mux(bank, pin - bank->pin_base); 913a076e2edSHeiko Stübner if (rc != RK_FUNC_GPIO) 914a076e2edSHeiko Stübner return -EINVAL; 915a076e2edSHeiko Stübner 916a076e2edSHeiko Stübner rc = rockchip_gpio_get(&bank->gpio_chip, pin - bank->pin_base); 917a076e2edSHeiko Stübner if (rc < 0) 918a076e2edSHeiko Stübner return rc; 919a076e2edSHeiko Stübner 920a076e2edSHeiko Stübner arg = rc ? 1 : 0; 921a076e2edSHeiko Stübner break; 922d3e51161SHeiko Stübner default: 923d3e51161SHeiko Stübner return -ENOTSUPP; 924d3e51161SHeiko Stübner break; 925d3e51161SHeiko Stübner } 926d3e51161SHeiko Stübner 927dab3eba7SHeiko Stübner *config = pinconf_to_config_packed(param, arg); 928dab3eba7SHeiko Stübner 929d3e51161SHeiko Stübner return 0; 930d3e51161SHeiko Stübner } 931d3e51161SHeiko Stübner 932d3e51161SHeiko Stübner static const struct pinconf_ops rockchip_pinconf_ops = { 933d3e51161SHeiko Stübner .pin_config_get = rockchip_pinconf_get, 934d3e51161SHeiko Stübner .pin_config_set = rockchip_pinconf_set, 935ed62f2f2SHeiko Stübner .is_generic = true, 936d3e51161SHeiko Stübner }; 937d3e51161SHeiko Stübner 93865fca613SHeiko Stübner static const struct of_device_id rockchip_bank_match[] = { 93965fca613SHeiko Stübner { .compatible = "rockchip,gpio-bank" }, 9406ca5274dSHeiko Stübner { .compatible = "rockchip,rk3188-gpio-bank0" }, 94165fca613SHeiko Stübner {}, 94265fca613SHeiko Stübner }; 943d3e51161SHeiko Stübner 944d3e51161SHeiko Stübner static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info, 945d3e51161SHeiko Stübner struct device_node *np) 946d3e51161SHeiko Stübner { 947d3e51161SHeiko Stübner struct device_node *child; 948d3e51161SHeiko Stübner 949d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 95065fca613SHeiko Stübner if (of_match_node(rockchip_bank_match, child)) 951d3e51161SHeiko Stübner continue; 952d3e51161SHeiko Stübner 953d3e51161SHeiko Stübner info->nfunctions++; 954d3e51161SHeiko Stübner info->ngroups += of_get_child_count(child); 955d3e51161SHeiko Stübner } 956d3e51161SHeiko Stübner } 957d3e51161SHeiko Stübner 958d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_groups(struct device_node *np, 959d3e51161SHeiko Stübner struct rockchip_pin_group *grp, 960d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 961d3e51161SHeiko Stübner u32 index) 962d3e51161SHeiko Stübner { 963d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 964d3e51161SHeiko Stübner int size; 965d3e51161SHeiko Stübner const __be32 *list; 966d3e51161SHeiko Stübner int num; 967d3e51161SHeiko Stübner int i, j; 968d3e51161SHeiko Stübner int ret; 969d3e51161SHeiko Stübner 970d3e51161SHeiko Stübner dev_dbg(info->dev, "group(%d): %s\n", index, np->name); 971d3e51161SHeiko Stübner 972d3e51161SHeiko Stübner /* Initialise group */ 973d3e51161SHeiko Stübner grp->name = np->name; 974d3e51161SHeiko Stübner 975d3e51161SHeiko Stübner /* 976d3e51161SHeiko Stübner * the binding format is rockchip,pins = <bank pin mux CONFIG>, 977d3e51161SHeiko Stübner * do sanity check and calculate pins number 978d3e51161SHeiko Stübner */ 979d3e51161SHeiko Stübner list = of_get_property(np, "rockchip,pins", &size); 980d3e51161SHeiko Stübner /* we do not check return since it's safe node passed down */ 981d3e51161SHeiko Stübner size /= sizeof(*list); 982d3e51161SHeiko Stübner if (!size || size % 4) { 983d3e51161SHeiko Stübner dev_err(info->dev, "wrong pins number or pins and configs should be by 4\n"); 984d3e51161SHeiko Stübner return -EINVAL; 985d3e51161SHeiko Stübner } 986d3e51161SHeiko Stübner 987d3e51161SHeiko Stübner grp->npins = size / 4; 988d3e51161SHeiko Stübner 989d3e51161SHeiko Stübner grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), 990d3e51161SHeiko Stübner GFP_KERNEL); 991d3e51161SHeiko Stübner grp->data = devm_kzalloc(info->dev, grp->npins * 992d3e51161SHeiko Stübner sizeof(struct rockchip_pin_config), 993d3e51161SHeiko Stübner GFP_KERNEL); 994d3e51161SHeiko Stübner if (!grp->pins || !grp->data) 995d3e51161SHeiko Stübner return -ENOMEM; 996d3e51161SHeiko Stübner 997d3e51161SHeiko Stübner for (i = 0, j = 0; i < size; i += 4, j++) { 998d3e51161SHeiko Stübner const __be32 *phandle; 999d3e51161SHeiko Stübner struct device_node *np_config; 1000d3e51161SHeiko Stübner 1001d3e51161SHeiko Stübner num = be32_to_cpu(*list++); 1002d3e51161SHeiko Stübner bank = bank_num_to_bank(info, num); 1003d3e51161SHeiko Stübner if (IS_ERR(bank)) 1004d3e51161SHeiko Stübner return PTR_ERR(bank); 1005d3e51161SHeiko Stübner 1006d3e51161SHeiko Stübner grp->pins[j] = bank->pin_base + be32_to_cpu(*list++); 1007d3e51161SHeiko Stübner grp->data[j].func = be32_to_cpu(*list++); 1008d3e51161SHeiko Stübner 1009d3e51161SHeiko Stübner phandle = list++; 1010d3e51161SHeiko Stübner if (!phandle) 1011d3e51161SHeiko Stübner return -EINVAL; 1012d3e51161SHeiko Stübner 1013d3e51161SHeiko Stübner np_config = of_find_node_by_phandle(be32_to_cpup(phandle)); 1014d3e51161SHeiko Stübner ret = pinconf_generic_parse_dt_config(np_config, 1015d3e51161SHeiko Stübner &grp->data[j].configs, &grp->data[j].nconfigs); 1016d3e51161SHeiko Stübner if (ret) 1017d3e51161SHeiko Stübner return ret; 1018d3e51161SHeiko Stübner } 1019d3e51161SHeiko Stübner 1020d3e51161SHeiko Stübner return 0; 1021d3e51161SHeiko Stübner } 1022d3e51161SHeiko Stübner 1023d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_functions(struct device_node *np, 1024d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 1025d3e51161SHeiko Stübner u32 index) 1026d3e51161SHeiko Stübner { 1027d3e51161SHeiko Stübner struct device_node *child; 1028d3e51161SHeiko Stübner struct rockchip_pmx_func *func; 1029d3e51161SHeiko Stübner struct rockchip_pin_group *grp; 1030d3e51161SHeiko Stübner int ret; 1031d3e51161SHeiko Stübner static u32 grp_index; 1032d3e51161SHeiko Stübner u32 i = 0; 1033d3e51161SHeiko Stübner 1034d3e51161SHeiko Stübner dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name); 1035d3e51161SHeiko Stübner 1036d3e51161SHeiko Stübner func = &info->functions[index]; 1037d3e51161SHeiko Stübner 1038d3e51161SHeiko Stübner /* Initialise function */ 1039d3e51161SHeiko Stübner func->name = np->name; 1040d3e51161SHeiko Stübner func->ngroups = of_get_child_count(np); 1041d3e51161SHeiko Stübner if (func->ngroups <= 0) 1042d3e51161SHeiko Stübner return 0; 1043d3e51161SHeiko Stübner 1044d3e51161SHeiko Stübner func->groups = devm_kzalloc(info->dev, 1045d3e51161SHeiko Stübner func->ngroups * sizeof(char *), GFP_KERNEL); 1046d3e51161SHeiko Stübner if (!func->groups) 1047d3e51161SHeiko Stübner return -ENOMEM; 1048d3e51161SHeiko Stübner 1049d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 1050d3e51161SHeiko Stübner func->groups[i] = child->name; 1051d3e51161SHeiko Stübner grp = &info->groups[grp_index++]; 1052d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_groups(child, grp, info, i++); 1053d3e51161SHeiko Stübner if (ret) 1054d3e51161SHeiko Stübner return ret; 1055d3e51161SHeiko Stübner } 1056d3e51161SHeiko Stübner 1057d3e51161SHeiko Stübner return 0; 1058d3e51161SHeiko Stübner } 1059d3e51161SHeiko Stübner 1060d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_dt(struct platform_device *pdev, 1061d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 1062d3e51161SHeiko Stübner { 1063d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 1064d3e51161SHeiko Stübner struct device_node *np = dev->of_node; 1065d3e51161SHeiko Stübner struct device_node *child; 1066d3e51161SHeiko Stübner int ret; 1067d3e51161SHeiko Stübner int i; 1068d3e51161SHeiko Stübner 1069d3e51161SHeiko Stübner rockchip_pinctrl_child_count(info, np); 1070d3e51161SHeiko Stübner 1071d3e51161SHeiko Stübner dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); 1072d3e51161SHeiko Stübner dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); 1073d3e51161SHeiko Stübner 1074d3e51161SHeiko Stübner info->functions = devm_kzalloc(dev, info->nfunctions * 1075d3e51161SHeiko Stübner sizeof(struct rockchip_pmx_func), 1076d3e51161SHeiko Stübner GFP_KERNEL); 1077d3e51161SHeiko Stübner if (!info->functions) { 1078d3e51161SHeiko Stübner dev_err(dev, "failed to allocate memory for function list\n"); 1079d3e51161SHeiko Stübner return -EINVAL; 1080d3e51161SHeiko Stübner } 1081d3e51161SHeiko Stübner 1082d3e51161SHeiko Stübner info->groups = devm_kzalloc(dev, info->ngroups * 1083d3e51161SHeiko Stübner sizeof(struct rockchip_pin_group), 1084d3e51161SHeiko Stübner GFP_KERNEL); 1085d3e51161SHeiko Stübner if (!info->groups) { 1086d3e51161SHeiko Stübner dev_err(dev, "failed allocate memory for ping group list\n"); 1087d3e51161SHeiko Stübner return -EINVAL; 1088d3e51161SHeiko Stübner } 1089d3e51161SHeiko Stübner 1090d3e51161SHeiko Stübner i = 0; 1091d3e51161SHeiko Stübner 1092d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 109365fca613SHeiko Stübner if (of_match_node(rockchip_bank_match, child)) 1094d3e51161SHeiko Stübner continue; 109565fca613SHeiko Stübner 1096d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_functions(child, info, i++); 1097d3e51161SHeiko Stübner if (ret) { 1098d3e51161SHeiko Stübner dev_err(&pdev->dev, "failed to parse function\n"); 1099d3e51161SHeiko Stübner return ret; 1100d3e51161SHeiko Stübner } 1101d3e51161SHeiko Stübner } 1102d3e51161SHeiko Stübner 1103d3e51161SHeiko Stübner return 0; 1104d3e51161SHeiko Stübner } 1105d3e51161SHeiko Stübner 1106d3e51161SHeiko Stübner static int rockchip_pinctrl_register(struct platform_device *pdev, 1107d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 1108d3e51161SHeiko Stübner { 1109d3e51161SHeiko Stübner struct pinctrl_desc *ctrldesc = &info->pctl; 1110d3e51161SHeiko Stübner struct pinctrl_pin_desc *pindesc, *pdesc; 1111d3e51161SHeiko Stübner struct rockchip_pin_bank *pin_bank; 1112d3e51161SHeiko Stübner int pin, bank, ret; 1113d3e51161SHeiko Stübner int k; 1114d3e51161SHeiko Stübner 1115d3e51161SHeiko Stübner ctrldesc->name = "rockchip-pinctrl"; 1116d3e51161SHeiko Stübner ctrldesc->owner = THIS_MODULE; 1117d3e51161SHeiko Stübner ctrldesc->pctlops = &rockchip_pctrl_ops; 1118d3e51161SHeiko Stübner ctrldesc->pmxops = &rockchip_pmx_ops; 1119d3e51161SHeiko Stübner ctrldesc->confops = &rockchip_pinconf_ops; 1120d3e51161SHeiko Stübner 1121d3e51161SHeiko Stübner pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) * 1122d3e51161SHeiko Stübner info->ctrl->nr_pins, GFP_KERNEL); 1123d3e51161SHeiko Stübner if (!pindesc) { 1124d3e51161SHeiko Stübner dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n"); 1125d3e51161SHeiko Stübner return -ENOMEM; 1126d3e51161SHeiko Stübner } 1127d3e51161SHeiko Stübner ctrldesc->pins = pindesc; 1128d3e51161SHeiko Stübner ctrldesc->npins = info->ctrl->nr_pins; 1129d3e51161SHeiko Stübner 1130d3e51161SHeiko Stübner pdesc = pindesc; 1131d3e51161SHeiko Stübner for (bank = 0 , k = 0; bank < info->ctrl->nr_banks; bank++) { 1132d3e51161SHeiko Stübner pin_bank = &info->ctrl->pin_banks[bank]; 1133d3e51161SHeiko Stübner for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) { 1134d3e51161SHeiko Stübner pdesc->number = k; 1135d3e51161SHeiko Stübner pdesc->name = kasprintf(GFP_KERNEL, "%s-%d", 1136d3e51161SHeiko Stübner pin_bank->name, pin); 1137d3e51161SHeiko Stübner pdesc++; 1138d3e51161SHeiko Stübner } 1139d3e51161SHeiko Stübner } 1140d3e51161SHeiko Stübner 1141d3e51161SHeiko Stübner info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info); 1142d3e51161SHeiko Stübner if (!info->pctl_dev) { 1143d3e51161SHeiko Stübner dev_err(&pdev->dev, "could not register pinctrl driver\n"); 1144d3e51161SHeiko Stübner return -EINVAL; 1145d3e51161SHeiko Stübner } 1146d3e51161SHeiko Stübner 1147d3e51161SHeiko Stübner for (bank = 0; bank < info->ctrl->nr_banks; ++bank) { 1148d3e51161SHeiko Stübner pin_bank = &info->ctrl->pin_banks[bank]; 1149d3e51161SHeiko Stübner pin_bank->grange.name = pin_bank->name; 1150d3e51161SHeiko Stübner pin_bank->grange.id = bank; 1151d3e51161SHeiko Stübner pin_bank->grange.pin_base = pin_bank->pin_base; 1152d3e51161SHeiko Stübner pin_bank->grange.base = pin_bank->gpio_chip.base; 1153d3e51161SHeiko Stübner pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; 1154d3e51161SHeiko Stübner pin_bank->grange.gc = &pin_bank->gpio_chip; 1155d3e51161SHeiko Stübner pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange); 1156d3e51161SHeiko Stübner } 1157d3e51161SHeiko Stübner 1158d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_dt(pdev, info); 1159d3e51161SHeiko Stübner if (ret) { 1160d3e51161SHeiko Stübner pinctrl_unregister(info->pctl_dev); 1161d3e51161SHeiko Stübner return ret; 1162d3e51161SHeiko Stübner } 1163d3e51161SHeiko Stübner 1164d3e51161SHeiko Stübner return 0; 1165d3e51161SHeiko Stübner } 1166d3e51161SHeiko Stübner 1167d3e51161SHeiko Stübner /* 1168d3e51161SHeiko Stübner * GPIO handling 1169d3e51161SHeiko Stübner */ 1170d3e51161SHeiko Stübner 11710351c287SAxel Lin static int rockchip_gpio_request(struct gpio_chip *chip, unsigned offset) 11720351c287SAxel Lin { 11730351c287SAxel Lin return pinctrl_request_gpio(chip->base + offset); 11740351c287SAxel Lin } 11750351c287SAxel Lin 11760351c287SAxel Lin static void rockchip_gpio_free(struct gpio_chip *chip, unsigned offset) 11770351c287SAxel Lin { 11780351c287SAxel Lin pinctrl_free_gpio(chip->base + offset); 11790351c287SAxel Lin } 11800351c287SAxel Lin 1181d3e51161SHeiko Stübner static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value) 1182d3e51161SHeiko Stübner { 1183d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); 1184d3e51161SHeiko Stübner void __iomem *reg = bank->reg_base + GPIO_SWPORT_DR; 1185d3e51161SHeiko Stübner unsigned long flags; 1186d3e51161SHeiko Stübner u32 data; 1187d3e51161SHeiko Stübner 1188d3e51161SHeiko Stübner spin_lock_irqsave(&bank->slock, flags); 1189d3e51161SHeiko Stübner 1190d3e51161SHeiko Stübner data = readl(reg); 1191d3e51161SHeiko Stübner data &= ~BIT(offset); 1192d3e51161SHeiko Stübner if (value) 1193d3e51161SHeiko Stübner data |= BIT(offset); 1194d3e51161SHeiko Stübner writel(data, reg); 1195d3e51161SHeiko Stübner 1196d3e51161SHeiko Stübner spin_unlock_irqrestore(&bank->slock, flags); 1197d3e51161SHeiko Stübner } 1198d3e51161SHeiko Stübner 1199d3e51161SHeiko Stübner /* 1200d3e51161SHeiko Stübner * Returns the level of the pin for input direction and setting of the DR 1201d3e51161SHeiko Stübner * register for output gpios. 1202d3e51161SHeiko Stübner */ 1203d3e51161SHeiko Stübner static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset) 1204d3e51161SHeiko Stübner { 1205d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); 1206d3e51161SHeiko Stübner u32 data; 1207d3e51161SHeiko Stübner 1208d3e51161SHeiko Stübner data = readl(bank->reg_base + GPIO_EXT_PORT); 1209d3e51161SHeiko Stübner data >>= offset; 1210d3e51161SHeiko Stübner data &= 1; 1211d3e51161SHeiko Stübner return data; 1212d3e51161SHeiko Stübner } 1213d3e51161SHeiko Stübner 1214d3e51161SHeiko Stübner /* 1215d3e51161SHeiko Stübner * gpiolib gpio_direction_input callback function. The setting of the pin 1216d3e51161SHeiko Stübner * mux function as 'gpio input' will be handled by the pinctrl susbsystem 1217d3e51161SHeiko Stübner * interface. 1218d3e51161SHeiko Stübner */ 1219d3e51161SHeiko Stübner static int rockchip_gpio_direction_input(struct gpio_chip *gc, unsigned offset) 1220d3e51161SHeiko Stübner { 1221d3e51161SHeiko Stübner return pinctrl_gpio_direction_input(gc->base + offset); 1222d3e51161SHeiko Stübner } 1223d3e51161SHeiko Stübner 1224d3e51161SHeiko Stübner /* 1225d3e51161SHeiko Stübner * gpiolib gpio_direction_output callback function. The setting of the pin 1226d3e51161SHeiko Stübner * mux function as 'gpio output' will be handled by the pinctrl susbsystem 1227d3e51161SHeiko Stübner * interface. 1228d3e51161SHeiko Stübner */ 1229d3e51161SHeiko Stübner static int rockchip_gpio_direction_output(struct gpio_chip *gc, 1230d3e51161SHeiko Stübner unsigned offset, int value) 1231d3e51161SHeiko Stübner { 1232d3e51161SHeiko Stübner rockchip_gpio_set(gc, offset, value); 1233d3e51161SHeiko Stübner return pinctrl_gpio_direction_output(gc->base + offset); 1234d3e51161SHeiko Stübner } 1235d3e51161SHeiko Stübner 1236d3e51161SHeiko Stübner /* 1237d3e51161SHeiko Stübner * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin 1238d3e51161SHeiko Stübner * and a virtual IRQ, if not already present. 1239d3e51161SHeiko Stübner */ 1240d3e51161SHeiko Stübner static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned offset) 1241d3e51161SHeiko Stübner { 1242d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc_to_pin_bank(gc); 1243d3e51161SHeiko Stübner unsigned int virq; 1244d3e51161SHeiko Stübner 1245d3e51161SHeiko Stübner if (!bank->domain) 1246d3e51161SHeiko Stübner return -ENXIO; 1247d3e51161SHeiko Stübner 1248d3e51161SHeiko Stübner virq = irq_create_mapping(bank->domain, offset); 1249d3e51161SHeiko Stübner 1250d3e51161SHeiko Stübner return (virq) ? : -ENXIO; 1251d3e51161SHeiko Stübner } 1252d3e51161SHeiko Stübner 1253d3e51161SHeiko Stübner static const struct gpio_chip rockchip_gpiolib_chip = { 12540351c287SAxel Lin .request = rockchip_gpio_request, 12550351c287SAxel Lin .free = rockchip_gpio_free, 1256d3e51161SHeiko Stübner .set = rockchip_gpio_set, 1257d3e51161SHeiko Stübner .get = rockchip_gpio_get, 1258d3e51161SHeiko Stübner .direction_input = rockchip_gpio_direction_input, 1259d3e51161SHeiko Stübner .direction_output = rockchip_gpio_direction_output, 1260d3e51161SHeiko Stübner .to_irq = rockchip_gpio_to_irq, 1261d3e51161SHeiko Stübner .owner = THIS_MODULE, 1262d3e51161SHeiko Stübner }; 1263d3e51161SHeiko Stübner 1264d3e51161SHeiko Stübner /* 1265d3e51161SHeiko Stübner * Interrupt handling 1266d3e51161SHeiko Stübner */ 1267d3e51161SHeiko Stübner 1268d3e51161SHeiko Stübner static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) 1269d3e51161SHeiko Stübner { 1270d3e51161SHeiko Stübner struct irq_chip *chip = irq_get_chip(irq); 1271d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = irq_get_handler_data(irq); 12725a927501SHeiko Stübner u32 polarity = 0, data = 0; 1273d3e51161SHeiko Stübner u32 pend; 12745a927501SHeiko Stübner bool edge_changed = false; 1275d3e51161SHeiko Stübner 1276d3e51161SHeiko Stübner dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); 1277d3e51161SHeiko Stübner 1278d3e51161SHeiko Stübner chained_irq_enter(chip, desc); 1279d3e51161SHeiko Stübner 1280d3e51161SHeiko Stübner pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); 1281d3e51161SHeiko Stübner 12825a927501SHeiko Stübner if (bank->toggle_edge_mode) { 12835a927501SHeiko Stübner polarity = readl_relaxed(bank->reg_base + 12845a927501SHeiko Stübner GPIO_INT_POLARITY); 12855a927501SHeiko Stübner data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); 12865a927501SHeiko Stübner } 12875a927501SHeiko Stübner 1288d3e51161SHeiko Stübner while (pend) { 1289d3e51161SHeiko Stübner unsigned int virq; 1290d3e51161SHeiko Stübner 1291d3e51161SHeiko Stübner irq = __ffs(pend); 1292d3e51161SHeiko Stübner pend &= ~BIT(irq); 1293d3e51161SHeiko Stübner virq = irq_linear_revmap(bank->domain, irq); 1294d3e51161SHeiko Stübner 1295d3e51161SHeiko Stübner if (!virq) { 1296d3e51161SHeiko Stübner dev_err(bank->drvdata->dev, "unmapped irq %d\n", irq); 1297d3e51161SHeiko Stübner continue; 1298d3e51161SHeiko Stübner } 1299d3e51161SHeiko Stübner 1300d3e51161SHeiko Stübner dev_dbg(bank->drvdata->dev, "handling irq %d\n", irq); 1301d3e51161SHeiko Stübner 13025a927501SHeiko Stübner /* 13035a927501SHeiko Stübner * Triggering IRQ on both rising and falling edge 13045a927501SHeiko Stübner * needs manual intervention. 13055a927501SHeiko Stübner */ 13065a927501SHeiko Stübner if (bank->toggle_edge_mode & BIT(irq)) { 13075a927501SHeiko Stübner if (data & BIT(irq)) 13085a927501SHeiko Stübner polarity &= ~BIT(irq); 13095a927501SHeiko Stübner else 13105a927501SHeiko Stübner polarity |= BIT(irq); 13115a927501SHeiko Stübner 13125a927501SHeiko Stübner edge_changed = true; 13135a927501SHeiko Stübner } 13145a927501SHeiko Stübner 1315d3e51161SHeiko Stübner generic_handle_irq(virq); 1316d3e51161SHeiko Stübner } 1317d3e51161SHeiko Stübner 13185a927501SHeiko Stübner if (bank->toggle_edge_mode && edge_changed) { 13195a927501SHeiko Stübner /* Interrupt params should only be set with ints disabled */ 13205a927501SHeiko Stübner data = readl_relaxed(bank->reg_base + GPIO_INTEN); 13215a927501SHeiko Stübner writel_relaxed(0, bank->reg_base + GPIO_INTEN); 13225a927501SHeiko Stübner writel(polarity, bank->reg_base + GPIO_INT_POLARITY); 13235a927501SHeiko Stübner writel(data, bank->reg_base + GPIO_INTEN); 13245a927501SHeiko Stübner } 13255a927501SHeiko Stübner 1326d3e51161SHeiko Stübner chained_irq_exit(chip, desc); 1327d3e51161SHeiko Stübner } 1328d3e51161SHeiko Stübner 1329d3e51161SHeiko Stübner static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) 1330d3e51161SHeiko Stübner { 1331d3e51161SHeiko Stübner struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 1332d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = gc->private; 1333d3e51161SHeiko Stübner u32 mask = BIT(d->hwirq); 1334d3e51161SHeiko Stübner u32 polarity; 1335d3e51161SHeiko Stübner u32 level; 1336d3e51161SHeiko Stübner u32 data; 133714797189SHeiko Stübner int ret; 1338d3e51161SHeiko Stübner 13395a927501SHeiko Stübner /* make sure the pin is configured as gpio input */ 134014797189SHeiko Stübner ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO); 134114797189SHeiko Stübner if (ret < 0) 134214797189SHeiko Stübner return ret; 134314797189SHeiko Stübner 13445a927501SHeiko Stübner data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); 13455a927501SHeiko Stübner data &= ~mask; 13465a927501SHeiko Stübner writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); 13475a927501SHeiko Stübner 1348d3e51161SHeiko Stübner if (type & IRQ_TYPE_EDGE_BOTH) 1349d3e51161SHeiko Stübner __irq_set_handler_locked(d->irq, handle_edge_irq); 1350d3e51161SHeiko Stübner else 1351d3e51161SHeiko Stübner __irq_set_handler_locked(d->irq, handle_level_irq); 1352d3e51161SHeiko Stübner 1353d3e51161SHeiko Stübner irq_gc_lock(gc); 1354d3e51161SHeiko Stübner 1355d3e51161SHeiko Stübner level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL); 1356d3e51161SHeiko Stübner polarity = readl_relaxed(gc->reg_base + GPIO_INT_POLARITY); 1357d3e51161SHeiko Stübner 1358d3e51161SHeiko Stübner switch (type) { 13595a927501SHeiko Stübner case IRQ_TYPE_EDGE_BOTH: 13605a927501SHeiko Stübner bank->toggle_edge_mode |= mask; 13615a927501SHeiko Stübner level |= mask; 13625a927501SHeiko Stübner 13635a927501SHeiko Stübner /* 13645a927501SHeiko Stübner * Determine gpio state. If 1 next interrupt should be falling 13655a927501SHeiko Stübner * otherwise rising. 13665a927501SHeiko Stübner */ 13675a927501SHeiko Stübner data = readl(bank->reg_base + GPIO_EXT_PORT); 13685a927501SHeiko Stübner if (data & mask) 13695a927501SHeiko Stübner polarity &= ~mask; 13705a927501SHeiko Stübner else 13715a927501SHeiko Stübner polarity |= mask; 13725a927501SHeiko Stübner break; 1373d3e51161SHeiko Stübner case IRQ_TYPE_EDGE_RISING: 13745a927501SHeiko Stübner bank->toggle_edge_mode &= ~mask; 1375d3e51161SHeiko Stübner level |= mask; 1376d3e51161SHeiko Stübner polarity |= mask; 1377d3e51161SHeiko Stübner break; 1378d3e51161SHeiko Stübner case IRQ_TYPE_EDGE_FALLING: 13795a927501SHeiko Stübner bank->toggle_edge_mode &= ~mask; 1380d3e51161SHeiko Stübner level |= mask; 1381d3e51161SHeiko Stübner polarity &= ~mask; 1382d3e51161SHeiko Stübner break; 1383d3e51161SHeiko Stübner case IRQ_TYPE_LEVEL_HIGH: 13845a927501SHeiko Stübner bank->toggle_edge_mode &= ~mask; 1385d3e51161SHeiko Stübner level &= ~mask; 1386d3e51161SHeiko Stübner polarity |= mask; 1387d3e51161SHeiko Stübner break; 1388d3e51161SHeiko Stübner case IRQ_TYPE_LEVEL_LOW: 13895a927501SHeiko Stübner bank->toggle_edge_mode &= ~mask; 1390d3e51161SHeiko Stübner level &= ~mask; 1391d3e51161SHeiko Stübner polarity &= ~mask; 1392d3e51161SHeiko Stübner break; 1393d3e51161SHeiko Stübner default: 13947cc5f970SAxel Lin irq_gc_unlock(gc); 1395d3e51161SHeiko Stübner return -EINVAL; 1396d3e51161SHeiko Stübner } 1397d3e51161SHeiko Stübner 1398d3e51161SHeiko Stübner writel_relaxed(level, gc->reg_base + GPIO_INTTYPE_LEVEL); 1399d3e51161SHeiko Stübner writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY); 1400d3e51161SHeiko Stübner 1401d3e51161SHeiko Stübner irq_gc_unlock(gc); 1402d3e51161SHeiko Stübner 1403d3e51161SHeiko Stübner return 0; 1404d3e51161SHeiko Stübner } 1405d3e51161SHeiko Stübner 1406d3e51161SHeiko Stübner static int rockchip_interrupts_register(struct platform_device *pdev, 1407d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 1408d3e51161SHeiko Stübner { 1409d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1410d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = ctrl->pin_banks; 1411d3e51161SHeiko Stübner unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; 1412d3e51161SHeiko Stübner struct irq_chip_generic *gc; 1413d3e51161SHeiko Stübner int ret; 1414d3e51161SHeiko Stübner int i; 1415d3e51161SHeiko Stübner 1416d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1417d3e51161SHeiko Stübner if (!bank->valid) { 1418d3e51161SHeiko Stübner dev_warn(&pdev->dev, "bank %s is not valid\n", 1419d3e51161SHeiko Stübner bank->name); 1420d3e51161SHeiko Stübner continue; 1421d3e51161SHeiko Stübner } 1422d3e51161SHeiko Stübner 1423d3e51161SHeiko Stübner bank->domain = irq_domain_add_linear(bank->of_node, 32, 1424d3e51161SHeiko Stübner &irq_generic_chip_ops, NULL); 1425d3e51161SHeiko Stübner if (!bank->domain) { 1426d3e51161SHeiko Stübner dev_warn(&pdev->dev, "could not initialize irq domain for bank %s\n", 1427d3e51161SHeiko Stübner bank->name); 1428d3e51161SHeiko Stübner continue; 1429d3e51161SHeiko Stübner } 1430d3e51161SHeiko Stübner 1431d3e51161SHeiko Stübner ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1, 1432d3e51161SHeiko Stübner "rockchip_gpio_irq", handle_level_irq, 1433d3e51161SHeiko Stübner clr, 0, IRQ_GC_INIT_MASK_CACHE); 1434d3e51161SHeiko Stübner if (ret) { 1435d3e51161SHeiko Stübner dev_err(&pdev->dev, "could not alloc generic chips for bank %s\n", 1436d3e51161SHeiko Stübner bank->name); 1437d3e51161SHeiko Stübner irq_domain_remove(bank->domain); 1438d3e51161SHeiko Stübner continue; 1439d3e51161SHeiko Stübner } 1440d3e51161SHeiko Stübner 1441d3e51161SHeiko Stübner gc = irq_get_domain_generic_chip(bank->domain, 0); 1442d3e51161SHeiko Stübner gc->reg_base = bank->reg_base; 1443d3e51161SHeiko Stübner gc->private = bank; 1444d3e51161SHeiko Stübner gc->chip_types[0].regs.mask = GPIO_INTEN; 1445d3e51161SHeiko Stübner gc->chip_types[0].regs.ack = GPIO_PORTS_EOI; 1446d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; 1447d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; 1448d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; 1449d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; 1450d3e51161SHeiko Stübner gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; 1451d3e51161SHeiko Stübner 1452d3e51161SHeiko Stübner irq_set_handler_data(bank->irq, bank); 1453d3e51161SHeiko Stübner irq_set_chained_handler(bank->irq, rockchip_irq_demux); 1454d3e51161SHeiko Stübner } 1455d3e51161SHeiko Stübner 1456d3e51161SHeiko Stübner return 0; 1457d3e51161SHeiko Stübner } 1458d3e51161SHeiko Stübner 1459d3e51161SHeiko Stübner static int rockchip_gpiolib_register(struct platform_device *pdev, 1460d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 1461d3e51161SHeiko Stübner { 1462d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1463d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = ctrl->pin_banks; 1464d3e51161SHeiko Stübner struct gpio_chip *gc; 1465d3e51161SHeiko Stübner int ret; 1466d3e51161SHeiko Stübner int i; 1467d3e51161SHeiko Stübner 1468d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1469d3e51161SHeiko Stübner if (!bank->valid) { 1470d3e51161SHeiko Stübner dev_warn(&pdev->dev, "bank %s is not valid\n", 1471d3e51161SHeiko Stübner bank->name); 1472d3e51161SHeiko Stübner continue; 1473d3e51161SHeiko Stübner } 1474d3e51161SHeiko Stübner 1475d3e51161SHeiko Stübner bank->gpio_chip = rockchip_gpiolib_chip; 1476d3e51161SHeiko Stübner 1477d3e51161SHeiko Stübner gc = &bank->gpio_chip; 1478d3e51161SHeiko Stübner gc->base = bank->pin_base; 1479d3e51161SHeiko Stübner gc->ngpio = bank->nr_pins; 1480d3e51161SHeiko Stübner gc->dev = &pdev->dev; 1481d3e51161SHeiko Stübner gc->of_node = bank->of_node; 1482d3e51161SHeiko Stübner gc->label = bank->name; 1483d3e51161SHeiko Stübner 1484d3e51161SHeiko Stübner ret = gpiochip_add(gc); 1485d3e51161SHeiko Stübner if (ret) { 1486d3e51161SHeiko Stübner dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n", 1487d3e51161SHeiko Stübner gc->label, ret); 1488d3e51161SHeiko Stübner goto fail; 1489d3e51161SHeiko Stübner } 1490d3e51161SHeiko Stübner } 1491d3e51161SHeiko Stübner 1492d3e51161SHeiko Stübner rockchip_interrupts_register(pdev, info); 1493d3e51161SHeiko Stübner 1494d3e51161SHeiko Stübner return 0; 1495d3e51161SHeiko Stübner 1496d3e51161SHeiko Stübner fail: 1497d3e51161SHeiko Stübner for (--i, --bank; i >= 0; --i, --bank) { 1498d3e51161SHeiko Stübner if (!bank->valid) 1499d3e51161SHeiko Stübner continue; 1500b4e7c55dSabdoulaye berthe gpiochip_remove(&bank->gpio_chip); 1501d3e51161SHeiko Stübner } 1502d3e51161SHeiko Stübner return ret; 1503d3e51161SHeiko Stübner } 1504d3e51161SHeiko Stübner 1505d3e51161SHeiko Stübner static int rockchip_gpiolib_unregister(struct platform_device *pdev, 1506d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 1507d3e51161SHeiko Stübner { 1508d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1509d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = ctrl->pin_banks; 1510d3e51161SHeiko Stübner int i; 1511d3e51161SHeiko Stübner 1512b4e7c55dSabdoulaye berthe for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1513d3e51161SHeiko Stübner if (!bank->valid) 1514d3e51161SHeiko Stübner continue; 1515b4e7c55dSabdoulaye berthe gpiochip_remove(&bank->gpio_chip); 1516d3e51161SHeiko Stübner } 1517d3e51161SHeiko Stübner 1518b4e7c55dSabdoulaye berthe return 0; 1519d3e51161SHeiko Stübner } 1520d3e51161SHeiko Stübner 1521d3e51161SHeiko Stübner static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, 1522622f3237SHeiko Stübner struct rockchip_pinctrl *info) 1523d3e51161SHeiko Stübner { 1524d3e51161SHeiko Stübner struct resource res; 1525751a99abSHeiko Stübner void __iomem *base; 1526d3e51161SHeiko Stübner 1527d3e51161SHeiko Stübner if (of_address_to_resource(bank->of_node, 0, &res)) { 1528622f3237SHeiko Stübner dev_err(info->dev, "cannot find IO resource for bank\n"); 1529d3e51161SHeiko Stübner return -ENOENT; 1530d3e51161SHeiko Stübner } 1531d3e51161SHeiko Stübner 1532622f3237SHeiko Stübner bank->reg_base = devm_ioremap_resource(info->dev, &res); 1533d3e51161SHeiko Stübner if (IS_ERR(bank->reg_base)) 1534d3e51161SHeiko Stübner return PTR_ERR(bank->reg_base); 1535d3e51161SHeiko Stübner 15366ca5274dSHeiko Stübner /* 15376ca5274dSHeiko Stübner * special case, where parts of the pull setting-registers are 15386ca5274dSHeiko Stübner * part of the PMU register space 15396ca5274dSHeiko Stübner */ 15406ca5274dSHeiko Stübner if (of_device_is_compatible(bank->of_node, 15416ca5274dSHeiko Stübner "rockchip,rk3188-gpio-bank0")) { 1542a658efaaSHeiko Stübner struct device_node *node; 1543bfc7a42aSHeiko Stübner 1544a658efaaSHeiko Stübner node = of_parse_phandle(bank->of_node->parent, 1545a658efaaSHeiko Stübner "rockchip,pmu", 0); 1546a658efaaSHeiko Stübner if (!node) { 15476ca5274dSHeiko Stübner if (of_address_to_resource(bank->of_node, 1, &res)) { 1548622f3237SHeiko Stübner dev_err(info->dev, "cannot find IO resource for bank\n"); 15496ca5274dSHeiko Stübner return -ENOENT; 15506ca5274dSHeiko Stübner } 15516ca5274dSHeiko Stübner 1552622f3237SHeiko Stübner base = devm_ioremap_resource(info->dev, &res); 1553751a99abSHeiko Stübner if (IS_ERR(base)) 1554751a99abSHeiko Stübner return PTR_ERR(base); 1555a658efaaSHeiko Stübner rockchip_regmap_config.max_register = 1556a658efaaSHeiko Stübner resource_size(&res) - 4; 1557a658efaaSHeiko Stübner rockchip_regmap_config.name = 1558a658efaaSHeiko Stübner "rockchip,rk3188-gpio-bank0-pull"; 1559a658efaaSHeiko Stübner bank->regmap_pull = devm_regmap_init_mmio(info->dev, 1560a658efaaSHeiko Stübner base, 1561751a99abSHeiko Stübner &rockchip_regmap_config); 1562a658efaaSHeiko Stübner } 15636ca5274dSHeiko Stübner } 156465fca613SHeiko Stübner 1565d3e51161SHeiko Stübner bank->irq = irq_of_parse_and_map(bank->of_node, 0); 1566d3e51161SHeiko Stübner 1567d3e51161SHeiko Stübner bank->clk = of_clk_get(bank->of_node, 0); 1568d3e51161SHeiko Stübner if (IS_ERR(bank->clk)) 1569d3e51161SHeiko Stübner return PTR_ERR(bank->clk); 1570d3e51161SHeiko Stübner 1571d3e51161SHeiko Stübner return clk_prepare_enable(bank->clk); 1572d3e51161SHeiko Stübner } 1573d3e51161SHeiko Stübner 1574d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[]; 1575d3e51161SHeiko Stübner 1576d3e51161SHeiko Stübner /* retrieve the soc specific data */ 1577d3e51161SHeiko Stübner static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( 1578d3e51161SHeiko Stübner struct rockchip_pinctrl *d, 1579d3e51161SHeiko Stübner struct platform_device *pdev) 1580d3e51161SHeiko Stübner { 1581d3e51161SHeiko Stübner const struct of_device_id *match; 1582d3e51161SHeiko Stübner struct device_node *node = pdev->dev.of_node; 1583d3e51161SHeiko Stübner struct device_node *np; 1584d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 1585d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 158695ec8ae4SHeiko Stübner int grf_offs, pmu_offs, i, j; 1587d3e51161SHeiko Stübner 1588d3e51161SHeiko Stübner match = of_match_node(rockchip_pinctrl_dt_match, node); 1589d3e51161SHeiko Stübner ctrl = (struct rockchip_pin_ctrl *)match->data; 1590d3e51161SHeiko Stübner 1591d3e51161SHeiko Stübner for_each_child_of_node(node, np) { 1592d3e51161SHeiko Stübner if (!of_find_property(np, "gpio-controller", NULL)) 1593d3e51161SHeiko Stübner continue; 1594d3e51161SHeiko Stübner 1595d3e51161SHeiko Stübner bank = ctrl->pin_banks; 1596d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 1597d3e51161SHeiko Stübner if (!strcmp(bank->name, np->name)) { 1598d3e51161SHeiko Stübner bank->of_node = np; 1599d3e51161SHeiko Stübner 1600622f3237SHeiko Stübner if (!rockchip_get_bank_data(bank, d)) 1601d3e51161SHeiko Stübner bank->valid = true; 1602d3e51161SHeiko Stübner 1603d3e51161SHeiko Stübner break; 1604d3e51161SHeiko Stübner } 1605d3e51161SHeiko Stübner } 1606d3e51161SHeiko Stübner } 1607d3e51161SHeiko Stübner 160895ec8ae4SHeiko Stübner grf_offs = ctrl->grf_mux_offset; 160995ec8ae4SHeiko Stübner pmu_offs = ctrl->pmu_mux_offset; 1610d3e51161SHeiko Stübner bank = ctrl->pin_banks; 1611d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 16126bc0d121SHeiko Stübner int bank_pins = 0; 16136bc0d121SHeiko Stübner 1614d3e51161SHeiko Stübner spin_lock_init(&bank->slock); 1615d3e51161SHeiko Stübner bank->drvdata = d; 1616d3e51161SHeiko Stübner bank->pin_base = ctrl->nr_pins; 1617d3e51161SHeiko Stübner ctrl->nr_pins += bank->nr_pins; 16186bc0d121SHeiko Stübner 16196bc0d121SHeiko Stübner /* calculate iomux offsets */ 16206bc0d121SHeiko Stübner for (j = 0; j < 4; j++) { 16216bc0d121SHeiko Stübner struct rockchip_iomux *iom = &bank->iomux[j]; 162203716e1dSHeiko Stübner int inc; 16236bc0d121SHeiko Stübner 16246bc0d121SHeiko Stübner if (bank_pins >= bank->nr_pins) 16256bc0d121SHeiko Stübner break; 16266bc0d121SHeiko Stübner 16276bc0d121SHeiko Stübner /* preset offset value, set new start value */ 16286bc0d121SHeiko Stübner if (iom->offset >= 0) { 162995ec8ae4SHeiko Stübner if (iom->type & IOMUX_SOURCE_PMU) 163095ec8ae4SHeiko Stübner pmu_offs = iom->offset; 163195ec8ae4SHeiko Stübner else 16326bc0d121SHeiko Stübner grf_offs = iom->offset; 16336bc0d121SHeiko Stübner } else { /* set current offset */ 163495ec8ae4SHeiko Stübner iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? 163595ec8ae4SHeiko Stübner pmu_offs : grf_offs; 16366bc0d121SHeiko Stübner } 16376bc0d121SHeiko Stübner 16386bc0d121SHeiko Stübner dev_dbg(d->dev, "bank %d, iomux %d has offset 0x%x\n", 16396bc0d121SHeiko Stübner i, j, iom->offset); 16406bc0d121SHeiko Stübner 16416bc0d121SHeiko Stübner /* 16426bc0d121SHeiko Stübner * Increase offset according to iomux width. 164303716e1dSHeiko Stübner * 4bit iomux'es are spread over two registers. 16446bc0d121SHeiko Stübner */ 164503716e1dSHeiko Stübner inc = (iom->type & IOMUX_WIDTH_4BIT) ? 8 : 4; 164695ec8ae4SHeiko Stübner if (iom->type & IOMUX_SOURCE_PMU) 164795ec8ae4SHeiko Stübner pmu_offs += inc; 164895ec8ae4SHeiko Stübner else 164903716e1dSHeiko Stübner grf_offs += inc; 16506bc0d121SHeiko Stübner 16516bc0d121SHeiko Stübner bank_pins += 8; 16526bc0d121SHeiko Stübner } 1653d3e51161SHeiko Stübner } 1654d3e51161SHeiko Stübner 1655d3e51161SHeiko Stübner return ctrl; 1656d3e51161SHeiko Stübner } 1657d3e51161SHeiko Stübner 1658d3e51161SHeiko Stübner static int rockchip_pinctrl_probe(struct platform_device *pdev) 1659d3e51161SHeiko Stübner { 1660d3e51161SHeiko Stübner struct rockchip_pinctrl *info; 1661d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 1662d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 166314dee867SHeiko Stübner struct device_node *np = pdev->dev.of_node, *node; 1664d3e51161SHeiko Stübner struct resource *res; 1665751a99abSHeiko Stübner void __iomem *base; 1666d3e51161SHeiko Stübner int ret; 1667d3e51161SHeiko Stübner 1668d3e51161SHeiko Stübner if (!dev->of_node) { 1669d3e51161SHeiko Stübner dev_err(dev, "device tree node not found\n"); 1670d3e51161SHeiko Stübner return -ENODEV; 1671d3e51161SHeiko Stübner } 1672d3e51161SHeiko Stübner 1673d3e51161SHeiko Stübner info = devm_kzalloc(dev, sizeof(struct rockchip_pinctrl), GFP_KERNEL); 1674d3e51161SHeiko Stübner if (!info) 1675d3e51161SHeiko Stübner return -ENOMEM; 1676d3e51161SHeiko Stübner 1677622f3237SHeiko Stübner info->dev = dev; 1678622f3237SHeiko Stübner 1679d3e51161SHeiko Stübner ctrl = rockchip_pinctrl_get_soc_data(info, pdev); 1680d3e51161SHeiko Stübner if (!ctrl) { 1681d3e51161SHeiko Stübner dev_err(dev, "driver data not available\n"); 1682d3e51161SHeiko Stübner return -EINVAL; 1683d3e51161SHeiko Stübner } 1684d3e51161SHeiko Stübner info->ctrl = ctrl; 1685d3e51161SHeiko Stübner 16861e747e59SHeiko Stübner node = of_parse_phandle(np, "rockchip,grf", 0); 16871e747e59SHeiko Stübner if (node) { 16881e747e59SHeiko Stübner info->regmap_base = syscon_node_to_regmap(node); 16891e747e59SHeiko Stübner if (IS_ERR(info->regmap_base)) 16901e747e59SHeiko Stübner return PTR_ERR(info->regmap_base); 16911e747e59SHeiko Stübner } else { 1692d3e51161SHeiko Stübner res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1693751a99abSHeiko Stübner base = devm_ioremap_resource(&pdev->dev, res); 1694751a99abSHeiko Stübner if (IS_ERR(base)) 1695751a99abSHeiko Stübner return PTR_ERR(base); 1696751a99abSHeiko Stübner 1697751a99abSHeiko Stübner rockchip_regmap_config.max_register = resource_size(res) - 4; 1698751a99abSHeiko Stübner rockchip_regmap_config.name = "rockchip,pinctrl"; 1699751a99abSHeiko Stübner info->regmap_base = devm_regmap_init_mmio(&pdev->dev, base, 1700751a99abSHeiko Stübner &rockchip_regmap_config); 1701d3e51161SHeiko Stübner 1702bfc7a42aSHeiko Stübner /* to check for the old dt-bindings */ 1703bfc7a42aSHeiko Stübner info->reg_size = resource_size(res); 1704bfc7a42aSHeiko Stübner 1705bfc7a42aSHeiko Stübner /* Honor the old binding, with pull registers as 2nd resource */ 1706bfc7a42aSHeiko Stübner if (ctrl->type == RK3188 && info->reg_size < 0x200) { 17076ca5274dSHeiko Stübner res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1708751a99abSHeiko Stübner base = devm_ioremap_resource(&pdev->dev, res); 1709751a99abSHeiko Stübner if (IS_ERR(base)) 1710751a99abSHeiko Stübner return PTR_ERR(base); 1711751a99abSHeiko Stübner 17121e747e59SHeiko Stübner rockchip_regmap_config.max_register = 17131e747e59SHeiko Stübner resource_size(res) - 4; 1714751a99abSHeiko Stübner rockchip_regmap_config.name = "rockchip,pinctrl-pull"; 17151e747e59SHeiko Stübner info->regmap_pull = devm_regmap_init_mmio(&pdev->dev, 17161e747e59SHeiko Stübner base, 1717751a99abSHeiko Stübner &rockchip_regmap_config); 17186ca5274dSHeiko Stübner } 17191e747e59SHeiko Stübner } 17206ca5274dSHeiko Stübner 172114dee867SHeiko Stübner /* try to find the optional reference to the pmu syscon */ 172214dee867SHeiko Stübner node = of_parse_phandle(np, "rockchip,pmu", 0); 172314dee867SHeiko Stübner if (node) { 172414dee867SHeiko Stübner info->regmap_pmu = syscon_node_to_regmap(node); 172514dee867SHeiko Stübner if (IS_ERR(info->regmap_pmu)) 172614dee867SHeiko Stübner return PTR_ERR(info->regmap_pmu); 172714dee867SHeiko Stübner } 172814dee867SHeiko Stübner 1729d3e51161SHeiko Stübner ret = rockchip_gpiolib_register(pdev, info); 1730d3e51161SHeiko Stübner if (ret) 1731d3e51161SHeiko Stübner return ret; 1732d3e51161SHeiko Stübner 1733d3e51161SHeiko Stübner ret = rockchip_pinctrl_register(pdev, info); 1734d3e51161SHeiko Stübner if (ret) { 1735d3e51161SHeiko Stübner rockchip_gpiolib_unregister(pdev, info); 1736d3e51161SHeiko Stübner return ret; 1737d3e51161SHeiko Stübner } 1738d3e51161SHeiko Stübner 1739d3e51161SHeiko Stübner platform_set_drvdata(pdev, info); 1740d3e51161SHeiko Stübner 1741d3e51161SHeiko Stübner return 0; 1742d3e51161SHeiko Stübner } 1743d3e51161SHeiko Stübner 1744d3e51161SHeiko Stübner static struct rockchip_pin_bank rk2928_pin_banks[] = { 1745d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 1746d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1747d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1748d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1749d3e51161SHeiko Stübner }; 1750d3e51161SHeiko Stübner 1751d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk2928_pin_ctrl = { 1752d3e51161SHeiko Stübner .pin_banks = rk2928_pin_banks, 1753d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk2928_pin_banks), 1754d3e51161SHeiko Stübner .label = "RK2928-GPIO", 1755a282926dSHeiko Stübner .type = RK2928, 175695ec8ae4SHeiko Stübner .grf_mux_offset = 0xa8, 1757a282926dSHeiko Stübner .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 1758d3e51161SHeiko Stübner }; 1759d3e51161SHeiko Stübner 1760d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066a_pin_banks[] = { 1761d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 1762d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1763d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1764d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1765d3e51161SHeiko Stübner PIN_BANK(4, 32, "gpio4"), 1766d3e51161SHeiko Stübner PIN_BANK(6, 16, "gpio6"), 1767d3e51161SHeiko Stübner }; 1768d3e51161SHeiko Stübner 1769d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { 1770d3e51161SHeiko Stübner .pin_banks = rk3066a_pin_banks, 1771d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), 1772d3e51161SHeiko Stübner .label = "RK3066a-GPIO", 1773a282926dSHeiko Stübner .type = RK2928, 177495ec8ae4SHeiko Stübner .grf_mux_offset = 0xa8, 1775a282926dSHeiko Stübner .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 1776d3e51161SHeiko Stübner }; 1777d3e51161SHeiko Stübner 1778d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066b_pin_banks[] = { 1779d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 1780d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1781d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1782d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1783d3e51161SHeiko Stübner }; 1784d3e51161SHeiko Stübner 1785d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { 1786d3e51161SHeiko Stübner .pin_banks = rk3066b_pin_banks, 1787d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), 1788d3e51161SHeiko Stübner .label = "RK3066b-GPIO", 1789a282926dSHeiko Stübner .type = RK3066B, 179095ec8ae4SHeiko Stübner .grf_mux_offset = 0x60, 1791d3e51161SHeiko Stübner }; 1792d3e51161SHeiko Stübner 1793d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3188_pin_banks[] = { 1794fc72c923SHeiko Stübner PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0), 1795d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 1796d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 1797d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 1798d3e51161SHeiko Stübner }; 1799d3e51161SHeiko Stübner 1800d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3188_pin_ctrl = { 1801d3e51161SHeiko Stübner .pin_banks = rk3188_pin_banks, 1802d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3188_pin_banks), 1803d3e51161SHeiko Stübner .label = "RK3188-GPIO", 1804a282926dSHeiko Stübner .type = RK3188, 180595ec8ae4SHeiko Stübner .grf_mux_offset = 0x60, 18066ca5274dSHeiko Stübner .pull_calc_reg = rk3188_calc_pull_reg_and_bit, 1807d3e51161SHeiko Stübner }; 1808d3e51161SHeiko Stübner 1809304f077dSHeiko Stübner static struct rockchip_pin_bank rk3288_pin_banks[] = { 1810304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU, 1811304f077dSHeiko Stübner IOMUX_SOURCE_PMU, 1812304f077dSHeiko Stübner IOMUX_SOURCE_PMU, 1813304f077dSHeiko Stübner IOMUX_UNROUTED 1814304f077dSHeiko Stübner ), 1815304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED, 1816304f077dSHeiko Stübner IOMUX_UNROUTED, 1817304f077dSHeiko Stübner IOMUX_UNROUTED, 1818304f077dSHeiko Stübner 0 1819304f077dSHeiko Stübner ), 1820304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED), 1821304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT), 1822304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, 1823304f077dSHeiko Stübner IOMUX_WIDTH_4BIT, 1824304f077dSHeiko Stübner 0, 1825304f077dSHeiko Stübner 0 1826304f077dSHeiko Stübner ), 1827304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED, 1828304f077dSHeiko Stübner 0, 1829304f077dSHeiko Stübner 0, 1830304f077dSHeiko Stübner IOMUX_UNROUTED 1831304f077dSHeiko Stübner ), 1832304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED), 1833304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0, 1834304f077dSHeiko Stübner 0, 1835304f077dSHeiko Stübner IOMUX_WIDTH_4BIT, 1836304f077dSHeiko Stübner IOMUX_UNROUTED 1837304f077dSHeiko Stübner ), 1838304f077dSHeiko Stübner PIN_BANK(8, 16, "gpio8"), 1839304f077dSHeiko Stübner }; 1840304f077dSHeiko Stübner 1841304f077dSHeiko Stübner static struct rockchip_pin_ctrl rk3288_pin_ctrl = { 1842304f077dSHeiko Stübner .pin_banks = rk3288_pin_banks, 1843304f077dSHeiko Stübner .nr_banks = ARRAY_SIZE(rk3288_pin_banks), 1844304f077dSHeiko Stübner .label = "RK3288-GPIO", 1845*66d750e1SHeiko Stübner .type = RK3288, 1846304f077dSHeiko Stübner .grf_mux_offset = 0x0, 1847304f077dSHeiko Stübner .pmu_mux_offset = 0x84, 1848304f077dSHeiko Stübner .pull_calc_reg = rk3288_calc_pull_reg_and_bit, 1849304f077dSHeiko Stübner }; 1850304f077dSHeiko Stübner 1851d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[] = { 1852d3e51161SHeiko Stübner { .compatible = "rockchip,rk2928-pinctrl", 1853d3e51161SHeiko Stübner .data = (void *)&rk2928_pin_ctrl }, 1854d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066a-pinctrl", 1855d3e51161SHeiko Stübner .data = (void *)&rk3066a_pin_ctrl }, 1856d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066b-pinctrl", 1857d3e51161SHeiko Stübner .data = (void *)&rk3066b_pin_ctrl }, 1858d3e51161SHeiko Stübner { .compatible = "rockchip,rk3188-pinctrl", 1859d3e51161SHeiko Stübner .data = (void *)&rk3188_pin_ctrl }, 1860304f077dSHeiko Stübner { .compatible = "rockchip,rk3288-pinctrl", 1861304f077dSHeiko Stübner .data = (void *)&rk3288_pin_ctrl }, 1862d3e51161SHeiko Stübner {}, 1863d3e51161SHeiko Stübner }; 1864d3e51161SHeiko Stübner MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); 1865d3e51161SHeiko Stübner 1866d3e51161SHeiko Stübner static struct platform_driver rockchip_pinctrl_driver = { 1867d3e51161SHeiko Stübner .probe = rockchip_pinctrl_probe, 1868d3e51161SHeiko Stübner .driver = { 1869d3e51161SHeiko Stübner .name = "rockchip-pinctrl", 1870d3e51161SHeiko Stübner .owner = THIS_MODULE, 18710be9e70dSAxel Lin .of_match_table = rockchip_pinctrl_dt_match, 1872d3e51161SHeiko Stübner }, 1873d3e51161SHeiko Stübner }; 1874d3e51161SHeiko Stübner 1875d3e51161SHeiko Stübner static int __init rockchip_pinctrl_drv_register(void) 1876d3e51161SHeiko Stübner { 1877d3e51161SHeiko Stübner return platform_driver_register(&rockchip_pinctrl_driver); 1878d3e51161SHeiko Stübner } 1879d3e51161SHeiko Stübner postcore_initcall(rockchip_pinctrl_drv_register); 1880d3e51161SHeiko Stübner 1881d3e51161SHeiko Stübner MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 1882d3e51161SHeiko Stübner MODULE_DESCRIPTION("Rockchip pinctrl driver"); 1883d3e51161SHeiko Stübner MODULE_LICENSE("GPL v2"); 1884