11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2d3e51161SHeiko Stübner /* 3d3e51161SHeiko Stübner * Pinctrl driver for Rockchip SoCs 4d3e51161SHeiko Stübner * 5d3e51161SHeiko Stübner * Copyright (c) 2013 MundoReader S.L. 6d3e51161SHeiko Stübner * Author: Heiko Stuebner <heiko@sntech.de> 7d3e51161SHeiko Stübner * 8d3e51161SHeiko Stübner * With some ideas taken from pinctrl-samsung: 9d3e51161SHeiko Stübner * Copyright (c) 2012 Samsung Electronics Co., Ltd. 10d3e51161SHeiko Stübner * http://www.samsung.com 11d3e51161SHeiko Stübner * Copyright (c) 2012 Linaro Ltd 123e3f742bSAlexander A. Klimov * https://www.linaro.org 13d3e51161SHeiko Stübner * 14d3e51161SHeiko Stübner * and pinctrl-at91: 15d3e51161SHeiko Stübner * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> 16d3e51161SHeiko Stübner */ 17d3e51161SHeiko Stübner 182f436204SPaul Gortmaker #include <linux/init.h> 19be786ac5SJianqun Xu #include <linux/module.h> 20d3e51161SHeiko Stübner #include <linux/platform_device.h> 21d3e51161SHeiko Stübner #include <linux/io.h> 22d3e51161SHeiko Stübner #include <linux/bitops.h> 231c5fb66aSLinus Walleij #include <linux/gpio/driver.h> 24d3e51161SHeiko Stübner #include <linux/of_address.h> 259ce9a020SJianqun Xu #include <linux/of_device.h> 26d3e51161SHeiko Stübner #include <linux/of_irq.h> 27d3e51161SHeiko Stübner #include <linux/pinctrl/machine.h> 28d3e51161SHeiko Stübner #include <linux/pinctrl/pinconf.h> 29d3e51161SHeiko Stübner #include <linux/pinctrl/pinctrl.h> 30d3e51161SHeiko Stübner #include <linux/pinctrl/pinmux.h> 31d3e51161SHeiko Stübner #include <linux/pinctrl/pinconf-generic.h> 32d3e51161SHeiko Stübner #include <linux/irqchip/chained_irq.h> 337e865abbSHeiko Stübner #include <linux/clk.h> 34751a99abSHeiko Stübner #include <linux/regmap.h> 3514dee867SHeiko Stübner #include <linux/mfd/syscon.h> 36069d7796SAndy Shevchenko #include <linux/string_helpers.h> 37069d7796SAndy Shevchenko 38d3e51161SHeiko Stübner #include <dt-bindings/pinctrl/rockchip.h> 39d3e51161SHeiko Stübner 40d3e51161SHeiko Stübner #include "core.h" 41d3e51161SHeiko Stübner #include "pinconf.h" 42e1450694SJianqun Xu #include "pinctrl-rockchip.h" 43d3e51161SHeiko Stübner 445a83227bSAndy Shevchenko /* 45c0dadc0eSJianqun Xu * Generate a bitmask for setting a value (v) with a write mask bit in hiword 46c0dadc0eSJianqun Xu * register 31:16 area. 47c0dadc0eSJianqun Xu */ 48c0dadc0eSJianqun Xu #define WRITE_MASK_VAL(h, l, v) \ 49c0dadc0eSJianqun Xu (GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l)))) 50c0dadc0eSJianqun Xu 51e1524ea8SLee Jones /* 52fc72c923SHeiko Stübner * Encode variants of iomux registers into a type variable 53fc72c923SHeiko Stübner */ 54fc72c923SHeiko Stübner #define IOMUX_GPIO_ONLY BIT(0) 5503716e1dSHeiko Stübner #define IOMUX_WIDTH_4BIT BIT(1) 5695ec8ae4SHeiko Stübner #define IOMUX_SOURCE_PMU BIT(2) 5762f49226SHeiko Stübner #define IOMUX_UNROUTED BIT(3) 588b6c6f93Sdavid.wu #define IOMUX_WIDTH_3BIT BIT(4) 597825aeb7SJianqun Xu #define IOMUX_WIDTH_2BIT BIT(5) 60fc72c923SHeiko Stübner 61d3e51161SHeiko Stübner #define PIN_BANK(id, pins, label) \ 62d3e51161SHeiko Stübner { \ 63d3e51161SHeiko Stübner .bank_num = id, \ 64d3e51161SHeiko Stübner .nr_pins = pins, \ 65d3e51161SHeiko Stübner .name = label, \ 666bc0d121SHeiko Stübner .iomux = { \ 676bc0d121SHeiko Stübner { .offset = -1 }, \ 686bc0d121SHeiko Stübner { .offset = -1 }, \ 696bc0d121SHeiko Stübner { .offset = -1 }, \ 706bc0d121SHeiko Stübner { .offset = -1 }, \ 716bc0d121SHeiko Stübner }, \ 72d3e51161SHeiko Stübner } 73d3e51161SHeiko Stübner 74fc72c923SHeiko Stübner #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ 75fc72c923SHeiko Stübner { \ 76fc72c923SHeiko Stübner .bank_num = id, \ 77fc72c923SHeiko Stübner .nr_pins = pins, \ 78fc72c923SHeiko Stübner .name = label, \ 79fc72c923SHeiko Stübner .iomux = { \ 806bc0d121SHeiko Stübner { .type = iom0, .offset = -1 }, \ 816bc0d121SHeiko Stübner { .type = iom1, .offset = -1 }, \ 826bc0d121SHeiko Stübner { .type = iom2, .offset = -1 }, \ 836bc0d121SHeiko Stübner { .type = iom3, .offset = -1 }, \ 84fc72c923SHeiko Stübner }, \ 85fc72c923SHeiko Stübner } 86fc72c923SHeiko Stübner 87b6c23275SDavid Wu #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \ 88b6c23275SDavid Wu { \ 89b6c23275SDavid Wu .bank_num = id, \ 90b6c23275SDavid Wu .nr_pins = pins, \ 91b6c23275SDavid Wu .name = label, \ 92b6c23275SDavid Wu .iomux = { \ 93b6c23275SDavid Wu { .offset = -1 }, \ 94b6c23275SDavid Wu { .offset = -1 }, \ 95b6c23275SDavid Wu { .offset = -1 }, \ 96b6c23275SDavid Wu { .offset = -1 }, \ 97b6c23275SDavid Wu }, \ 98b6c23275SDavid Wu .drv = { \ 99b6c23275SDavid Wu { .drv_type = type0, .offset = -1 }, \ 100b6c23275SDavid Wu { .drv_type = type1, .offset = -1 }, \ 101b6c23275SDavid Wu { .drv_type = type2, .offset = -1 }, \ 102b6c23275SDavid Wu { .drv_type = type3, .offset = -1 }, \ 103b6c23275SDavid Wu }, \ 104b6c23275SDavid Wu } 105b6c23275SDavid Wu 1063ba6767aSDavid Wu #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1, \ 1073ba6767aSDavid Wu drv2, drv3, pull0, pull1, \ 1083ba6767aSDavid Wu pull2, pull3) \ 1093ba6767aSDavid Wu { \ 1103ba6767aSDavid Wu .bank_num = id, \ 1113ba6767aSDavid Wu .nr_pins = pins, \ 1123ba6767aSDavid Wu .name = label, \ 1133ba6767aSDavid Wu .iomux = { \ 1143ba6767aSDavid Wu { .offset = -1 }, \ 1153ba6767aSDavid Wu { .offset = -1 }, \ 1163ba6767aSDavid Wu { .offset = -1 }, \ 1173ba6767aSDavid Wu { .offset = -1 }, \ 1183ba6767aSDavid Wu }, \ 1193ba6767aSDavid Wu .drv = { \ 1203ba6767aSDavid Wu { .drv_type = drv0, .offset = -1 }, \ 1213ba6767aSDavid Wu { .drv_type = drv1, .offset = -1 }, \ 1223ba6767aSDavid Wu { .drv_type = drv2, .offset = -1 }, \ 1233ba6767aSDavid Wu { .drv_type = drv3, .offset = -1 }, \ 1243ba6767aSDavid Wu }, \ 1253ba6767aSDavid Wu .pull_type[0] = pull0, \ 1263ba6767aSDavid Wu .pull_type[1] = pull1, \ 1273ba6767aSDavid Wu .pull_type[2] = pull2, \ 1283ba6767aSDavid Wu .pull_type[3] = pull3, \ 1293ba6767aSDavid Wu } 1303ba6767aSDavid Wu 131b6c23275SDavid Wu #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1, \ 132b6c23275SDavid Wu iom2, iom3, drv0, drv1, drv2, \ 133b6c23275SDavid Wu drv3, offset0, offset1, \ 134b6c23275SDavid Wu offset2, offset3) \ 135b6c23275SDavid Wu { \ 136b6c23275SDavid Wu .bank_num = id, \ 137b6c23275SDavid Wu .nr_pins = pins, \ 138b6c23275SDavid Wu .name = label, \ 139b6c23275SDavid Wu .iomux = { \ 140b6c23275SDavid Wu { .type = iom0, .offset = -1 }, \ 141b6c23275SDavid Wu { .type = iom1, .offset = -1 }, \ 142b6c23275SDavid Wu { .type = iom2, .offset = -1 }, \ 143b6c23275SDavid Wu { .type = iom3, .offset = -1 }, \ 144b6c23275SDavid Wu }, \ 145b6c23275SDavid Wu .drv = { \ 146b6c23275SDavid Wu { .drv_type = drv0, .offset = offset0 }, \ 147b6c23275SDavid Wu { .drv_type = drv1, .offset = offset1 }, \ 148b6c23275SDavid Wu { .drv_type = drv2, .offset = offset2 }, \ 149b6c23275SDavid Wu { .drv_type = drv3, .offset = offset3 }, \ 150b6c23275SDavid Wu }, \ 151b6c23275SDavid Wu } 152b6c23275SDavid Wu 1533ba6767aSDavid Wu #define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins, \ 1543ba6767aSDavid Wu label, iom0, iom1, iom2, \ 1553ba6767aSDavid Wu iom3, drv0, drv1, drv2, \ 1563ba6767aSDavid Wu drv3, offset0, offset1, \ 1573ba6767aSDavid Wu offset2, offset3, pull0, \ 1583ba6767aSDavid Wu pull1, pull2, pull3) \ 1593ba6767aSDavid Wu { \ 1603ba6767aSDavid Wu .bank_num = id, \ 1613ba6767aSDavid Wu .nr_pins = pins, \ 1623ba6767aSDavid Wu .name = label, \ 1633ba6767aSDavid Wu .iomux = { \ 1643ba6767aSDavid Wu { .type = iom0, .offset = -1 }, \ 1653ba6767aSDavid Wu { .type = iom1, .offset = -1 }, \ 1663ba6767aSDavid Wu { .type = iom2, .offset = -1 }, \ 1673ba6767aSDavid Wu { .type = iom3, .offset = -1 }, \ 1683ba6767aSDavid Wu }, \ 1693ba6767aSDavid Wu .drv = { \ 1703ba6767aSDavid Wu { .drv_type = drv0, .offset = offset0 }, \ 1713ba6767aSDavid Wu { .drv_type = drv1, .offset = offset1 }, \ 1723ba6767aSDavid Wu { .drv_type = drv2, .offset = offset2 }, \ 1733ba6767aSDavid Wu { .drv_type = drv3, .offset = offset3 }, \ 1743ba6767aSDavid Wu }, \ 1753ba6767aSDavid Wu .pull_type[0] = pull0, \ 1763ba6767aSDavid Wu .pull_type[1] = pull1, \ 1773ba6767aSDavid Wu .pull_type[2] = pull2, \ 1783ba6767aSDavid Wu .pull_type[3] = pull3, \ 1793ba6767aSDavid Wu } 1803ba6767aSDavid Wu 181c0dadc0eSJianqun Xu #define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG) \ 182c0dadc0eSJianqun Xu { \ 183c0dadc0eSJianqun Xu .bank_num = ID, \ 184c0dadc0eSJianqun Xu .pin = PIN, \ 185c0dadc0eSJianqun Xu .func = FUNC, \ 186c0dadc0eSJianqun Xu .route_offset = REG, \ 187c0dadc0eSJianqun Xu .route_val = VAL, \ 188c0dadc0eSJianqun Xu .route_location = FLAG, \ 189c0dadc0eSJianqun Xu } 190c0dadc0eSJianqun Xu 191c0dadc0eSJianqun Xu #define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL) \ 192c0dadc0eSJianqun Xu PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME) 193c0dadc0eSJianqun Xu 194c0dadc0eSJianqun Xu #define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL) \ 195c0dadc0eSJianqun Xu PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF) 196c0dadc0eSJianqun Xu 197c0dadc0eSJianqun Xu #define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \ 198c0dadc0eSJianqun Xu PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU) 199c0dadc0eSJianqun Xu 200751a99abSHeiko Stübner static struct regmap_config rockchip_regmap_config = { 201751a99abSHeiko Stübner .reg_bits = 32, 202751a99abSHeiko Stübner .val_bits = 32, 203751a99abSHeiko Stübner .reg_stride = 4, 204751a99abSHeiko Stübner }; 205751a99abSHeiko Stübner 20656411f3cSArnd Bergmann static inline const struct rockchip_pin_group *pinctrl_name_to_group( 207d3e51161SHeiko Stübner const struct rockchip_pinctrl *info, 208d3e51161SHeiko Stübner const char *name) 209d3e51161SHeiko Stübner { 210d3e51161SHeiko Stübner int i; 211d3e51161SHeiko Stübner 212d3e51161SHeiko Stübner for (i = 0; i < info->ngroups; i++) { 2131cb95395SAxel Lin if (!strcmp(info->groups[i].name, name)) 2141cb95395SAxel Lin return &info->groups[i]; 215d3e51161SHeiko Stübner } 216d3e51161SHeiko Stübner 2171cb95395SAxel Lin return NULL; 218d3e51161SHeiko Stübner } 219d3e51161SHeiko Stübner 220d3e51161SHeiko Stübner /* 221d3e51161SHeiko Stübner * given a pin number that is local to a pin controller, find out the pin bank 222d3e51161SHeiko Stübner * and the register base of the pin bank. 223d3e51161SHeiko Stübner */ 224d3e51161SHeiko Stübner static struct rockchip_pin_bank *pin_to_bank(struct rockchip_pinctrl *info, 225d3e51161SHeiko Stübner unsigned pin) 226d3e51161SHeiko Stübner { 227d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 228d3e51161SHeiko Stübner 22951578b9bSAxel Lin while (pin >= (b->pin_base + b->nr_pins)) 230d3e51161SHeiko Stübner b++; 231d3e51161SHeiko Stübner 232d3e51161SHeiko Stübner return b; 233d3e51161SHeiko Stübner } 234d3e51161SHeiko Stübner 235d3e51161SHeiko Stübner static struct rockchip_pin_bank *bank_num_to_bank( 236d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 237d3e51161SHeiko Stübner unsigned num) 238d3e51161SHeiko Stübner { 239d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 240d3e51161SHeiko Stübner int i; 241d3e51161SHeiko Stübner 2421cb95395SAxel Lin for (i = 0; i < info->ctrl->nr_banks; i++, b++) { 243d3e51161SHeiko Stübner if (b->bank_num == num) 2441cb95395SAxel Lin return b; 245d3e51161SHeiko Stübner } 246d3e51161SHeiko Stübner 247d3e51161SHeiko Stübner return ERR_PTR(-EINVAL); 248d3e51161SHeiko Stübner } 249d3e51161SHeiko Stübner 250d3e51161SHeiko Stübner /* 251d3e51161SHeiko Stübner * Pinctrl_ops handling 252d3e51161SHeiko Stübner */ 253d3e51161SHeiko Stübner 254d3e51161SHeiko Stübner static int rockchip_get_groups_count(struct pinctrl_dev *pctldev) 255d3e51161SHeiko Stübner { 256d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 257d3e51161SHeiko Stübner 258d3e51161SHeiko Stübner return info->ngroups; 259d3e51161SHeiko Stübner } 260d3e51161SHeiko Stübner 261d3e51161SHeiko Stübner static const char *rockchip_get_group_name(struct pinctrl_dev *pctldev, 262d3e51161SHeiko Stübner unsigned selector) 263d3e51161SHeiko Stübner { 264d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 265d3e51161SHeiko Stübner 266d3e51161SHeiko Stübner return info->groups[selector].name; 267d3e51161SHeiko Stübner } 268d3e51161SHeiko Stübner 269d3e51161SHeiko Stübner static int rockchip_get_group_pins(struct pinctrl_dev *pctldev, 270d3e51161SHeiko Stübner unsigned selector, const unsigned **pins, 271d3e51161SHeiko Stübner unsigned *npins) 272d3e51161SHeiko Stübner { 273d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 274d3e51161SHeiko Stübner 275d3e51161SHeiko Stübner if (selector >= info->ngroups) 276d3e51161SHeiko Stübner return -EINVAL; 277d3e51161SHeiko Stübner 278d3e51161SHeiko Stübner *pins = info->groups[selector].pins; 279d3e51161SHeiko Stübner *npins = info->groups[selector].npins; 280d3e51161SHeiko Stübner 281d3e51161SHeiko Stübner return 0; 282d3e51161SHeiko Stübner } 283d3e51161SHeiko Stübner 284d3e51161SHeiko Stübner static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev, 285d3e51161SHeiko Stübner struct device_node *np, 286d3e51161SHeiko Stübner struct pinctrl_map **map, unsigned *num_maps) 287d3e51161SHeiko Stübner { 288d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 289d3e51161SHeiko Stübner const struct rockchip_pin_group *grp; 290e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 291d3e51161SHeiko Stübner struct pinctrl_map *new_map; 292d3e51161SHeiko Stübner struct device_node *parent; 293d3e51161SHeiko Stübner int map_num = 1; 294d3e51161SHeiko Stübner int i; 295d3e51161SHeiko Stübner 296d3e51161SHeiko Stübner /* 297d3e51161SHeiko Stübner * first find the group of this node and check if we need to create 298d3e51161SHeiko Stübner * config maps for pins 299d3e51161SHeiko Stübner */ 300d3e51161SHeiko Stübner grp = pinctrl_name_to_group(info, np->name); 301d3e51161SHeiko Stübner if (!grp) { 302e4dd7fd5SAndy Shevchenko dev_err(dev, "unable to find group for node %pOFn\n", np); 303d3e51161SHeiko Stübner return -EINVAL; 304d3e51161SHeiko Stübner } 305d3e51161SHeiko Stübner 306d3e51161SHeiko Stübner map_num += grp->npins; 307d7faa8ffSDafna Hirschfeld 308d7faa8ffSDafna Hirschfeld new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL); 309d3e51161SHeiko Stübner if (!new_map) 310d3e51161SHeiko Stübner return -ENOMEM; 311d3e51161SHeiko Stübner 312d3e51161SHeiko Stübner *map = new_map; 313d3e51161SHeiko Stübner *num_maps = map_num; 314d3e51161SHeiko Stübner 315d3e51161SHeiko Stübner /* create mux map */ 316d3e51161SHeiko Stübner parent = of_get_parent(np); 317d3e51161SHeiko Stübner if (!parent) { 318d7faa8ffSDafna Hirschfeld kfree(new_map); 319d3e51161SHeiko Stübner return -EINVAL; 320d3e51161SHeiko Stübner } 321d3e51161SHeiko Stübner new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; 322d3e51161SHeiko Stübner new_map[0].data.mux.function = parent->name; 323d3e51161SHeiko Stübner new_map[0].data.mux.group = np->name; 324d3e51161SHeiko Stübner of_node_put(parent); 325d3e51161SHeiko Stübner 326d3e51161SHeiko Stübner /* create config map */ 327d3e51161SHeiko Stübner new_map++; 328d3e51161SHeiko Stübner for (i = 0; i < grp->npins; i++) { 329d3e51161SHeiko Stübner new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; 330d3e51161SHeiko Stübner new_map[i].data.configs.group_or_pin = 331d3e51161SHeiko Stübner pin_get_name(pctldev, grp->pins[i]); 332d3e51161SHeiko Stübner new_map[i].data.configs.configs = grp->data[i].configs; 333d3e51161SHeiko Stübner new_map[i].data.configs.num_configs = grp->data[i].nconfigs; 334d3e51161SHeiko Stübner } 335d3e51161SHeiko Stübner 336e4dd7fd5SAndy Shevchenko dev_dbg(dev, "maps: function %s group %s num %d\n", 337d3e51161SHeiko Stübner (*map)->data.mux.function, (*map)->data.mux.group, map_num); 338d3e51161SHeiko Stübner 339d3e51161SHeiko Stübner return 0; 340d3e51161SHeiko Stübner } 341d3e51161SHeiko Stübner 342d3e51161SHeiko Stübner static void rockchip_dt_free_map(struct pinctrl_dev *pctldev, 343d3e51161SHeiko Stübner struct pinctrl_map *map, unsigned num_maps) 344d3e51161SHeiko Stübner { 345d7faa8ffSDafna Hirschfeld kfree(map); 346d3e51161SHeiko Stübner } 347d3e51161SHeiko Stübner 348d3e51161SHeiko Stübner static const struct pinctrl_ops rockchip_pctrl_ops = { 349d3e51161SHeiko Stübner .get_groups_count = rockchip_get_groups_count, 350d3e51161SHeiko Stübner .get_group_name = rockchip_get_group_name, 351d3e51161SHeiko Stübner .get_group_pins = rockchip_get_group_pins, 352d3e51161SHeiko Stübner .dt_node_to_map = rockchip_dt_node_to_map, 353d3e51161SHeiko Stübner .dt_free_map = rockchip_dt_free_map, 354d3e51161SHeiko Stübner }; 355d3e51161SHeiko Stübner 356d3e51161SHeiko Stübner /* 357d3e51161SHeiko Stübner * Hardware access 358d3e51161SHeiko Stübner */ 359d3e51161SHeiko Stübner 36012b8f018SDavid Wu static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = { 36112b8f018SDavid Wu { 36212b8f018SDavid Wu .num = 1, 36312b8f018SDavid Wu .pin = 0, 36412b8f018SDavid Wu .reg = 0x418, 36512b8f018SDavid Wu .bit = 0, 36612b8f018SDavid Wu .mask = 0x3 36712b8f018SDavid Wu }, { 36812b8f018SDavid Wu .num = 1, 36912b8f018SDavid Wu .pin = 1, 37012b8f018SDavid Wu .reg = 0x418, 37112b8f018SDavid Wu .bit = 2, 37212b8f018SDavid Wu .mask = 0x3 37312b8f018SDavid Wu }, { 37412b8f018SDavid Wu .num = 1, 37512b8f018SDavid Wu .pin = 2, 37612b8f018SDavid Wu .reg = 0x418, 37712b8f018SDavid Wu .bit = 4, 37812b8f018SDavid Wu .mask = 0x3 37912b8f018SDavid Wu }, { 38012b8f018SDavid Wu .num = 1, 38112b8f018SDavid Wu .pin = 3, 38212b8f018SDavid Wu .reg = 0x418, 38312b8f018SDavid Wu .bit = 6, 38412b8f018SDavid Wu .mask = 0x3 38512b8f018SDavid Wu }, { 38612b8f018SDavid Wu .num = 1, 38712b8f018SDavid Wu .pin = 4, 38812b8f018SDavid Wu .reg = 0x418, 38912b8f018SDavid Wu .bit = 8, 39012b8f018SDavid Wu .mask = 0x3 39112b8f018SDavid Wu }, { 39212b8f018SDavid Wu .num = 1, 39312b8f018SDavid Wu .pin = 5, 39412b8f018SDavid Wu .reg = 0x418, 39512b8f018SDavid Wu .bit = 10, 39612b8f018SDavid Wu .mask = 0x3 39712b8f018SDavid Wu }, { 39812b8f018SDavid Wu .num = 1, 39912b8f018SDavid Wu .pin = 6, 40012b8f018SDavid Wu .reg = 0x418, 40112b8f018SDavid Wu .bit = 12, 40212b8f018SDavid Wu .mask = 0x3 40312b8f018SDavid Wu }, { 40412b8f018SDavid Wu .num = 1, 40512b8f018SDavid Wu .pin = 7, 40612b8f018SDavid Wu .reg = 0x418, 40712b8f018SDavid Wu .bit = 14, 40812b8f018SDavid Wu .mask = 0x3 40912b8f018SDavid Wu }, { 41012b8f018SDavid Wu .num = 1, 41112b8f018SDavid Wu .pin = 8, 41212b8f018SDavid Wu .reg = 0x41c, 41312b8f018SDavid Wu .bit = 0, 41412b8f018SDavid Wu .mask = 0x3 41512b8f018SDavid Wu }, { 41612b8f018SDavid Wu .num = 1, 41712b8f018SDavid Wu .pin = 9, 41812b8f018SDavid Wu .reg = 0x41c, 41912b8f018SDavid Wu .bit = 2, 42012b8f018SDavid Wu .mask = 0x3 42112b8f018SDavid Wu }, 42212b8f018SDavid Wu }; 42312b8f018SDavid Wu 424d23c66dfSDavid Wu static struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = { 425d23c66dfSDavid Wu { 426d23c66dfSDavid Wu .num = 2, 427d23c66dfSDavid Wu .pin = 20, 428d23c66dfSDavid Wu .reg = 0xe8, 429d23c66dfSDavid Wu .bit = 0, 430d23c66dfSDavid Wu .mask = 0x7 431d23c66dfSDavid Wu }, { 432d23c66dfSDavid Wu .num = 2, 433d23c66dfSDavid Wu .pin = 21, 434d23c66dfSDavid Wu .reg = 0xe8, 435d23c66dfSDavid Wu .bit = 4, 436d23c66dfSDavid Wu .mask = 0x7 437d23c66dfSDavid Wu }, { 438d23c66dfSDavid Wu .num = 2, 439d23c66dfSDavid Wu .pin = 22, 440d23c66dfSDavid Wu .reg = 0xe8, 441d23c66dfSDavid Wu .bit = 8, 442d23c66dfSDavid Wu .mask = 0x7 443d23c66dfSDavid Wu }, { 444d23c66dfSDavid Wu .num = 2, 445d23c66dfSDavid Wu .pin = 23, 446d23c66dfSDavid Wu .reg = 0xe8, 447d23c66dfSDavid Wu .bit = 12, 448d23c66dfSDavid Wu .mask = 0x7 449d23c66dfSDavid Wu }, { 450d23c66dfSDavid Wu .num = 2, 451d23c66dfSDavid Wu .pin = 24, 452d23c66dfSDavid Wu .reg = 0xd4, 453d23c66dfSDavid Wu .bit = 12, 454d23c66dfSDavid Wu .mask = 0x7 455d23c66dfSDavid Wu }, 456d23c66dfSDavid Wu }; 457d23c66dfSDavid Wu 4587825aeb7SJianqun Xu static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { 4597825aeb7SJianqun Xu { 4607825aeb7SJianqun Xu .num = 1, 4617825aeb7SJianqun Xu .pin = 14, 4627825aeb7SJianqun Xu .reg = 0x28, 4637825aeb7SJianqun Xu .bit = 12, 4647825aeb7SJianqun Xu .mask = 0xf 4657825aeb7SJianqun Xu }, { 4667825aeb7SJianqun Xu .num = 1, 4677825aeb7SJianqun Xu .pin = 15, 4687825aeb7SJianqun Xu .reg = 0x2c, 4697825aeb7SJianqun Xu .bit = 0, 4707825aeb7SJianqun Xu .mask = 0x3 4717825aeb7SJianqun Xu }, { 4727825aeb7SJianqun Xu .num = 1, 4737825aeb7SJianqun Xu .pin = 18, 4747825aeb7SJianqun Xu .reg = 0x30, 4757825aeb7SJianqun Xu .bit = 4, 4767825aeb7SJianqun Xu .mask = 0xf 4777825aeb7SJianqun Xu }, { 4787825aeb7SJianqun Xu .num = 1, 4797825aeb7SJianqun Xu .pin = 19, 4807825aeb7SJianqun Xu .reg = 0x30, 4817825aeb7SJianqun Xu .bit = 8, 4827825aeb7SJianqun Xu .mask = 0xf 4837825aeb7SJianqun Xu }, { 4847825aeb7SJianqun Xu .num = 1, 4857825aeb7SJianqun Xu .pin = 20, 4867825aeb7SJianqun Xu .reg = 0x30, 4877825aeb7SJianqun Xu .bit = 12, 4887825aeb7SJianqun Xu .mask = 0xf 4897825aeb7SJianqun Xu }, { 4907825aeb7SJianqun Xu .num = 1, 4917825aeb7SJianqun Xu .pin = 21, 4927825aeb7SJianqun Xu .reg = 0x34, 4937825aeb7SJianqun Xu .bit = 0, 4947825aeb7SJianqun Xu .mask = 0xf 4957825aeb7SJianqun Xu }, { 4967825aeb7SJianqun Xu .num = 1, 4977825aeb7SJianqun Xu .pin = 22, 4987825aeb7SJianqun Xu .reg = 0x34, 4997825aeb7SJianqun Xu .bit = 4, 5007825aeb7SJianqun Xu .mask = 0xf 5017825aeb7SJianqun Xu }, { 5027825aeb7SJianqun Xu .num = 1, 5037825aeb7SJianqun Xu .pin = 23, 5047825aeb7SJianqun Xu .reg = 0x34, 5057825aeb7SJianqun Xu .bit = 8, 5067825aeb7SJianqun Xu .mask = 0xf 5077825aeb7SJianqun Xu }, { 5087825aeb7SJianqun Xu .num = 3, 5097825aeb7SJianqun Xu .pin = 12, 5107825aeb7SJianqun Xu .reg = 0x68, 5117825aeb7SJianqun Xu .bit = 8, 5127825aeb7SJianqun Xu .mask = 0xf 5137825aeb7SJianqun Xu }, { 5147825aeb7SJianqun Xu .num = 3, 5157825aeb7SJianqun Xu .pin = 13, 5167825aeb7SJianqun Xu .reg = 0x68, 5177825aeb7SJianqun Xu .bit = 12, 5187825aeb7SJianqun Xu .mask = 0xf 5197825aeb7SJianqun Xu }, { 5207825aeb7SJianqun Xu .num = 2, 5217825aeb7SJianqun Xu .pin = 2, 5227825aeb7SJianqun Xu .reg = 0x608, 5237825aeb7SJianqun Xu .bit = 0, 5247825aeb7SJianqun Xu .mask = 0x7 5257825aeb7SJianqun Xu }, { 5267825aeb7SJianqun Xu .num = 2, 5277825aeb7SJianqun Xu .pin = 3, 5287825aeb7SJianqun Xu .reg = 0x608, 5297825aeb7SJianqun Xu .bit = 4, 5307825aeb7SJianqun Xu .mask = 0x7 5317825aeb7SJianqun Xu }, { 5327825aeb7SJianqun Xu .num = 2, 5337825aeb7SJianqun Xu .pin = 16, 5347825aeb7SJianqun Xu .reg = 0x610, 5357825aeb7SJianqun Xu .bit = 8, 5367825aeb7SJianqun Xu .mask = 0x7 5377825aeb7SJianqun Xu }, { 5387825aeb7SJianqun Xu .num = 3, 5397825aeb7SJianqun Xu .pin = 10, 5407825aeb7SJianqun Xu .reg = 0x610, 5417825aeb7SJianqun Xu .bit = 0, 5427825aeb7SJianqun Xu .mask = 0x7 5437825aeb7SJianqun Xu }, { 5447825aeb7SJianqun Xu .num = 3, 5457825aeb7SJianqun Xu .pin = 11, 5467825aeb7SJianqun Xu .reg = 0x610, 5477825aeb7SJianqun Xu .bit = 4, 5487825aeb7SJianqun Xu .mask = 0x7 5497825aeb7SJianqun Xu }, 5507825aeb7SJianqun Xu }; 5517825aeb7SJianqun Xu 552c04c3fa6SDavid Wu static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = { 5533818e4a7Sdavid.wu { 5543818e4a7Sdavid.wu .num = 2, 5553818e4a7Sdavid.wu .pin = 12, 5563818e4a7Sdavid.wu .reg = 0x24, 5573818e4a7Sdavid.wu .bit = 8, 5583818e4a7Sdavid.wu .mask = 0x3 5593818e4a7Sdavid.wu }, { 5603818e4a7Sdavid.wu .num = 2, 5613818e4a7Sdavid.wu .pin = 15, 5623818e4a7Sdavid.wu .reg = 0x28, 5633818e4a7Sdavid.wu .bit = 0, 5643818e4a7Sdavid.wu .mask = 0x7 5653818e4a7Sdavid.wu }, { 5663818e4a7Sdavid.wu .num = 2, 5673818e4a7Sdavid.wu .pin = 23, 5683818e4a7Sdavid.wu .reg = 0x30, 5693818e4a7Sdavid.wu .bit = 14, 5703818e4a7Sdavid.wu .mask = 0x3 5713818e4a7Sdavid.wu }, 5723818e4a7Sdavid.wu }; 5733818e4a7Sdavid.wu 574c04c3fa6SDavid Wu static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin, 575c04c3fa6SDavid Wu int *reg, u8 *bit, int *mask) 5763818e4a7Sdavid.wu { 577c04c3fa6SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 578c04c3fa6SDavid Wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 579c04c3fa6SDavid Wu struct rockchip_mux_recalced_data *data; 5803818e4a7Sdavid.wu int i; 5813818e4a7Sdavid.wu 582c04c3fa6SDavid Wu for (i = 0; i < ctrl->niomux_recalced; i++) { 583c04c3fa6SDavid Wu data = &ctrl->iomux_recalced[i]; 584c04c3fa6SDavid Wu if (data->num == bank->bank_num && 585c04c3fa6SDavid Wu data->pin == pin) 5863818e4a7Sdavid.wu break; 5873818e4a7Sdavid.wu } 5883818e4a7Sdavid.wu 589c04c3fa6SDavid Wu if (i >= ctrl->niomux_recalced) 5903818e4a7Sdavid.wu return; 5913818e4a7Sdavid.wu 5923818e4a7Sdavid.wu *reg = data->reg; 5933818e4a7Sdavid.wu *mask = data->mask; 5943818e4a7Sdavid.wu *bit = data->bit; 5953818e4a7Sdavid.wu } 5963818e4a7Sdavid.wu 59787065ca9SDavid Wu static struct rockchip_mux_route_data px30_mux_route_data[] = { 598fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */ 599fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */ 600fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */ 601fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */ 602fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */ 603fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */ 604fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */ 605fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */ 60687065ca9SDavid Wu }; 60787065ca9SDavid Wu 608d23c66dfSDavid Wu static struct rockchip_mux_route_data rk3128_mux_route_data[] = { 609fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x144, BIT(16 + 3) | BIT(16 + 4)), /* spi-0 */ 610fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PD3, 3, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(3)), /* spi-1 */ 611fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(4)), /* spi-2 */ 612fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA5, 1, 0x144, BIT(16 + 5)), /* i2s-0 */ 613fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB6, 1, 0x144, BIT(16 + 5) | BIT(5)), /* i2s-1 */ 614fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x144, BIT(16 + 6)), /* emmc-0 */ 615fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x144, BIT(16 + 6) | BIT(6)), /* emmc-1 */ 616d23c66dfSDavid Wu }; 617d23c66dfSDavid Wu 618ada62b7cSHeiko Stuebner static struct rockchip_mux_route_data rk3188_mux_route_data[] = { 619fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */ 620fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */ 621ada62b7cSHeiko Stuebner }; 622ada62b7cSHeiko Stuebner 623d4970ee0SDavid Wu static struct rockchip_mux_route_data rk3228_mux_route_data[] = { 624fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD2, 1, 0x50, BIT(16)), /* pwm0-0 */ 625fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PC5, 1, 0x50, BIT(16) | BIT(0)), /* pwm0-1 */ 626fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD3, 1, 0x50, BIT(16 + 1)), /* pwm1-0 */ 627fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD6, 2, 0x50, BIT(16 + 1) | BIT(1)), /* pwm1-1 */ 628fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD4, 1, 0x50, BIT(16 + 2)), /* pwm2-0 */ 629fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x50, BIT(16 + 2) | BIT(2)), /* pwm2-1 */ 630fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PD2, 1, 0x50, BIT(16 + 3)), /* pwm3-0 */ 631fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 3) | BIT(3)), /* pwm3-1 */ 632fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA1, 1, 0x50, BIT(16 + 4)), /* sdio-0_d0 */ 633fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA2, 1, 0x50, BIT(16 + 4) | BIT(4)), /* sdio-1_d0 */ 634fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x50, BIT(16 + 5)), /* spi-0_rx */ 635fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA0, 2, 0x50, BIT(16 + 5) | BIT(5)), /* spi-1_rx */ 636fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x50, BIT(16 + 7)), /* emmc-0_cmd */ 637fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x50, BIT(16 + 7) | BIT(7)), /* emmc-1_cmd */ 638fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC3, 2, 0x50, BIT(16 + 8)), /* uart2-0_rx */ 639fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB2, 2, 0x50, BIT(16 + 8) | BIT(8)), /* uart2-1_rx */ 640fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x50, BIT(16 + 11)), /* uart1-0_rx */ 641fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB5, 1, 0x50, BIT(16 + 11) | BIT(11)), /* uart1-1_rx */ 642d4970ee0SDavid Wu }; 643d4970ee0SDavid Wu 6444e96fd30SHeiko Stuebner static struct rockchip_mux_route_data rk3288_mux_route_data[] = { 645fe202ea8SJianqun Xu RK_MUXROUTE_SAME(7, RK_PC0, 2, 0x264, BIT(16 + 12) | BIT(12)), /* edphdmi_cecinoutt1 */ 646fe202ea8SJianqun Xu RK_MUXROUTE_SAME(7, RK_PC7, 4, 0x264, BIT(16 + 12)), /* edphdmi_cecinout */ 6474e96fd30SHeiko Stuebner }; 6484e96fd30SHeiko Stuebner 6497825aeb7SJianqun Xu static struct rockchip_mux_route_data rk3308_mux_route_data[] = { 650fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, BIT(16 + 0) | BIT(0)), /* rtc_clk */ 651fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, BIT(16 + 2) | BIT(16 + 3)), /* uart2_rxm0 */ 652fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, BIT(16 + 2) | BIT(16 + 3) | BIT(2)), /* uart2_rxm1 */ 653fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x608, BIT(16 + 8) | BIT(16 + 9)), /* i2c3_sdam0 */ 654fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(8)), /* i2c3_sdam1 */ 655fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA0, 3, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(9)), /* i2c3_sdam2 */ 656fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */ 657fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */ 658fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */ 659fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclkrxm1 */ 660fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, BIT(16 + 12) | BIT(16 + 13)), /* pdm-clkm0 */ 661fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */ 662fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */ 663fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */ 664fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB2, 3, 0x314, BIT(16 + 9)), /* spi1_miso */ 665fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x314, BIT(16 + 9) | BIT(9)), /* spi1_miso_m1 */ 666fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB3, 3, 0x314, BIT(16 + 10) | BIT(16 + 11)), /* owire_m0 */ 667fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 7, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* owire_m1 */ 668fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA2, 5, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* owire_m2 */ 669fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB3, 2, 0x314, BIT(16 + 12) | BIT(16 + 13)), /* can_rxd_m0 */ 670fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 5, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* can_rxd_m1 */ 671fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA2, 4, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* can_rxd_m2 */ 672fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC4, 3, 0x314, BIT(16 + 14)), /* mac_rxd0_m0 */ 673fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PA2, 2, 0x314, BIT(16 + 14) | BIT(14)), /* mac_rxd0_m1 */ 674fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB4, 4, 0x314, BIT(16 + 15)), /* uart3_rx */ 675fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PC1, 3, 0x314, BIT(16 + 15) | BIT(15)), /* uart3_rx_m1 */ 6767825aeb7SJianqun Xu }; 6777825aeb7SJianqun Xu 678cedc964aSDavid Wu static struct rockchip_mux_route_data rk3328_mux_route_data[] = { 679fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA1, 2, 0x50, BIT(16) | BIT(16 + 1)), /* uart2dbg_rxm0 */ 680fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x50, BIT(16) | BIT(16 + 1) | BIT(0)), /* uart2dbg_rxm1 */ 681fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 2) | BIT(2)), /* gmac-m1_rxd0 */ 682fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x50, BIT(16 + 10) | BIT(10)), /* gmac-m1-optimized_rxd3 */ 683fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC3, 2, 0x50, BIT(16 + 3)), /* pdm_sdi0m0 */ 684fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC7, 3, 0x50, BIT(16 + 3) | BIT(3)), /* pdm_sdi0m1 */ 685fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA2, 4, 0x50, BIT(16 + 4) | BIT(16 + 5) | BIT(5)), /* spi_rxdm2 */ 686fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PD0, 1, 0x50, BIT(16 + 6)), /* i2s2_sdim0 */ 687fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA2, 6, 0x50, BIT(16 + 6) | BIT(6)), /* i2s2_sdim1 */ 688fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC6, 3, 0x50, BIT(16 + 7) | BIT(7)), /* card_iom1 */ 689fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC0, 3, 0x50, BIT(16 + 8) | BIT(8)), /* tsp_d5m1 */ 690fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC0, 4, 0x50, BIT(16 + 9) | BIT(9)), /* cif_data5m1 */ 691cedc964aSDavid Wu }; 692cedc964aSDavid Wu 693accc1ce7SDavid Wu static struct rockchip_mux_route_data rk3399_mux_route_data[] = { 694fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PB0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11)), /* uart2dbga_rx */ 695fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PC0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* uart2dbgb_rx */ 696fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PC3, 1, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* uart2dbgc_rx */ 697fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PD2, 2, 0xe21c, BIT(16 + 14)), /* pcie_clkreqn */ 698fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PD0, 1, 0xe21c, BIT(16 + 14) | BIT(14)), /* pcie_clkreqnb */ 699accc1ce7SDavid Wu }; 700accc1ce7SDavid Wu 701c0dadc0eSJianqun Xu static struct rockchip_mux_route_data rk3568_mux_route_data[] = { 702c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */ 703c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */ 704c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */ 705c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */ 706c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */ 707c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */ 708c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ 709c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */ 710c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */ 711c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */ 712c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */ 713c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */ 714c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */ 715c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ 716c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */ 717c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */ 718c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */ 719c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ 720c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ 721c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */ 722c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */ 723c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */ 724c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */ 725c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */ 726c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */ 727c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */ 728c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */ 729c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */ 730c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */ 731c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */ 732c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */ 733c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */ 734c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */ 735c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */ 736c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */ 737c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */ 738c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */ 739c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */ 740c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */ 741c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */ 742c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */ 743c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */ 744c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */ 745c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */ 746c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ 747c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */ 748c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */ 749c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */ 750c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */ 751c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */ 752c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */ 753c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */ 754c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */ 755c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ 756c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ 757c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */ 758c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */ 759c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */ 760c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */ 761c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */ 762c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */ 763c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */ 764c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */ 765c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */ 766c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */ 767c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */ 768c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */ 769c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */ 770c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */ 771c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */ 772c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */ 773c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */ 774c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */ 775c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */ 776c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */ 777c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */ 778c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */ 779c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */ 780c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */ 781c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ 782c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ 783c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ 784c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ 785c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */ 786c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ 787c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */ 788c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */ 789c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ 790c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */ 791c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */ 792c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ 793c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */ 794c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */ 795d3e51161SHeiko Stübner }; 796d3e51161SHeiko Stübner 797bd35b9bfSDavid Wu static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, 79851ff47aaSHeiko Stuebner int mux, u32 *loc, u32 *reg, u32 *value) 799bd35b9bfSDavid Wu { 800bd35b9bfSDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 801bd35b9bfSDavid Wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 802bd35b9bfSDavid Wu struct rockchip_mux_route_data *data; 803bd35b9bfSDavid Wu int i; 804bd35b9bfSDavid Wu 805bd35b9bfSDavid Wu for (i = 0; i < ctrl->niomux_routes; i++) { 806bd35b9bfSDavid Wu data = &ctrl->iomux_routes[i]; 807bd35b9bfSDavid Wu if ((data->bank_num == bank->bank_num) && 808bd35b9bfSDavid Wu (data->pin == pin) && (data->func == mux)) 809bd35b9bfSDavid Wu break; 810bd35b9bfSDavid Wu } 811bd35b9bfSDavid Wu 812bd35b9bfSDavid Wu if (i >= ctrl->niomux_routes) 813bd35b9bfSDavid Wu return false; 814bd35b9bfSDavid Wu 81551ff47aaSHeiko Stuebner *loc = data->route_location; 816bd35b9bfSDavid Wu *reg = data->route_offset; 817bd35b9bfSDavid Wu *value = data->route_val; 818bd35b9bfSDavid Wu 819bd35b9bfSDavid Wu return true; 820bd35b9bfSDavid Wu } 821bd35b9bfSDavid Wu 822a076e2edSHeiko Stübner static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) 823a076e2edSHeiko Stübner { 824a076e2edSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 825fc72c923SHeiko Stübner int iomux_num = (pin / 8); 82695ec8ae4SHeiko Stübner struct regmap *regmap; 827751a99abSHeiko Stübner unsigned int val; 828ea262ad6Sdavid.wu int reg, ret, mask, mux_type; 829a076e2edSHeiko Stübner u8 bit; 830a076e2edSHeiko Stübner 831fc72c923SHeiko Stübner if (iomux_num > 3) 832fc72c923SHeiko Stübner return -EINVAL; 833fc72c923SHeiko Stübner 83462f49226SHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 83562f49226SHeiko Stübner dev_err(info->dev, "pin %d is unrouted\n", pin); 83662f49226SHeiko Stübner return -EINVAL; 83762f49226SHeiko Stübner } 83862f49226SHeiko Stübner 839fc72c923SHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 840a076e2edSHeiko Stübner return RK_FUNC_GPIO; 841a076e2edSHeiko Stübner 84295ec8ae4SHeiko Stübner regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 84395ec8ae4SHeiko Stübner ? info->regmap_pmu : info->regmap_base; 84495ec8ae4SHeiko Stübner 845a076e2edSHeiko Stübner /* get basic quadrupel of mux registers and the correct reg inside */ 846ea262ad6Sdavid.wu mux_type = bank->iomux[iomux_num].type; 8476bc0d121SHeiko Stübner reg = bank->iomux[iomux_num].offset; 848ea262ad6Sdavid.wu if (mux_type & IOMUX_WIDTH_4BIT) { 84903716e1dSHeiko Stübner if ((pin % 8) >= 4) 85003716e1dSHeiko Stübner reg += 0x4; 85103716e1dSHeiko Stübner bit = (pin % 4) * 4; 8528b6c6f93Sdavid.wu mask = 0xf; 853ea262ad6Sdavid.wu } else if (mux_type & IOMUX_WIDTH_3BIT) { 8548b6c6f93Sdavid.wu if ((pin % 8) >= 5) 8558b6c6f93Sdavid.wu reg += 0x4; 8568b6c6f93Sdavid.wu bit = (pin % 8 % 5) * 3; 8578b6c6f93Sdavid.wu mask = 0x7; 85803716e1dSHeiko Stübner } else { 859a076e2edSHeiko Stübner bit = (pin % 8) * 2; 8608b6c6f93Sdavid.wu mask = 0x3; 86103716e1dSHeiko Stübner } 862a076e2edSHeiko Stübner 863c04c3fa6SDavid Wu if (bank->recalced_mask & BIT(pin)) 864c04c3fa6SDavid Wu rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 865ea262ad6Sdavid.wu 86695ec8ae4SHeiko Stübner ret = regmap_read(regmap, reg, &val); 867751a99abSHeiko Stübner if (ret) 868751a99abSHeiko Stübner return ret; 869751a99abSHeiko Stübner 87003716e1dSHeiko Stübner return ((val >> bit) & mask); 871a076e2edSHeiko Stübner } 872a076e2edSHeiko Stübner 87305709c3eSJohn Keeping static int rockchip_verify_mux(struct rockchip_pin_bank *bank, 87405709c3eSJohn Keeping int pin, int mux) 87505709c3eSJohn Keeping { 87605709c3eSJohn Keeping struct rockchip_pinctrl *info = bank->drvdata; 877e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 87805709c3eSJohn Keeping int iomux_num = (pin / 8); 87905709c3eSJohn Keeping 88005709c3eSJohn Keeping if (iomux_num > 3) 88105709c3eSJohn Keeping return -EINVAL; 88205709c3eSJohn Keeping 88305709c3eSJohn Keeping if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 884e4dd7fd5SAndy Shevchenko dev_err(dev, "pin %d is unrouted\n", pin); 88505709c3eSJohn Keeping return -EINVAL; 88605709c3eSJohn Keeping } 88705709c3eSJohn Keeping 88805709c3eSJohn Keeping if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { 88905709c3eSJohn Keeping if (mux != RK_FUNC_GPIO) { 890e4dd7fd5SAndy Shevchenko dev_err(dev, "pin %d only supports a gpio mux\n", pin); 89105709c3eSJohn Keeping return -ENOTSUPP; 89205709c3eSJohn Keeping } 89305709c3eSJohn Keeping } 89405709c3eSJohn Keeping 89505709c3eSJohn Keeping return 0; 89605709c3eSJohn Keeping } 89705709c3eSJohn Keeping 898d3e51161SHeiko Stübner /* 899d3e51161SHeiko Stübner * Set a new mux function for a pin. 900d3e51161SHeiko Stübner * 901d3e51161SHeiko Stübner * The register is divided into the upper and lower 16 bit. When changing 902d3e51161SHeiko Stübner * a value, the previous register value is not read and changed. Instead 903d3e51161SHeiko Stübner * it seems the changed bits are marked in the upper 16 bit, while the 904d3e51161SHeiko Stübner * changed value gets set in the same offset in the lower 16 bit. 905d3e51161SHeiko Stübner * All pin settings seem to be 2 bit wide in both the upper and lower 906d3e51161SHeiko Stübner * parts. 907d3e51161SHeiko Stübner * @bank: pin bank to change 908d3e51161SHeiko Stübner * @pin: pin to change 909d3e51161SHeiko Stübner * @mux: new mux function to set 910d3e51161SHeiko Stübner */ 91114797189SHeiko Stübner static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 912d3e51161SHeiko Stübner { 913d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 914e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 915fc72c923SHeiko Stübner int iomux_num = (pin / 8); 91695ec8ae4SHeiko Stübner struct regmap *regmap; 917ea262ad6Sdavid.wu int reg, ret, mask, mux_type; 918d3e51161SHeiko Stübner u8 bit; 91951ff47aaSHeiko Stuebner u32 data, rmask, route_location, route_reg, route_val; 920d3e51161SHeiko Stübner 92105709c3eSJohn Keeping ret = rockchip_verify_mux(bank, pin, mux); 92205709c3eSJohn Keeping if (ret < 0) 92305709c3eSJohn Keeping return ret; 924fc72c923SHeiko Stübner 92505709c3eSJohn Keeping if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 926c4a532deSHeiko Stübner return 0; 927c4a532deSHeiko Stübner 928e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); 929d3e51161SHeiko Stübner 93095ec8ae4SHeiko Stübner regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 93195ec8ae4SHeiko Stübner ? info->regmap_pmu : info->regmap_base; 93295ec8ae4SHeiko Stübner 933d3e51161SHeiko Stübner /* get basic quadrupel of mux registers and the correct reg inside */ 934ea262ad6Sdavid.wu mux_type = bank->iomux[iomux_num].type; 9356bc0d121SHeiko Stübner reg = bank->iomux[iomux_num].offset; 936ea262ad6Sdavid.wu if (mux_type & IOMUX_WIDTH_4BIT) { 93703716e1dSHeiko Stübner if ((pin % 8) >= 4) 93803716e1dSHeiko Stübner reg += 0x4; 93903716e1dSHeiko Stübner bit = (pin % 4) * 4; 9408b6c6f93Sdavid.wu mask = 0xf; 941ea262ad6Sdavid.wu } else if (mux_type & IOMUX_WIDTH_3BIT) { 9428b6c6f93Sdavid.wu if ((pin % 8) >= 5) 9438b6c6f93Sdavid.wu reg += 0x4; 9448b6c6f93Sdavid.wu bit = (pin % 8 % 5) * 3; 9458b6c6f93Sdavid.wu mask = 0x7; 94603716e1dSHeiko Stübner } else { 947d3e51161SHeiko Stübner bit = (pin % 8) * 2; 9488b6c6f93Sdavid.wu mask = 0x3; 94903716e1dSHeiko Stübner } 950d3e51161SHeiko Stübner 951c04c3fa6SDavid Wu if (bank->recalced_mask & BIT(pin)) 952c04c3fa6SDavid Wu rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 953ea262ad6Sdavid.wu 954bd35b9bfSDavid Wu if (bank->route_mask & BIT(pin)) { 95551ff47aaSHeiko Stuebner if (rockchip_get_mux_route(bank, pin, mux, &route_location, 95651ff47aaSHeiko Stuebner &route_reg, &route_val)) { 95751ff47aaSHeiko Stuebner struct regmap *route_regmap = regmap; 95851ff47aaSHeiko Stuebner 95951ff47aaSHeiko Stuebner /* handle special locations */ 96051ff47aaSHeiko Stuebner switch (route_location) { 96151ff47aaSHeiko Stuebner case ROCKCHIP_ROUTE_PMU: 96251ff47aaSHeiko Stuebner route_regmap = info->regmap_pmu; 96351ff47aaSHeiko Stuebner break; 96451ff47aaSHeiko Stuebner case ROCKCHIP_ROUTE_GRF: 96551ff47aaSHeiko Stuebner route_regmap = info->regmap_base; 96651ff47aaSHeiko Stuebner break; 96751ff47aaSHeiko Stuebner } 96851ff47aaSHeiko Stuebner 96951ff47aaSHeiko Stuebner ret = regmap_write(route_regmap, route_reg, route_val); 970bd35b9bfSDavid Wu if (ret) 971bd35b9bfSDavid Wu return ret; 972bd35b9bfSDavid Wu } 973bd35b9bfSDavid Wu } 974bd35b9bfSDavid Wu 97503716e1dSHeiko Stübner data = (mask << (bit + 16)); 97699e872d9SSonny Rao rmask = data | (data >> 16); 97703716e1dSHeiko Stübner data |= (mux & mask) << bit; 97899e872d9SSonny Rao ret = regmap_update_bits(regmap, reg, rmask, data); 979d3e51161SHeiko Stübner 980751a99abSHeiko Stübner return ret; 981d3e51161SHeiko Stübner } 982d3e51161SHeiko Stübner 98387065ca9SDavid Wu #define PX30_PULL_PMU_OFFSET 0x10 98487065ca9SDavid Wu #define PX30_PULL_GRF_OFFSET 0x60 98587065ca9SDavid Wu #define PX30_PULL_BITS_PER_PIN 2 98687065ca9SDavid Wu #define PX30_PULL_PINS_PER_REG 8 98787065ca9SDavid Wu #define PX30_PULL_BANK_STRIDE 16 98887065ca9SDavid Wu 98987065ca9SDavid Wu static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 99087065ca9SDavid Wu int pin_num, struct regmap **regmap, 99187065ca9SDavid Wu int *reg, u8 *bit) 99287065ca9SDavid Wu { 99387065ca9SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 99487065ca9SDavid Wu 99587065ca9SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 99687065ca9SDavid Wu if (bank->bank_num == 0) { 99787065ca9SDavid Wu *regmap = info->regmap_pmu; 99887065ca9SDavid Wu *reg = PX30_PULL_PMU_OFFSET; 99987065ca9SDavid Wu } else { 100087065ca9SDavid Wu *regmap = info->regmap_base; 100187065ca9SDavid Wu *reg = PX30_PULL_GRF_OFFSET; 100287065ca9SDavid Wu 100387065ca9SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 100487065ca9SDavid Wu *reg -= 0x10; 100587065ca9SDavid Wu *reg += bank->bank_num * PX30_PULL_BANK_STRIDE; 100687065ca9SDavid Wu } 100787065ca9SDavid Wu 100887065ca9SDavid Wu *reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4); 100987065ca9SDavid Wu *bit = (pin_num % PX30_PULL_PINS_PER_REG); 101087065ca9SDavid Wu *bit *= PX30_PULL_BITS_PER_PIN; 101187065ca9SDavid Wu } 101287065ca9SDavid Wu 101387065ca9SDavid Wu #define PX30_DRV_PMU_OFFSET 0x20 101487065ca9SDavid Wu #define PX30_DRV_GRF_OFFSET 0xf0 101587065ca9SDavid Wu #define PX30_DRV_BITS_PER_PIN 2 101687065ca9SDavid Wu #define PX30_DRV_PINS_PER_REG 8 101787065ca9SDavid Wu #define PX30_DRV_BANK_STRIDE 16 101887065ca9SDavid Wu 101987065ca9SDavid Wu static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 102087065ca9SDavid Wu int pin_num, struct regmap **regmap, 102187065ca9SDavid Wu int *reg, u8 *bit) 102287065ca9SDavid Wu { 102387065ca9SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 102487065ca9SDavid Wu 102587065ca9SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 102687065ca9SDavid Wu if (bank->bank_num == 0) { 102787065ca9SDavid Wu *regmap = info->regmap_pmu; 102887065ca9SDavid Wu *reg = PX30_DRV_PMU_OFFSET; 102987065ca9SDavid Wu } else { 103087065ca9SDavid Wu *regmap = info->regmap_base; 103187065ca9SDavid Wu *reg = PX30_DRV_GRF_OFFSET; 103287065ca9SDavid Wu 103387065ca9SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 103487065ca9SDavid Wu *reg -= 0x10; 103587065ca9SDavid Wu *reg += bank->bank_num * PX30_DRV_BANK_STRIDE; 103687065ca9SDavid Wu } 103787065ca9SDavid Wu 103887065ca9SDavid Wu *reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4); 103987065ca9SDavid Wu *bit = (pin_num % PX30_DRV_PINS_PER_REG); 104087065ca9SDavid Wu *bit *= PX30_DRV_BITS_PER_PIN; 104187065ca9SDavid Wu } 104287065ca9SDavid Wu 104387065ca9SDavid Wu #define PX30_SCHMITT_PMU_OFFSET 0x38 104487065ca9SDavid Wu #define PX30_SCHMITT_GRF_OFFSET 0xc0 104587065ca9SDavid Wu #define PX30_SCHMITT_PINS_PER_PMU_REG 16 104687065ca9SDavid Wu #define PX30_SCHMITT_BANK_STRIDE 16 104787065ca9SDavid Wu #define PX30_SCHMITT_PINS_PER_GRF_REG 8 104887065ca9SDavid Wu 104987065ca9SDavid Wu static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 105087065ca9SDavid Wu int pin_num, 105187065ca9SDavid Wu struct regmap **regmap, 105287065ca9SDavid Wu int *reg, u8 *bit) 105387065ca9SDavid Wu { 105487065ca9SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 105587065ca9SDavid Wu int pins_per_reg; 105687065ca9SDavid Wu 105787065ca9SDavid Wu if (bank->bank_num == 0) { 105887065ca9SDavid Wu *regmap = info->regmap_pmu; 105987065ca9SDavid Wu *reg = PX30_SCHMITT_PMU_OFFSET; 106087065ca9SDavid Wu pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG; 106187065ca9SDavid Wu } else { 106287065ca9SDavid Wu *regmap = info->regmap_base; 106387065ca9SDavid Wu *reg = PX30_SCHMITT_GRF_OFFSET; 106487065ca9SDavid Wu pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG; 106587065ca9SDavid Wu *reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE; 106687065ca9SDavid Wu } 106787065ca9SDavid Wu 106887065ca9SDavid Wu *reg += ((pin_num / pins_per_reg) * 4); 106987065ca9SDavid Wu *bit = pin_num % pins_per_reg; 107087065ca9SDavid Wu 107187065ca9SDavid Wu return 0; 107287065ca9SDavid Wu } 107387065ca9SDavid Wu 1074b9c6dcabSAndy Yan #define RV1108_PULL_PMU_OFFSET 0x10 1075b9c6dcabSAndy Yan #define RV1108_PULL_OFFSET 0x110 1076b9c6dcabSAndy Yan #define RV1108_PULL_PINS_PER_REG 8 1077b9c6dcabSAndy Yan #define RV1108_PULL_BITS_PER_PIN 2 1078b9c6dcabSAndy Yan #define RV1108_PULL_BANK_STRIDE 16 1079688daf23SAndy Yan 1080b9c6dcabSAndy Yan static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1081688daf23SAndy Yan int pin_num, struct regmap **regmap, 1082688daf23SAndy Yan int *reg, u8 *bit) 1083688daf23SAndy Yan { 1084688daf23SAndy Yan struct rockchip_pinctrl *info = bank->drvdata; 1085688daf23SAndy Yan 1086688daf23SAndy Yan /* The first 24 pins of the first bank are located in PMU */ 1087688daf23SAndy Yan if (bank->bank_num == 0) { 1088688daf23SAndy Yan *regmap = info->regmap_pmu; 1089b9c6dcabSAndy Yan *reg = RV1108_PULL_PMU_OFFSET; 1090688daf23SAndy Yan } else { 1091b9c6dcabSAndy Yan *reg = RV1108_PULL_OFFSET; 1092688daf23SAndy Yan *regmap = info->regmap_base; 1093688daf23SAndy Yan /* correct the offset, as we're starting with the 2nd bank */ 1094688daf23SAndy Yan *reg -= 0x10; 1095b9c6dcabSAndy Yan *reg += bank->bank_num * RV1108_PULL_BANK_STRIDE; 1096688daf23SAndy Yan } 1097688daf23SAndy Yan 1098b9c6dcabSAndy Yan *reg += ((pin_num / RV1108_PULL_PINS_PER_REG) * 4); 1099b9c6dcabSAndy Yan *bit = (pin_num % RV1108_PULL_PINS_PER_REG); 1100b9c6dcabSAndy Yan *bit *= RV1108_PULL_BITS_PER_PIN; 1101688daf23SAndy Yan } 1102688daf23SAndy Yan 1103b9c6dcabSAndy Yan #define RV1108_DRV_PMU_OFFSET 0x20 1104b9c6dcabSAndy Yan #define RV1108_DRV_GRF_OFFSET 0x210 1105b9c6dcabSAndy Yan #define RV1108_DRV_BITS_PER_PIN 2 1106b9c6dcabSAndy Yan #define RV1108_DRV_PINS_PER_REG 8 1107b9c6dcabSAndy Yan #define RV1108_DRV_BANK_STRIDE 16 1108688daf23SAndy Yan 1109b9c6dcabSAndy Yan static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1110688daf23SAndy Yan int pin_num, struct regmap **regmap, 1111688daf23SAndy Yan int *reg, u8 *bit) 1112688daf23SAndy Yan { 1113688daf23SAndy Yan struct rockchip_pinctrl *info = bank->drvdata; 1114688daf23SAndy Yan 1115688daf23SAndy Yan /* The first 24 pins of the first bank are located in PMU */ 1116688daf23SAndy Yan if (bank->bank_num == 0) { 1117688daf23SAndy Yan *regmap = info->regmap_pmu; 1118b9c6dcabSAndy Yan *reg = RV1108_DRV_PMU_OFFSET; 1119688daf23SAndy Yan } else { 1120688daf23SAndy Yan *regmap = info->regmap_base; 1121b9c6dcabSAndy Yan *reg = RV1108_DRV_GRF_OFFSET; 1122688daf23SAndy Yan 1123688daf23SAndy Yan /* correct the offset, as we're starting with the 2nd bank */ 1124688daf23SAndy Yan *reg -= 0x10; 1125b9c6dcabSAndy Yan *reg += bank->bank_num * RV1108_DRV_BANK_STRIDE; 1126688daf23SAndy Yan } 1127688daf23SAndy Yan 1128b9c6dcabSAndy Yan *reg += ((pin_num / RV1108_DRV_PINS_PER_REG) * 4); 1129b9c6dcabSAndy Yan *bit = pin_num % RV1108_DRV_PINS_PER_REG; 1130b9c6dcabSAndy Yan *bit *= RV1108_DRV_BITS_PER_PIN; 1131688daf23SAndy Yan } 1132688daf23SAndy Yan 11335caff7eaSAndy Yan #define RV1108_SCHMITT_PMU_OFFSET 0x30 11345caff7eaSAndy Yan #define RV1108_SCHMITT_GRF_OFFSET 0x388 11355caff7eaSAndy Yan #define RV1108_SCHMITT_BANK_STRIDE 8 11365caff7eaSAndy Yan #define RV1108_SCHMITT_PINS_PER_GRF_REG 16 11375caff7eaSAndy Yan #define RV1108_SCHMITT_PINS_PER_PMU_REG 8 11385caff7eaSAndy Yan 11395caff7eaSAndy Yan static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 11405caff7eaSAndy Yan int pin_num, 11415caff7eaSAndy Yan struct regmap **regmap, 11425caff7eaSAndy Yan int *reg, u8 *bit) 11435caff7eaSAndy Yan { 11445caff7eaSAndy Yan struct rockchip_pinctrl *info = bank->drvdata; 11455caff7eaSAndy Yan int pins_per_reg; 11465caff7eaSAndy Yan 11475caff7eaSAndy Yan if (bank->bank_num == 0) { 11485caff7eaSAndy Yan *regmap = info->regmap_pmu; 11495caff7eaSAndy Yan *reg = RV1108_SCHMITT_PMU_OFFSET; 11505caff7eaSAndy Yan pins_per_reg = RV1108_SCHMITT_PINS_PER_PMU_REG; 11515caff7eaSAndy Yan } else { 11525caff7eaSAndy Yan *regmap = info->regmap_base; 11535caff7eaSAndy Yan *reg = RV1108_SCHMITT_GRF_OFFSET; 11545caff7eaSAndy Yan pins_per_reg = RV1108_SCHMITT_PINS_PER_GRF_REG; 11555caff7eaSAndy Yan *reg += (bank->bank_num - 1) * RV1108_SCHMITT_BANK_STRIDE; 11565caff7eaSAndy Yan } 11575caff7eaSAndy Yan *reg += ((pin_num / pins_per_reg) * 4); 11585caff7eaSAndy Yan *bit = pin_num % pins_per_reg; 11595caff7eaSAndy Yan 11605caff7eaSAndy Yan return 0; 11615caff7eaSAndy Yan } 11625caff7eaSAndy Yan 11637825aeb7SJianqun Xu #define RK3308_SCHMITT_PINS_PER_REG 8 11647825aeb7SJianqun Xu #define RK3308_SCHMITT_BANK_STRIDE 16 11657825aeb7SJianqun Xu #define RK3308_SCHMITT_GRF_OFFSET 0x1a0 11667825aeb7SJianqun Xu 11677825aeb7SJianqun Xu static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 11687825aeb7SJianqun Xu int pin_num, struct regmap **regmap, 11697825aeb7SJianqun Xu int *reg, u8 *bit) 11707825aeb7SJianqun Xu { 11717825aeb7SJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 11727825aeb7SJianqun Xu 11737825aeb7SJianqun Xu *regmap = info->regmap_base; 11747825aeb7SJianqun Xu *reg = RK3308_SCHMITT_GRF_OFFSET; 11757825aeb7SJianqun Xu 11767825aeb7SJianqun Xu *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE; 11777825aeb7SJianqun Xu *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4); 11787825aeb7SJianqun Xu *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG; 11797825aeb7SJianqun Xu 11807825aeb7SJianqun Xu return 0; 11817825aeb7SJianqun Xu } 11827825aeb7SJianqun Xu 1183a282926dSHeiko Stübner #define RK2928_PULL_OFFSET 0x118 1184a282926dSHeiko Stübner #define RK2928_PULL_PINS_PER_REG 16 1185a282926dSHeiko Stübner #define RK2928_PULL_BANK_STRIDE 8 1186a282926dSHeiko Stübner 1187a282926dSHeiko Stübner static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1188751a99abSHeiko Stübner int pin_num, struct regmap **regmap, 1189751a99abSHeiko Stübner int *reg, u8 *bit) 1190a282926dSHeiko Stübner { 1191a282926dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1192a282926dSHeiko Stübner 1193751a99abSHeiko Stübner *regmap = info->regmap_base; 1194751a99abSHeiko Stübner *reg = RK2928_PULL_OFFSET; 1195a282926dSHeiko Stübner *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 1196a282926dSHeiko Stübner *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4; 1197a282926dSHeiko Stübner 1198a282926dSHeiko Stübner *bit = pin_num % RK2928_PULL_PINS_PER_REG; 1199a282926dSHeiko Stübner }; 1200a282926dSHeiko Stübner 1201d23c66dfSDavid Wu #define RK3128_PULL_OFFSET 0x118 1202d23c66dfSDavid Wu 1203d23c66dfSDavid Wu static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1204d23c66dfSDavid Wu int pin_num, struct regmap **regmap, 1205d23c66dfSDavid Wu int *reg, u8 *bit) 1206d23c66dfSDavid Wu { 1207d23c66dfSDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 1208d23c66dfSDavid Wu 1209d23c66dfSDavid Wu *regmap = info->regmap_base; 1210d23c66dfSDavid Wu *reg = RK3128_PULL_OFFSET; 1211d23c66dfSDavid Wu *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 1212d23c66dfSDavid Wu *reg += ((pin_num / RK2928_PULL_PINS_PER_REG) * 4); 1213d23c66dfSDavid Wu 1214d23c66dfSDavid Wu *bit = pin_num % RK2928_PULL_PINS_PER_REG; 1215d23c66dfSDavid Wu } 1216d23c66dfSDavid Wu 1217bfc7a42aSHeiko Stübner #define RK3188_PULL_OFFSET 0x164 12186ca5274dSHeiko Stübner #define RK3188_PULL_BITS_PER_PIN 2 12196ca5274dSHeiko Stübner #define RK3188_PULL_PINS_PER_REG 8 12206ca5274dSHeiko Stübner #define RK3188_PULL_BANK_STRIDE 16 122114dee867SHeiko Stübner #define RK3188_PULL_PMU_OFFSET 0x64 12226ca5274dSHeiko Stübner 12236ca5274dSHeiko Stübner static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1224751a99abSHeiko Stübner int pin_num, struct regmap **regmap, 1225751a99abSHeiko Stübner int *reg, u8 *bit) 12266ca5274dSHeiko Stübner { 12276ca5274dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 12286ca5274dSHeiko Stübner 12296ca5274dSHeiko Stübner /* The first 12 pins of the first bank are located elsewhere */ 1230fc72c923SHeiko Stübner if (bank->bank_num == 0 && pin_num < 12) { 123114dee867SHeiko Stübner *regmap = info->regmap_pmu ? info->regmap_pmu 123214dee867SHeiko Stübner : bank->regmap_pull; 123314dee867SHeiko Stübner *reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0; 1234751a99abSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 12356ca5274dSHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 12366ca5274dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 12376ca5274dSHeiko Stübner } else { 1238751a99abSHeiko Stübner *regmap = info->regmap_pull ? info->regmap_pull 1239751a99abSHeiko Stübner : info->regmap_base; 1240751a99abSHeiko Stübner *reg = info->regmap_pull ? 0 : RK3188_PULL_OFFSET; 1241751a99abSHeiko Stübner 1242bfc7a42aSHeiko Stübner /* correct the offset, as it is the 2nd pull register */ 1243bfc7a42aSHeiko Stübner *reg -= 4; 12446ca5274dSHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 12456ca5274dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 12466ca5274dSHeiko Stübner 12476ca5274dSHeiko Stübner /* 12486ca5274dSHeiko Stübner * The bits in these registers have an inverse ordering 12496ca5274dSHeiko Stübner * with the lowest pin being in bits 15:14 and the highest 12506ca5274dSHeiko Stübner * pin in bits 1:0 12516ca5274dSHeiko Stübner */ 12526ca5274dSHeiko Stübner *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG); 12536ca5274dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 12546ca5274dSHeiko Stübner } 12556ca5274dSHeiko Stübner } 12566ca5274dSHeiko Stübner 1257304f077dSHeiko Stübner #define RK3288_PULL_OFFSET 0x140 1258304f077dSHeiko Stübner static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1259304f077dSHeiko Stübner int pin_num, struct regmap **regmap, 1260304f077dSHeiko Stübner int *reg, u8 *bit) 1261304f077dSHeiko Stübner { 1262304f077dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1263304f077dSHeiko Stübner 1264304f077dSHeiko Stübner /* The first 24 pins of the first bank are located in PMU */ 1265304f077dSHeiko Stübner if (bank->bank_num == 0) { 1266304f077dSHeiko Stübner *regmap = info->regmap_pmu; 1267304f077dSHeiko Stübner *reg = RK3188_PULL_PMU_OFFSET; 1268304f077dSHeiko Stübner 1269304f077dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1270304f077dSHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 1271304f077dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1272304f077dSHeiko Stübner } else { 1273304f077dSHeiko Stübner *regmap = info->regmap_base; 1274304f077dSHeiko Stübner *reg = RK3288_PULL_OFFSET; 1275304f077dSHeiko Stübner 1276304f077dSHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1277304f077dSHeiko Stübner *reg -= 0x10; 1278304f077dSHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1279304f077dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1280304f077dSHeiko Stübner 1281304f077dSHeiko Stübner *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1282304f077dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1283304f077dSHeiko Stübner } 1284304f077dSHeiko Stübner } 1285304f077dSHeiko Stübner 1286b547c800SHeiko Stübner #define RK3288_DRV_PMU_OFFSET 0x70 1287b547c800SHeiko Stübner #define RK3288_DRV_GRF_OFFSET 0x1c0 1288b547c800SHeiko Stübner #define RK3288_DRV_BITS_PER_PIN 2 1289b547c800SHeiko Stübner #define RK3288_DRV_PINS_PER_REG 8 1290b547c800SHeiko Stübner #define RK3288_DRV_BANK_STRIDE 16 1291b547c800SHeiko Stübner 1292b547c800SHeiko Stübner static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1293b547c800SHeiko Stübner int pin_num, struct regmap **regmap, 1294b547c800SHeiko Stübner int *reg, u8 *bit) 1295b547c800SHeiko Stübner { 1296b547c800SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1297b547c800SHeiko Stübner 1298b547c800SHeiko Stübner /* The first 24 pins of the first bank are located in PMU */ 1299b547c800SHeiko Stübner if (bank->bank_num == 0) { 1300b547c800SHeiko Stübner *regmap = info->regmap_pmu; 1301b547c800SHeiko Stübner *reg = RK3288_DRV_PMU_OFFSET; 1302b547c800SHeiko Stübner 1303b547c800SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1304b547c800SHeiko Stübner *bit = pin_num % RK3288_DRV_PINS_PER_REG; 1305b547c800SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1306b547c800SHeiko Stübner } else { 1307b547c800SHeiko Stübner *regmap = info->regmap_base; 1308b547c800SHeiko Stübner *reg = RK3288_DRV_GRF_OFFSET; 1309b547c800SHeiko Stübner 1310b547c800SHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1311b547c800SHeiko Stübner *reg -= 0x10; 1312b547c800SHeiko Stübner *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 1313b547c800SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1314b547c800SHeiko Stübner 1315b547c800SHeiko Stübner *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 1316b547c800SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1317b547c800SHeiko Stübner } 1318b547c800SHeiko Stübner } 1319b547c800SHeiko Stübner 1320fea0fe60SJeffy Chen #define RK3228_PULL_OFFSET 0x100 1321fea0fe60SJeffy Chen 1322fea0fe60SJeffy Chen static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1323fea0fe60SJeffy Chen int pin_num, struct regmap **regmap, 1324fea0fe60SJeffy Chen int *reg, u8 *bit) 1325fea0fe60SJeffy Chen { 1326fea0fe60SJeffy Chen struct rockchip_pinctrl *info = bank->drvdata; 1327fea0fe60SJeffy Chen 1328fea0fe60SJeffy Chen *regmap = info->regmap_base; 1329fea0fe60SJeffy Chen *reg = RK3228_PULL_OFFSET; 1330fea0fe60SJeffy Chen *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1331fea0fe60SJeffy Chen *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1332fea0fe60SJeffy Chen 1333fea0fe60SJeffy Chen *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1334fea0fe60SJeffy Chen *bit *= RK3188_PULL_BITS_PER_PIN; 1335fea0fe60SJeffy Chen } 1336fea0fe60SJeffy Chen 1337fea0fe60SJeffy Chen #define RK3228_DRV_GRF_OFFSET 0x200 1338fea0fe60SJeffy Chen 1339fea0fe60SJeffy Chen static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1340fea0fe60SJeffy Chen int pin_num, struct regmap **regmap, 1341fea0fe60SJeffy Chen int *reg, u8 *bit) 1342fea0fe60SJeffy Chen { 1343fea0fe60SJeffy Chen struct rockchip_pinctrl *info = bank->drvdata; 1344fea0fe60SJeffy Chen 1345fea0fe60SJeffy Chen *regmap = info->regmap_base; 1346fea0fe60SJeffy Chen *reg = RK3228_DRV_GRF_OFFSET; 1347fea0fe60SJeffy Chen *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 1348fea0fe60SJeffy Chen *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1349fea0fe60SJeffy Chen 1350fea0fe60SJeffy Chen *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 1351fea0fe60SJeffy Chen *bit *= RK3288_DRV_BITS_PER_PIN; 1352fea0fe60SJeffy Chen } 1353fea0fe60SJeffy Chen 13547825aeb7SJianqun Xu #define RK3308_PULL_OFFSET 0xa0 13557825aeb7SJianqun Xu 13567825aeb7SJianqun Xu static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 13577825aeb7SJianqun Xu int pin_num, struct regmap **regmap, 13587825aeb7SJianqun Xu int *reg, u8 *bit) 13597825aeb7SJianqun Xu { 13607825aeb7SJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 13617825aeb7SJianqun Xu 13627825aeb7SJianqun Xu *regmap = info->regmap_base; 13637825aeb7SJianqun Xu *reg = RK3308_PULL_OFFSET; 13647825aeb7SJianqun Xu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 13657825aeb7SJianqun Xu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 13667825aeb7SJianqun Xu 13677825aeb7SJianqun Xu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 13687825aeb7SJianqun Xu *bit *= RK3188_PULL_BITS_PER_PIN; 13697825aeb7SJianqun Xu } 13707825aeb7SJianqun Xu 13717825aeb7SJianqun Xu #define RK3308_DRV_GRF_OFFSET 0x100 13727825aeb7SJianqun Xu 13737825aeb7SJianqun Xu static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 13747825aeb7SJianqun Xu int pin_num, struct regmap **regmap, 13757825aeb7SJianqun Xu int *reg, u8 *bit) 13767825aeb7SJianqun Xu { 13777825aeb7SJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 13787825aeb7SJianqun Xu 13797825aeb7SJianqun Xu *regmap = info->regmap_base; 13807825aeb7SJianqun Xu *reg = RK3308_DRV_GRF_OFFSET; 13817825aeb7SJianqun Xu *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 13827825aeb7SJianqun Xu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 13837825aeb7SJianqun Xu 13847825aeb7SJianqun Xu *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 13857825aeb7SJianqun Xu *bit *= RK3288_DRV_BITS_PER_PIN; 13867825aeb7SJianqun Xu } 13877825aeb7SJianqun Xu 1388daecdc66SHeiko Stübner #define RK3368_PULL_GRF_OFFSET 0x100 1389daecdc66SHeiko Stübner #define RK3368_PULL_PMU_OFFSET 0x10 1390daecdc66SHeiko Stübner 1391daecdc66SHeiko Stübner static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1392daecdc66SHeiko Stübner int pin_num, struct regmap **regmap, 1393daecdc66SHeiko Stübner int *reg, u8 *bit) 1394daecdc66SHeiko Stübner { 1395daecdc66SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1396daecdc66SHeiko Stübner 1397daecdc66SHeiko Stübner /* The first 32 pins of the first bank are located in PMU */ 1398daecdc66SHeiko Stübner if (bank->bank_num == 0) { 1399daecdc66SHeiko Stübner *regmap = info->regmap_pmu; 1400daecdc66SHeiko Stübner *reg = RK3368_PULL_PMU_OFFSET; 1401daecdc66SHeiko Stübner 1402daecdc66SHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1403daecdc66SHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 1404daecdc66SHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1405daecdc66SHeiko Stübner } else { 1406daecdc66SHeiko Stübner *regmap = info->regmap_base; 1407daecdc66SHeiko Stübner *reg = RK3368_PULL_GRF_OFFSET; 1408daecdc66SHeiko Stübner 1409daecdc66SHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1410daecdc66SHeiko Stübner *reg -= 0x10; 1411daecdc66SHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1412daecdc66SHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1413daecdc66SHeiko Stübner 1414daecdc66SHeiko Stübner *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1415daecdc66SHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1416daecdc66SHeiko Stübner } 1417daecdc66SHeiko Stübner } 1418daecdc66SHeiko Stübner 1419daecdc66SHeiko Stübner #define RK3368_DRV_PMU_OFFSET 0x20 1420daecdc66SHeiko Stübner #define RK3368_DRV_GRF_OFFSET 0x200 1421daecdc66SHeiko Stübner 1422daecdc66SHeiko Stübner static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1423daecdc66SHeiko Stübner int pin_num, struct regmap **regmap, 1424daecdc66SHeiko Stübner int *reg, u8 *bit) 1425daecdc66SHeiko Stübner { 1426daecdc66SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1427daecdc66SHeiko Stübner 1428daecdc66SHeiko Stübner /* The first 32 pins of the first bank are located in PMU */ 1429daecdc66SHeiko Stübner if (bank->bank_num == 0) { 1430daecdc66SHeiko Stübner *regmap = info->regmap_pmu; 1431daecdc66SHeiko Stübner *reg = RK3368_DRV_PMU_OFFSET; 1432daecdc66SHeiko Stübner 1433daecdc66SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1434daecdc66SHeiko Stübner *bit = pin_num % RK3288_DRV_PINS_PER_REG; 1435daecdc66SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1436daecdc66SHeiko Stübner } else { 1437daecdc66SHeiko Stübner *regmap = info->regmap_base; 1438daecdc66SHeiko Stübner *reg = RK3368_DRV_GRF_OFFSET; 1439daecdc66SHeiko Stübner 1440daecdc66SHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1441daecdc66SHeiko Stübner *reg -= 0x10; 1442daecdc66SHeiko Stübner *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 1443daecdc66SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1444daecdc66SHeiko Stübner 1445daecdc66SHeiko Stübner *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 1446daecdc66SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1447daecdc66SHeiko Stübner } 1448daecdc66SHeiko Stübner } 1449daecdc66SHeiko Stübner 1450b6c23275SDavid Wu #define RK3399_PULL_GRF_OFFSET 0xe040 1451b6c23275SDavid Wu #define RK3399_PULL_PMU_OFFSET 0x40 1452b6c23275SDavid Wu #define RK3399_DRV_3BITS_PER_PIN 3 1453b6c23275SDavid Wu 1454b6c23275SDavid Wu static void rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1455b6c23275SDavid Wu int pin_num, struct regmap **regmap, 1456b6c23275SDavid Wu int *reg, u8 *bit) 1457b6c23275SDavid Wu { 1458b6c23275SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 1459b6c23275SDavid Wu 1460b6c23275SDavid Wu /* The bank0:16 and bank1:32 pins are located in PMU */ 1461b6c23275SDavid Wu if ((bank->bank_num == 0) || (bank->bank_num == 1)) { 1462b6c23275SDavid Wu *regmap = info->regmap_pmu; 1463b6c23275SDavid Wu *reg = RK3399_PULL_PMU_OFFSET; 1464b6c23275SDavid Wu 1465b6c23275SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1466b6c23275SDavid Wu 1467b6c23275SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1468b6c23275SDavid Wu *bit = pin_num % RK3188_PULL_PINS_PER_REG; 1469b6c23275SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 1470b6c23275SDavid Wu } else { 1471b6c23275SDavid Wu *regmap = info->regmap_base; 1472b6c23275SDavid Wu *reg = RK3399_PULL_GRF_OFFSET; 1473b6c23275SDavid Wu 1474b6c23275SDavid Wu /* correct the offset, as we're starting with the 3rd bank */ 1475b6c23275SDavid Wu *reg -= 0x20; 1476b6c23275SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1477b6c23275SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1478b6c23275SDavid Wu 1479b6c23275SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1480b6c23275SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 1481b6c23275SDavid Wu } 1482b6c23275SDavid Wu } 1483b6c23275SDavid Wu 1484b6c23275SDavid Wu static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1485b6c23275SDavid Wu int pin_num, struct regmap **regmap, 1486b6c23275SDavid Wu int *reg, u8 *bit) 1487b6c23275SDavid Wu { 1488b6c23275SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 1489b6c23275SDavid Wu int drv_num = (pin_num / 8); 1490b6c23275SDavid Wu 1491b6c23275SDavid Wu /* The bank0:16 and bank1:32 pins are located in PMU */ 1492b6c23275SDavid Wu if ((bank->bank_num == 0) || (bank->bank_num == 1)) 1493b6c23275SDavid Wu *regmap = info->regmap_pmu; 1494b6c23275SDavid Wu else 1495b6c23275SDavid Wu *regmap = info->regmap_base; 1496b6c23275SDavid Wu 1497b6c23275SDavid Wu *reg = bank->drv[drv_num].offset; 1498b6c23275SDavid Wu if ((bank->drv[drv_num].drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || 1499b6c23275SDavid Wu (bank->drv[drv_num].drv_type == DRV_TYPE_IO_3V3_ONLY)) 1500b6c23275SDavid Wu *bit = (pin_num % 8) * 3; 1501b6c23275SDavid Wu else 1502b6c23275SDavid Wu *bit = (pin_num % 8) * 2; 1503b6c23275SDavid Wu } 1504b6c23275SDavid Wu 1505c0dadc0eSJianqun Xu #define RK3568_PULL_PMU_OFFSET 0x20 1506c0dadc0eSJianqun Xu #define RK3568_PULL_GRF_OFFSET 0x80 1507c0dadc0eSJianqun Xu #define RK3568_PULL_BITS_PER_PIN 2 1508c0dadc0eSJianqun Xu #define RK3568_PULL_PINS_PER_REG 8 1509c0dadc0eSJianqun Xu #define RK3568_PULL_BANK_STRIDE 0x10 1510c0dadc0eSJianqun Xu 1511c0dadc0eSJianqun Xu static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1512c0dadc0eSJianqun Xu int pin_num, struct regmap **regmap, 1513c0dadc0eSJianqun Xu int *reg, u8 *bit) 1514c0dadc0eSJianqun Xu { 1515c0dadc0eSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 1516c0dadc0eSJianqun Xu 1517c0dadc0eSJianqun Xu if (bank->bank_num == 0) { 1518c0dadc0eSJianqun Xu *regmap = info->regmap_pmu; 1519c0dadc0eSJianqun Xu *reg = RK3568_PULL_PMU_OFFSET; 1520c0dadc0eSJianqun Xu *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; 1521c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); 1522c0dadc0eSJianqun Xu 1523c0dadc0eSJianqun Xu *bit = pin_num % RK3568_PULL_PINS_PER_REG; 1524c0dadc0eSJianqun Xu *bit *= RK3568_PULL_BITS_PER_PIN; 1525c0dadc0eSJianqun Xu } else { 1526c0dadc0eSJianqun Xu *regmap = info->regmap_base; 1527c0dadc0eSJianqun Xu *reg = RK3568_PULL_GRF_OFFSET; 1528c0dadc0eSJianqun Xu *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; 1529c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); 1530c0dadc0eSJianqun Xu 1531c0dadc0eSJianqun Xu *bit = (pin_num % RK3568_PULL_PINS_PER_REG); 1532c0dadc0eSJianqun Xu *bit *= RK3568_PULL_BITS_PER_PIN; 1533c0dadc0eSJianqun Xu } 1534c0dadc0eSJianqun Xu } 1535c0dadc0eSJianqun Xu 1536c0dadc0eSJianqun Xu #define RK3568_DRV_PMU_OFFSET 0x70 1537c0dadc0eSJianqun Xu #define RK3568_DRV_GRF_OFFSET 0x200 1538c0dadc0eSJianqun Xu #define RK3568_DRV_BITS_PER_PIN 8 1539c0dadc0eSJianqun Xu #define RK3568_DRV_PINS_PER_REG 2 1540c0dadc0eSJianqun Xu #define RK3568_DRV_BANK_STRIDE 0x40 1541c0dadc0eSJianqun Xu 1542c0dadc0eSJianqun Xu static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1543c0dadc0eSJianqun Xu int pin_num, struct regmap **regmap, 1544c0dadc0eSJianqun Xu int *reg, u8 *bit) 1545c0dadc0eSJianqun Xu { 1546c0dadc0eSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 1547c0dadc0eSJianqun Xu 1548c0dadc0eSJianqun Xu /* The first 32 pins of the first bank are located in PMU */ 1549c0dadc0eSJianqun Xu if (bank->bank_num == 0) { 1550c0dadc0eSJianqun Xu *regmap = info->regmap_pmu; 1551c0dadc0eSJianqun Xu *reg = RK3568_DRV_PMU_OFFSET; 1552c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); 1553c0dadc0eSJianqun Xu 1554c0dadc0eSJianqun Xu *bit = pin_num % RK3568_DRV_PINS_PER_REG; 1555c0dadc0eSJianqun Xu *bit *= RK3568_DRV_BITS_PER_PIN; 1556c0dadc0eSJianqun Xu } else { 1557c0dadc0eSJianqun Xu *regmap = info->regmap_base; 1558c0dadc0eSJianqun Xu *reg = RK3568_DRV_GRF_OFFSET; 1559c0dadc0eSJianqun Xu *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; 1560c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); 1561c0dadc0eSJianqun Xu 1562c0dadc0eSJianqun Xu *bit = (pin_num % RK3568_DRV_PINS_PER_REG); 1563c0dadc0eSJianqun Xu *bit *= RK3568_DRV_BITS_PER_PIN; 1564c0dadc0eSJianqun Xu } 1565c0dadc0eSJianqun Xu } 1566c0dadc0eSJianqun Xu 1567b6c23275SDavid Wu static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { 1568b6c23275SDavid Wu { 2, 4, 8, 12, -1, -1, -1, -1 }, 1569b6c23275SDavid Wu { 3, 6, 9, 12, -1, -1, -1, -1 }, 1570b6c23275SDavid Wu { 5, 10, 15, 20, -1, -1, -1, -1 }, 1571b6c23275SDavid Wu { 4, 6, 8, 10, 12, 14, 16, 18 }, 1572b6c23275SDavid Wu { 4, 7, 10, 13, 16, 19, 22, 26 } 1573b6c23275SDavid Wu }; 1574ef17f69fSHeiko Stübner 1575ef17f69fSHeiko Stübner static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank, 1576ef17f69fSHeiko Stübner int pin_num) 1577b547c800SHeiko Stübner { 1578ef17f69fSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1579ef17f69fSHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1580e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 1581b547c800SHeiko Stübner struct regmap *regmap; 1582b547c800SHeiko Stübner int reg, ret; 1583b6c23275SDavid Wu u32 data, temp, rmask_bits; 1584b547c800SHeiko Stübner u8 bit; 1585b6c23275SDavid Wu int drv_type = bank->drv[pin_num / 8].drv_type; 1586b547c800SHeiko Stübner 1587ef17f69fSHeiko Stübner ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); 1588b547c800SHeiko Stübner 1589b6c23275SDavid Wu switch (drv_type) { 1590b6c23275SDavid Wu case DRV_TYPE_IO_1V8_3V0_AUTO: 1591b6c23275SDavid Wu case DRV_TYPE_IO_3V3_ONLY: 1592b6c23275SDavid Wu rmask_bits = RK3399_DRV_3BITS_PER_PIN; 1593b6c23275SDavid Wu switch (bit) { 1594b6c23275SDavid Wu case 0 ... 12: 1595b6c23275SDavid Wu /* regular case, nothing to do */ 1596b6c23275SDavid Wu break; 1597b6c23275SDavid Wu case 15: 1598b6c23275SDavid Wu /* 1599b6c23275SDavid Wu * drive-strength offset is special, as it is 1600b6c23275SDavid Wu * spread over 2 registers 1601b6c23275SDavid Wu */ 1602b6c23275SDavid Wu ret = regmap_read(regmap, reg, &data); 1603b6c23275SDavid Wu if (ret) 1604b6c23275SDavid Wu return ret; 1605b6c23275SDavid Wu 1606b6c23275SDavid Wu ret = regmap_read(regmap, reg + 0x4, &temp); 1607b6c23275SDavid Wu if (ret) 1608b6c23275SDavid Wu return ret; 1609b6c23275SDavid Wu 1610b6c23275SDavid Wu /* 1611b6c23275SDavid Wu * the bit data[15] contains bit 0 of the value 1612b6c23275SDavid Wu * while temp[1:0] contains bits 2 and 1 1613b6c23275SDavid Wu */ 1614b6c23275SDavid Wu data >>= 15; 1615b6c23275SDavid Wu temp &= 0x3; 1616b6c23275SDavid Wu temp <<= 1; 1617b6c23275SDavid Wu data |= temp; 1618b6c23275SDavid Wu 1619b6c23275SDavid Wu return rockchip_perpin_drv_list[drv_type][data]; 1620b6c23275SDavid Wu case 18 ... 21: 1621b6c23275SDavid Wu /* setting fully enclosed in the second register */ 1622b6c23275SDavid Wu reg += 4; 1623b6c23275SDavid Wu bit -= 16; 1624b6c23275SDavid Wu break; 1625b6c23275SDavid Wu default: 1626e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n", 1627b6c23275SDavid Wu bit, drv_type); 1628b6c23275SDavid Wu return -EINVAL; 1629b6c23275SDavid Wu } 1630b6c23275SDavid Wu 1631b6c23275SDavid Wu break; 1632b6c23275SDavid Wu case DRV_TYPE_IO_DEFAULT: 1633b6c23275SDavid Wu case DRV_TYPE_IO_1V8_OR_3V0: 1634b6c23275SDavid Wu case DRV_TYPE_IO_1V8_ONLY: 1635b6c23275SDavid Wu rmask_bits = RK3288_DRV_BITS_PER_PIN; 1636b6c23275SDavid Wu break; 1637b6c23275SDavid Wu default: 1638e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type); 1639b6c23275SDavid Wu return -EINVAL; 1640b6c23275SDavid Wu } 1641b6c23275SDavid Wu 1642b547c800SHeiko Stübner ret = regmap_read(regmap, reg, &data); 1643b547c800SHeiko Stübner if (ret) 1644b547c800SHeiko Stübner return ret; 1645b547c800SHeiko Stübner 1646b547c800SHeiko Stübner data >>= bit; 1647b6c23275SDavid Wu data &= (1 << rmask_bits) - 1; 1648b547c800SHeiko Stübner 1649b6c23275SDavid Wu return rockchip_perpin_drv_list[drv_type][data]; 1650b547c800SHeiko Stübner } 1651b547c800SHeiko Stübner 1652ef17f69fSHeiko Stübner static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, 1653ef17f69fSHeiko Stübner int pin_num, int strength) 1654b547c800SHeiko Stübner { 1655b547c800SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1656ef17f69fSHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1657e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 1658b547c800SHeiko Stübner struct regmap *regmap; 1659b547c800SHeiko Stübner int reg, ret, i; 1660b6c23275SDavid Wu u32 data, rmask, rmask_bits, temp; 1661b547c800SHeiko Stübner u8 bit; 1662b6c23275SDavid Wu int drv_type = bank->drv[pin_num / 8].drv_type; 1663b6c23275SDavid Wu 1664e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting drive of GPIO%d-%d to %d\n", 1665b6c23275SDavid Wu bank->bank_num, pin_num, strength); 1666b547c800SHeiko Stübner 1667ef17f69fSHeiko Stübner ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); 1668c0dadc0eSJianqun Xu if (ctrl->type == RK3568) { 1669c0dadc0eSJianqun Xu rmask_bits = RK3568_DRV_BITS_PER_PIN; 1670c0dadc0eSJianqun Xu ret = (1 << (strength + 1)) - 1; 1671c0dadc0eSJianqun Xu goto config; 1672c0dadc0eSJianqun Xu } 1673b547c800SHeiko Stübner 1674b547c800SHeiko Stübner ret = -EINVAL; 1675b6c23275SDavid Wu for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) { 1676b6c23275SDavid Wu if (rockchip_perpin_drv_list[drv_type][i] == strength) { 1677b547c800SHeiko Stübner ret = i; 1678b547c800SHeiko Stübner break; 1679b6c23275SDavid Wu } else if (rockchip_perpin_drv_list[drv_type][i] < 0) { 1680b6c23275SDavid Wu ret = rockchip_perpin_drv_list[drv_type][i]; 1681b6c23275SDavid Wu break; 1682b547c800SHeiko Stübner } 1683b547c800SHeiko Stübner } 1684b547c800SHeiko Stübner 1685b547c800SHeiko Stübner if (ret < 0) { 1686e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported driver strength %d\n", strength); 1687b547c800SHeiko Stübner return ret; 1688b547c800SHeiko Stübner } 1689b547c800SHeiko Stübner 1690b6c23275SDavid Wu switch (drv_type) { 1691b6c23275SDavid Wu case DRV_TYPE_IO_1V8_3V0_AUTO: 1692b6c23275SDavid Wu case DRV_TYPE_IO_3V3_ONLY: 1693b6c23275SDavid Wu rmask_bits = RK3399_DRV_3BITS_PER_PIN; 1694b6c23275SDavid Wu switch (bit) { 1695b6c23275SDavid Wu case 0 ... 12: 1696b6c23275SDavid Wu /* regular case, nothing to do */ 1697b6c23275SDavid Wu break; 1698b6c23275SDavid Wu case 15: 1699b6c23275SDavid Wu /* 1700b6c23275SDavid Wu * drive-strength offset is special, as it is spread 1701b6c23275SDavid Wu * over 2 registers, the bit data[15] contains bit 0 1702b6c23275SDavid Wu * of the value while temp[1:0] contains bits 2 and 1 1703b6c23275SDavid Wu */ 1704b6c23275SDavid Wu data = (ret & 0x1) << 15; 1705b6c23275SDavid Wu temp = (ret >> 0x1) & 0x3; 1706b6c23275SDavid Wu 1707b6c23275SDavid Wu rmask = BIT(15) | BIT(31); 1708b6c23275SDavid Wu data |= BIT(31); 1709b6c23275SDavid Wu ret = regmap_update_bits(regmap, reg, rmask, data); 1710f07bedc3SJohn Keeping if (ret) 1711b6c23275SDavid Wu return ret; 1712b6c23275SDavid Wu 1713b6c23275SDavid Wu rmask = 0x3 | (0x3 << 16); 1714b6c23275SDavid Wu temp |= (0x3 << 16); 1715b6c23275SDavid Wu reg += 0x4; 1716b6c23275SDavid Wu ret = regmap_update_bits(regmap, reg, rmask, temp); 1717b6c23275SDavid Wu 1718b6c23275SDavid Wu return ret; 1719b6c23275SDavid Wu case 18 ... 21: 1720b6c23275SDavid Wu /* setting fully enclosed in the second register */ 1721b6c23275SDavid Wu reg += 4; 1722b6c23275SDavid Wu bit -= 16; 1723b6c23275SDavid Wu break; 1724b6c23275SDavid Wu default: 1725e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n", 1726b6c23275SDavid Wu bit, drv_type); 1727b6c23275SDavid Wu return -EINVAL; 1728b6c23275SDavid Wu } 1729b6c23275SDavid Wu break; 1730b6c23275SDavid Wu case DRV_TYPE_IO_DEFAULT: 1731b6c23275SDavid Wu case DRV_TYPE_IO_1V8_OR_3V0: 1732b6c23275SDavid Wu case DRV_TYPE_IO_1V8_ONLY: 1733b6c23275SDavid Wu rmask_bits = RK3288_DRV_BITS_PER_PIN; 1734b6c23275SDavid Wu break; 1735b6c23275SDavid Wu default: 1736e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type); 1737b6c23275SDavid Wu return -EINVAL; 1738b6c23275SDavid Wu } 1739b6c23275SDavid Wu 1740c0dadc0eSJianqun Xu config: 1741b547c800SHeiko Stübner /* enable the write to the equivalent lower bits */ 1742b6c23275SDavid Wu data = ((1 << rmask_bits) - 1) << (bit + 16); 174399e872d9SSonny Rao rmask = data | (data >> 16); 1744b547c800SHeiko Stübner data |= (ret << bit); 1745b547c800SHeiko Stübner 174699e872d9SSonny Rao ret = regmap_update_bits(regmap, reg, rmask, data); 1747b547c800SHeiko Stübner 1748b547c800SHeiko Stübner return ret; 1749b547c800SHeiko Stübner } 1750b547c800SHeiko Stübner 17513ba6767aSDavid Wu static int rockchip_pull_list[PULL_TYPE_MAX][4] = { 17523ba6767aSDavid Wu { 17533ba6767aSDavid Wu PIN_CONFIG_BIAS_DISABLE, 17543ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_UP, 17553ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_DOWN, 17563ba6767aSDavid Wu PIN_CONFIG_BIAS_BUS_HOLD 17573ba6767aSDavid Wu }, 17583ba6767aSDavid Wu { 17593ba6767aSDavid Wu PIN_CONFIG_BIAS_DISABLE, 17603ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_DOWN, 17613ba6767aSDavid Wu PIN_CONFIG_BIAS_DISABLE, 17623ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_UP 17633ba6767aSDavid Wu }, 17643ba6767aSDavid Wu }; 17653ba6767aSDavid Wu 1766d3e51161SHeiko Stübner static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) 1767d3e51161SHeiko Stübner { 1768d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1769d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1770e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 1771751a99abSHeiko Stübner struct regmap *regmap; 17723ba6767aSDavid Wu int reg, ret, pull_type; 1773d3e51161SHeiko Stübner u8 bit; 17746ca5274dSHeiko Stübner u32 data; 1775d3e51161SHeiko Stübner 1776d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 1777a282926dSHeiko Stübner if (ctrl->type == RK3066B) 1778d3e51161SHeiko Stübner return PIN_CONFIG_BIAS_DISABLE; 1779d3e51161SHeiko Stübner 1780751a99abSHeiko Stübner ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); 1781751a99abSHeiko Stübner 1782751a99abSHeiko Stübner ret = regmap_read(regmap, reg, &data); 1783751a99abSHeiko Stübner if (ret) 1784751a99abSHeiko Stübner return ret; 17856ca5274dSHeiko Stübner 1786a282926dSHeiko Stübner switch (ctrl->type) { 1787a282926dSHeiko Stübner case RK2928: 1788d23c66dfSDavid Wu case RK3128: 1789751a99abSHeiko Stübner return !(data & BIT(bit)) 1790d3e51161SHeiko Stübner ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT 1791d3e51161SHeiko Stübner : PIN_CONFIG_BIAS_DISABLE; 179287065ca9SDavid Wu case PX30: 1793b9c6dcabSAndy Yan case RV1108: 1794a282926dSHeiko Stübner case RK3188: 179566d750e1SHeiko Stübner case RK3288: 17967825aeb7SJianqun Xu case RK3308: 1797daecdc66SHeiko Stübner case RK3368: 1798b6c23275SDavid Wu case RK3399: 17993ba6767aSDavid Wu pull_type = bank->pull_type[pin_num / 8]; 1800751a99abSHeiko Stübner data >>= bit; 18016ca5274dSHeiko Stübner data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; 18026ca5274dSHeiko Stübner 18033ba6767aSDavid Wu return rockchip_pull_list[pull_type][data]; 1804a282926dSHeiko Stübner default: 1805e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl type\n"); 1806a282926dSHeiko Stübner return -EINVAL; 1807a282926dSHeiko Stübner }; 1808d3e51161SHeiko Stübner } 1809d3e51161SHeiko Stübner 1810d3e51161SHeiko Stübner static int rockchip_set_pull(struct rockchip_pin_bank *bank, 1811d3e51161SHeiko Stübner int pin_num, int pull) 1812d3e51161SHeiko Stübner { 1813d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1814d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1815e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 1816751a99abSHeiko Stübner struct regmap *regmap; 18173ba6767aSDavid Wu int reg, ret, i, pull_type; 1818d3e51161SHeiko Stübner u8 bit; 181999e872d9SSonny Rao u32 data, rmask; 1820d3e51161SHeiko Stübner 1821e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting pull of GPIO%d-%d to %d\n", bank->bank_num, pin_num, pull); 1822d3e51161SHeiko Stübner 1823d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 1824a282926dSHeiko Stübner if (ctrl->type == RK3066B) 1825d3e51161SHeiko Stübner return pull ? -EINVAL : 0; 1826d3e51161SHeiko Stübner 1827751a99abSHeiko Stübner ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); 1828d3e51161SHeiko Stübner 18296ca5274dSHeiko Stübner switch (ctrl->type) { 18306ca5274dSHeiko Stübner case RK2928: 1831d23c66dfSDavid Wu case RK3128: 1832d3e51161SHeiko Stübner data = BIT(bit + 16); 1833d3e51161SHeiko Stübner if (pull == PIN_CONFIG_BIAS_DISABLE) 1834d3e51161SHeiko Stübner data |= BIT(bit); 1835751a99abSHeiko Stübner ret = regmap_write(regmap, reg, data); 1836a282926dSHeiko Stübner break; 183787065ca9SDavid Wu case PX30: 1838b9c6dcabSAndy Yan case RV1108: 1839a282926dSHeiko Stübner case RK3188: 184066d750e1SHeiko Stübner case RK3288: 18417825aeb7SJianqun Xu case RK3308: 1842daecdc66SHeiko Stübner case RK3368: 1843b6c23275SDavid Wu case RK3399: 1844c0dadc0eSJianqun Xu case RK3568: 18453ba6767aSDavid Wu pull_type = bank->pull_type[pin_num / 8]; 18463ba6767aSDavid Wu ret = -EINVAL; 18473ba6767aSDavid Wu for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); 18483ba6767aSDavid Wu i++) { 18493ba6767aSDavid Wu if (rockchip_pull_list[pull_type][i] == pull) { 18503ba6767aSDavid Wu ret = i; 18513ba6767aSDavid Wu break; 18523ba6767aSDavid Wu } 18533ba6767aSDavid Wu } 1854c0dadc0eSJianqun Xu /* 1855c0dadc0eSJianqun Xu * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6, 1856c0dadc0eSJianqun Xu * where that pull up value becomes 3. 1857c0dadc0eSJianqun Xu */ 1858c0dadc0eSJianqun Xu if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { 1859c0dadc0eSJianqun Xu if (ret == 1) 1860c0dadc0eSJianqun Xu ret = 3; 1861c0dadc0eSJianqun Xu } 18623ba6767aSDavid Wu 18633ba6767aSDavid Wu if (ret < 0) { 1864e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pull setting %d\n", pull); 18653ba6767aSDavid Wu return ret; 18663ba6767aSDavid Wu } 18673ba6767aSDavid Wu 18686ca5274dSHeiko Stübner /* enable the write to the equivalent lower bits */ 18696ca5274dSHeiko Stübner data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); 187099e872d9SSonny Rao rmask = data | (data >> 16); 18713ba6767aSDavid Wu data |= (ret << bit); 18726ca5274dSHeiko Stübner 187399e872d9SSonny Rao ret = regmap_update_bits(regmap, reg, rmask, data); 18746ca5274dSHeiko Stübner break; 1875a282926dSHeiko Stübner default: 1876e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl type\n"); 1877a282926dSHeiko Stübner return -EINVAL; 1878d3e51161SHeiko Stübner } 1879d3e51161SHeiko Stübner 1880751a99abSHeiko Stübner return ret; 1881d3e51161SHeiko Stübner } 1882d3e51161SHeiko Stübner 1883728d3f5aSdavid.wu #define RK3328_SCHMITT_BITS_PER_PIN 1 1884728d3f5aSdavid.wu #define RK3328_SCHMITT_PINS_PER_REG 16 1885728d3f5aSdavid.wu #define RK3328_SCHMITT_BANK_STRIDE 8 1886728d3f5aSdavid.wu #define RK3328_SCHMITT_GRF_OFFSET 0x380 1887728d3f5aSdavid.wu 1888728d3f5aSdavid.wu static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 1889728d3f5aSdavid.wu int pin_num, 1890728d3f5aSdavid.wu struct regmap **regmap, 1891728d3f5aSdavid.wu int *reg, u8 *bit) 1892728d3f5aSdavid.wu { 1893728d3f5aSdavid.wu struct rockchip_pinctrl *info = bank->drvdata; 1894728d3f5aSdavid.wu 1895728d3f5aSdavid.wu *regmap = info->regmap_base; 1896728d3f5aSdavid.wu *reg = RK3328_SCHMITT_GRF_OFFSET; 1897728d3f5aSdavid.wu 1898728d3f5aSdavid.wu *reg += bank->bank_num * RK3328_SCHMITT_BANK_STRIDE; 1899728d3f5aSdavid.wu *reg += ((pin_num / RK3328_SCHMITT_PINS_PER_REG) * 4); 1900728d3f5aSdavid.wu *bit = pin_num % RK3328_SCHMITT_PINS_PER_REG; 1901728d3f5aSdavid.wu 1902728d3f5aSdavid.wu return 0; 1903728d3f5aSdavid.wu } 1904728d3f5aSdavid.wu 1905c0dadc0eSJianqun Xu #define RK3568_SCHMITT_BITS_PER_PIN 2 1906c0dadc0eSJianqun Xu #define RK3568_SCHMITT_PINS_PER_REG 8 1907c0dadc0eSJianqun Xu #define RK3568_SCHMITT_BANK_STRIDE 0x10 1908c0dadc0eSJianqun Xu #define RK3568_SCHMITT_GRF_OFFSET 0xc0 1909c0dadc0eSJianqun Xu #define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 1910c0dadc0eSJianqun Xu 1911c0dadc0eSJianqun Xu static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 1912c0dadc0eSJianqun Xu int pin_num, 1913c0dadc0eSJianqun Xu struct regmap **regmap, 1914c0dadc0eSJianqun Xu int *reg, u8 *bit) 1915c0dadc0eSJianqun Xu { 1916c0dadc0eSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 1917c0dadc0eSJianqun Xu 1918c0dadc0eSJianqun Xu if (bank->bank_num == 0) { 1919c0dadc0eSJianqun Xu *regmap = info->regmap_pmu; 1920c0dadc0eSJianqun Xu *reg = RK3568_SCHMITT_PMUGRF_OFFSET; 1921c0dadc0eSJianqun Xu } else { 1922c0dadc0eSJianqun Xu *regmap = info->regmap_base; 1923c0dadc0eSJianqun Xu *reg = RK3568_SCHMITT_GRF_OFFSET; 1924c0dadc0eSJianqun Xu *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; 1925c0dadc0eSJianqun Xu } 1926c0dadc0eSJianqun Xu 1927c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); 1928c0dadc0eSJianqun Xu *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; 1929c0dadc0eSJianqun Xu *bit *= RK3568_SCHMITT_BITS_PER_PIN; 1930c0dadc0eSJianqun Xu 1931c0dadc0eSJianqun Xu return 0; 1932c0dadc0eSJianqun Xu } 1933c0dadc0eSJianqun Xu 1934e3b357d7Sdavid.wu static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num) 1935e3b357d7Sdavid.wu { 1936e3b357d7Sdavid.wu struct rockchip_pinctrl *info = bank->drvdata; 1937e3b357d7Sdavid.wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 1938e3b357d7Sdavid.wu struct regmap *regmap; 1939e3b357d7Sdavid.wu int reg, ret; 1940e3b357d7Sdavid.wu u8 bit; 1941e3b357d7Sdavid.wu u32 data; 1942e3b357d7Sdavid.wu 1943e3b357d7Sdavid.wu ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit); 1944e3b357d7Sdavid.wu if (ret) 1945e3b357d7Sdavid.wu return ret; 1946e3b357d7Sdavid.wu 1947e3b357d7Sdavid.wu ret = regmap_read(regmap, reg, &data); 1948e3b357d7Sdavid.wu if (ret) 1949e3b357d7Sdavid.wu return ret; 1950e3b357d7Sdavid.wu 1951e3b357d7Sdavid.wu data >>= bit; 1952c0dadc0eSJianqun Xu switch (ctrl->type) { 1953c0dadc0eSJianqun Xu case RK3568: 1954c0dadc0eSJianqun Xu return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1); 1955c0dadc0eSJianqun Xu default: 1956c0dadc0eSJianqun Xu break; 1957c0dadc0eSJianqun Xu } 1958c0dadc0eSJianqun Xu 1959e3b357d7Sdavid.wu return data & 0x1; 1960e3b357d7Sdavid.wu } 1961e3b357d7Sdavid.wu 1962e3b357d7Sdavid.wu static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, 1963e3b357d7Sdavid.wu int pin_num, int enable) 1964e3b357d7Sdavid.wu { 1965e3b357d7Sdavid.wu struct rockchip_pinctrl *info = bank->drvdata; 1966e3b357d7Sdavid.wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 1967e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 1968e3b357d7Sdavid.wu struct regmap *regmap; 1969e3b357d7Sdavid.wu int reg, ret; 1970e3b357d7Sdavid.wu u8 bit; 1971e3b357d7Sdavid.wu u32 data, rmask; 1972e3b357d7Sdavid.wu 1973e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting input schmitt of GPIO%d-%d to %d\n", 1974e3b357d7Sdavid.wu bank->bank_num, pin_num, enable); 1975e3b357d7Sdavid.wu 1976e3b357d7Sdavid.wu ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit); 1977e3b357d7Sdavid.wu if (ret) 1978e3b357d7Sdavid.wu return ret; 1979e3b357d7Sdavid.wu 1980e3b357d7Sdavid.wu /* enable the write to the equivalent lower bits */ 1981c0dadc0eSJianqun Xu switch (ctrl->type) { 1982c0dadc0eSJianqun Xu case RK3568: 1983c0dadc0eSJianqun Xu data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); 1984c0dadc0eSJianqun Xu rmask = data | (data >> 16); 1985c0dadc0eSJianqun Xu data |= ((enable ? 0x2 : 0x1) << bit); 1986c0dadc0eSJianqun Xu break; 1987c0dadc0eSJianqun Xu default: 1988e3b357d7Sdavid.wu data = BIT(bit + 16) | (enable << bit); 1989e3b357d7Sdavid.wu rmask = BIT(bit + 16) | BIT(bit); 1990c0dadc0eSJianqun Xu break; 1991c0dadc0eSJianqun Xu } 1992e3b357d7Sdavid.wu 1993f07bedc3SJohn Keeping return regmap_update_bits(regmap, reg, rmask, data); 1994e3b357d7Sdavid.wu } 1995e3b357d7Sdavid.wu 1996d3e51161SHeiko Stübner /* 1997d3e51161SHeiko Stübner * Pinmux_ops handling 1998d3e51161SHeiko Stübner */ 1999d3e51161SHeiko Stübner 2000d3e51161SHeiko Stübner static int rockchip_pmx_get_funcs_count(struct pinctrl_dev *pctldev) 2001d3e51161SHeiko Stübner { 2002d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2003d3e51161SHeiko Stübner 2004d3e51161SHeiko Stübner return info->nfunctions; 2005d3e51161SHeiko Stübner } 2006d3e51161SHeiko Stübner 2007d3e51161SHeiko Stübner static const char *rockchip_pmx_get_func_name(struct pinctrl_dev *pctldev, 2008d3e51161SHeiko Stübner unsigned selector) 2009d3e51161SHeiko Stübner { 2010d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2011d3e51161SHeiko Stübner 2012d3e51161SHeiko Stübner return info->functions[selector].name; 2013d3e51161SHeiko Stübner } 2014d3e51161SHeiko Stübner 2015d3e51161SHeiko Stübner static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev, 2016d3e51161SHeiko Stübner unsigned selector, const char * const **groups, 2017d3e51161SHeiko Stübner unsigned * const num_groups) 2018d3e51161SHeiko Stübner { 2019d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2020d3e51161SHeiko Stübner 2021d3e51161SHeiko Stübner *groups = info->functions[selector].groups; 2022d3e51161SHeiko Stübner *num_groups = info->functions[selector].ngroups; 2023d3e51161SHeiko Stübner 2024d3e51161SHeiko Stübner return 0; 2025d3e51161SHeiko Stübner } 2026d3e51161SHeiko Stübner 202703e9f0caSLinus Walleij static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, 2028d3e51161SHeiko Stübner unsigned group) 2029d3e51161SHeiko Stübner { 2030d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2031d3e51161SHeiko Stübner const unsigned int *pins = info->groups[group].pins; 2032d3e51161SHeiko Stübner const struct rockchip_pin_config *data = info->groups[group].data; 2033e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2034d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 203514797189SHeiko Stübner int cnt, ret = 0; 2036d3e51161SHeiko Stübner 2037e4dd7fd5SAndy Shevchenko dev_dbg(dev, "enable function %s group %s\n", 2038d3e51161SHeiko Stübner info->functions[selector].name, info->groups[group].name); 2039d3e51161SHeiko Stübner 2040d3e51161SHeiko Stübner /* 204185dc397aSMarkus Elfring * for each pin in the pin group selected, program the corresponding 2042d3e51161SHeiko Stübner * pin function number in the config register. 2043d3e51161SHeiko Stübner */ 2044d3e51161SHeiko Stübner for (cnt = 0; cnt < info->groups[group].npins; cnt++) { 2045d3e51161SHeiko Stübner bank = pin_to_bank(info, pins[cnt]); 204614797189SHeiko Stübner ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 2047d3e51161SHeiko Stübner data[cnt].func); 204814797189SHeiko Stübner if (ret) 204914797189SHeiko Stübner break; 205014797189SHeiko Stübner } 205114797189SHeiko Stübner 205214797189SHeiko Stübner if (ret) { 205314797189SHeiko Stübner /* revert the already done pin settings */ 205414797189SHeiko Stübner for (cnt--; cnt >= 0; cnt--) 205514797189SHeiko Stübner rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); 205614797189SHeiko Stübner 205714797189SHeiko Stübner return ret; 2058d3e51161SHeiko Stübner } 2059d3e51161SHeiko Stübner 2060d3e51161SHeiko Stübner return 0; 2061d3e51161SHeiko Stübner } 2062d3e51161SHeiko Stübner 2063d3e51161SHeiko Stübner static const struct pinmux_ops rockchip_pmx_ops = { 2064d3e51161SHeiko Stübner .get_functions_count = rockchip_pmx_get_funcs_count, 2065d3e51161SHeiko Stübner .get_function_name = rockchip_pmx_get_func_name, 2066d3e51161SHeiko Stübner .get_function_groups = rockchip_pmx_get_groups, 206703e9f0caSLinus Walleij .set_mux = rockchip_pmx_set, 2068d3e51161SHeiko Stübner }; 2069d3e51161SHeiko Stübner 2070d3e51161SHeiko Stübner /* 2071d3e51161SHeiko Stübner * Pinconf_ops handling 2072d3e51161SHeiko Stübner */ 2073d3e51161SHeiko Stübner 207444b6d930SHeiko Stübner static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, 207544b6d930SHeiko Stübner enum pin_config_param pull) 207644b6d930SHeiko Stübner { 2077a282926dSHeiko Stübner switch (ctrl->type) { 2078a282926dSHeiko Stübner case RK2928: 2079d23c66dfSDavid Wu case RK3128: 2080a282926dSHeiko Stübner return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT || 2081a282926dSHeiko Stübner pull == PIN_CONFIG_BIAS_DISABLE); 2082a282926dSHeiko Stübner case RK3066B: 208344b6d930SHeiko Stübner return pull ? false : true; 208487065ca9SDavid Wu case PX30: 2085b9c6dcabSAndy Yan case RV1108: 2086a282926dSHeiko Stübner case RK3188: 208766d750e1SHeiko Stübner case RK3288: 20887825aeb7SJianqun Xu case RK3308: 2089daecdc66SHeiko Stübner case RK3368: 2090b6c23275SDavid Wu case RK3399: 2091c0dadc0eSJianqun Xu case RK3568: 2092a282926dSHeiko Stübner return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); 209344b6d930SHeiko Stübner } 209444b6d930SHeiko Stübner 2095a282926dSHeiko Stübner return false; 209644b6d930SHeiko Stübner } 209744b6d930SHeiko Stübner 2098e7165b1dSHeiko Stuebner static int rockchip_pinconf_defer_output(struct rockchip_pin_bank *bank, 2099e7165b1dSHeiko Stuebner unsigned int pin, u32 arg) 2100e7165b1dSHeiko Stuebner { 2101e7165b1dSHeiko Stuebner struct rockchip_pin_output_deferred *cfg; 2102e7165b1dSHeiko Stuebner 2103e7165b1dSHeiko Stuebner cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 2104e7165b1dSHeiko Stuebner if (!cfg) 2105e7165b1dSHeiko Stuebner return -ENOMEM; 2106e7165b1dSHeiko Stuebner 2107e7165b1dSHeiko Stuebner cfg->pin = pin; 2108e7165b1dSHeiko Stuebner cfg->arg = arg; 2109e7165b1dSHeiko Stuebner 2110e7165b1dSHeiko Stuebner list_add_tail(&cfg->head, &bank->deferred_output); 2111e7165b1dSHeiko Stuebner 2112e7165b1dSHeiko Stuebner return 0; 2113e7165b1dSHeiko Stuebner } 2114e7165b1dSHeiko Stuebner 2115d3e51161SHeiko Stübner /* set the pin config settings for a specified pin */ 2116d3e51161SHeiko Stübner static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, 211703b054e9SSherman Yin unsigned long *configs, unsigned num_configs) 2118d3e51161SHeiko Stübner { 2119d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2120d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 21219ce9a020SJianqun Xu struct gpio_chip *gpio = &bank->gpio_chip; 212203b054e9SSherman Yin enum pin_config_param param; 212358957d2eSMika Westerberg u32 arg; 212403b054e9SSherman Yin int i; 212503b054e9SSherman Yin int rc; 212603b054e9SSherman Yin 212703b054e9SSherman Yin for (i = 0; i < num_configs; i++) { 212803b054e9SSherman Yin param = pinconf_to_config_param(configs[i]); 212903b054e9SSherman Yin arg = pinconf_to_config_argument(configs[i]); 2130d3e51161SHeiko Stübner 2131d3e51161SHeiko Stübner switch (param) { 2132d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 213303b054e9SSherman Yin rc = rockchip_set_pull(bank, pin - bank->pin_base, 213403b054e9SSherman Yin param); 213503b054e9SSherman Yin if (rc) 213603b054e9SSherman Yin return rc; 213744b6d930SHeiko Stübner break; 2138d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 2139d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 2140d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 21416ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 214244b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 214344b6d930SHeiko Stübner return -ENOTSUPP; 214444b6d930SHeiko Stübner 214544b6d930SHeiko Stübner if (!arg) 214644b6d930SHeiko Stübner return -EINVAL; 214744b6d930SHeiko Stübner 214803b054e9SSherman Yin rc = rockchip_set_pull(bank, pin - bank->pin_base, 214903b054e9SSherman Yin param); 215003b054e9SSherman Yin if (rc) 215103b054e9SSherman Yin return rc; 2152d3e51161SHeiko Stübner break; 2153a076e2edSHeiko Stübner case PIN_CONFIG_OUTPUT: 21549ce9a020SJianqun Xu rc = rockchip_set_mux(bank, pin - bank->pin_base, 21559ce9a020SJianqun Xu RK_FUNC_GPIO); 21569ce9a020SJianqun Xu if (rc != RK_FUNC_GPIO) 21579ce9a020SJianqun Xu return -EINVAL; 21589ce9a020SJianqun Xu 2159e7165b1dSHeiko Stuebner /* 2160e7165b1dSHeiko Stuebner * Check for gpio driver not being probed yet. 2161e7165b1dSHeiko Stuebner * The lock makes sure that either gpio-probe has completed 2162e7165b1dSHeiko Stuebner * or the gpio driver hasn't probed yet. 2163e7165b1dSHeiko Stuebner */ 2164e7165b1dSHeiko Stuebner mutex_lock(&bank->deferred_lock); 2165e7165b1dSHeiko Stuebner if (!gpio || !gpio->direction_output) { 2166e7165b1dSHeiko Stuebner rc = rockchip_pinconf_defer_output(bank, pin - bank->pin_base, arg); 2167e7165b1dSHeiko Stuebner mutex_unlock(&bank->deferred_lock); 2168e7165b1dSHeiko Stuebner if (rc) 2169e7165b1dSHeiko Stuebner return rc; 2170e7165b1dSHeiko Stuebner 2171e7165b1dSHeiko Stuebner break; 2172e7165b1dSHeiko Stuebner } 2173e7165b1dSHeiko Stuebner mutex_unlock(&bank->deferred_lock); 2174e7165b1dSHeiko Stuebner 21759ce9a020SJianqun Xu rc = gpio->direction_output(gpio, pin - bank->pin_base, 21769ce9a020SJianqun Xu arg); 2177a076e2edSHeiko Stübner if (rc) 2178a076e2edSHeiko Stübner return rc; 2179a076e2edSHeiko Stübner break; 2180b547c800SHeiko Stübner case PIN_CONFIG_DRIVE_STRENGTH: 2181b547c800SHeiko Stübner /* rk3288 is the first with per-pin drive-strength */ 2182ef17f69fSHeiko Stübner if (!info->ctrl->drv_calc_reg) 2183b547c800SHeiko Stübner return -ENOTSUPP; 2184b547c800SHeiko Stübner 2185ef17f69fSHeiko Stübner rc = rockchip_set_drive_perpin(bank, 2186ef17f69fSHeiko Stübner pin - bank->pin_base, arg); 2187b547c800SHeiko Stübner if (rc < 0) 2188b547c800SHeiko Stübner return rc; 2189b547c800SHeiko Stübner break; 2190e3b357d7Sdavid.wu case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 2191e3b357d7Sdavid.wu if (!info->ctrl->schmitt_calc_reg) 2192e3b357d7Sdavid.wu return -ENOTSUPP; 2193e3b357d7Sdavid.wu 2194e3b357d7Sdavid.wu rc = rockchip_set_schmitt(bank, 2195e3b357d7Sdavid.wu pin - bank->pin_base, arg); 2196e3b357d7Sdavid.wu if (rc < 0) 2197e3b357d7Sdavid.wu return rc; 2198e3b357d7Sdavid.wu break; 2199d3e51161SHeiko Stübner default: 2200d3e51161SHeiko Stübner return -ENOTSUPP; 2201d3e51161SHeiko Stübner break; 2202d3e51161SHeiko Stübner } 220303b054e9SSherman Yin } /* for each config */ 2204d3e51161SHeiko Stübner 2205d3e51161SHeiko Stübner return 0; 2206d3e51161SHeiko Stübner } 2207d3e51161SHeiko Stübner 2208d3e51161SHeiko Stübner /* get the pin config settings for a specified pin */ 2209d3e51161SHeiko Stübner static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, 2210d3e51161SHeiko Stübner unsigned long *config) 2211d3e51161SHeiko Stübner { 2212d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2213d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 22149ce9a020SJianqun Xu struct gpio_chip *gpio = &bank->gpio_chip; 2215d3e51161SHeiko Stübner enum pin_config_param param = pinconf_to_config_param(*config); 2216dab3eba7SHeiko Stübner u16 arg; 2217a076e2edSHeiko Stübner int rc; 2218d3e51161SHeiko Stübner 2219d3e51161SHeiko Stübner switch (param) { 2220d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 222144b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 2222d3e51161SHeiko Stübner return -EINVAL; 2223d3e51161SHeiko Stübner 2224dab3eba7SHeiko Stübner arg = 0; 2225d3e51161SHeiko Stübner break; 222644b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 222744b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 222844b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 22296ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 223044b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 223144b6d930SHeiko Stübner return -ENOTSUPP; 223244b6d930SHeiko Stübner 223344b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 223444b6d930SHeiko Stübner return -EINVAL; 223544b6d930SHeiko Stübner 2236dab3eba7SHeiko Stübner arg = 1; 223744b6d930SHeiko Stübner break; 2238a076e2edSHeiko Stübner case PIN_CONFIG_OUTPUT: 2239a076e2edSHeiko Stübner rc = rockchip_get_mux(bank, pin - bank->pin_base); 2240a076e2edSHeiko Stübner if (rc != RK_FUNC_GPIO) 2241a076e2edSHeiko Stübner return -EINVAL; 2242a076e2edSHeiko Stübner 2243e7165b1dSHeiko Stuebner if (!gpio || !gpio->get) { 2244e7165b1dSHeiko Stuebner arg = 0; 2245e7165b1dSHeiko Stuebner break; 2246e7165b1dSHeiko Stuebner } 2247e7165b1dSHeiko Stuebner 22489ce9a020SJianqun Xu rc = gpio->get(gpio, pin - bank->pin_base); 2249a076e2edSHeiko Stübner if (rc < 0) 2250a076e2edSHeiko Stübner return rc; 2251a076e2edSHeiko Stübner 2252a076e2edSHeiko Stübner arg = rc ? 1 : 0; 2253a076e2edSHeiko Stübner break; 2254b547c800SHeiko Stübner case PIN_CONFIG_DRIVE_STRENGTH: 2255b547c800SHeiko Stübner /* rk3288 is the first with per-pin drive-strength */ 2256ef17f69fSHeiko Stübner if (!info->ctrl->drv_calc_reg) 2257b547c800SHeiko Stübner return -ENOTSUPP; 2258b547c800SHeiko Stübner 2259ef17f69fSHeiko Stübner rc = rockchip_get_drive_perpin(bank, pin - bank->pin_base); 2260b547c800SHeiko Stübner if (rc < 0) 2261b547c800SHeiko Stübner return rc; 2262b547c800SHeiko Stübner 2263b547c800SHeiko Stübner arg = rc; 2264b547c800SHeiko Stübner break; 2265e3b357d7Sdavid.wu case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 2266e3b357d7Sdavid.wu if (!info->ctrl->schmitt_calc_reg) 2267e3b357d7Sdavid.wu return -ENOTSUPP; 2268e3b357d7Sdavid.wu 2269e3b357d7Sdavid.wu rc = rockchip_get_schmitt(bank, pin - bank->pin_base); 2270e3b357d7Sdavid.wu if (rc < 0) 2271e3b357d7Sdavid.wu return rc; 2272e3b357d7Sdavid.wu 2273e3b357d7Sdavid.wu arg = rc; 2274e3b357d7Sdavid.wu break; 2275d3e51161SHeiko Stübner default: 2276d3e51161SHeiko Stübner return -ENOTSUPP; 2277d3e51161SHeiko Stübner break; 2278d3e51161SHeiko Stübner } 2279d3e51161SHeiko Stübner 2280dab3eba7SHeiko Stübner *config = pinconf_to_config_packed(param, arg); 2281dab3eba7SHeiko Stübner 2282d3e51161SHeiko Stübner return 0; 2283d3e51161SHeiko Stübner } 2284d3e51161SHeiko Stübner 2285d3e51161SHeiko Stübner static const struct pinconf_ops rockchip_pinconf_ops = { 2286d3e51161SHeiko Stübner .pin_config_get = rockchip_pinconf_get, 2287d3e51161SHeiko Stübner .pin_config_set = rockchip_pinconf_set, 2288ed62f2f2SHeiko Stübner .is_generic = true, 2289d3e51161SHeiko Stübner }; 2290d3e51161SHeiko Stübner 229165fca613SHeiko Stübner static const struct of_device_id rockchip_bank_match[] = { 229265fca613SHeiko Stübner { .compatible = "rockchip,gpio-bank" }, 22936ca5274dSHeiko Stübner { .compatible = "rockchip,rk3188-gpio-bank0" }, 229465fca613SHeiko Stübner {}, 229565fca613SHeiko Stübner }; 2296d3e51161SHeiko Stübner 2297d3e51161SHeiko Stübner static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info, 2298d3e51161SHeiko Stübner struct device_node *np) 2299d3e51161SHeiko Stübner { 2300d3e51161SHeiko Stübner struct device_node *child; 2301d3e51161SHeiko Stübner 2302d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 230365fca613SHeiko Stübner if (of_match_node(rockchip_bank_match, child)) 2304d3e51161SHeiko Stübner continue; 2305d3e51161SHeiko Stübner 2306d3e51161SHeiko Stübner info->nfunctions++; 2307d3e51161SHeiko Stübner info->ngroups += of_get_child_count(child); 2308d3e51161SHeiko Stübner } 2309d3e51161SHeiko Stübner } 2310d3e51161SHeiko Stübner 2311d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_groups(struct device_node *np, 2312d3e51161SHeiko Stübner struct rockchip_pin_group *grp, 2313d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 2314d3e51161SHeiko Stübner u32 index) 2315d3e51161SHeiko Stübner { 2316e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2317d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 2318d3e51161SHeiko Stübner int size; 2319d3e51161SHeiko Stübner const __be32 *list; 2320d3e51161SHeiko Stübner int num; 2321d3e51161SHeiko Stübner int i, j; 2322d3e51161SHeiko Stübner int ret; 2323d3e51161SHeiko Stübner 2324e4dd7fd5SAndy Shevchenko dev_dbg(dev, "group(%d): %pOFn\n", index, np); 2325d3e51161SHeiko Stübner 2326d3e51161SHeiko Stübner /* Initialise group */ 2327d3e51161SHeiko Stübner grp->name = np->name; 2328d3e51161SHeiko Stübner 2329d3e51161SHeiko Stübner /* 2330d3e51161SHeiko Stübner * the binding format is rockchip,pins = <bank pin mux CONFIG>, 2331d3e51161SHeiko Stübner * do sanity check and calculate pins number 2332d3e51161SHeiko Stübner */ 2333d3e51161SHeiko Stübner list = of_get_property(np, "rockchip,pins", &size); 2334d3e51161SHeiko Stübner /* we do not check return since it's safe node passed down */ 2335d3e51161SHeiko Stübner size /= sizeof(*list); 23360045028fSAndy Shevchenko if (!size || size % 4) 23370045028fSAndy Shevchenko return dev_err_probe(dev, -EINVAL, "wrong pins number or pins and configs should be by 4\n"); 2338d3e51161SHeiko Stübner 2339d3e51161SHeiko Stübner grp->npins = size / 4; 2340d3e51161SHeiko Stübner 2341e4dd7fd5SAndy Shevchenko grp->pins = devm_kcalloc(dev, grp->npins, sizeof(*grp->pins), GFP_KERNEL); 2342e4dd7fd5SAndy Shevchenko grp->data = devm_kcalloc(dev, grp->npins, sizeof(*grp->data), GFP_KERNEL); 2343d3e51161SHeiko Stübner if (!grp->pins || !grp->data) 2344d3e51161SHeiko Stübner return -ENOMEM; 2345d3e51161SHeiko Stübner 2346d3e51161SHeiko Stübner for (i = 0, j = 0; i < size; i += 4, j++) { 2347d3e51161SHeiko Stübner const __be32 *phandle; 2348d3e51161SHeiko Stübner struct device_node *np_config; 2349d3e51161SHeiko Stübner 2350d3e51161SHeiko Stübner num = be32_to_cpu(*list++); 2351d3e51161SHeiko Stübner bank = bank_num_to_bank(info, num); 2352d3e51161SHeiko Stübner if (IS_ERR(bank)) 2353d3e51161SHeiko Stübner return PTR_ERR(bank); 2354d3e51161SHeiko Stübner 2355d3e51161SHeiko Stübner grp->pins[j] = bank->pin_base + be32_to_cpu(*list++); 2356d3e51161SHeiko Stübner grp->data[j].func = be32_to_cpu(*list++); 2357d3e51161SHeiko Stübner 2358d3e51161SHeiko Stübner phandle = list++; 2359d3e51161SHeiko Stübner if (!phandle) 2360d3e51161SHeiko Stübner return -EINVAL; 2361d3e51161SHeiko Stübner 2362d3e51161SHeiko Stübner np_config = of_find_node_by_phandle(be32_to_cpup(phandle)); 2363dd4d01f7SSoren Brinkmann ret = pinconf_generic_parse_dt_config(np_config, NULL, 2364d3e51161SHeiko Stübner &grp->data[j].configs, &grp->data[j].nconfigs); 2365d3e51161SHeiko Stübner if (ret) 2366d3e51161SHeiko Stübner return ret; 2367d3e51161SHeiko Stübner } 2368d3e51161SHeiko Stübner 2369d3e51161SHeiko Stübner return 0; 2370d3e51161SHeiko Stübner } 2371d3e51161SHeiko Stübner 2372d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_functions(struct device_node *np, 2373d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 2374d3e51161SHeiko Stübner u32 index) 2375d3e51161SHeiko Stübner { 2376e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2377d3e51161SHeiko Stübner struct device_node *child; 2378d3e51161SHeiko Stübner struct rockchip_pmx_func *func; 2379d3e51161SHeiko Stübner struct rockchip_pin_group *grp; 2380d3e51161SHeiko Stübner int ret; 2381d3e51161SHeiko Stübner static u32 grp_index; 2382d3e51161SHeiko Stübner u32 i = 0; 2383d3e51161SHeiko Stübner 2384e4dd7fd5SAndy Shevchenko dev_dbg(dev, "parse function(%d): %pOFn\n", index, np); 2385d3e51161SHeiko Stübner 2386d3e51161SHeiko Stübner func = &info->functions[index]; 2387d3e51161SHeiko Stübner 2388d3e51161SHeiko Stübner /* Initialise function */ 2389d3e51161SHeiko Stübner func->name = np->name; 2390d3e51161SHeiko Stübner func->ngroups = of_get_child_count(np); 2391d3e51161SHeiko Stübner if (func->ngroups <= 0) 2392d3e51161SHeiko Stübner return 0; 2393d3e51161SHeiko Stübner 2394e4dd7fd5SAndy Shevchenko func->groups = devm_kcalloc(dev, func->ngroups, sizeof(*func->groups), GFP_KERNEL); 2395d3e51161SHeiko Stübner if (!func->groups) 2396d3e51161SHeiko Stübner return -ENOMEM; 2397d3e51161SHeiko Stübner 2398d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 2399d3e51161SHeiko Stübner func->groups[i] = child->name; 2400d3e51161SHeiko Stübner grp = &info->groups[grp_index++]; 2401d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_groups(child, grp, info, i++); 2402f7a81b7fSJulia Lawall if (ret) { 2403f7a81b7fSJulia Lawall of_node_put(child); 2404d3e51161SHeiko Stübner return ret; 2405d3e51161SHeiko Stübner } 2406f7a81b7fSJulia Lawall } 2407d3e51161SHeiko Stübner 2408d3e51161SHeiko Stübner return 0; 2409d3e51161SHeiko Stübner } 2410d3e51161SHeiko Stübner 2411d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_dt(struct platform_device *pdev, 2412d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 2413d3e51161SHeiko Stübner { 2414d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 2415d3e51161SHeiko Stübner struct device_node *np = dev->of_node; 2416d3e51161SHeiko Stübner struct device_node *child; 2417d3e51161SHeiko Stübner int ret; 2418d3e51161SHeiko Stübner int i; 2419d3e51161SHeiko Stübner 2420d3e51161SHeiko Stübner rockchip_pinctrl_child_count(info, np); 2421d3e51161SHeiko Stübner 2422e4dd7fd5SAndy Shevchenko dev_dbg(dev, "nfunctions = %d\n", info->nfunctions); 2423e4dd7fd5SAndy Shevchenko dev_dbg(dev, "ngroups = %d\n", info->ngroups); 2424d3e51161SHeiko Stübner 2425e4dd7fd5SAndy Shevchenko info->functions = devm_kcalloc(dev, info->nfunctions, sizeof(*info->functions), GFP_KERNEL); 242698c8ee73SMarkus Elfring if (!info->functions) 2427c4f333b7SDafna Hirschfeld return -ENOMEM; 2428d3e51161SHeiko Stübner 2429e4dd7fd5SAndy Shevchenko info->groups = devm_kcalloc(dev, info->ngroups, sizeof(*info->groups), GFP_KERNEL); 243098c8ee73SMarkus Elfring if (!info->groups) 2431c4f333b7SDafna Hirschfeld return -ENOMEM; 2432d3e51161SHeiko Stübner 2433d3e51161SHeiko Stübner i = 0; 2434d3e51161SHeiko Stübner 2435d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 243665fca613SHeiko Stübner if (of_match_node(rockchip_bank_match, child)) 2437d3e51161SHeiko Stübner continue; 243865fca613SHeiko Stübner 2439d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_functions(child, info, i++); 2440d3e51161SHeiko Stübner if (ret) { 2441e4dd7fd5SAndy Shevchenko dev_err(dev, "failed to parse function\n"); 2442f7a81b7fSJulia Lawall of_node_put(child); 2443d3e51161SHeiko Stübner return ret; 2444d3e51161SHeiko Stübner } 2445d3e51161SHeiko Stübner } 2446d3e51161SHeiko Stübner 2447d3e51161SHeiko Stübner return 0; 2448d3e51161SHeiko Stübner } 2449d3e51161SHeiko Stübner 2450d3e51161SHeiko Stübner static int rockchip_pinctrl_register(struct platform_device *pdev, 2451d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 2452d3e51161SHeiko Stübner { 2453d3e51161SHeiko Stübner struct pinctrl_desc *ctrldesc = &info->pctl; 2454d3e51161SHeiko Stübner struct pinctrl_pin_desc *pindesc, *pdesc; 2455d3e51161SHeiko Stübner struct rockchip_pin_bank *pin_bank; 2456e4dd7fd5SAndy Shevchenko struct device *dev = &pdev->dev; 2457069d7796SAndy Shevchenko char **pin_names; 2458d3e51161SHeiko Stübner int pin, bank, ret; 2459d3e51161SHeiko Stübner int k; 2460d3e51161SHeiko Stübner 2461d3e51161SHeiko Stübner ctrldesc->name = "rockchip-pinctrl"; 2462d3e51161SHeiko Stübner ctrldesc->owner = THIS_MODULE; 2463d3e51161SHeiko Stübner ctrldesc->pctlops = &rockchip_pctrl_ops; 2464d3e51161SHeiko Stübner ctrldesc->pmxops = &rockchip_pmx_ops; 2465d3e51161SHeiko Stübner ctrldesc->confops = &rockchip_pinconf_ops; 2466d3e51161SHeiko Stübner 2467e4dd7fd5SAndy Shevchenko pindesc = devm_kcalloc(dev, info->ctrl->nr_pins, sizeof(*pindesc), GFP_KERNEL); 246898c8ee73SMarkus Elfring if (!pindesc) 2469d3e51161SHeiko Stübner return -ENOMEM; 247098c8ee73SMarkus Elfring 2471d3e51161SHeiko Stübner ctrldesc->pins = pindesc; 2472d3e51161SHeiko Stübner ctrldesc->npins = info->ctrl->nr_pins; 2473d3e51161SHeiko Stübner 2474d3e51161SHeiko Stübner pdesc = pindesc; 2475d3e51161SHeiko Stübner for (bank = 0, k = 0; bank < info->ctrl->nr_banks; bank++) { 2476d3e51161SHeiko Stübner pin_bank = &info->ctrl->pin_banks[bank]; 2477069d7796SAndy Shevchenko 2478069d7796SAndy Shevchenko pin_names = devm_kasprintf_strarray(dev, pin_bank->name, pin_bank->nr_pins); 2479069d7796SAndy Shevchenko if (IS_ERR(pin_names)) 2480069d7796SAndy Shevchenko return PTR_ERR(pin_names); 2481069d7796SAndy Shevchenko 2482d3e51161SHeiko Stübner for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) { 2483d3e51161SHeiko Stübner pdesc->number = k; 2484069d7796SAndy Shevchenko pdesc->name = pin_names[pin]; 2485d3e51161SHeiko Stübner pdesc++; 2486d3e51161SHeiko Stübner } 2487e7165b1dSHeiko Stuebner 2488e7165b1dSHeiko Stuebner INIT_LIST_HEAD(&pin_bank->deferred_output); 2489e7165b1dSHeiko Stuebner mutex_init(&pin_bank->deferred_lock); 2490d3e51161SHeiko Stübner } 2491d3e51161SHeiko Stübner 24920fb7dcb1SDoug Anderson ret = rockchip_pinctrl_parse_dt(pdev, info); 24930fb7dcb1SDoug Anderson if (ret) 24940fb7dcb1SDoug Anderson return ret; 24950fb7dcb1SDoug Anderson 2496e4dd7fd5SAndy Shevchenko info->pctl_dev = devm_pinctrl_register(dev, ctrldesc, info); 24970045028fSAndy Shevchenko if (IS_ERR(info->pctl_dev)) 24980045028fSAndy Shevchenko return dev_err_probe(dev, PTR_ERR(info->pctl_dev), "could not register pinctrl driver\n"); 2499d3e51161SHeiko Stübner 2500d3e51161SHeiko Stübner return 0; 2501d3e51161SHeiko Stübner } 2502d3e51161SHeiko Stübner 2503d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[]; 2504d3e51161SHeiko Stübner 2505d3e51161SHeiko Stübner /* retrieve the soc specific data */ 2506d3e51161SHeiko Stübner static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( 2507d3e51161SHeiko Stübner struct rockchip_pinctrl *d, 2508d3e51161SHeiko Stübner struct platform_device *pdev) 2509d3e51161SHeiko Stübner { 2510e4dd7fd5SAndy Shevchenko struct device *dev = &pdev->dev; 2511e4dd7fd5SAndy Shevchenko struct device_node *node = dev->of_node; 2512d3e51161SHeiko Stübner const struct of_device_id *match; 2513d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 2514d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 2515b6c23275SDavid Wu int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j; 2516d3e51161SHeiko Stübner 2517d3e51161SHeiko Stübner match = of_match_node(rockchip_pinctrl_dt_match, node); 2518d3e51161SHeiko Stübner ctrl = (struct rockchip_pin_ctrl *)match->data; 2519d3e51161SHeiko Stübner 252095ec8ae4SHeiko Stübner grf_offs = ctrl->grf_mux_offset; 252195ec8ae4SHeiko Stübner pmu_offs = ctrl->pmu_mux_offset; 2522b6c23275SDavid Wu drv_pmu_offs = ctrl->pmu_drv_offset; 2523b6c23275SDavid Wu drv_grf_offs = ctrl->grf_drv_offset; 2524d3e51161SHeiko Stübner bank = ctrl->pin_banks; 2525d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 25266bc0d121SHeiko Stübner int bank_pins = 0; 25276bc0d121SHeiko Stübner 252870b7aa7aSJohn Keeping raw_spin_lock_init(&bank->slock); 2529d3e51161SHeiko Stübner bank->drvdata = d; 2530d3e51161SHeiko Stübner bank->pin_base = ctrl->nr_pins; 2531d3e51161SHeiko Stübner ctrl->nr_pins += bank->nr_pins; 25326bc0d121SHeiko Stübner 2533b6c23275SDavid Wu /* calculate iomux and drv offsets */ 25346bc0d121SHeiko Stübner for (j = 0; j < 4; j++) { 25356bc0d121SHeiko Stübner struct rockchip_iomux *iom = &bank->iomux[j]; 2536b6c23275SDavid Wu struct rockchip_drv *drv = &bank->drv[j]; 253703716e1dSHeiko Stübner int inc; 25386bc0d121SHeiko Stübner 25396bc0d121SHeiko Stübner if (bank_pins >= bank->nr_pins) 25406bc0d121SHeiko Stübner break; 25416bc0d121SHeiko Stübner 2542b6c23275SDavid Wu /* preset iomux offset value, set new start value */ 25436bc0d121SHeiko Stübner if (iom->offset >= 0) { 254495ec8ae4SHeiko Stübner if (iom->type & IOMUX_SOURCE_PMU) 254595ec8ae4SHeiko Stübner pmu_offs = iom->offset; 254695ec8ae4SHeiko Stübner else 25476bc0d121SHeiko Stübner grf_offs = iom->offset; 2548b6c23275SDavid Wu } else { /* set current iomux offset */ 254995ec8ae4SHeiko Stübner iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? 255095ec8ae4SHeiko Stübner pmu_offs : grf_offs; 25516bc0d121SHeiko Stübner } 25526bc0d121SHeiko Stübner 2553b6c23275SDavid Wu /* preset drv offset value, set new start value */ 2554b6c23275SDavid Wu if (drv->offset >= 0) { 2555b6c23275SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 2556b6c23275SDavid Wu drv_pmu_offs = drv->offset; 2557b6c23275SDavid Wu else 2558b6c23275SDavid Wu drv_grf_offs = drv->offset; 2559b6c23275SDavid Wu } else { /* set current drv offset */ 2560b6c23275SDavid Wu drv->offset = (iom->type & IOMUX_SOURCE_PMU) ? 2561b6c23275SDavid Wu drv_pmu_offs : drv_grf_offs; 2562b6c23275SDavid Wu } 2563b6c23275SDavid Wu 2564e4dd7fd5SAndy Shevchenko dev_dbg(dev, "bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n", 2565b6c23275SDavid Wu i, j, iom->offset, drv->offset); 25666bc0d121SHeiko Stübner 25676bc0d121SHeiko Stübner /* 25686bc0d121SHeiko Stübner * Increase offset according to iomux width. 256903716e1dSHeiko Stübner * 4bit iomux'es are spread over two registers. 25706bc0d121SHeiko Stübner */ 25718b6c6f93Sdavid.wu inc = (iom->type & (IOMUX_WIDTH_4BIT | 25727825aeb7SJianqun Xu IOMUX_WIDTH_3BIT | 25737825aeb7SJianqun Xu IOMUX_WIDTH_2BIT)) ? 8 : 4; 257495ec8ae4SHeiko Stübner if (iom->type & IOMUX_SOURCE_PMU) 257595ec8ae4SHeiko Stübner pmu_offs += inc; 257695ec8ae4SHeiko Stübner else 257703716e1dSHeiko Stübner grf_offs += inc; 25786bc0d121SHeiko Stübner 2579b6c23275SDavid Wu /* 2580b6c23275SDavid Wu * Increase offset according to drv width. 2581b6c23275SDavid Wu * 3bit drive-strenth'es are spread over two registers. 2582b6c23275SDavid Wu */ 2583b6c23275SDavid Wu if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || 2584b6c23275SDavid Wu (drv->drv_type == DRV_TYPE_IO_3V3_ONLY)) 2585b6c23275SDavid Wu inc = 8; 2586b6c23275SDavid Wu else 2587b6c23275SDavid Wu inc = 4; 2588b6c23275SDavid Wu 2589b6c23275SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 2590b6c23275SDavid Wu drv_pmu_offs += inc; 2591b6c23275SDavid Wu else 2592b6c23275SDavid Wu drv_grf_offs += inc; 2593b6c23275SDavid Wu 25946bc0d121SHeiko Stübner bank_pins += 8; 25956bc0d121SHeiko Stübner } 2596bd35b9bfSDavid Wu 2597c04c3fa6SDavid Wu /* calculate the per-bank recalced_mask */ 2598c04c3fa6SDavid Wu for (j = 0; j < ctrl->niomux_recalced; j++) { 2599c04c3fa6SDavid Wu int pin = 0; 2600c04c3fa6SDavid Wu 2601c04c3fa6SDavid Wu if (ctrl->iomux_recalced[j].num == bank->bank_num) { 2602c04c3fa6SDavid Wu pin = ctrl->iomux_recalced[j].pin; 2603c04c3fa6SDavid Wu bank->recalced_mask |= BIT(pin); 2604c04c3fa6SDavid Wu } 2605c04c3fa6SDavid Wu } 2606c04c3fa6SDavid Wu 2607bd35b9bfSDavid Wu /* calculate the per-bank route_mask */ 2608bd35b9bfSDavid Wu for (j = 0; j < ctrl->niomux_routes; j++) { 2609bd35b9bfSDavid Wu int pin = 0; 2610bd35b9bfSDavid Wu 2611bd35b9bfSDavid Wu if (ctrl->iomux_routes[j].bank_num == bank->bank_num) { 2612bd35b9bfSDavid Wu pin = ctrl->iomux_routes[j].pin; 2613bd35b9bfSDavid Wu bank->route_mask |= BIT(pin); 2614bd35b9bfSDavid Wu } 2615bd35b9bfSDavid Wu } 2616d3e51161SHeiko Stübner } 2617d3e51161SHeiko Stübner 2618d3e51161SHeiko Stübner return ctrl; 2619d3e51161SHeiko Stübner } 2620d3e51161SHeiko Stübner 26218dca9331SChris Zhong #define RK3288_GRF_GPIO6C_IOMUX 0x64 26228dca9331SChris Zhong #define GPIO6C6_SEL_WRITE_ENABLE BIT(28) 26238dca9331SChris Zhong 26248dca9331SChris Zhong static u32 rk3288_grf_gpio6c_iomux; 26258dca9331SChris Zhong 26269198f509SChris Zhong static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev) 26279198f509SChris Zhong { 26289198f509SChris Zhong struct rockchip_pinctrl *info = dev_get_drvdata(dev); 26298dca9331SChris Zhong int ret = pinctrl_force_sleep(info->pctl_dev); 26309198f509SChris Zhong 26318dca9331SChris Zhong if (ret) 26328dca9331SChris Zhong return ret; 26338dca9331SChris Zhong 26348dca9331SChris Zhong /* 26358dca9331SChris Zhong * RK3288 GPIO6_C6 mux would be modified by Maskrom when resume, so save 26368dca9331SChris Zhong * the setting here, and restore it at resume. 26378dca9331SChris Zhong */ 26388dca9331SChris Zhong if (info->ctrl->type == RK3288) { 26398dca9331SChris Zhong ret = regmap_read(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, 26408dca9331SChris Zhong &rk3288_grf_gpio6c_iomux); 26418dca9331SChris Zhong if (ret) { 26428dca9331SChris Zhong pinctrl_force_default(info->pctl_dev); 26438dca9331SChris Zhong return ret; 26448dca9331SChris Zhong } 26458dca9331SChris Zhong } 26468dca9331SChris Zhong 26478dca9331SChris Zhong return 0; 26489198f509SChris Zhong } 26499198f509SChris Zhong 26509198f509SChris Zhong static int __maybe_unused rockchip_pinctrl_resume(struct device *dev) 26519198f509SChris Zhong { 26529198f509SChris Zhong struct rockchip_pinctrl *info = dev_get_drvdata(dev); 2653c971af25SWang Panzhenzhuan int ret; 2654c971af25SWang Panzhenzhuan 2655c971af25SWang Panzhenzhuan if (info->ctrl->type == RK3288) { 2656c971af25SWang Panzhenzhuan ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, 26578dca9331SChris Zhong rk3288_grf_gpio6c_iomux | 26588dca9331SChris Zhong GPIO6C6_SEL_WRITE_ENABLE); 26598dca9331SChris Zhong if (ret) 26608dca9331SChris Zhong return ret; 2661c971af25SWang Panzhenzhuan } 26629198f509SChris Zhong 26639198f509SChris Zhong return pinctrl_force_default(info->pctl_dev); 26649198f509SChris Zhong } 26659198f509SChris Zhong 26669198f509SChris Zhong static SIMPLE_DEV_PM_OPS(rockchip_pinctrl_dev_pm_ops, rockchip_pinctrl_suspend, 26679198f509SChris Zhong rockchip_pinctrl_resume); 26689198f509SChris Zhong 2669d3e51161SHeiko Stübner static int rockchip_pinctrl_probe(struct platform_device *pdev) 2670d3e51161SHeiko Stübner { 2671d3e51161SHeiko Stübner struct rockchip_pinctrl *info; 2672d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 2673e4dd7fd5SAndy Shevchenko struct device_node *np = dev->of_node, *node; 2674d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 2675d3e51161SHeiko Stübner struct resource *res; 2676751a99abSHeiko Stübner void __iomem *base; 2677d3e51161SHeiko Stübner int ret; 2678d3e51161SHeiko Stübner 26790045028fSAndy Shevchenko if (!dev->of_node) 26800045028fSAndy Shevchenko return dev_err_probe(dev, -ENODEV, "device tree node not found\n"); 2681d3e51161SHeiko Stübner 2682283b7ac9SMarkus Elfring info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 2683d3e51161SHeiko Stübner if (!info) 2684d3e51161SHeiko Stübner return -ENOMEM; 2685d3e51161SHeiko Stübner 2686622f3237SHeiko Stübner info->dev = dev; 2687622f3237SHeiko Stübner 2688d3e51161SHeiko Stübner ctrl = rockchip_pinctrl_get_soc_data(info, pdev); 26890045028fSAndy Shevchenko if (!ctrl) 26900045028fSAndy Shevchenko return dev_err_probe(dev, -EINVAL, "driver data not available\n"); 2691d3e51161SHeiko Stübner info->ctrl = ctrl; 2692d3e51161SHeiko Stübner 26931e747e59SHeiko Stübner node = of_parse_phandle(np, "rockchip,grf", 0); 26941e747e59SHeiko Stübner if (node) { 26951e747e59SHeiko Stübner info->regmap_base = syscon_node_to_regmap(node); 26961e747e59SHeiko Stübner if (IS_ERR(info->regmap_base)) 26971e747e59SHeiko Stübner return PTR_ERR(info->regmap_base); 26981e747e59SHeiko Stübner } else { 2699fb17dcd7SAndy Shevchenko base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 2700751a99abSHeiko Stübner if (IS_ERR(base)) 2701751a99abSHeiko Stübner return PTR_ERR(base); 2702751a99abSHeiko Stübner 2703751a99abSHeiko Stübner rockchip_regmap_config.max_register = resource_size(res) - 4; 2704751a99abSHeiko Stübner rockchip_regmap_config.name = "rockchip,pinctrl"; 2705e4dd7fd5SAndy Shevchenko info->regmap_base = 2706e4dd7fd5SAndy Shevchenko devm_regmap_init_mmio(dev, base, &rockchip_regmap_config); 2707d3e51161SHeiko Stübner 2708bfc7a42aSHeiko Stübner /* to check for the old dt-bindings */ 2709bfc7a42aSHeiko Stübner info->reg_size = resource_size(res); 2710bfc7a42aSHeiko Stübner 2711bfc7a42aSHeiko Stübner /* Honor the old binding, with pull registers as 2nd resource */ 2712bfc7a42aSHeiko Stübner if (ctrl->type == RK3188 && info->reg_size < 0x200) { 2713fb17dcd7SAndy Shevchenko base = devm_platform_get_and_ioremap_resource(pdev, 1, &res); 2714751a99abSHeiko Stübner if (IS_ERR(base)) 2715751a99abSHeiko Stübner return PTR_ERR(base); 2716751a99abSHeiko Stübner 2717e4dd7fd5SAndy Shevchenko rockchip_regmap_config.max_register = resource_size(res) - 4; 2718751a99abSHeiko Stübner rockchip_regmap_config.name = "rockchip,pinctrl-pull"; 2719e4dd7fd5SAndy Shevchenko info->regmap_pull = 2720e4dd7fd5SAndy Shevchenko devm_regmap_init_mmio(dev, base, &rockchip_regmap_config); 27216ca5274dSHeiko Stübner } 27221e747e59SHeiko Stübner } 27236ca5274dSHeiko Stübner 272414dee867SHeiko Stübner /* try to find the optional reference to the pmu syscon */ 272514dee867SHeiko Stübner node = of_parse_phandle(np, "rockchip,pmu", 0); 272614dee867SHeiko Stübner if (node) { 272714dee867SHeiko Stübner info->regmap_pmu = syscon_node_to_regmap(node); 272814dee867SHeiko Stübner if (IS_ERR(info->regmap_pmu)) 272914dee867SHeiko Stübner return PTR_ERR(info->regmap_pmu); 273014dee867SHeiko Stübner } 273114dee867SHeiko Stübner 27329ce9a020SJianqun Xu ret = rockchip_pinctrl_register(pdev, info); 2733d3e51161SHeiko Stübner if (ret) 2734d3e51161SHeiko Stübner return ret; 2735d3e51161SHeiko Stübner 27369ce9a020SJianqun Xu platform_set_drvdata(pdev, info); 27379ce9a020SJianqun Xu 2738*bceb6732SJohn Keeping ret = of_platform_populate(np, NULL, NULL, &pdev->dev); 27390045028fSAndy Shevchenko if (ret) 27400045028fSAndy Shevchenko return dev_err_probe(dev, ret, "failed to register gpio device\n"); 2741d3e51161SHeiko Stübner 2742d3e51161SHeiko Stübner return 0; 2743d3e51161SHeiko Stübner } 2744d3e51161SHeiko Stübner 2745e7165b1dSHeiko Stuebner static int rockchip_pinctrl_remove(struct platform_device *pdev) 2746e7165b1dSHeiko Stuebner { 2747e7165b1dSHeiko Stuebner struct rockchip_pinctrl *info = platform_get_drvdata(pdev); 2748e7165b1dSHeiko Stuebner struct rockchip_pin_bank *bank; 2749e7165b1dSHeiko Stuebner struct rockchip_pin_output_deferred *cfg; 2750e7165b1dSHeiko Stuebner int i; 2751e7165b1dSHeiko Stuebner 2752e7165b1dSHeiko Stuebner of_platform_depopulate(&pdev->dev); 2753e7165b1dSHeiko Stuebner 2754e7165b1dSHeiko Stuebner for (i = 0; i < info->ctrl->nr_banks; i++) { 2755e7165b1dSHeiko Stuebner bank = &info->ctrl->pin_banks[i]; 2756e7165b1dSHeiko Stuebner 2757e7165b1dSHeiko Stuebner mutex_lock(&bank->deferred_lock); 2758e7165b1dSHeiko Stuebner while (!list_empty(&bank->deferred_output)) { 2759e7165b1dSHeiko Stuebner cfg = list_first_entry(&bank->deferred_output, 2760e7165b1dSHeiko Stuebner struct rockchip_pin_output_deferred, head); 2761e7165b1dSHeiko Stuebner list_del(&cfg->head); 2762e7165b1dSHeiko Stuebner kfree(cfg); 2763e7165b1dSHeiko Stuebner } 2764e7165b1dSHeiko Stuebner mutex_unlock(&bank->deferred_lock); 2765e7165b1dSHeiko Stuebner } 2766e7165b1dSHeiko Stuebner 2767e7165b1dSHeiko Stuebner return 0; 2768e7165b1dSHeiko Stuebner } 2769e7165b1dSHeiko Stuebner 277087065ca9SDavid Wu static struct rockchip_pin_bank px30_pin_banks[] = { 277187065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 277287065ca9SDavid Wu IOMUX_SOURCE_PMU, 277387065ca9SDavid Wu IOMUX_SOURCE_PMU, 277487065ca9SDavid Wu IOMUX_SOURCE_PMU 277587065ca9SDavid Wu ), 277687065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, 277787065ca9SDavid Wu IOMUX_WIDTH_4BIT, 277887065ca9SDavid Wu IOMUX_WIDTH_4BIT, 277987065ca9SDavid Wu IOMUX_WIDTH_4BIT 278087065ca9SDavid Wu ), 278187065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, 278287065ca9SDavid Wu IOMUX_WIDTH_4BIT, 278387065ca9SDavid Wu IOMUX_WIDTH_4BIT, 278487065ca9SDavid Wu IOMUX_WIDTH_4BIT 278587065ca9SDavid Wu ), 278687065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, 278787065ca9SDavid Wu IOMUX_WIDTH_4BIT, 278887065ca9SDavid Wu IOMUX_WIDTH_4BIT, 278987065ca9SDavid Wu IOMUX_WIDTH_4BIT 279087065ca9SDavid Wu ), 279187065ca9SDavid Wu }; 279287065ca9SDavid Wu 279387065ca9SDavid Wu static struct rockchip_pin_ctrl px30_pin_ctrl = { 279487065ca9SDavid Wu .pin_banks = px30_pin_banks, 279587065ca9SDavid Wu .nr_banks = ARRAY_SIZE(px30_pin_banks), 279687065ca9SDavid Wu .label = "PX30-GPIO", 279787065ca9SDavid Wu .type = PX30, 279887065ca9SDavid Wu .grf_mux_offset = 0x0, 279987065ca9SDavid Wu .pmu_mux_offset = 0x0, 280087065ca9SDavid Wu .iomux_routes = px30_mux_route_data, 280187065ca9SDavid Wu .niomux_routes = ARRAY_SIZE(px30_mux_route_data), 280287065ca9SDavid Wu .pull_calc_reg = px30_calc_pull_reg_and_bit, 280387065ca9SDavid Wu .drv_calc_reg = px30_calc_drv_reg_and_bit, 280487065ca9SDavid Wu .schmitt_calc_reg = px30_calc_schmitt_reg_and_bit, 280587065ca9SDavid Wu }; 280687065ca9SDavid Wu 2807b9c6dcabSAndy Yan static struct rockchip_pin_bank rv1108_pin_banks[] = { 2808688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 2809688daf23SAndy Yan IOMUX_SOURCE_PMU, 2810688daf23SAndy Yan IOMUX_SOURCE_PMU, 2811688daf23SAndy Yan IOMUX_SOURCE_PMU), 2812688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 2813688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0), 2814688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0), 2815688daf23SAndy Yan }; 2816688daf23SAndy Yan 2817b9c6dcabSAndy Yan static struct rockchip_pin_ctrl rv1108_pin_ctrl = { 2818b9c6dcabSAndy Yan .pin_banks = rv1108_pin_banks, 2819b9c6dcabSAndy Yan .nr_banks = ARRAY_SIZE(rv1108_pin_banks), 2820b9c6dcabSAndy Yan .label = "RV1108-GPIO", 2821b9c6dcabSAndy Yan .type = RV1108, 2822688daf23SAndy Yan .grf_mux_offset = 0x10, 2823688daf23SAndy Yan .pmu_mux_offset = 0x0, 282412b8f018SDavid Wu .iomux_recalced = rv1108_mux_recalced_data, 282512b8f018SDavid Wu .niomux_recalced = ARRAY_SIZE(rv1108_mux_recalced_data), 2826b9c6dcabSAndy Yan .pull_calc_reg = rv1108_calc_pull_reg_and_bit, 2827b9c6dcabSAndy Yan .drv_calc_reg = rv1108_calc_drv_reg_and_bit, 28285caff7eaSAndy Yan .schmitt_calc_reg = rv1108_calc_schmitt_reg_and_bit, 2829688daf23SAndy Yan }; 2830688daf23SAndy Yan 2831d3e51161SHeiko Stübner static struct rockchip_pin_bank rk2928_pin_banks[] = { 2832d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 2833d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 2834d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 2835d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 2836d3e51161SHeiko Stübner }; 2837d3e51161SHeiko Stübner 2838d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk2928_pin_ctrl = { 2839d3e51161SHeiko Stübner .pin_banks = rk2928_pin_banks, 2840d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk2928_pin_banks), 2841d3e51161SHeiko Stübner .label = "RK2928-GPIO", 2842a282926dSHeiko Stübner .type = RK2928, 284395ec8ae4SHeiko Stübner .grf_mux_offset = 0xa8, 2844a282926dSHeiko Stübner .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 2845d3e51161SHeiko Stübner }; 2846d3e51161SHeiko Stübner 2847c5ce7670SXing Zheng static struct rockchip_pin_bank rk3036_pin_banks[] = { 2848c5ce7670SXing Zheng PIN_BANK(0, 32, "gpio0"), 2849c5ce7670SXing Zheng PIN_BANK(1, 32, "gpio1"), 2850c5ce7670SXing Zheng PIN_BANK(2, 32, "gpio2"), 2851c5ce7670SXing Zheng }; 2852c5ce7670SXing Zheng 2853c5ce7670SXing Zheng static struct rockchip_pin_ctrl rk3036_pin_ctrl = { 2854c5ce7670SXing Zheng .pin_banks = rk3036_pin_banks, 2855c5ce7670SXing Zheng .nr_banks = ARRAY_SIZE(rk3036_pin_banks), 2856c5ce7670SXing Zheng .label = "RK3036-GPIO", 2857c5ce7670SXing Zheng .type = RK2928, 2858c5ce7670SXing Zheng .grf_mux_offset = 0xa8, 2859c5ce7670SXing Zheng .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 2860c5ce7670SXing Zheng }; 2861c5ce7670SXing Zheng 2862d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066a_pin_banks[] = { 2863d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 2864d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 2865d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 2866d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 2867d3e51161SHeiko Stübner PIN_BANK(4, 32, "gpio4"), 2868d3e51161SHeiko Stübner PIN_BANK(6, 16, "gpio6"), 2869d3e51161SHeiko Stübner }; 2870d3e51161SHeiko Stübner 2871d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { 2872d3e51161SHeiko Stübner .pin_banks = rk3066a_pin_banks, 2873d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), 2874d3e51161SHeiko Stübner .label = "RK3066a-GPIO", 2875a282926dSHeiko Stübner .type = RK2928, 287695ec8ae4SHeiko Stübner .grf_mux_offset = 0xa8, 2877a282926dSHeiko Stübner .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 2878d3e51161SHeiko Stübner }; 2879d3e51161SHeiko Stübner 2880d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066b_pin_banks[] = { 2881d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 2882d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 2883d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 2884d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 2885d3e51161SHeiko Stübner }; 2886d3e51161SHeiko Stübner 2887d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { 2888d3e51161SHeiko Stübner .pin_banks = rk3066b_pin_banks, 2889d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), 2890d3e51161SHeiko Stübner .label = "RK3066b-GPIO", 2891a282926dSHeiko Stübner .type = RK3066B, 289295ec8ae4SHeiko Stübner .grf_mux_offset = 0x60, 2893d3e51161SHeiko Stübner }; 2894d3e51161SHeiko Stübner 2895d23c66dfSDavid Wu static struct rockchip_pin_bank rk3128_pin_banks[] = { 2896d23c66dfSDavid Wu PIN_BANK(0, 32, "gpio0"), 2897d23c66dfSDavid Wu PIN_BANK(1, 32, "gpio1"), 2898d23c66dfSDavid Wu PIN_BANK(2, 32, "gpio2"), 2899d23c66dfSDavid Wu PIN_BANK(3, 32, "gpio3"), 2900d23c66dfSDavid Wu }; 2901d23c66dfSDavid Wu 2902d23c66dfSDavid Wu static struct rockchip_pin_ctrl rk3128_pin_ctrl = { 2903d23c66dfSDavid Wu .pin_banks = rk3128_pin_banks, 2904d23c66dfSDavid Wu .nr_banks = ARRAY_SIZE(rk3128_pin_banks), 2905d23c66dfSDavid Wu .label = "RK3128-GPIO", 2906d23c66dfSDavid Wu .type = RK3128, 2907d23c66dfSDavid Wu .grf_mux_offset = 0xa8, 2908d23c66dfSDavid Wu .iomux_recalced = rk3128_mux_recalced_data, 2909d23c66dfSDavid Wu .niomux_recalced = ARRAY_SIZE(rk3128_mux_recalced_data), 2910d23c66dfSDavid Wu .iomux_routes = rk3128_mux_route_data, 2911d23c66dfSDavid Wu .niomux_routes = ARRAY_SIZE(rk3128_mux_route_data), 2912d23c66dfSDavid Wu .pull_calc_reg = rk3128_calc_pull_reg_and_bit, 2913d23c66dfSDavid Wu }; 2914d23c66dfSDavid Wu 2915d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3188_pin_banks[] = { 2916fc72c923SHeiko Stübner PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0), 2917d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 2918d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 2919d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 2920d3e51161SHeiko Stübner }; 2921d3e51161SHeiko Stübner 2922d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3188_pin_ctrl = { 2923d3e51161SHeiko Stübner .pin_banks = rk3188_pin_banks, 2924d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3188_pin_banks), 2925d3e51161SHeiko Stübner .label = "RK3188-GPIO", 2926a282926dSHeiko Stübner .type = RK3188, 292795ec8ae4SHeiko Stübner .grf_mux_offset = 0x60, 2928ada62b7cSHeiko Stuebner .iomux_routes = rk3188_mux_route_data, 2929ada62b7cSHeiko Stuebner .niomux_routes = ARRAY_SIZE(rk3188_mux_route_data), 29306ca5274dSHeiko Stübner .pull_calc_reg = rk3188_calc_pull_reg_and_bit, 2931d3e51161SHeiko Stübner }; 2932d3e51161SHeiko Stübner 2933fea0fe60SJeffy Chen static struct rockchip_pin_bank rk3228_pin_banks[] = { 2934fea0fe60SJeffy Chen PIN_BANK(0, 32, "gpio0"), 2935fea0fe60SJeffy Chen PIN_BANK(1, 32, "gpio1"), 2936fea0fe60SJeffy Chen PIN_BANK(2, 32, "gpio2"), 2937fea0fe60SJeffy Chen PIN_BANK(3, 32, "gpio3"), 2938fea0fe60SJeffy Chen }; 2939fea0fe60SJeffy Chen 2940fea0fe60SJeffy Chen static struct rockchip_pin_ctrl rk3228_pin_ctrl = { 2941fea0fe60SJeffy Chen .pin_banks = rk3228_pin_banks, 2942fea0fe60SJeffy Chen .nr_banks = ARRAY_SIZE(rk3228_pin_banks), 2943fea0fe60SJeffy Chen .label = "RK3228-GPIO", 2944fea0fe60SJeffy Chen .type = RK3288, 2945fea0fe60SJeffy Chen .grf_mux_offset = 0x0, 2946d4970ee0SDavid Wu .iomux_routes = rk3228_mux_route_data, 2947d4970ee0SDavid Wu .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), 2948fea0fe60SJeffy Chen .pull_calc_reg = rk3228_calc_pull_reg_and_bit, 2949fea0fe60SJeffy Chen .drv_calc_reg = rk3228_calc_drv_reg_and_bit, 2950fea0fe60SJeffy Chen }; 2951fea0fe60SJeffy Chen 2952304f077dSHeiko Stübner static struct rockchip_pin_bank rk3288_pin_banks[] = { 2953304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU, 2954304f077dSHeiko Stübner IOMUX_SOURCE_PMU, 2955304f077dSHeiko Stübner IOMUX_SOURCE_PMU, 2956304f077dSHeiko Stübner IOMUX_UNROUTED 2957304f077dSHeiko Stübner ), 2958304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED, 2959304f077dSHeiko Stübner IOMUX_UNROUTED, 2960304f077dSHeiko Stübner IOMUX_UNROUTED, 2961304f077dSHeiko Stübner 0 2962304f077dSHeiko Stübner ), 2963304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED), 2964304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT), 2965304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, 2966304f077dSHeiko Stübner IOMUX_WIDTH_4BIT, 2967304f077dSHeiko Stübner 0, 2968304f077dSHeiko Stübner 0 2969304f077dSHeiko Stübner ), 2970304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED, 2971304f077dSHeiko Stübner 0, 2972304f077dSHeiko Stübner 0, 2973304f077dSHeiko Stübner IOMUX_UNROUTED 2974304f077dSHeiko Stübner ), 2975304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED), 2976304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0, 2977304f077dSHeiko Stübner 0, 2978304f077dSHeiko Stübner IOMUX_WIDTH_4BIT, 2979304f077dSHeiko Stübner IOMUX_UNROUTED 2980304f077dSHeiko Stübner ), 2981304f077dSHeiko Stübner PIN_BANK(8, 16, "gpio8"), 2982304f077dSHeiko Stübner }; 2983304f077dSHeiko Stübner 2984304f077dSHeiko Stübner static struct rockchip_pin_ctrl rk3288_pin_ctrl = { 2985304f077dSHeiko Stübner .pin_banks = rk3288_pin_banks, 2986304f077dSHeiko Stübner .nr_banks = ARRAY_SIZE(rk3288_pin_banks), 2987304f077dSHeiko Stübner .label = "RK3288-GPIO", 298866d750e1SHeiko Stübner .type = RK3288, 2989304f077dSHeiko Stübner .grf_mux_offset = 0x0, 2990304f077dSHeiko Stübner .pmu_mux_offset = 0x84, 29914e96fd30SHeiko Stuebner .iomux_routes = rk3288_mux_route_data, 29924e96fd30SHeiko Stuebner .niomux_routes = ARRAY_SIZE(rk3288_mux_route_data), 2993304f077dSHeiko Stübner .pull_calc_reg = rk3288_calc_pull_reg_and_bit, 2994ef17f69fSHeiko Stübner .drv_calc_reg = rk3288_calc_drv_reg_and_bit, 2995304f077dSHeiko Stübner }; 2996304f077dSHeiko Stübner 29977825aeb7SJianqun Xu static struct rockchip_pin_bank rk3308_pin_banks[] = { 29987825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_WIDTH_2BIT, 29997825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30007825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30017825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 30027825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_2BIT, 30037825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30047825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30057825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 30067825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_2BIT, 30077825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30087825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30097825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 30107825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_2BIT, 30117825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30127825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30137825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 30147825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_2BIT, 30157825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30167825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30177825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 30187825aeb7SJianqun Xu }; 30197825aeb7SJianqun Xu 30207825aeb7SJianqun Xu static struct rockchip_pin_ctrl rk3308_pin_ctrl = { 30217825aeb7SJianqun Xu .pin_banks = rk3308_pin_banks, 30227825aeb7SJianqun Xu .nr_banks = ARRAY_SIZE(rk3308_pin_banks), 30237825aeb7SJianqun Xu .label = "RK3308-GPIO", 30247825aeb7SJianqun Xu .type = RK3308, 30257825aeb7SJianqun Xu .grf_mux_offset = 0x0, 30267825aeb7SJianqun Xu .iomux_recalced = rk3308_mux_recalced_data, 30277825aeb7SJianqun Xu .niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data), 30287825aeb7SJianqun Xu .iomux_routes = rk3308_mux_route_data, 30297825aeb7SJianqun Xu .niomux_routes = ARRAY_SIZE(rk3308_mux_route_data), 30307825aeb7SJianqun Xu .pull_calc_reg = rk3308_calc_pull_reg_and_bit, 30317825aeb7SJianqun Xu .drv_calc_reg = rk3308_calc_drv_reg_and_bit, 30327825aeb7SJianqun Xu .schmitt_calc_reg = rk3308_calc_schmitt_reg_and_bit, 30337825aeb7SJianqun Xu }; 30347825aeb7SJianqun Xu 30353818e4a7Sdavid.wu static struct rockchip_pin_bank rk3328_pin_banks[] = { 30363818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), 30373818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 30383818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 3039c04c3fa6SDavid Wu IOMUX_WIDTH_3BIT, 3040c04c3fa6SDavid Wu IOMUX_WIDTH_3BIT, 30413818e4a7Sdavid.wu 0), 30423818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 30433818e4a7Sdavid.wu IOMUX_WIDTH_3BIT, 3044c04c3fa6SDavid Wu IOMUX_WIDTH_3BIT, 30453818e4a7Sdavid.wu 0, 30463818e4a7Sdavid.wu 0), 30473818e4a7Sdavid.wu }; 30483818e4a7Sdavid.wu 30493818e4a7Sdavid.wu static struct rockchip_pin_ctrl rk3328_pin_ctrl = { 30503818e4a7Sdavid.wu .pin_banks = rk3328_pin_banks, 30513818e4a7Sdavid.wu .nr_banks = ARRAY_SIZE(rk3328_pin_banks), 30523818e4a7Sdavid.wu .label = "RK3328-GPIO", 30533818e4a7Sdavid.wu .type = RK3288, 30543818e4a7Sdavid.wu .grf_mux_offset = 0x0, 3055c04c3fa6SDavid Wu .iomux_recalced = rk3328_mux_recalced_data, 3056c04c3fa6SDavid Wu .niomux_recalced = ARRAY_SIZE(rk3328_mux_recalced_data), 3057cedc964aSDavid Wu .iomux_routes = rk3328_mux_route_data, 3058cedc964aSDavid Wu .niomux_routes = ARRAY_SIZE(rk3328_mux_route_data), 30593818e4a7Sdavid.wu .pull_calc_reg = rk3228_calc_pull_reg_and_bit, 30603818e4a7Sdavid.wu .drv_calc_reg = rk3228_calc_drv_reg_and_bit, 3061728d3f5aSdavid.wu .schmitt_calc_reg = rk3328_calc_schmitt_reg_and_bit, 30623818e4a7Sdavid.wu }; 30633818e4a7Sdavid.wu 3064daecdc66SHeiko Stübner static struct rockchip_pin_bank rk3368_pin_banks[] = { 3065daecdc66SHeiko Stübner PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 3066daecdc66SHeiko Stübner IOMUX_SOURCE_PMU, 3067daecdc66SHeiko Stübner IOMUX_SOURCE_PMU, 3068daecdc66SHeiko Stübner IOMUX_SOURCE_PMU 3069daecdc66SHeiko Stübner ), 3070daecdc66SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 3071daecdc66SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 3072daecdc66SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 3073daecdc66SHeiko Stübner }; 3074daecdc66SHeiko Stübner 3075daecdc66SHeiko Stübner static struct rockchip_pin_ctrl rk3368_pin_ctrl = { 3076daecdc66SHeiko Stübner .pin_banks = rk3368_pin_banks, 3077daecdc66SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3368_pin_banks), 3078daecdc66SHeiko Stübner .label = "RK3368-GPIO", 3079daecdc66SHeiko Stübner .type = RK3368, 3080daecdc66SHeiko Stübner .grf_mux_offset = 0x0, 3081daecdc66SHeiko Stübner .pmu_mux_offset = 0x0, 3082daecdc66SHeiko Stübner .pull_calc_reg = rk3368_calc_pull_reg_and_bit, 3083daecdc66SHeiko Stübner .drv_calc_reg = rk3368_calc_drv_reg_and_bit, 3084daecdc66SHeiko Stübner }; 3085daecdc66SHeiko Stübner 3086b6c23275SDavid Wu static struct rockchip_pin_bank rk3399_pin_banks[] = { 30873ba6767aSDavid Wu PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0", 30883ba6767aSDavid Wu IOMUX_SOURCE_PMU, 3089b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3090b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3091b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3092b6c23275SDavid Wu DRV_TYPE_IO_1V8_ONLY, 3093b6c23275SDavid Wu DRV_TYPE_IO_1V8_ONLY, 3094b6c23275SDavid Wu DRV_TYPE_IO_DEFAULT, 3095b6c23275SDavid Wu DRV_TYPE_IO_DEFAULT, 3096c437f65cSDavid Wu 0x80, 3097c437f65cSDavid Wu 0x88, 3098b6c23275SDavid Wu -1, 30993ba6767aSDavid Wu -1, 31003ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY, 31013ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY, 31023ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT, 31033ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT 3104b6c23275SDavid Wu ), 3105b6c23275SDavid Wu PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU, 3106b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3107b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3108b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3109b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3110b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3111b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3112b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3113c437f65cSDavid Wu 0xa0, 3114c437f65cSDavid Wu 0xa8, 3115c437f65cSDavid Wu 0xb0, 3116c437f65cSDavid Wu 0xb8 3117b6c23275SDavid Wu ), 31183ba6767aSDavid Wu PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0, 3119b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3120b6c23275SDavid Wu DRV_TYPE_IO_1V8_ONLY, 31213ba6767aSDavid Wu DRV_TYPE_IO_1V8_ONLY, 31223ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT, 31233ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT, 31243ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY, 31253ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY 3126b6c23275SDavid Wu ), 3127b6c23275SDavid Wu PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY, 3128b6c23275SDavid Wu DRV_TYPE_IO_3V3_ONLY, 3129b6c23275SDavid Wu DRV_TYPE_IO_3V3_ONLY, 3130b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0 3131b6c23275SDavid Wu ), 3132b6c23275SDavid Wu PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0, 3133b6c23275SDavid Wu DRV_TYPE_IO_1V8_3V0_AUTO, 3134b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3135b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0 3136b6c23275SDavid Wu ), 3137b6c23275SDavid Wu }; 3138b6c23275SDavid Wu 3139b6c23275SDavid Wu static struct rockchip_pin_ctrl rk3399_pin_ctrl = { 3140b6c23275SDavid Wu .pin_banks = rk3399_pin_banks, 3141b6c23275SDavid Wu .nr_banks = ARRAY_SIZE(rk3399_pin_banks), 3142b6c23275SDavid Wu .label = "RK3399-GPIO", 3143b6c23275SDavid Wu .type = RK3399, 3144b6c23275SDavid Wu .grf_mux_offset = 0xe000, 3145b6c23275SDavid Wu .pmu_mux_offset = 0x0, 3146b6c23275SDavid Wu .grf_drv_offset = 0xe100, 3147b6c23275SDavid Wu .pmu_drv_offset = 0x80, 3148accc1ce7SDavid Wu .iomux_routes = rk3399_mux_route_data, 3149accc1ce7SDavid Wu .niomux_routes = ARRAY_SIZE(rk3399_mux_route_data), 3150b6c23275SDavid Wu .pull_calc_reg = rk3399_calc_pull_reg_and_bit, 3151b6c23275SDavid Wu .drv_calc_reg = rk3399_calc_drv_reg_and_bit, 3152b6c23275SDavid Wu }; 3153daecdc66SHeiko Stübner 3154c0dadc0eSJianqun Xu static struct rockchip_pin_bank rk3568_pin_banks[] = { 3155c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, 3156c0dadc0eSJianqun Xu IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, 3157c0dadc0eSJianqun Xu IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, 3158c0dadc0eSJianqun Xu IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), 3159c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, 3160c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3161c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3162c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3163c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, 3164c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3165c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3166c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3167c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, 3168c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3169c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3170c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3171c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, 3172c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3173c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3174c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3175c0dadc0eSJianqun Xu }; 3176c0dadc0eSJianqun Xu 3177c0dadc0eSJianqun Xu static struct rockchip_pin_ctrl rk3568_pin_ctrl = { 3178c0dadc0eSJianqun Xu .pin_banks = rk3568_pin_banks, 3179c0dadc0eSJianqun Xu .nr_banks = ARRAY_SIZE(rk3568_pin_banks), 3180c0dadc0eSJianqun Xu .label = "RK3568-GPIO", 3181c0dadc0eSJianqun Xu .type = RK3568, 3182c0dadc0eSJianqun Xu .grf_mux_offset = 0x0, 3183c0dadc0eSJianqun Xu .pmu_mux_offset = 0x0, 3184c0dadc0eSJianqun Xu .grf_drv_offset = 0x0200, 3185c0dadc0eSJianqun Xu .pmu_drv_offset = 0x0070, 3186c0dadc0eSJianqun Xu .iomux_routes = rk3568_mux_route_data, 3187c0dadc0eSJianqun Xu .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), 3188c0dadc0eSJianqun Xu .pull_calc_reg = rk3568_calc_pull_reg_and_bit, 3189c0dadc0eSJianqun Xu .drv_calc_reg = rk3568_calc_drv_reg_and_bit, 3190c0dadc0eSJianqun Xu .schmitt_calc_reg = rk3568_calc_schmitt_reg_and_bit, 3191c0dadc0eSJianqun Xu }; 3192c0dadc0eSJianqun Xu 3193d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[] = { 319487065ca9SDavid Wu { .compatible = "rockchip,px30-pinctrl", 319587065ca9SDavid Wu .data = &px30_pin_ctrl }, 3196b9c6dcabSAndy Yan { .compatible = "rockchip,rv1108-pinctrl", 3197cdbbd26fSMasahiro Yamada .data = &rv1108_pin_ctrl }, 3198d3e51161SHeiko Stübner { .compatible = "rockchip,rk2928-pinctrl", 3199cdbbd26fSMasahiro Yamada .data = &rk2928_pin_ctrl }, 3200c5ce7670SXing Zheng { .compatible = "rockchip,rk3036-pinctrl", 3201cdbbd26fSMasahiro Yamada .data = &rk3036_pin_ctrl }, 3202d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066a-pinctrl", 3203cdbbd26fSMasahiro Yamada .data = &rk3066a_pin_ctrl }, 3204d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066b-pinctrl", 3205cdbbd26fSMasahiro Yamada .data = &rk3066b_pin_ctrl }, 3206d23c66dfSDavid Wu { .compatible = "rockchip,rk3128-pinctrl", 3207d23c66dfSDavid Wu .data = (void *)&rk3128_pin_ctrl }, 3208d3e51161SHeiko Stübner { .compatible = "rockchip,rk3188-pinctrl", 3209cdbbd26fSMasahiro Yamada .data = &rk3188_pin_ctrl }, 3210fea0fe60SJeffy Chen { .compatible = "rockchip,rk3228-pinctrl", 3211cdbbd26fSMasahiro Yamada .data = &rk3228_pin_ctrl }, 3212304f077dSHeiko Stübner { .compatible = "rockchip,rk3288-pinctrl", 3213cdbbd26fSMasahiro Yamada .data = &rk3288_pin_ctrl }, 32147825aeb7SJianqun Xu { .compatible = "rockchip,rk3308-pinctrl", 32157825aeb7SJianqun Xu .data = &rk3308_pin_ctrl }, 32163818e4a7Sdavid.wu { .compatible = "rockchip,rk3328-pinctrl", 3217cdbbd26fSMasahiro Yamada .data = &rk3328_pin_ctrl }, 3218daecdc66SHeiko Stübner { .compatible = "rockchip,rk3368-pinctrl", 3219cdbbd26fSMasahiro Yamada .data = &rk3368_pin_ctrl }, 3220b6c23275SDavid Wu { .compatible = "rockchip,rk3399-pinctrl", 3221cdbbd26fSMasahiro Yamada .data = &rk3399_pin_ctrl }, 3222c0dadc0eSJianqun Xu { .compatible = "rockchip,rk3568-pinctrl", 3223c0dadc0eSJianqun Xu .data = &rk3568_pin_ctrl }, 3224d3e51161SHeiko Stübner {}, 3225d3e51161SHeiko Stübner }; 3226d3e51161SHeiko Stübner 3227d3e51161SHeiko Stübner static struct platform_driver rockchip_pinctrl_driver = { 3228d3e51161SHeiko Stübner .probe = rockchip_pinctrl_probe, 3229e7165b1dSHeiko Stuebner .remove = rockchip_pinctrl_remove, 3230d3e51161SHeiko Stübner .driver = { 3231d3e51161SHeiko Stübner .name = "rockchip-pinctrl", 32329198f509SChris Zhong .pm = &rockchip_pinctrl_dev_pm_ops, 32330be9e70dSAxel Lin .of_match_table = rockchip_pinctrl_dt_match, 3234d3e51161SHeiko Stübner }, 3235d3e51161SHeiko Stübner }; 3236d3e51161SHeiko Stübner 3237d3e51161SHeiko Stübner static int __init rockchip_pinctrl_drv_register(void) 3238d3e51161SHeiko Stübner { 3239d3e51161SHeiko Stübner return platform_driver_register(&rockchip_pinctrl_driver); 3240d3e51161SHeiko Stübner } 3241d3e51161SHeiko Stübner postcore_initcall(rockchip_pinctrl_drv_register); 3242be786ac5SJianqun Xu 3243be786ac5SJianqun Xu static void __exit rockchip_pinctrl_drv_unregister(void) 3244be786ac5SJianqun Xu { 3245be786ac5SJianqun Xu platform_driver_unregister(&rockchip_pinctrl_driver); 3246be786ac5SJianqun Xu } 3247be786ac5SJianqun Xu module_exit(rockchip_pinctrl_drv_unregister); 3248be786ac5SJianqun Xu 3249be786ac5SJianqun Xu MODULE_DESCRIPTION("ROCKCHIP Pin Controller Driver"); 3250be786ac5SJianqun Xu MODULE_LICENSE("GPL"); 3251be786ac5SJianqun Xu MODULE_ALIAS("platform:pinctrl-rockchip"); 3252be786ac5SJianqun Xu MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); 3253