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) 60fd4ea486SJagan Teki #define IOMUX_L_SOURCE_PMU BIT(6) 61fc72c923SHeiko Stübner 62d3e51161SHeiko Stübner #define PIN_BANK(id, pins, label) \ 63d3e51161SHeiko Stübner { \ 64d3e51161SHeiko Stübner .bank_num = id, \ 65d3e51161SHeiko Stübner .nr_pins = pins, \ 66d3e51161SHeiko Stübner .name = label, \ 676bc0d121SHeiko Stübner .iomux = { \ 686bc0d121SHeiko Stübner { .offset = -1 }, \ 696bc0d121SHeiko Stübner { .offset = -1 }, \ 706bc0d121SHeiko Stübner { .offset = -1 }, \ 716bc0d121SHeiko Stübner { .offset = -1 }, \ 726bc0d121SHeiko Stübner }, \ 73d3e51161SHeiko Stübner } 74d3e51161SHeiko Stübner 75fc72c923SHeiko Stübner #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ 76fc72c923SHeiko Stübner { \ 77fc72c923SHeiko Stübner .bank_num = id, \ 78fc72c923SHeiko Stübner .nr_pins = pins, \ 79fc72c923SHeiko Stübner .name = label, \ 80fc72c923SHeiko Stübner .iomux = { \ 816bc0d121SHeiko Stübner { .type = iom0, .offset = -1 }, \ 826bc0d121SHeiko Stübner { .type = iom1, .offset = -1 }, \ 836bc0d121SHeiko Stübner { .type = iom2, .offset = -1 }, \ 846bc0d121SHeiko Stübner { .type = iom3, .offset = -1 }, \ 85fc72c923SHeiko Stübner }, \ 86fc72c923SHeiko Stübner } 87fc72c923SHeiko Stübner 88b6c23275SDavid Wu #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \ 89b6c23275SDavid Wu { \ 90b6c23275SDavid Wu .bank_num = id, \ 91b6c23275SDavid Wu .nr_pins = pins, \ 92b6c23275SDavid Wu .name = label, \ 93b6c23275SDavid Wu .iomux = { \ 94b6c23275SDavid Wu { .offset = -1 }, \ 95b6c23275SDavid Wu { .offset = -1 }, \ 96b6c23275SDavid Wu { .offset = -1 }, \ 97b6c23275SDavid Wu { .offset = -1 }, \ 98b6c23275SDavid Wu }, \ 99b6c23275SDavid Wu .drv = { \ 100b6c23275SDavid Wu { .drv_type = type0, .offset = -1 }, \ 101b6c23275SDavid Wu { .drv_type = type1, .offset = -1 }, \ 102b6c23275SDavid Wu { .drv_type = type2, .offset = -1 }, \ 103b6c23275SDavid Wu { .drv_type = type3, .offset = -1 }, \ 104b6c23275SDavid Wu }, \ 105b6c23275SDavid Wu } 106b6c23275SDavid Wu 107fdc33ebaSJianqun Xu #define PIN_BANK_IOMUX_FLAGS_PULL_FLAGS(id, pins, label, iom0, iom1, \ 108fdc33ebaSJianqun Xu iom2, iom3, pull0, pull1, \ 109fdc33ebaSJianqun Xu pull2, pull3) \ 110fdc33ebaSJianqun Xu { \ 111fdc33ebaSJianqun Xu .bank_num = id, \ 112fdc33ebaSJianqun Xu .nr_pins = pins, \ 113fdc33ebaSJianqun Xu .name = label, \ 114fdc33ebaSJianqun Xu .iomux = { \ 115fdc33ebaSJianqun Xu { .type = iom0, .offset = -1 }, \ 116fdc33ebaSJianqun Xu { .type = iom1, .offset = -1 }, \ 117fdc33ebaSJianqun Xu { .type = iom2, .offset = -1 }, \ 118fdc33ebaSJianqun Xu { .type = iom3, .offset = -1 }, \ 119fdc33ebaSJianqun Xu }, \ 120fdc33ebaSJianqun Xu .pull_type[0] = pull0, \ 121fdc33ebaSJianqun Xu .pull_type[1] = pull1, \ 122fdc33ebaSJianqun Xu .pull_type[2] = pull2, \ 123fdc33ebaSJianqun Xu .pull_type[3] = pull3, \ 124fdc33ebaSJianqun Xu } 125fdc33ebaSJianqun Xu 1263ba6767aSDavid Wu #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1, \ 1273ba6767aSDavid Wu drv2, drv3, pull0, pull1, \ 1283ba6767aSDavid Wu pull2, pull3) \ 1293ba6767aSDavid Wu { \ 1303ba6767aSDavid Wu .bank_num = id, \ 1313ba6767aSDavid Wu .nr_pins = pins, \ 1323ba6767aSDavid Wu .name = label, \ 1333ba6767aSDavid Wu .iomux = { \ 1343ba6767aSDavid Wu { .offset = -1 }, \ 1353ba6767aSDavid Wu { .offset = -1 }, \ 1363ba6767aSDavid Wu { .offset = -1 }, \ 1373ba6767aSDavid Wu { .offset = -1 }, \ 1383ba6767aSDavid Wu }, \ 1393ba6767aSDavid Wu .drv = { \ 1403ba6767aSDavid Wu { .drv_type = drv0, .offset = -1 }, \ 1413ba6767aSDavid Wu { .drv_type = drv1, .offset = -1 }, \ 1423ba6767aSDavid Wu { .drv_type = drv2, .offset = -1 }, \ 1433ba6767aSDavid Wu { .drv_type = drv3, .offset = -1 }, \ 1443ba6767aSDavid Wu }, \ 1453ba6767aSDavid Wu .pull_type[0] = pull0, \ 1463ba6767aSDavid Wu .pull_type[1] = pull1, \ 1473ba6767aSDavid Wu .pull_type[2] = pull2, \ 1483ba6767aSDavid Wu .pull_type[3] = pull3, \ 1493ba6767aSDavid Wu } 1503ba6767aSDavid Wu 151fd4ea486SJagan Teki #define PIN_BANK_IOMUX_FLAGS_OFFSET(id, pins, label, iom0, iom1, iom2, \ 152fd4ea486SJagan Teki iom3, offset0, offset1, offset2, \ 153fd4ea486SJagan Teki offset3) \ 154fd4ea486SJagan Teki { \ 155fd4ea486SJagan Teki .bank_num = id, \ 156fd4ea486SJagan Teki .nr_pins = pins, \ 157fd4ea486SJagan Teki .name = label, \ 158fd4ea486SJagan Teki .iomux = { \ 159fd4ea486SJagan Teki { .type = iom0, .offset = offset0 }, \ 160fd4ea486SJagan Teki { .type = iom1, .offset = offset1 }, \ 161fd4ea486SJagan Teki { .type = iom2, .offset = offset2 }, \ 162fd4ea486SJagan Teki { .type = iom3, .offset = offset3 }, \ 163fd4ea486SJagan Teki }, \ 164fd4ea486SJagan Teki } 165fd4ea486SJagan Teki 166b6c23275SDavid Wu #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1, \ 167b6c23275SDavid Wu iom2, iom3, drv0, drv1, drv2, \ 168b6c23275SDavid Wu drv3, offset0, offset1, \ 169b6c23275SDavid Wu offset2, offset3) \ 170b6c23275SDavid Wu { \ 171b6c23275SDavid Wu .bank_num = id, \ 172b6c23275SDavid Wu .nr_pins = pins, \ 173b6c23275SDavid Wu .name = label, \ 174b6c23275SDavid Wu .iomux = { \ 175b6c23275SDavid Wu { .type = iom0, .offset = -1 }, \ 176b6c23275SDavid Wu { .type = iom1, .offset = -1 }, \ 177b6c23275SDavid Wu { .type = iom2, .offset = -1 }, \ 178b6c23275SDavid Wu { .type = iom3, .offset = -1 }, \ 179b6c23275SDavid Wu }, \ 180b6c23275SDavid Wu .drv = { \ 181b6c23275SDavid Wu { .drv_type = drv0, .offset = offset0 }, \ 182b6c23275SDavid Wu { .drv_type = drv1, .offset = offset1 }, \ 183b6c23275SDavid Wu { .drv_type = drv2, .offset = offset2 }, \ 184b6c23275SDavid Wu { .drv_type = drv3, .offset = offset3 }, \ 185b6c23275SDavid Wu }, \ 186b6c23275SDavid Wu } 187b6c23275SDavid Wu 1883ba6767aSDavid Wu #define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins, \ 1893ba6767aSDavid Wu label, iom0, iom1, iom2, \ 1903ba6767aSDavid Wu iom3, drv0, drv1, drv2, \ 1913ba6767aSDavid Wu drv3, offset0, offset1, \ 1923ba6767aSDavid Wu offset2, offset3, pull0, \ 1933ba6767aSDavid Wu pull1, pull2, pull3) \ 1943ba6767aSDavid Wu { \ 1953ba6767aSDavid Wu .bank_num = id, \ 1963ba6767aSDavid Wu .nr_pins = pins, \ 1973ba6767aSDavid Wu .name = label, \ 1983ba6767aSDavid Wu .iomux = { \ 1993ba6767aSDavid Wu { .type = iom0, .offset = -1 }, \ 2003ba6767aSDavid Wu { .type = iom1, .offset = -1 }, \ 2013ba6767aSDavid Wu { .type = iom2, .offset = -1 }, \ 2023ba6767aSDavid Wu { .type = iom3, .offset = -1 }, \ 2033ba6767aSDavid Wu }, \ 2043ba6767aSDavid Wu .drv = { \ 2053ba6767aSDavid Wu { .drv_type = drv0, .offset = offset0 }, \ 2063ba6767aSDavid Wu { .drv_type = drv1, .offset = offset1 }, \ 2073ba6767aSDavid Wu { .drv_type = drv2, .offset = offset2 }, \ 2083ba6767aSDavid Wu { .drv_type = drv3, .offset = offset3 }, \ 2093ba6767aSDavid Wu }, \ 2103ba6767aSDavid Wu .pull_type[0] = pull0, \ 2113ba6767aSDavid Wu .pull_type[1] = pull1, \ 2123ba6767aSDavid Wu .pull_type[2] = pull2, \ 2133ba6767aSDavid Wu .pull_type[3] = pull3, \ 2143ba6767aSDavid Wu } 2153ba6767aSDavid Wu 216c0dadc0eSJianqun Xu #define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG) \ 217c0dadc0eSJianqun Xu { \ 218c0dadc0eSJianqun Xu .bank_num = ID, \ 219c0dadc0eSJianqun Xu .pin = PIN, \ 220c0dadc0eSJianqun Xu .func = FUNC, \ 221c0dadc0eSJianqun Xu .route_offset = REG, \ 222c0dadc0eSJianqun Xu .route_val = VAL, \ 223c0dadc0eSJianqun Xu .route_location = FLAG, \ 224c0dadc0eSJianqun Xu } 225c0dadc0eSJianqun Xu 226c0dadc0eSJianqun Xu #define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL) \ 227c0dadc0eSJianqun Xu PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME) 228c0dadc0eSJianqun Xu 229c0dadc0eSJianqun Xu #define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL) \ 230c0dadc0eSJianqun Xu PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF) 231c0dadc0eSJianqun Xu 232c0dadc0eSJianqun Xu #define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \ 233c0dadc0eSJianqun Xu PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU) 234c0dadc0eSJianqun Xu 235fdc33ebaSJianqun Xu #define RK3588_PIN_BANK_FLAGS(ID, PIN, LABEL, M, P) \ 236fdc33ebaSJianqun Xu PIN_BANK_IOMUX_FLAGS_PULL_FLAGS(ID, PIN, LABEL, M, M, M, M, P, P, P, P) 237fdc33ebaSJianqun Xu 238751a99abSHeiko Stübner static struct regmap_config rockchip_regmap_config = { 239751a99abSHeiko Stübner .reg_bits = 32, 240751a99abSHeiko Stübner .val_bits = 32, 241751a99abSHeiko Stübner .reg_stride = 4, 242751a99abSHeiko Stübner }; 243751a99abSHeiko Stübner 24456411f3cSArnd Bergmann static inline const struct rockchip_pin_group *pinctrl_name_to_group( 245d3e51161SHeiko Stübner const struct rockchip_pinctrl *info, 246d3e51161SHeiko Stübner const char *name) 247d3e51161SHeiko Stübner { 248d3e51161SHeiko Stübner int i; 249d3e51161SHeiko Stübner 250d3e51161SHeiko Stübner for (i = 0; i < info->ngroups; i++) { 2511cb95395SAxel Lin if (!strcmp(info->groups[i].name, name)) 2521cb95395SAxel Lin return &info->groups[i]; 253d3e51161SHeiko Stübner } 254d3e51161SHeiko Stübner 2551cb95395SAxel Lin return NULL; 256d3e51161SHeiko Stübner } 257d3e51161SHeiko Stübner 258d3e51161SHeiko Stübner /* 259d3e51161SHeiko Stübner * given a pin number that is local to a pin controller, find out the pin bank 260d3e51161SHeiko Stübner * and the register base of the pin bank. 261d3e51161SHeiko Stübner */ 262d3e51161SHeiko Stübner static struct rockchip_pin_bank *pin_to_bank(struct rockchip_pinctrl *info, 263d3e51161SHeiko Stübner unsigned pin) 264d3e51161SHeiko Stübner { 265d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 266d3e51161SHeiko Stübner 26751578b9bSAxel Lin while (pin >= (b->pin_base + b->nr_pins)) 268d3e51161SHeiko Stübner b++; 269d3e51161SHeiko Stübner 270d3e51161SHeiko Stübner return b; 271d3e51161SHeiko Stübner } 272d3e51161SHeiko Stübner 273d3e51161SHeiko Stübner static struct rockchip_pin_bank *bank_num_to_bank( 274d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 275d3e51161SHeiko Stübner unsigned num) 276d3e51161SHeiko Stübner { 277d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 278d3e51161SHeiko Stübner int i; 279d3e51161SHeiko Stübner 2801cb95395SAxel Lin for (i = 0; i < info->ctrl->nr_banks; i++, b++) { 281d3e51161SHeiko Stübner if (b->bank_num == num) 2821cb95395SAxel Lin return b; 283d3e51161SHeiko Stübner } 284d3e51161SHeiko Stübner 285d3e51161SHeiko Stübner return ERR_PTR(-EINVAL); 286d3e51161SHeiko Stübner } 287d3e51161SHeiko Stübner 288d3e51161SHeiko Stübner /* 289d3e51161SHeiko Stübner * Pinctrl_ops handling 290d3e51161SHeiko Stübner */ 291d3e51161SHeiko Stübner 292d3e51161SHeiko Stübner static int rockchip_get_groups_count(struct pinctrl_dev *pctldev) 293d3e51161SHeiko Stübner { 294d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 295d3e51161SHeiko Stübner 296d3e51161SHeiko Stübner return info->ngroups; 297d3e51161SHeiko Stübner } 298d3e51161SHeiko Stübner 299d3e51161SHeiko Stübner static const char *rockchip_get_group_name(struct pinctrl_dev *pctldev, 300d3e51161SHeiko Stübner unsigned selector) 301d3e51161SHeiko Stübner { 302d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 303d3e51161SHeiko Stübner 304d3e51161SHeiko Stübner return info->groups[selector].name; 305d3e51161SHeiko Stübner } 306d3e51161SHeiko Stübner 307d3e51161SHeiko Stübner static int rockchip_get_group_pins(struct pinctrl_dev *pctldev, 308d3e51161SHeiko Stübner unsigned selector, const unsigned **pins, 309d3e51161SHeiko Stübner unsigned *npins) 310d3e51161SHeiko Stübner { 311d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 312d3e51161SHeiko Stübner 313d3e51161SHeiko Stübner if (selector >= info->ngroups) 314d3e51161SHeiko Stübner return -EINVAL; 315d3e51161SHeiko Stübner 316d3e51161SHeiko Stübner *pins = info->groups[selector].pins; 317d3e51161SHeiko Stübner *npins = info->groups[selector].npins; 318d3e51161SHeiko Stübner 319d3e51161SHeiko Stübner return 0; 320d3e51161SHeiko Stübner } 321d3e51161SHeiko Stübner 322d3e51161SHeiko Stübner static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev, 323d3e51161SHeiko Stübner struct device_node *np, 324d3e51161SHeiko Stübner struct pinctrl_map **map, unsigned *num_maps) 325d3e51161SHeiko Stübner { 326d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 327d3e51161SHeiko Stübner const struct rockchip_pin_group *grp; 328e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 329d3e51161SHeiko Stübner struct pinctrl_map *new_map; 330d3e51161SHeiko Stübner struct device_node *parent; 331d3e51161SHeiko Stübner int map_num = 1; 332d3e51161SHeiko Stübner int i; 333d3e51161SHeiko Stübner 334d3e51161SHeiko Stübner /* 335d3e51161SHeiko Stübner * first find the group of this node and check if we need to create 336d3e51161SHeiko Stübner * config maps for pins 337d3e51161SHeiko Stübner */ 338d3e51161SHeiko Stübner grp = pinctrl_name_to_group(info, np->name); 339d3e51161SHeiko Stübner if (!grp) { 340e4dd7fd5SAndy Shevchenko dev_err(dev, "unable to find group for node %pOFn\n", np); 341d3e51161SHeiko Stübner return -EINVAL; 342d3e51161SHeiko Stübner } 343d3e51161SHeiko Stübner 344d3e51161SHeiko Stübner map_num += grp->npins; 345d7faa8ffSDafna Hirschfeld 346d7faa8ffSDafna Hirschfeld new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL); 347d3e51161SHeiko Stübner if (!new_map) 348d3e51161SHeiko Stübner return -ENOMEM; 349d3e51161SHeiko Stübner 350d3e51161SHeiko Stübner *map = new_map; 351d3e51161SHeiko Stübner *num_maps = map_num; 352d3e51161SHeiko Stübner 353d3e51161SHeiko Stübner /* create mux map */ 354d3e51161SHeiko Stübner parent = of_get_parent(np); 355d3e51161SHeiko Stübner if (!parent) { 356d7faa8ffSDafna Hirschfeld kfree(new_map); 357d3e51161SHeiko Stübner return -EINVAL; 358d3e51161SHeiko Stübner } 359d3e51161SHeiko Stübner new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; 360d3e51161SHeiko Stübner new_map[0].data.mux.function = parent->name; 361d3e51161SHeiko Stübner new_map[0].data.mux.group = np->name; 362d3e51161SHeiko Stübner of_node_put(parent); 363d3e51161SHeiko Stübner 364d3e51161SHeiko Stübner /* create config map */ 365d3e51161SHeiko Stübner new_map++; 366d3e51161SHeiko Stübner for (i = 0; i < grp->npins; i++) { 367d3e51161SHeiko Stübner new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; 368d3e51161SHeiko Stübner new_map[i].data.configs.group_or_pin = 369d3e51161SHeiko Stübner pin_get_name(pctldev, grp->pins[i]); 370d3e51161SHeiko Stübner new_map[i].data.configs.configs = grp->data[i].configs; 371d3e51161SHeiko Stübner new_map[i].data.configs.num_configs = grp->data[i].nconfigs; 372d3e51161SHeiko Stübner } 373d3e51161SHeiko Stübner 374e4dd7fd5SAndy Shevchenko dev_dbg(dev, "maps: function %s group %s num %d\n", 375d3e51161SHeiko Stübner (*map)->data.mux.function, (*map)->data.mux.group, map_num); 376d3e51161SHeiko Stübner 377d3e51161SHeiko Stübner return 0; 378d3e51161SHeiko Stübner } 379d3e51161SHeiko Stübner 380d3e51161SHeiko Stübner static void rockchip_dt_free_map(struct pinctrl_dev *pctldev, 381d3e51161SHeiko Stübner struct pinctrl_map *map, unsigned num_maps) 382d3e51161SHeiko Stübner { 383d7faa8ffSDafna Hirschfeld kfree(map); 384d3e51161SHeiko Stübner } 385d3e51161SHeiko Stübner 386d3e51161SHeiko Stübner static const struct pinctrl_ops rockchip_pctrl_ops = { 387d3e51161SHeiko Stübner .get_groups_count = rockchip_get_groups_count, 388d3e51161SHeiko Stübner .get_group_name = rockchip_get_group_name, 389d3e51161SHeiko Stübner .get_group_pins = rockchip_get_group_pins, 390d3e51161SHeiko Stübner .dt_node_to_map = rockchip_dt_node_to_map, 391d3e51161SHeiko Stübner .dt_free_map = rockchip_dt_free_map, 392d3e51161SHeiko Stübner }; 393d3e51161SHeiko Stübner 394d3e51161SHeiko Stübner /* 395d3e51161SHeiko Stübner * Hardware access 396d3e51161SHeiko Stübner */ 397d3e51161SHeiko Stübner 39812b8f018SDavid Wu static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = { 39912b8f018SDavid Wu { 40012b8f018SDavid Wu .num = 1, 40112b8f018SDavid Wu .pin = 0, 40212b8f018SDavid Wu .reg = 0x418, 40312b8f018SDavid Wu .bit = 0, 40412b8f018SDavid Wu .mask = 0x3 40512b8f018SDavid Wu }, { 40612b8f018SDavid Wu .num = 1, 40712b8f018SDavid Wu .pin = 1, 40812b8f018SDavid Wu .reg = 0x418, 40912b8f018SDavid Wu .bit = 2, 41012b8f018SDavid Wu .mask = 0x3 41112b8f018SDavid Wu }, { 41212b8f018SDavid Wu .num = 1, 41312b8f018SDavid Wu .pin = 2, 41412b8f018SDavid Wu .reg = 0x418, 41512b8f018SDavid Wu .bit = 4, 41612b8f018SDavid Wu .mask = 0x3 41712b8f018SDavid Wu }, { 41812b8f018SDavid Wu .num = 1, 41912b8f018SDavid Wu .pin = 3, 42012b8f018SDavid Wu .reg = 0x418, 42112b8f018SDavid Wu .bit = 6, 42212b8f018SDavid Wu .mask = 0x3 42312b8f018SDavid Wu }, { 42412b8f018SDavid Wu .num = 1, 42512b8f018SDavid Wu .pin = 4, 42612b8f018SDavid Wu .reg = 0x418, 42712b8f018SDavid Wu .bit = 8, 42812b8f018SDavid Wu .mask = 0x3 42912b8f018SDavid Wu }, { 43012b8f018SDavid Wu .num = 1, 43112b8f018SDavid Wu .pin = 5, 43212b8f018SDavid Wu .reg = 0x418, 43312b8f018SDavid Wu .bit = 10, 43412b8f018SDavid Wu .mask = 0x3 43512b8f018SDavid Wu }, { 43612b8f018SDavid Wu .num = 1, 43712b8f018SDavid Wu .pin = 6, 43812b8f018SDavid Wu .reg = 0x418, 43912b8f018SDavid Wu .bit = 12, 44012b8f018SDavid Wu .mask = 0x3 44112b8f018SDavid Wu }, { 44212b8f018SDavid Wu .num = 1, 44312b8f018SDavid Wu .pin = 7, 44412b8f018SDavid Wu .reg = 0x418, 44512b8f018SDavid Wu .bit = 14, 44612b8f018SDavid Wu .mask = 0x3 44712b8f018SDavid Wu }, { 44812b8f018SDavid Wu .num = 1, 44912b8f018SDavid Wu .pin = 8, 45012b8f018SDavid Wu .reg = 0x41c, 45112b8f018SDavid Wu .bit = 0, 45212b8f018SDavid Wu .mask = 0x3 45312b8f018SDavid Wu }, { 45412b8f018SDavid Wu .num = 1, 45512b8f018SDavid Wu .pin = 9, 45612b8f018SDavid Wu .reg = 0x41c, 45712b8f018SDavid Wu .bit = 2, 45812b8f018SDavid Wu .mask = 0x3 45912b8f018SDavid Wu }, 46012b8f018SDavid Wu }; 46112b8f018SDavid Wu 462fd4ea486SJagan Teki static struct rockchip_mux_recalced_data rv1126_mux_recalced_data[] = { 463fd4ea486SJagan Teki { 464fd4ea486SJagan Teki .num = 0, 465fd4ea486SJagan Teki .pin = 20, 466fd4ea486SJagan Teki .reg = 0x10000, 467fd4ea486SJagan Teki .bit = 0, 468fd4ea486SJagan Teki .mask = 0xf 469fd4ea486SJagan Teki }, 470fd4ea486SJagan Teki { 471fd4ea486SJagan Teki .num = 0, 472fd4ea486SJagan Teki .pin = 21, 473fd4ea486SJagan Teki .reg = 0x10000, 474fd4ea486SJagan Teki .bit = 4, 475fd4ea486SJagan Teki .mask = 0xf 476fd4ea486SJagan Teki }, 477fd4ea486SJagan Teki { 478fd4ea486SJagan Teki .num = 0, 479fd4ea486SJagan Teki .pin = 22, 480fd4ea486SJagan Teki .reg = 0x10000, 481fd4ea486SJagan Teki .bit = 8, 482fd4ea486SJagan Teki .mask = 0xf 483fd4ea486SJagan Teki }, 484fd4ea486SJagan Teki { 485fd4ea486SJagan Teki .num = 0, 486fd4ea486SJagan Teki .pin = 23, 487fd4ea486SJagan Teki .reg = 0x10000, 488fd4ea486SJagan Teki .bit = 12, 489fd4ea486SJagan Teki .mask = 0xf 490fd4ea486SJagan Teki }, 491fd4ea486SJagan Teki }; 492fd4ea486SJagan Teki 493d23c66dfSDavid Wu static struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = { 494d23c66dfSDavid Wu { 495d23c66dfSDavid Wu .num = 2, 496d23c66dfSDavid Wu .pin = 20, 497d23c66dfSDavid Wu .reg = 0xe8, 498d23c66dfSDavid Wu .bit = 0, 499d23c66dfSDavid Wu .mask = 0x7 500d23c66dfSDavid Wu }, { 501d23c66dfSDavid Wu .num = 2, 502d23c66dfSDavid Wu .pin = 21, 503d23c66dfSDavid Wu .reg = 0xe8, 504d23c66dfSDavid Wu .bit = 4, 505d23c66dfSDavid Wu .mask = 0x7 506d23c66dfSDavid Wu }, { 507d23c66dfSDavid Wu .num = 2, 508d23c66dfSDavid Wu .pin = 22, 509d23c66dfSDavid Wu .reg = 0xe8, 510d23c66dfSDavid Wu .bit = 8, 511d23c66dfSDavid Wu .mask = 0x7 512d23c66dfSDavid Wu }, { 513d23c66dfSDavid Wu .num = 2, 514d23c66dfSDavid Wu .pin = 23, 515d23c66dfSDavid Wu .reg = 0xe8, 516d23c66dfSDavid Wu .bit = 12, 517d23c66dfSDavid Wu .mask = 0x7 518d23c66dfSDavid Wu }, { 519d23c66dfSDavid Wu .num = 2, 520d23c66dfSDavid Wu .pin = 24, 521d23c66dfSDavid Wu .reg = 0xd4, 522d23c66dfSDavid Wu .bit = 12, 523d23c66dfSDavid Wu .mask = 0x7 524d23c66dfSDavid Wu }, 525d23c66dfSDavid Wu }; 526d23c66dfSDavid Wu 5277825aeb7SJianqun Xu static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { 5287825aeb7SJianqun Xu { 5291f3e25a0SLuca Ceresoli /* gpio1b6_sel */ 5307825aeb7SJianqun Xu .num = 1, 5317825aeb7SJianqun Xu .pin = 14, 5327825aeb7SJianqun Xu .reg = 0x28, 5337825aeb7SJianqun Xu .bit = 12, 5347825aeb7SJianqun Xu .mask = 0xf 5357825aeb7SJianqun Xu }, { 5361f3e25a0SLuca Ceresoli /* gpio1b7_sel */ 5377825aeb7SJianqun Xu .num = 1, 5387825aeb7SJianqun Xu .pin = 15, 5397825aeb7SJianqun Xu .reg = 0x2c, 5407825aeb7SJianqun Xu .bit = 0, 5417825aeb7SJianqun Xu .mask = 0x3 5427825aeb7SJianqun Xu }, { 5431f3e25a0SLuca Ceresoli /* gpio1c2_sel */ 5447825aeb7SJianqun Xu .num = 1, 5457825aeb7SJianqun Xu .pin = 18, 5467825aeb7SJianqun Xu .reg = 0x30, 5477825aeb7SJianqun Xu .bit = 4, 5487825aeb7SJianqun Xu .mask = 0xf 5497825aeb7SJianqun Xu }, { 5501f3e25a0SLuca Ceresoli /* gpio1c3_sel */ 5517825aeb7SJianqun Xu .num = 1, 5527825aeb7SJianqun Xu .pin = 19, 5537825aeb7SJianqun Xu .reg = 0x30, 5547825aeb7SJianqun Xu .bit = 8, 5557825aeb7SJianqun Xu .mask = 0xf 5567825aeb7SJianqun Xu }, { 5571f3e25a0SLuca Ceresoli /* gpio1c4_sel */ 5587825aeb7SJianqun Xu .num = 1, 5597825aeb7SJianqun Xu .pin = 20, 5607825aeb7SJianqun Xu .reg = 0x30, 5617825aeb7SJianqun Xu .bit = 12, 5627825aeb7SJianqun Xu .mask = 0xf 5637825aeb7SJianqun Xu }, { 5641f3e25a0SLuca Ceresoli /* gpio1c5_sel */ 5657825aeb7SJianqun Xu .num = 1, 5667825aeb7SJianqun Xu .pin = 21, 5677825aeb7SJianqun Xu .reg = 0x34, 5687825aeb7SJianqun Xu .bit = 0, 5697825aeb7SJianqun Xu .mask = 0xf 5707825aeb7SJianqun Xu }, { 5711f3e25a0SLuca Ceresoli /* gpio1c6_sel */ 5727825aeb7SJianqun Xu .num = 1, 5737825aeb7SJianqun Xu .pin = 22, 5747825aeb7SJianqun Xu .reg = 0x34, 5757825aeb7SJianqun Xu .bit = 4, 5767825aeb7SJianqun Xu .mask = 0xf 5777825aeb7SJianqun Xu }, { 5781f3e25a0SLuca Ceresoli /* gpio1c7_sel */ 5797825aeb7SJianqun Xu .num = 1, 5807825aeb7SJianqun Xu .pin = 23, 5817825aeb7SJianqun Xu .reg = 0x34, 5827825aeb7SJianqun Xu .bit = 8, 5837825aeb7SJianqun Xu .mask = 0xf 5847825aeb7SJianqun Xu }, { 5851f3e25a0SLuca Ceresoli /* gpio2a2_sel */ 5867825aeb7SJianqun Xu .num = 2, 5877825aeb7SJianqun Xu .pin = 2, 5881f3e25a0SLuca Ceresoli .reg = 0x40, 5891f3e25a0SLuca Ceresoli .bit = 4, 5901f3e25a0SLuca Ceresoli .mask = 0x3 5917825aeb7SJianqun Xu }, { 5921f3e25a0SLuca Ceresoli /* gpio2a3_sel */ 5937825aeb7SJianqun Xu .num = 2, 5947825aeb7SJianqun Xu .pin = 3, 5951f3e25a0SLuca Ceresoli .reg = 0x40, 5961f3e25a0SLuca Ceresoli .bit = 6, 5971f3e25a0SLuca Ceresoli .mask = 0x3 5987825aeb7SJianqun Xu }, { 5991f3e25a0SLuca Ceresoli /* gpio2c0_sel */ 6007825aeb7SJianqun Xu .num = 2, 6017825aeb7SJianqun Xu .pin = 16, 6021f3e25a0SLuca Ceresoli .reg = 0x50, 6031f3e25a0SLuca Ceresoli .bit = 0, 6041f3e25a0SLuca Ceresoli .mask = 0x3 6057825aeb7SJianqun Xu }, { 6061f3e25a0SLuca Ceresoli /* gpio3b2_sel */ 6077825aeb7SJianqun Xu .num = 3, 6087825aeb7SJianqun Xu .pin = 10, 6091f3e25a0SLuca Ceresoli .reg = 0x68, 6101f3e25a0SLuca Ceresoli .bit = 4, 6111f3e25a0SLuca Ceresoli .mask = 0x3 6127825aeb7SJianqun Xu }, { 6131f3e25a0SLuca Ceresoli /* gpio3b3_sel */ 6147825aeb7SJianqun Xu .num = 3, 6157825aeb7SJianqun Xu .pin = 11, 6161f3e25a0SLuca Ceresoli .reg = 0x68, 6171f3e25a0SLuca Ceresoli .bit = 6, 6181f3e25a0SLuca Ceresoli .mask = 0x3 6197c4cffc5SLuca Ceresoli }, { 6207c4cffc5SLuca Ceresoli /* gpio3b4_sel */ 6217825aeb7SJianqun Xu .num = 3, 6227825aeb7SJianqun Xu .pin = 12, 6237825aeb7SJianqun Xu .reg = 0x68, 6247825aeb7SJianqun Xu .bit = 8, 6257825aeb7SJianqun Xu .mask = 0xf 6267825aeb7SJianqun Xu }, { 6277c4cffc5SLuca Ceresoli /* gpio3b5_sel */ 6287825aeb7SJianqun Xu .num = 3, 6297825aeb7SJianqun Xu .pin = 13, 6307825aeb7SJianqun Xu .reg = 0x68, 6317825aeb7SJianqun Xu .bit = 12, 6327825aeb7SJianqun Xu .mask = 0xf 6337825aeb7SJianqun Xu }, 6347825aeb7SJianqun Xu }; 6357825aeb7SJianqun Xu 636c04c3fa6SDavid Wu static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = { 6373818e4a7Sdavid.wu { 6383818e4a7Sdavid.wu .num = 2, 6393818e4a7Sdavid.wu .pin = 12, 6403818e4a7Sdavid.wu .reg = 0x24, 6413818e4a7Sdavid.wu .bit = 8, 6423818e4a7Sdavid.wu .mask = 0x3 6433818e4a7Sdavid.wu }, { 6443818e4a7Sdavid.wu .num = 2, 6453818e4a7Sdavid.wu .pin = 15, 6463818e4a7Sdavid.wu .reg = 0x28, 6473818e4a7Sdavid.wu .bit = 0, 6483818e4a7Sdavid.wu .mask = 0x7 6493818e4a7Sdavid.wu }, { 6503818e4a7Sdavid.wu .num = 2, 6513818e4a7Sdavid.wu .pin = 23, 6523818e4a7Sdavid.wu .reg = 0x30, 6533818e4a7Sdavid.wu .bit = 14, 6543818e4a7Sdavid.wu .mask = 0x3 6553818e4a7Sdavid.wu }, 6563818e4a7Sdavid.wu }; 6573818e4a7Sdavid.wu 658c04c3fa6SDavid Wu static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin, 659c04c3fa6SDavid Wu int *reg, u8 *bit, int *mask) 6603818e4a7Sdavid.wu { 661c04c3fa6SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 662c04c3fa6SDavid Wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 663c04c3fa6SDavid Wu struct rockchip_mux_recalced_data *data; 6643818e4a7Sdavid.wu int i; 6653818e4a7Sdavid.wu 666c04c3fa6SDavid Wu for (i = 0; i < ctrl->niomux_recalced; i++) { 667c04c3fa6SDavid Wu data = &ctrl->iomux_recalced[i]; 668c04c3fa6SDavid Wu if (data->num == bank->bank_num && 669c04c3fa6SDavid Wu data->pin == pin) 6703818e4a7Sdavid.wu break; 6713818e4a7Sdavid.wu } 6723818e4a7Sdavid.wu 673c04c3fa6SDavid Wu if (i >= ctrl->niomux_recalced) 6743818e4a7Sdavid.wu return; 6753818e4a7Sdavid.wu 6763818e4a7Sdavid.wu *reg = data->reg; 6773818e4a7Sdavid.wu *mask = data->mask; 6783818e4a7Sdavid.wu *bit = data->bit; 6793818e4a7Sdavid.wu } 6803818e4a7Sdavid.wu 68187065ca9SDavid Wu static struct rockchip_mux_route_data px30_mux_route_data[] = { 682*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PB4, 1, 0x184, BIT(16 + 7)), /* cif-d0m0 */ 683*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PA1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d0m1 */ 684*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PB6, 1, 0x184, BIT(16 + 7)), /* cif-d1m0 */ 685*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PA2, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d1m1 */ 686fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */ 687fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */ 688*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x184, BIT(16 + 7)), /* cif-d3m0 */ 689*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PA5, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d3m1 */ 690*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PA2, 1, 0x184, BIT(16 + 7)), /* cif-d4m0 */ 691*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PA7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d4m1 */ 692*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PA3, 1, 0x184, BIT(16 + 7)), /* cif-d5m0 */ 693*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PB0, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d5m1 */ 694*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PA4, 1, 0x184, BIT(16 + 7)), /* cif-d6m0 */ 695*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PB1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d6m1 */ 696*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PA5, 1, 0x184, BIT(16 + 7)), /* cif-d7m0 */ 697*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PB4, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d7m1 */ 698*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PA6, 1, 0x184, BIT(16 + 7)), /* cif-d8m0 */ 699*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PB6, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d8m1 */ 700*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PA7, 1, 0x184, BIT(16 + 7)), /* cif-d9m0 */ 701*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PB7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d9m1 */ 702*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PB7, 1, 0x184, BIT(16 + 7)), /* cif-d10m0 */ 703*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PC6, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d10m1 */ 704*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PC0, 1, 0x184, BIT(16 + 7)), /* cif-d11m0 */ 705*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PC7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d11m1 */ 706*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PB0, 1, 0x184, BIT(16 + 7)), /* cif-vsyncm0 */ 707*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PD1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-vsyncm1 */ 708*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PB1, 1, 0x184, BIT(16 + 7)), /* cif-hrefm0 */ 709*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PD2, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-hrefm1 */ 710*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PB2, 1, 0x184, BIT(16 + 7)), /* cif-clkinm0 */ 711*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PD3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-clkinm1 */ 712*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PB3, 1, 0x184, BIT(16 + 7)), /* cif-clkoutm0 */ 713*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PD0, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-clkoutm1 */ 714fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */ 715fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */ 716*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(3, RK_PD3, 2, 0x184, BIT(16 + 8)), /* pdm-sdi0m0 */ 717*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PC5, 2, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-sdi0m1 */ 718fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */ 719fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */ 720*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(1, RK_PD2, 2, 0x184, BIT(16 + 10)), /* uart2-txm0 */ 721*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(2, RK_PB4, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-txm1 */ 722fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */ 723fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */ 724*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(0, RK_PC0, 2, 0x184, BIT(16 + 9)), /* uart3-txm0 */ 725*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-txm1 */ 726*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(0, RK_PC2, 2, 0x184, BIT(16 + 9)), /* uart3-ctsm0 */ 727*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-ctsm1 */ 728*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(0, RK_PC3, 2, 0x184, BIT(16 + 9)), /* uart3-rtsm0 */ 729*bee55f2eSQuentin Schulz RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rtsm1 */ 73087065ca9SDavid Wu }; 73187065ca9SDavid Wu 732fd4ea486SJagan Teki static struct rockchip_mux_route_data rv1126_mux_route_data[] = { 733fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PD2, 1, 0x10260, WRITE_MASK_VAL(0, 0, 0)), /* I2S0_MCLK_M0 */ 734fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PB0, 3, 0x10260, WRITE_MASK_VAL(0, 0, 1)), /* I2S0_MCLK_M1 */ 735fd4ea486SJagan Teki 736fd4ea486SJagan Teki RK_MUXROUTE_GRF(0, RK_PD4, 4, 0x10260, WRITE_MASK_VAL(3, 2, 0)), /* I2S1_MCLK_M0 */ 737fd4ea486SJagan Teki RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x10260, WRITE_MASK_VAL(3, 2, 1)), /* I2S1_MCLK_M1 */ 738fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PC7, 6, 0x10260, WRITE_MASK_VAL(3, 2, 2)), /* I2S1_MCLK_M2 */ 739fd4ea486SJagan Teki 740fd4ea486SJagan Teki RK_MUXROUTE_GRF(1, RK_PD0, 1, 0x10260, WRITE_MASK_VAL(4, 4, 0)), /* I2S2_MCLK_M0 */ 741fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PB3, 2, 0x10260, WRITE_MASK_VAL(4, 4, 1)), /* I2S2_MCLK_M1 */ 742fd4ea486SJagan Teki 743fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PD4, 2, 0x10260, WRITE_MASK_VAL(12, 12, 0)), /* PDM_CLK0_M0 */ 744fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PC0, 3, 0x10260, WRITE_MASK_VAL(12, 12, 1)), /* PDM_CLK0_M1 */ 745fd4ea486SJagan Teki 746fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PC6, 1, 0x10264, WRITE_MASK_VAL(0, 0, 0)), /* CIF_CLKOUT_M0 */ 747fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PD1, 3, 0x10264, WRITE_MASK_VAL(0, 0, 1)), /* CIF_CLKOUT_M1 */ 748fd4ea486SJagan Teki 749fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA4, 5, 0x10264, WRITE_MASK_VAL(5, 4, 0)), /* I2C3_SCL_M0 */ 750fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PD4, 7, 0x10264, WRITE_MASK_VAL(5, 4, 1)), /* I2C3_SCL_M1 */ 751fd4ea486SJagan Teki RK_MUXROUTE_GRF(1, RK_PD6, 3, 0x10264, WRITE_MASK_VAL(5, 4, 2)), /* I2C3_SCL_M2 */ 752fd4ea486SJagan Teki 753fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA0, 7, 0x10264, WRITE_MASK_VAL(6, 6, 0)), /* I2C4_SCL_M0 */ 754fd4ea486SJagan Teki RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x10264, WRITE_MASK_VAL(6, 6, 1)), /* I2C4_SCL_M1 */ 755fd4ea486SJagan Teki 756fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PA5, 7, 0x10264, WRITE_MASK_VAL(9, 8, 0)), /* I2C5_SCL_M0 */ 757fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PB0, 5, 0x10264, WRITE_MASK_VAL(9, 8, 1)), /* I2C5_SCL_M1 */ 758fd4ea486SJagan Teki RK_MUXROUTE_GRF(1, RK_PD0, 4, 0x10264, WRITE_MASK_VAL(9, 8, 2)), /* I2C5_SCL_M2 */ 759fd4ea486SJagan Teki 760fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PC0, 5, 0x10264, WRITE_MASK_VAL(11, 10, 0)), /* SPI1_CLK_M0 */ 761fd4ea486SJagan Teki RK_MUXROUTE_GRF(1, RK_PC6, 3, 0x10264, WRITE_MASK_VAL(11, 10, 1)), /* SPI1_CLK_M1 */ 762fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PD5, 6, 0x10264, WRITE_MASK_VAL(11, 10, 2)), /* SPI1_CLK_M2 */ 763fd4ea486SJagan Teki 764fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x10264, WRITE_MASK_VAL(12, 12, 0)), /* RGMII_CLK_M0 */ 765fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PB7, 2, 0x10264, WRITE_MASK_VAL(12, 12, 1)), /* RGMII_CLK_M1 */ 766fd4ea486SJagan Teki 767fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA1, 3, 0x10264, WRITE_MASK_VAL(13, 13, 0)), /* CAN_TXD_M0 */ 768fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA7, 5, 0x10264, WRITE_MASK_VAL(13, 13, 1)), /* CAN_TXD_M1 */ 769fd4ea486SJagan Teki 770fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA4, 6, 0x10268, WRITE_MASK_VAL(0, 0, 0)), /* PWM8_M0 */ 771fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PD7, 5, 0x10268, WRITE_MASK_VAL(0, 0, 1)), /* PWM8_M1 */ 772fd4ea486SJagan Teki 773fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA5, 6, 0x10268, WRITE_MASK_VAL(2, 2, 0)), /* PWM9_M0 */ 774fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PD6, 5, 0x10268, WRITE_MASK_VAL(2, 2, 1)), /* PWM9_M1 */ 775fd4ea486SJagan Teki 776fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA6, 6, 0x10268, WRITE_MASK_VAL(4, 4, 0)), /* PWM10_M0 */ 777fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PD5, 5, 0x10268, WRITE_MASK_VAL(4, 4, 1)), /* PWM10_M1 */ 778fd4ea486SJagan Teki 779fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA7, 6, 0x10268, WRITE_MASK_VAL(6, 6, 0)), /* PWM11_IR_M0 */ 780fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA1, 5, 0x10268, WRITE_MASK_VAL(6, 6, 1)), /* PWM11_IR_M1 */ 781fd4ea486SJagan Teki 782fd4ea486SJagan Teki RK_MUXROUTE_GRF(1, RK_PA5, 3, 0x10268, WRITE_MASK_VAL(8, 8, 0)), /* UART2_TX_M0 */ 783fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA2, 1, 0x10268, WRITE_MASK_VAL(8, 8, 1)), /* UART2_TX_M1 */ 784fd4ea486SJagan Teki 785fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PC6, 3, 0x10268, WRITE_MASK_VAL(11, 10, 0)), /* UART3_TX_M0 */ 786fd4ea486SJagan Teki RK_MUXROUTE_GRF(1, RK_PA7, 2, 0x10268, WRITE_MASK_VAL(11, 10, 1)), /* UART3_TX_M1 */ 787fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA0, 4, 0x10268, WRITE_MASK_VAL(11, 10, 2)), /* UART3_TX_M2 */ 788fd4ea486SJagan Teki 789fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA4, 4, 0x10268, WRITE_MASK_VAL(13, 12, 0)), /* UART4_TX_M0 */ 790fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PA6, 4, 0x10268, WRITE_MASK_VAL(13, 12, 1)), /* UART4_TX_M1 */ 791fd4ea486SJagan Teki RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x10268, WRITE_MASK_VAL(13, 12, 2)), /* UART4_TX_M2 */ 792fd4ea486SJagan Teki 793fd4ea486SJagan Teki RK_MUXROUTE_GRF(3, RK_PA6, 4, 0x10268, WRITE_MASK_VAL(15, 14, 0)), /* UART5_TX_M0 */ 794fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PB0, 4, 0x10268, WRITE_MASK_VAL(15, 14, 1)), /* UART5_TX_M1 */ 795fd4ea486SJagan Teki RK_MUXROUTE_GRF(2, RK_PA0, 3, 0x10268, WRITE_MASK_VAL(15, 14, 2)), /* UART5_TX_M2 */ 796fd4ea486SJagan Teki 797fd4ea486SJagan Teki RK_MUXROUTE_PMU(0, RK_PB6, 3, 0x0114, WRITE_MASK_VAL(0, 0, 0)), /* PWM0_M0 */ 798fd4ea486SJagan Teki RK_MUXROUTE_PMU(2, RK_PB3, 5, 0x0114, WRITE_MASK_VAL(0, 0, 1)), /* PWM0_M1 */ 799fd4ea486SJagan Teki 800fd4ea486SJagan Teki RK_MUXROUTE_PMU(0, RK_PB7, 3, 0x0114, WRITE_MASK_VAL(2, 2, 0)), /* PWM1_M0 */ 801fd4ea486SJagan Teki RK_MUXROUTE_PMU(2, RK_PB2, 5, 0x0114, WRITE_MASK_VAL(2, 2, 1)), /* PWM1_M1 */ 802fd4ea486SJagan Teki 803fd4ea486SJagan Teki RK_MUXROUTE_PMU(0, RK_PC0, 3, 0x0114, WRITE_MASK_VAL(4, 4, 0)), /* PWM2_M0 */ 804fd4ea486SJagan Teki RK_MUXROUTE_PMU(2, RK_PB1, 5, 0x0114, WRITE_MASK_VAL(4, 4, 1)), /* PWM2_M1 */ 805fd4ea486SJagan Teki 806fd4ea486SJagan Teki RK_MUXROUTE_PMU(0, RK_PC1, 3, 0x0114, WRITE_MASK_VAL(6, 6, 0)), /* PWM3_IR_M0 */ 807fd4ea486SJagan Teki RK_MUXROUTE_PMU(2, RK_PB0, 5, 0x0114, WRITE_MASK_VAL(6, 6, 1)), /* PWM3_IR_M1 */ 808fd4ea486SJagan Teki 809fd4ea486SJagan Teki RK_MUXROUTE_PMU(0, RK_PC2, 3, 0x0114, WRITE_MASK_VAL(8, 8, 0)), /* PWM4_M0 */ 810fd4ea486SJagan Teki RK_MUXROUTE_PMU(2, RK_PA7, 5, 0x0114, WRITE_MASK_VAL(8, 8, 1)), /* PWM4_M1 */ 811fd4ea486SJagan Teki 812fd4ea486SJagan Teki RK_MUXROUTE_PMU(0, RK_PC3, 3, 0x0114, WRITE_MASK_VAL(10, 10, 0)), /* PWM5_M0 */ 813fd4ea486SJagan Teki RK_MUXROUTE_PMU(2, RK_PA6, 5, 0x0114, WRITE_MASK_VAL(10, 10, 1)), /* PWM5_M1 */ 814fd4ea486SJagan Teki 815fd4ea486SJagan Teki RK_MUXROUTE_PMU(0, RK_PB2, 3, 0x0114, WRITE_MASK_VAL(12, 12, 0)), /* PWM6_M0 */ 816fd4ea486SJagan Teki RK_MUXROUTE_PMU(2, RK_PD4, 5, 0x0114, WRITE_MASK_VAL(12, 12, 1)), /* PWM6_M1 */ 817fd4ea486SJagan Teki 818fd4ea486SJagan Teki RK_MUXROUTE_PMU(0, RK_PB1, 3, 0x0114, WRITE_MASK_VAL(14, 14, 0)), /* PWM7_IR_M0 */ 819fd4ea486SJagan Teki RK_MUXROUTE_PMU(3, RK_PA0, 5, 0x0114, WRITE_MASK_VAL(14, 14, 1)), /* PWM7_IR_M1 */ 820fd4ea486SJagan Teki 821fd4ea486SJagan Teki RK_MUXROUTE_PMU(0, RK_PB0, 1, 0x0118, WRITE_MASK_VAL(1, 0, 0)), /* SPI0_CLK_M0 */ 822fd4ea486SJagan Teki RK_MUXROUTE_PMU(2, RK_PA1, 1, 0x0118, WRITE_MASK_VAL(1, 0, 1)), /* SPI0_CLK_M1 */ 823fd4ea486SJagan Teki RK_MUXROUTE_PMU(2, RK_PB2, 6, 0x0118, WRITE_MASK_VAL(1, 0, 2)), /* SPI0_CLK_M2 */ 824fd4ea486SJagan Teki 825fd4ea486SJagan Teki RK_MUXROUTE_PMU(0, RK_PB6, 2, 0x0118, WRITE_MASK_VAL(2, 2, 0)), /* UART1_TX_M0 */ 826fd4ea486SJagan Teki RK_MUXROUTE_PMU(1, RK_PD0, 5, 0x0118, WRITE_MASK_VAL(2, 2, 1)), /* UART1_TX_M1 */ 827fd4ea486SJagan Teki }; 828fd4ea486SJagan Teki 829d23c66dfSDavid Wu static struct rockchip_mux_route_data rk3128_mux_route_data[] = { 830fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x144, BIT(16 + 3) | BIT(16 + 4)), /* spi-0 */ 831fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PD3, 3, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(3)), /* spi-1 */ 832fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(4)), /* spi-2 */ 833fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA5, 1, 0x144, BIT(16 + 5)), /* i2s-0 */ 834fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB6, 1, 0x144, BIT(16 + 5) | BIT(5)), /* i2s-1 */ 835fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x144, BIT(16 + 6)), /* emmc-0 */ 836fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x144, BIT(16 + 6) | BIT(6)), /* emmc-1 */ 837d23c66dfSDavid Wu }; 838d23c66dfSDavid Wu 839ada62b7cSHeiko Stuebner static struct rockchip_mux_route_data rk3188_mux_route_data[] = { 840fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */ 841fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */ 842ada62b7cSHeiko Stuebner }; 843ada62b7cSHeiko Stuebner 844d4970ee0SDavid Wu static struct rockchip_mux_route_data rk3228_mux_route_data[] = { 845fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD2, 1, 0x50, BIT(16)), /* pwm0-0 */ 846fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PC5, 1, 0x50, BIT(16) | BIT(0)), /* pwm0-1 */ 847fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD3, 1, 0x50, BIT(16 + 1)), /* pwm1-0 */ 848fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD6, 2, 0x50, BIT(16 + 1) | BIT(1)), /* pwm1-1 */ 849fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD4, 1, 0x50, BIT(16 + 2)), /* pwm2-0 */ 850fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x50, BIT(16 + 2) | BIT(2)), /* pwm2-1 */ 851fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PD2, 1, 0x50, BIT(16 + 3)), /* pwm3-0 */ 852fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 3) | BIT(3)), /* pwm3-1 */ 853fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA1, 1, 0x50, BIT(16 + 4)), /* sdio-0_d0 */ 854fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA2, 1, 0x50, BIT(16 + 4) | BIT(4)), /* sdio-1_d0 */ 855fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x50, BIT(16 + 5)), /* spi-0_rx */ 856fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA0, 2, 0x50, BIT(16 + 5) | BIT(5)), /* spi-1_rx */ 857fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x50, BIT(16 + 7)), /* emmc-0_cmd */ 858fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x50, BIT(16 + 7) | BIT(7)), /* emmc-1_cmd */ 859fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC3, 2, 0x50, BIT(16 + 8)), /* uart2-0_rx */ 860fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB2, 2, 0x50, BIT(16 + 8) | BIT(8)), /* uart2-1_rx */ 861fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x50, BIT(16 + 11)), /* uart1-0_rx */ 862fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB5, 1, 0x50, BIT(16 + 11) | BIT(11)), /* uart1-1_rx */ 863d4970ee0SDavid Wu }; 864d4970ee0SDavid Wu 8654e96fd30SHeiko Stuebner static struct rockchip_mux_route_data rk3288_mux_route_data[] = { 866fe202ea8SJianqun Xu RK_MUXROUTE_SAME(7, RK_PC0, 2, 0x264, BIT(16 + 12) | BIT(12)), /* edphdmi_cecinoutt1 */ 867fe202ea8SJianqun Xu RK_MUXROUTE_SAME(7, RK_PC7, 4, 0x264, BIT(16 + 12)), /* edphdmi_cecinout */ 8684e96fd30SHeiko Stuebner }; 8694e96fd30SHeiko Stuebner 8707825aeb7SJianqun Xu static struct rockchip_mux_route_data rk3308_mux_route_data[] = { 871fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, BIT(16 + 0) | BIT(0)), /* rtc_clk */ 872fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, BIT(16 + 2) | BIT(16 + 3)), /* uart2_rxm0 */ 873fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, BIT(16 + 2) | BIT(16 + 3) | BIT(2)), /* uart2_rxm1 */ 874fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x608, BIT(16 + 8) | BIT(16 + 9)), /* i2c3_sdam0 */ 875fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(8)), /* i2c3_sdam1 */ 876fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA0, 3, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(9)), /* i2c3_sdam2 */ 877fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */ 878fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */ 879fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */ 880fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclkrxm1 */ 881fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, BIT(16 + 12) | BIT(16 + 13)), /* pdm-clkm0 */ 882fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */ 883fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */ 884fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */ 885fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB2, 3, 0x314, BIT(16 + 9)), /* spi1_miso */ 886fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x314, BIT(16 + 9) | BIT(9)), /* spi1_miso_m1 */ 887fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB3, 3, 0x314, BIT(16 + 10) | BIT(16 + 11)), /* owire_m0 */ 888fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 7, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* owire_m1 */ 889fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA2, 5, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* owire_m2 */ 890fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB3, 2, 0x314, BIT(16 + 12) | BIT(16 + 13)), /* can_rxd_m0 */ 891fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 5, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* can_rxd_m1 */ 892fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA2, 4, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* can_rxd_m2 */ 893fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC4, 3, 0x314, BIT(16 + 14)), /* mac_rxd0_m0 */ 894fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PA2, 2, 0x314, BIT(16 + 14) | BIT(14)), /* mac_rxd0_m1 */ 895fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB4, 4, 0x314, BIT(16 + 15)), /* uart3_rx */ 896fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PC1, 3, 0x314, BIT(16 + 15) | BIT(15)), /* uart3_rx_m1 */ 8977825aeb7SJianqun Xu }; 8987825aeb7SJianqun Xu 899cedc964aSDavid Wu static struct rockchip_mux_route_data rk3328_mux_route_data[] = { 900fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA1, 2, 0x50, BIT(16) | BIT(16 + 1)), /* uart2dbg_rxm0 */ 901fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x50, BIT(16) | BIT(16 + 1) | BIT(0)), /* uart2dbg_rxm1 */ 902fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 2) | BIT(2)), /* gmac-m1_rxd0 */ 903fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x50, BIT(16 + 10) | BIT(10)), /* gmac-m1-optimized_rxd3 */ 904fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC3, 2, 0x50, BIT(16 + 3)), /* pdm_sdi0m0 */ 905fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC7, 3, 0x50, BIT(16 + 3) | BIT(3)), /* pdm_sdi0m1 */ 906fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA2, 4, 0x50, BIT(16 + 4) | BIT(16 + 5) | BIT(5)), /* spi_rxdm2 */ 907fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PD0, 1, 0x50, BIT(16 + 6)), /* i2s2_sdim0 */ 908fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA2, 6, 0x50, BIT(16 + 6) | BIT(6)), /* i2s2_sdim1 */ 909fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC6, 3, 0x50, BIT(16 + 7) | BIT(7)), /* card_iom1 */ 910fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC0, 3, 0x50, BIT(16 + 8) | BIT(8)), /* tsp_d5m1 */ 911fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC0, 4, 0x50, BIT(16 + 9) | BIT(9)), /* cif_data5m1 */ 912cedc964aSDavid Wu }; 913cedc964aSDavid Wu 914accc1ce7SDavid Wu static struct rockchip_mux_route_data rk3399_mux_route_data[] = { 915fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PB0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11)), /* uart2dbga_rx */ 916fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PC0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* uart2dbgb_rx */ 917fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PC3, 1, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* uart2dbgc_rx */ 918fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PD2, 2, 0xe21c, BIT(16 + 14)), /* pcie_clkreqn */ 919fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PD0, 1, 0xe21c, BIT(16 + 14) | BIT(14)), /* pcie_clkreqnb */ 920accc1ce7SDavid Wu }; 921accc1ce7SDavid Wu 922c0dadc0eSJianqun Xu static struct rockchip_mux_route_data rk3568_mux_route_data[] = { 923c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */ 924c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */ 925c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */ 926c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */ 927c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */ 928c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */ 929c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ 930c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */ 931c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */ 932c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */ 933c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */ 934c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */ 935c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */ 936c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ 937c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */ 938c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */ 939c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */ 940c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ 941c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ 942c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */ 943c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */ 944c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */ 945c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */ 946c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */ 947c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */ 948c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */ 949c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */ 950c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */ 951c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */ 952c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */ 953c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */ 954c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */ 955c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */ 956c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */ 957c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */ 958c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */ 959c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */ 960c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */ 961c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */ 962c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */ 963c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */ 964c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */ 965c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */ 966c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */ 967c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ 968c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */ 969c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */ 970c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */ 971c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */ 972c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */ 973c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */ 974c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */ 975c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */ 976c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ 977c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ 978c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */ 979c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */ 980c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */ 981c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */ 982c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */ 983c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */ 984c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */ 985c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */ 986c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */ 987c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */ 988c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */ 989c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */ 990c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */ 991c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */ 992c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */ 993c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */ 994c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */ 995c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */ 996c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */ 997c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */ 998c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */ 999c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */ 1000c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */ 1001c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */ 1002c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ 1003c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ 1004c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ 1005c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ 1006c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */ 1007c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ 1008c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */ 1009c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */ 1010c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ 1011c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */ 1012c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */ 1013c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ 1014c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */ 1015c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */ 1016d3e51161SHeiko Stübner }; 1017d3e51161SHeiko Stübner 1018bd35b9bfSDavid Wu static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, 101951ff47aaSHeiko Stuebner int mux, u32 *loc, u32 *reg, u32 *value) 1020bd35b9bfSDavid Wu { 1021bd35b9bfSDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 1022bd35b9bfSDavid Wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 1023bd35b9bfSDavid Wu struct rockchip_mux_route_data *data; 1024bd35b9bfSDavid Wu int i; 1025bd35b9bfSDavid Wu 1026bd35b9bfSDavid Wu for (i = 0; i < ctrl->niomux_routes; i++) { 1027bd35b9bfSDavid Wu data = &ctrl->iomux_routes[i]; 1028bd35b9bfSDavid Wu if ((data->bank_num == bank->bank_num) && 1029bd35b9bfSDavid Wu (data->pin == pin) && (data->func == mux)) 1030bd35b9bfSDavid Wu break; 1031bd35b9bfSDavid Wu } 1032bd35b9bfSDavid Wu 1033bd35b9bfSDavid Wu if (i >= ctrl->niomux_routes) 1034bd35b9bfSDavid Wu return false; 1035bd35b9bfSDavid Wu 103651ff47aaSHeiko Stuebner *loc = data->route_location; 1037bd35b9bfSDavid Wu *reg = data->route_offset; 1038bd35b9bfSDavid Wu *value = data->route_val; 1039bd35b9bfSDavid Wu 1040bd35b9bfSDavid Wu return true; 1041bd35b9bfSDavid Wu } 1042bd35b9bfSDavid Wu 1043a076e2edSHeiko Stübner static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) 1044a076e2edSHeiko Stübner { 1045a076e2edSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1046fdc33ebaSJianqun Xu struct rockchip_pin_ctrl *ctrl = info->ctrl; 1047fc72c923SHeiko Stübner int iomux_num = (pin / 8); 104895ec8ae4SHeiko Stübner struct regmap *regmap; 1049751a99abSHeiko Stübner unsigned int val; 1050ea262ad6Sdavid.wu int reg, ret, mask, mux_type; 1051a076e2edSHeiko Stübner u8 bit; 1052a076e2edSHeiko Stübner 1053fc72c923SHeiko Stübner if (iomux_num > 3) 1054fc72c923SHeiko Stübner return -EINVAL; 1055fc72c923SHeiko Stübner 105662f49226SHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 105762f49226SHeiko Stübner dev_err(info->dev, "pin %d is unrouted\n", pin); 105862f49226SHeiko Stübner return -EINVAL; 105962f49226SHeiko Stübner } 106062f49226SHeiko Stübner 1061fc72c923SHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 1062a076e2edSHeiko Stübner return RK_FUNC_GPIO; 1063a076e2edSHeiko Stübner 1064fd4ea486SJagan Teki if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 1065fd4ea486SJagan Teki regmap = info->regmap_pmu; 1066fd4ea486SJagan Teki else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU) 1067fd4ea486SJagan Teki regmap = (pin % 8 < 4) ? info->regmap_pmu : info->regmap_base; 1068fd4ea486SJagan Teki else 1069fd4ea486SJagan Teki regmap = info->regmap_base; 107095ec8ae4SHeiko Stübner 1071a076e2edSHeiko Stübner /* get basic quadrupel of mux registers and the correct reg inside */ 1072ea262ad6Sdavid.wu mux_type = bank->iomux[iomux_num].type; 10736bc0d121SHeiko Stübner reg = bank->iomux[iomux_num].offset; 1074ea262ad6Sdavid.wu if (mux_type & IOMUX_WIDTH_4BIT) { 107503716e1dSHeiko Stübner if ((pin % 8) >= 4) 107603716e1dSHeiko Stübner reg += 0x4; 107703716e1dSHeiko Stübner bit = (pin % 4) * 4; 10788b6c6f93Sdavid.wu mask = 0xf; 1079ea262ad6Sdavid.wu } else if (mux_type & IOMUX_WIDTH_3BIT) { 10808b6c6f93Sdavid.wu if ((pin % 8) >= 5) 10818b6c6f93Sdavid.wu reg += 0x4; 10828b6c6f93Sdavid.wu bit = (pin % 8 % 5) * 3; 10838b6c6f93Sdavid.wu mask = 0x7; 108403716e1dSHeiko Stübner } else { 1085a076e2edSHeiko Stübner bit = (pin % 8) * 2; 10868b6c6f93Sdavid.wu mask = 0x3; 108703716e1dSHeiko Stübner } 1088a076e2edSHeiko Stübner 1089c04c3fa6SDavid Wu if (bank->recalced_mask & BIT(pin)) 1090c04c3fa6SDavid Wu rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 1091ea262ad6Sdavid.wu 1092fdc33ebaSJianqun Xu if (ctrl->type == RK3588) { 1093fdc33ebaSJianqun Xu if (bank->bank_num == 0) { 1094fdc33ebaSJianqun Xu if ((pin >= RK_PB4) && (pin <= RK_PD7)) { 1095fdc33ebaSJianqun Xu u32 reg0 = 0; 1096fdc33ebaSJianqun Xu 1097fdc33ebaSJianqun Xu reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */ 1098fdc33ebaSJianqun Xu ret = regmap_read(regmap, reg0, &val); 1099fdc33ebaSJianqun Xu if (ret) 1100fdc33ebaSJianqun Xu return ret; 1101fdc33ebaSJianqun Xu 1102fdc33ebaSJianqun Xu if (!(val & BIT(8))) 1103fdc33ebaSJianqun Xu return ((val >> bit) & mask); 1104fdc33ebaSJianqun Xu 1105fdc33ebaSJianqun Xu reg = reg + 0x8000; /* BUS_IOC_BASE */ 1106fdc33ebaSJianqun Xu regmap = info->regmap_base; 1107fdc33ebaSJianqun Xu } 1108fdc33ebaSJianqun Xu } else if (bank->bank_num > 0) { 1109fdc33ebaSJianqun Xu reg += 0x8000; /* BUS_IOC_BASE */ 1110fdc33ebaSJianqun Xu } 1111fdc33ebaSJianqun Xu } 1112fdc33ebaSJianqun Xu 111395ec8ae4SHeiko Stübner ret = regmap_read(regmap, reg, &val); 1114751a99abSHeiko Stübner if (ret) 1115751a99abSHeiko Stübner return ret; 1116751a99abSHeiko Stübner 111703716e1dSHeiko Stübner return ((val >> bit) & mask); 1118a076e2edSHeiko Stübner } 1119a076e2edSHeiko Stübner 112005709c3eSJohn Keeping static int rockchip_verify_mux(struct rockchip_pin_bank *bank, 112105709c3eSJohn Keeping int pin, int mux) 112205709c3eSJohn Keeping { 112305709c3eSJohn Keeping struct rockchip_pinctrl *info = bank->drvdata; 1124e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 112505709c3eSJohn Keeping int iomux_num = (pin / 8); 112605709c3eSJohn Keeping 112705709c3eSJohn Keeping if (iomux_num > 3) 112805709c3eSJohn Keeping return -EINVAL; 112905709c3eSJohn Keeping 113005709c3eSJohn Keeping if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 1131e4dd7fd5SAndy Shevchenko dev_err(dev, "pin %d is unrouted\n", pin); 113205709c3eSJohn Keeping return -EINVAL; 113305709c3eSJohn Keeping } 113405709c3eSJohn Keeping 113505709c3eSJohn Keeping if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { 113605709c3eSJohn Keeping if (mux != RK_FUNC_GPIO) { 1137e4dd7fd5SAndy Shevchenko dev_err(dev, "pin %d only supports a gpio mux\n", pin); 113805709c3eSJohn Keeping return -ENOTSUPP; 113905709c3eSJohn Keeping } 114005709c3eSJohn Keeping } 114105709c3eSJohn Keeping 114205709c3eSJohn Keeping return 0; 114305709c3eSJohn Keeping } 114405709c3eSJohn Keeping 1145d3e51161SHeiko Stübner /* 1146d3e51161SHeiko Stübner * Set a new mux function for a pin. 1147d3e51161SHeiko Stübner * 1148d3e51161SHeiko Stübner * The register is divided into the upper and lower 16 bit. When changing 1149d3e51161SHeiko Stübner * a value, the previous register value is not read and changed. Instead 1150d3e51161SHeiko Stübner * it seems the changed bits are marked in the upper 16 bit, while the 1151d3e51161SHeiko Stübner * changed value gets set in the same offset in the lower 16 bit. 1152d3e51161SHeiko Stübner * All pin settings seem to be 2 bit wide in both the upper and lower 1153d3e51161SHeiko Stübner * parts. 1154d3e51161SHeiko Stübner * @bank: pin bank to change 1155d3e51161SHeiko Stübner * @pin: pin to change 1156d3e51161SHeiko Stübner * @mux: new mux function to set 1157d3e51161SHeiko Stübner */ 115814797189SHeiko Stübner static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 1159d3e51161SHeiko Stübner { 1160d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1161fdc33ebaSJianqun Xu struct rockchip_pin_ctrl *ctrl = info->ctrl; 1162e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 1163fc72c923SHeiko Stübner int iomux_num = (pin / 8); 116495ec8ae4SHeiko Stübner struct regmap *regmap; 1165ea262ad6Sdavid.wu int reg, ret, mask, mux_type; 1166d3e51161SHeiko Stübner u8 bit; 116751ff47aaSHeiko Stuebner u32 data, rmask, route_location, route_reg, route_val; 1168d3e51161SHeiko Stübner 116905709c3eSJohn Keeping ret = rockchip_verify_mux(bank, pin, mux); 117005709c3eSJohn Keeping if (ret < 0) 117105709c3eSJohn Keeping return ret; 1172fc72c923SHeiko Stübner 117305709c3eSJohn Keeping if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 1174c4a532deSHeiko Stübner return 0; 1175c4a532deSHeiko Stübner 1176e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); 1177d3e51161SHeiko Stübner 1178fd4ea486SJagan Teki if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 1179fd4ea486SJagan Teki regmap = info->regmap_pmu; 1180fd4ea486SJagan Teki else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU) 1181fd4ea486SJagan Teki regmap = (pin % 8 < 4) ? info->regmap_pmu : info->regmap_base; 1182fd4ea486SJagan Teki else 1183fd4ea486SJagan Teki regmap = info->regmap_base; 118495ec8ae4SHeiko Stübner 1185d3e51161SHeiko Stübner /* get basic quadrupel of mux registers and the correct reg inside */ 1186ea262ad6Sdavid.wu mux_type = bank->iomux[iomux_num].type; 11876bc0d121SHeiko Stübner reg = bank->iomux[iomux_num].offset; 1188ea262ad6Sdavid.wu if (mux_type & IOMUX_WIDTH_4BIT) { 118903716e1dSHeiko Stübner if ((pin % 8) >= 4) 119003716e1dSHeiko Stübner reg += 0x4; 119103716e1dSHeiko Stübner bit = (pin % 4) * 4; 11928b6c6f93Sdavid.wu mask = 0xf; 1193ea262ad6Sdavid.wu } else if (mux_type & IOMUX_WIDTH_3BIT) { 11948b6c6f93Sdavid.wu if ((pin % 8) >= 5) 11958b6c6f93Sdavid.wu reg += 0x4; 11968b6c6f93Sdavid.wu bit = (pin % 8 % 5) * 3; 11978b6c6f93Sdavid.wu mask = 0x7; 119803716e1dSHeiko Stübner } else { 1199d3e51161SHeiko Stübner bit = (pin % 8) * 2; 12008b6c6f93Sdavid.wu mask = 0x3; 120103716e1dSHeiko Stübner } 1202d3e51161SHeiko Stübner 1203c04c3fa6SDavid Wu if (bank->recalced_mask & BIT(pin)) 1204c04c3fa6SDavid Wu rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 1205ea262ad6Sdavid.wu 1206fdc33ebaSJianqun Xu if (ctrl->type == RK3588) { 1207fdc33ebaSJianqun Xu if (bank->bank_num == 0) { 1208fdc33ebaSJianqun Xu if ((pin >= RK_PB4) && (pin <= RK_PD7)) { 1209fdc33ebaSJianqun Xu if (mux < 8) { 1210fdc33ebaSJianqun Xu reg += 0x4000 - 0xC; /* PMU2_IOC_BASE */ 1211fdc33ebaSJianqun Xu data = (mask << (bit + 16)); 1212fdc33ebaSJianqun Xu rmask = data | (data >> 16); 1213fdc33ebaSJianqun Xu data |= (mux & mask) << bit; 1214fdc33ebaSJianqun Xu ret = regmap_update_bits(regmap, reg, rmask, data); 1215fdc33ebaSJianqun Xu } else { 1216fdc33ebaSJianqun Xu u32 reg0 = 0; 1217fdc33ebaSJianqun Xu 1218fdc33ebaSJianqun Xu reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */ 1219fdc33ebaSJianqun Xu data = (mask << (bit + 16)); 1220fdc33ebaSJianqun Xu rmask = data | (data >> 16); 1221fdc33ebaSJianqun Xu data |= 8 << bit; 1222fdc33ebaSJianqun Xu ret = regmap_update_bits(regmap, reg0, rmask, data); 1223fdc33ebaSJianqun Xu 1224fdc33ebaSJianqun Xu reg0 = reg + 0x8000; /* BUS_IOC_BASE */ 1225fdc33ebaSJianqun Xu data = (mask << (bit + 16)); 1226fdc33ebaSJianqun Xu rmask = data | (data >> 16); 1227fdc33ebaSJianqun Xu data |= mux << bit; 1228fdc33ebaSJianqun Xu regmap = info->regmap_base; 1229fdc33ebaSJianqun Xu ret |= regmap_update_bits(regmap, reg0, rmask, data); 1230fdc33ebaSJianqun Xu } 1231fdc33ebaSJianqun Xu } else { 1232fdc33ebaSJianqun Xu data = (mask << (bit + 16)); 1233fdc33ebaSJianqun Xu rmask = data | (data >> 16); 1234fdc33ebaSJianqun Xu data |= (mux & mask) << bit; 1235fdc33ebaSJianqun Xu ret = regmap_update_bits(regmap, reg, rmask, data); 1236fdc33ebaSJianqun Xu } 1237fdc33ebaSJianqun Xu return ret; 1238fdc33ebaSJianqun Xu } else if (bank->bank_num > 0) { 1239fdc33ebaSJianqun Xu reg += 0x8000; /* BUS_IOC_BASE */ 1240fdc33ebaSJianqun Xu } 1241fdc33ebaSJianqun Xu } 1242fdc33ebaSJianqun Xu 1243fdc33ebaSJianqun Xu if (mux > mask) 1244fdc33ebaSJianqun Xu return -EINVAL; 1245fdc33ebaSJianqun Xu 1246bd35b9bfSDavid Wu if (bank->route_mask & BIT(pin)) { 124751ff47aaSHeiko Stuebner if (rockchip_get_mux_route(bank, pin, mux, &route_location, 124851ff47aaSHeiko Stuebner &route_reg, &route_val)) { 124951ff47aaSHeiko Stuebner struct regmap *route_regmap = regmap; 125051ff47aaSHeiko Stuebner 125151ff47aaSHeiko Stuebner /* handle special locations */ 125251ff47aaSHeiko Stuebner switch (route_location) { 125351ff47aaSHeiko Stuebner case ROCKCHIP_ROUTE_PMU: 125451ff47aaSHeiko Stuebner route_regmap = info->regmap_pmu; 125551ff47aaSHeiko Stuebner break; 125651ff47aaSHeiko Stuebner case ROCKCHIP_ROUTE_GRF: 125751ff47aaSHeiko Stuebner route_regmap = info->regmap_base; 125851ff47aaSHeiko Stuebner break; 125951ff47aaSHeiko Stuebner } 126051ff47aaSHeiko Stuebner 126151ff47aaSHeiko Stuebner ret = regmap_write(route_regmap, route_reg, route_val); 1262bd35b9bfSDavid Wu if (ret) 1263bd35b9bfSDavid Wu return ret; 1264bd35b9bfSDavid Wu } 1265bd35b9bfSDavid Wu } 1266bd35b9bfSDavid Wu 126703716e1dSHeiko Stübner data = (mask << (bit + 16)); 126899e872d9SSonny Rao rmask = data | (data >> 16); 126903716e1dSHeiko Stübner data |= (mux & mask) << bit; 127099e872d9SSonny Rao ret = regmap_update_bits(regmap, reg, rmask, data); 1271d3e51161SHeiko Stübner 1272751a99abSHeiko Stübner return ret; 1273d3e51161SHeiko Stübner } 1274d3e51161SHeiko Stübner 127587065ca9SDavid Wu #define PX30_PULL_PMU_OFFSET 0x10 127687065ca9SDavid Wu #define PX30_PULL_GRF_OFFSET 0x60 127787065ca9SDavid Wu #define PX30_PULL_BITS_PER_PIN 2 127887065ca9SDavid Wu #define PX30_PULL_PINS_PER_REG 8 127987065ca9SDavid Wu #define PX30_PULL_BANK_STRIDE 16 128087065ca9SDavid Wu 128142573ab3SSebastian Reichel static int px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 128287065ca9SDavid Wu int pin_num, struct regmap **regmap, 128387065ca9SDavid Wu int *reg, u8 *bit) 128487065ca9SDavid Wu { 128587065ca9SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 128687065ca9SDavid Wu 128787065ca9SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 128887065ca9SDavid Wu if (bank->bank_num == 0) { 128987065ca9SDavid Wu *regmap = info->regmap_pmu; 129087065ca9SDavid Wu *reg = PX30_PULL_PMU_OFFSET; 129187065ca9SDavid Wu } else { 129287065ca9SDavid Wu *regmap = info->regmap_base; 129387065ca9SDavid Wu *reg = PX30_PULL_GRF_OFFSET; 129487065ca9SDavid Wu 129587065ca9SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 129687065ca9SDavid Wu *reg -= 0x10; 129787065ca9SDavid Wu *reg += bank->bank_num * PX30_PULL_BANK_STRIDE; 129887065ca9SDavid Wu } 129987065ca9SDavid Wu 130087065ca9SDavid Wu *reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4); 130187065ca9SDavid Wu *bit = (pin_num % PX30_PULL_PINS_PER_REG); 130287065ca9SDavid Wu *bit *= PX30_PULL_BITS_PER_PIN; 130342573ab3SSebastian Reichel 130442573ab3SSebastian Reichel return 0; 130587065ca9SDavid Wu } 130687065ca9SDavid Wu 130787065ca9SDavid Wu #define PX30_DRV_PMU_OFFSET 0x20 130887065ca9SDavid Wu #define PX30_DRV_GRF_OFFSET 0xf0 130987065ca9SDavid Wu #define PX30_DRV_BITS_PER_PIN 2 131087065ca9SDavid Wu #define PX30_DRV_PINS_PER_REG 8 131187065ca9SDavid Wu #define PX30_DRV_BANK_STRIDE 16 131287065ca9SDavid Wu 131342573ab3SSebastian Reichel static int px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 131487065ca9SDavid Wu int pin_num, struct regmap **regmap, 131587065ca9SDavid Wu int *reg, u8 *bit) 131687065ca9SDavid Wu { 131787065ca9SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 131887065ca9SDavid Wu 131987065ca9SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 132087065ca9SDavid Wu if (bank->bank_num == 0) { 132187065ca9SDavid Wu *regmap = info->regmap_pmu; 132287065ca9SDavid Wu *reg = PX30_DRV_PMU_OFFSET; 132387065ca9SDavid Wu } else { 132487065ca9SDavid Wu *regmap = info->regmap_base; 132587065ca9SDavid Wu *reg = PX30_DRV_GRF_OFFSET; 132687065ca9SDavid Wu 132787065ca9SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 132887065ca9SDavid Wu *reg -= 0x10; 132987065ca9SDavid Wu *reg += bank->bank_num * PX30_DRV_BANK_STRIDE; 133087065ca9SDavid Wu } 133187065ca9SDavid Wu 133287065ca9SDavid Wu *reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4); 133387065ca9SDavid Wu *bit = (pin_num % PX30_DRV_PINS_PER_REG); 133487065ca9SDavid Wu *bit *= PX30_DRV_BITS_PER_PIN; 133542573ab3SSebastian Reichel 133642573ab3SSebastian Reichel return 0; 133787065ca9SDavid Wu } 133887065ca9SDavid Wu 133987065ca9SDavid Wu #define PX30_SCHMITT_PMU_OFFSET 0x38 134087065ca9SDavid Wu #define PX30_SCHMITT_GRF_OFFSET 0xc0 134187065ca9SDavid Wu #define PX30_SCHMITT_PINS_PER_PMU_REG 16 134287065ca9SDavid Wu #define PX30_SCHMITT_BANK_STRIDE 16 134387065ca9SDavid Wu #define PX30_SCHMITT_PINS_PER_GRF_REG 8 134487065ca9SDavid Wu 134587065ca9SDavid Wu static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 134687065ca9SDavid Wu int pin_num, 134787065ca9SDavid Wu struct regmap **regmap, 134887065ca9SDavid Wu int *reg, u8 *bit) 134987065ca9SDavid Wu { 135087065ca9SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 135187065ca9SDavid Wu int pins_per_reg; 135287065ca9SDavid Wu 135387065ca9SDavid Wu if (bank->bank_num == 0) { 135487065ca9SDavid Wu *regmap = info->regmap_pmu; 135587065ca9SDavid Wu *reg = PX30_SCHMITT_PMU_OFFSET; 135687065ca9SDavid Wu pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG; 135787065ca9SDavid Wu } else { 135887065ca9SDavid Wu *regmap = info->regmap_base; 135987065ca9SDavid Wu *reg = PX30_SCHMITT_GRF_OFFSET; 136087065ca9SDavid Wu pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG; 136187065ca9SDavid Wu *reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE; 136287065ca9SDavid Wu } 136387065ca9SDavid Wu 136487065ca9SDavid Wu *reg += ((pin_num / pins_per_reg) * 4); 136587065ca9SDavid Wu *bit = pin_num % pins_per_reg; 136687065ca9SDavid Wu 136787065ca9SDavid Wu return 0; 136887065ca9SDavid Wu } 136987065ca9SDavid Wu 1370b9c6dcabSAndy Yan #define RV1108_PULL_PMU_OFFSET 0x10 1371b9c6dcabSAndy Yan #define RV1108_PULL_OFFSET 0x110 1372b9c6dcabSAndy Yan #define RV1108_PULL_PINS_PER_REG 8 1373b9c6dcabSAndy Yan #define RV1108_PULL_BITS_PER_PIN 2 1374b9c6dcabSAndy Yan #define RV1108_PULL_BANK_STRIDE 16 1375688daf23SAndy Yan 137642573ab3SSebastian Reichel static int rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1377688daf23SAndy Yan int pin_num, struct regmap **regmap, 1378688daf23SAndy Yan int *reg, u8 *bit) 1379688daf23SAndy Yan { 1380688daf23SAndy Yan struct rockchip_pinctrl *info = bank->drvdata; 1381688daf23SAndy Yan 1382688daf23SAndy Yan /* The first 24 pins of the first bank are located in PMU */ 1383688daf23SAndy Yan if (bank->bank_num == 0) { 1384688daf23SAndy Yan *regmap = info->regmap_pmu; 1385b9c6dcabSAndy Yan *reg = RV1108_PULL_PMU_OFFSET; 1386688daf23SAndy Yan } else { 1387b9c6dcabSAndy Yan *reg = RV1108_PULL_OFFSET; 1388688daf23SAndy Yan *regmap = info->regmap_base; 1389688daf23SAndy Yan /* correct the offset, as we're starting with the 2nd bank */ 1390688daf23SAndy Yan *reg -= 0x10; 1391b9c6dcabSAndy Yan *reg += bank->bank_num * RV1108_PULL_BANK_STRIDE; 1392688daf23SAndy Yan } 1393688daf23SAndy Yan 1394b9c6dcabSAndy Yan *reg += ((pin_num / RV1108_PULL_PINS_PER_REG) * 4); 1395b9c6dcabSAndy Yan *bit = (pin_num % RV1108_PULL_PINS_PER_REG); 1396b9c6dcabSAndy Yan *bit *= RV1108_PULL_BITS_PER_PIN; 139742573ab3SSebastian Reichel 139842573ab3SSebastian Reichel return 0; 1399688daf23SAndy Yan } 1400688daf23SAndy Yan 1401b9c6dcabSAndy Yan #define RV1108_DRV_PMU_OFFSET 0x20 1402b9c6dcabSAndy Yan #define RV1108_DRV_GRF_OFFSET 0x210 1403b9c6dcabSAndy Yan #define RV1108_DRV_BITS_PER_PIN 2 1404b9c6dcabSAndy Yan #define RV1108_DRV_PINS_PER_REG 8 1405b9c6dcabSAndy Yan #define RV1108_DRV_BANK_STRIDE 16 1406688daf23SAndy Yan 140742573ab3SSebastian Reichel static int rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1408688daf23SAndy Yan int pin_num, struct regmap **regmap, 1409688daf23SAndy Yan int *reg, u8 *bit) 1410688daf23SAndy Yan { 1411688daf23SAndy Yan struct rockchip_pinctrl *info = bank->drvdata; 1412688daf23SAndy Yan 1413688daf23SAndy Yan /* The first 24 pins of the first bank are located in PMU */ 1414688daf23SAndy Yan if (bank->bank_num == 0) { 1415688daf23SAndy Yan *regmap = info->regmap_pmu; 1416b9c6dcabSAndy Yan *reg = RV1108_DRV_PMU_OFFSET; 1417688daf23SAndy Yan } else { 1418688daf23SAndy Yan *regmap = info->regmap_base; 1419b9c6dcabSAndy Yan *reg = RV1108_DRV_GRF_OFFSET; 1420688daf23SAndy Yan 1421688daf23SAndy Yan /* correct the offset, as we're starting with the 2nd bank */ 1422688daf23SAndy Yan *reg -= 0x10; 1423b9c6dcabSAndy Yan *reg += bank->bank_num * RV1108_DRV_BANK_STRIDE; 1424688daf23SAndy Yan } 1425688daf23SAndy Yan 1426b9c6dcabSAndy Yan *reg += ((pin_num / RV1108_DRV_PINS_PER_REG) * 4); 1427b9c6dcabSAndy Yan *bit = pin_num % RV1108_DRV_PINS_PER_REG; 1428b9c6dcabSAndy Yan *bit *= RV1108_DRV_BITS_PER_PIN; 142942573ab3SSebastian Reichel 143042573ab3SSebastian Reichel return 0; 1431688daf23SAndy Yan } 1432688daf23SAndy Yan 14335caff7eaSAndy Yan #define RV1108_SCHMITT_PMU_OFFSET 0x30 14345caff7eaSAndy Yan #define RV1108_SCHMITT_GRF_OFFSET 0x388 14355caff7eaSAndy Yan #define RV1108_SCHMITT_BANK_STRIDE 8 14365caff7eaSAndy Yan #define RV1108_SCHMITT_PINS_PER_GRF_REG 16 14375caff7eaSAndy Yan #define RV1108_SCHMITT_PINS_PER_PMU_REG 8 14385caff7eaSAndy Yan 14395caff7eaSAndy Yan static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 14405caff7eaSAndy Yan int pin_num, 14415caff7eaSAndy Yan struct regmap **regmap, 14425caff7eaSAndy Yan int *reg, u8 *bit) 14435caff7eaSAndy Yan { 14445caff7eaSAndy Yan struct rockchip_pinctrl *info = bank->drvdata; 14455caff7eaSAndy Yan int pins_per_reg; 14465caff7eaSAndy Yan 14475caff7eaSAndy Yan if (bank->bank_num == 0) { 14485caff7eaSAndy Yan *regmap = info->regmap_pmu; 14495caff7eaSAndy Yan *reg = RV1108_SCHMITT_PMU_OFFSET; 14505caff7eaSAndy Yan pins_per_reg = RV1108_SCHMITT_PINS_PER_PMU_REG; 14515caff7eaSAndy Yan } else { 14525caff7eaSAndy Yan *regmap = info->regmap_base; 14535caff7eaSAndy Yan *reg = RV1108_SCHMITT_GRF_OFFSET; 14545caff7eaSAndy Yan pins_per_reg = RV1108_SCHMITT_PINS_PER_GRF_REG; 14555caff7eaSAndy Yan *reg += (bank->bank_num - 1) * RV1108_SCHMITT_BANK_STRIDE; 14565caff7eaSAndy Yan } 14575caff7eaSAndy Yan *reg += ((pin_num / pins_per_reg) * 4); 14585caff7eaSAndy Yan *bit = pin_num % pins_per_reg; 14595caff7eaSAndy Yan 14605caff7eaSAndy Yan return 0; 14615caff7eaSAndy Yan } 14625caff7eaSAndy Yan 1463fd4ea486SJagan Teki #define RV1126_PULL_PMU_OFFSET 0x40 1464fd4ea486SJagan Teki #define RV1126_PULL_GRF_GPIO1A0_OFFSET 0x10108 1465fd4ea486SJagan Teki #define RV1126_PULL_PINS_PER_REG 8 1466fd4ea486SJagan Teki #define RV1126_PULL_BITS_PER_PIN 2 1467fd4ea486SJagan Teki #define RV1126_PULL_BANK_STRIDE 16 1468fd4ea486SJagan Teki #define RV1126_GPIO_C4_D7(p) (p >= 20 && p <= 31) /* GPIO0_C4 ~ GPIO0_D7 */ 1469fd4ea486SJagan Teki 1470fd4ea486SJagan Teki static int rv1126_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1471fd4ea486SJagan Teki int pin_num, struct regmap **regmap, 1472fd4ea486SJagan Teki int *reg, u8 *bit) 1473fd4ea486SJagan Teki { 1474fd4ea486SJagan Teki struct rockchip_pinctrl *info = bank->drvdata; 1475fd4ea486SJagan Teki 1476fd4ea486SJagan Teki /* The first 24 pins of the first bank are located in PMU */ 1477fd4ea486SJagan Teki if (bank->bank_num == 0) { 1478fd4ea486SJagan Teki if (RV1126_GPIO_C4_D7(pin_num)) { 1479fd4ea486SJagan Teki *regmap = info->regmap_base; 1480fd4ea486SJagan Teki *reg = RV1126_PULL_GRF_GPIO1A0_OFFSET; 1481fd4ea486SJagan Teki *reg -= (((31 - pin_num) / RV1126_PULL_PINS_PER_REG + 1) * 4); 1482fd4ea486SJagan Teki *bit = pin_num % RV1126_PULL_PINS_PER_REG; 1483fd4ea486SJagan Teki *bit *= RV1126_PULL_BITS_PER_PIN; 1484fd4ea486SJagan Teki return 0; 1485fd4ea486SJagan Teki } 1486fd4ea486SJagan Teki *regmap = info->regmap_pmu; 1487fd4ea486SJagan Teki *reg = RV1126_PULL_PMU_OFFSET; 1488fd4ea486SJagan Teki } else { 1489fd4ea486SJagan Teki *reg = RV1126_PULL_GRF_GPIO1A0_OFFSET; 1490fd4ea486SJagan Teki *regmap = info->regmap_base; 1491fd4ea486SJagan Teki *reg += (bank->bank_num - 1) * RV1126_PULL_BANK_STRIDE; 1492fd4ea486SJagan Teki } 1493fd4ea486SJagan Teki 1494fd4ea486SJagan Teki *reg += ((pin_num / RV1126_PULL_PINS_PER_REG) * 4); 1495fd4ea486SJagan Teki *bit = (pin_num % RV1126_PULL_PINS_PER_REG); 1496fd4ea486SJagan Teki *bit *= RV1126_PULL_BITS_PER_PIN; 1497fd4ea486SJagan Teki 1498fd4ea486SJagan Teki return 0; 1499fd4ea486SJagan Teki } 1500fd4ea486SJagan Teki 1501fd4ea486SJagan Teki #define RV1126_DRV_PMU_OFFSET 0x20 1502fd4ea486SJagan Teki #define RV1126_DRV_GRF_GPIO1A0_OFFSET 0x10090 1503fd4ea486SJagan Teki #define RV1126_DRV_BITS_PER_PIN 4 1504fd4ea486SJagan Teki #define RV1126_DRV_PINS_PER_REG 4 1505fd4ea486SJagan Teki #define RV1126_DRV_BANK_STRIDE 32 1506fd4ea486SJagan Teki 1507fd4ea486SJagan Teki static int rv1126_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1508fd4ea486SJagan Teki int pin_num, struct regmap **regmap, 1509fd4ea486SJagan Teki int *reg, u8 *bit) 1510fd4ea486SJagan Teki { 1511fd4ea486SJagan Teki struct rockchip_pinctrl *info = bank->drvdata; 1512fd4ea486SJagan Teki 1513fd4ea486SJagan Teki /* The first 24 pins of the first bank are located in PMU */ 1514fd4ea486SJagan Teki if (bank->bank_num == 0) { 1515fd4ea486SJagan Teki if (RV1126_GPIO_C4_D7(pin_num)) { 1516fd4ea486SJagan Teki *regmap = info->regmap_base; 1517fd4ea486SJagan Teki *reg = RV1126_DRV_GRF_GPIO1A0_OFFSET; 1518fd4ea486SJagan Teki *reg -= (((31 - pin_num) / RV1126_DRV_PINS_PER_REG + 1) * 4); 1519fd4ea486SJagan Teki *reg -= 0x4; 1520fd4ea486SJagan Teki *bit = pin_num % RV1126_DRV_PINS_PER_REG; 1521fd4ea486SJagan Teki *bit *= RV1126_DRV_BITS_PER_PIN; 1522fd4ea486SJagan Teki return 0; 1523fd4ea486SJagan Teki } 1524fd4ea486SJagan Teki *regmap = info->regmap_pmu; 1525fd4ea486SJagan Teki *reg = RV1126_DRV_PMU_OFFSET; 1526fd4ea486SJagan Teki } else { 1527fd4ea486SJagan Teki *regmap = info->regmap_base; 1528fd4ea486SJagan Teki *reg = RV1126_DRV_GRF_GPIO1A0_OFFSET; 1529fd4ea486SJagan Teki *reg += (bank->bank_num - 1) * RV1126_DRV_BANK_STRIDE; 1530fd4ea486SJagan Teki } 1531fd4ea486SJagan Teki 1532fd4ea486SJagan Teki *reg += ((pin_num / RV1126_DRV_PINS_PER_REG) * 4); 1533fd4ea486SJagan Teki *bit = pin_num % RV1126_DRV_PINS_PER_REG; 1534fd4ea486SJagan Teki *bit *= RV1126_DRV_BITS_PER_PIN; 1535fd4ea486SJagan Teki 1536fd4ea486SJagan Teki return 0; 1537fd4ea486SJagan Teki } 1538fd4ea486SJagan Teki 1539fd4ea486SJagan Teki #define RV1126_SCHMITT_PMU_OFFSET 0x60 1540fd4ea486SJagan Teki #define RV1126_SCHMITT_GRF_GPIO1A0_OFFSET 0x10188 1541fd4ea486SJagan Teki #define RV1126_SCHMITT_BANK_STRIDE 16 1542fd4ea486SJagan Teki #define RV1126_SCHMITT_PINS_PER_GRF_REG 8 1543fd4ea486SJagan Teki #define RV1126_SCHMITT_PINS_PER_PMU_REG 8 1544fd4ea486SJagan Teki 1545fd4ea486SJagan Teki static int rv1126_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 1546fd4ea486SJagan Teki int pin_num, 1547fd4ea486SJagan Teki struct regmap **regmap, 1548fd4ea486SJagan Teki int *reg, u8 *bit) 1549fd4ea486SJagan Teki { 1550fd4ea486SJagan Teki struct rockchip_pinctrl *info = bank->drvdata; 1551fd4ea486SJagan Teki int pins_per_reg; 1552fd4ea486SJagan Teki 1553fd4ea486SJagan Teki if (bank->bank_num == 0) { 1554fd4ea486SJagan Teki if (RV1126_GPIO_C4_D7(pin_num)) { 1555fd4ea486SJagan Teki *regmap = info->regmap_base; 1556fd4ea486SJagan Teki *reg = RV1126_SCHMITT_GRF_GPIO1A0_OFFSET; 1557fd4ea486SJagan Teki *reg -= (((31 - pin_num) / RV1126_SCHMITT_PINS_PER_GRF_REG + 1) * 4); 1558fd4ea486SJagan Teki *bit = pin_num % RV1126_SCHMITT_PINS_PER_GRF_REG; 1559fd4ea486SJagan Teki return 0; 1560fd4ea486SJagan Teki } 1561fd4ea486SJagan Teki *regmap = info->regmap_pmu; 1562fd4ea486SJagan Teki *reg = RV1126_SCHMITT_PMU_OFFSET; 1563fd4ea486SJagan Teki pins_per_reg = RV1126_SCHMITT_PINS_PER_PMU_REG; 1564fd4ea486SJagan Teki } else { 1565fd4ea486SJagan Teki *regmap = info->regmap_base; 1566fd4ea486SJagan Teki *reg = RV1126_SCHMITT_GRF_GPIO1A0_OFFSET; 1567fd4ea486SJagan Teki pins_per_reg = RV1126_SCHMITT_PINS_PER_GRF_REG; 1568fd4ea486SJagan Teki *reg += (bank->bank_num - 1) * RV1126_SCHMITT_BANK_STRIDE; 1569fd4ea486SJagan Teki } 1570fd4ea486SJagan Teki *reg += ((pin_num / pins_per_reg) * 4); 1571fd4ea486SJagan Teki *bit = pin_num % pins_per_reg; 1572fd4ea486SJagan Teki 1573fd4ea486SJagan Teki return 0; 1574fd4ea486SJagan Teki } 1575fd4ea486SJagan Teki 15767825aeb7SJianqun Xu #define RK3308_SCHMITT_PINS_PER_REG 8 15777825aeb7SJianqun Xu #define RK3308_SCHMITT_BANK_STRIDE 16 15787825aeb7SJianqun Xu #define RK3308_SCHMITT_GRF_OFFSET 0x1a0 15797825aeb7SJianqun Xu 15807825aeb7SJianqun Xu static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 15817825aeb7SJianqun Xu int pin_num, struct regmap **regmap, 15827825aeb7SJianqun Xu int *reg, u8 *bit) 15837825aeb7SJianqun Xu { 15847825aeb7SJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 15857825aeb7SJianqun Xu 15867825aeb7SJianqun Xu *regmap = info->regmap_base; 15877825aeb7SJianqun Xu *reg = RK3308_SCHMITT_GRF_OFFSET; 15887825aeb7SJianqun Xu 15897825aeb7SJianqun Xu *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE; 15907825aeb7SJianqun Xu *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4); 15917825aeb7SJianqun Xu *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG; 15927825aeb7SJianqun Xu 15937825aeb7SJianqun Xu return 0; 15947825aeb7SJianqun Xu } 15957825aeb7SJianqun Xu 1596a282926dSHeiko Stübner #define RK2928_PULL_OFFSET 0x118 1597a282926dSHeiko Stübner #define RK2928_PULL_PINS_PER_REG 16 1598a282926dSHeiko Stübner #define RK2928_PULL_BANK_STRIDE 8 1599a282926dSHeiko Stübner 160042573ab3SSebastian Reichel static int rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1601751a99abSHeiko Stübner int pin_num, struct regmap **regmap, 1602751a99abSHeiko Stübner int *reg, u8 *bit) 1603a282926dSHeiko Stübner { 1604a282926dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1605a282926dSHeiko Stübner 1606751a99abSHeiko Stübner *regmap = info->regmap_base; 1607751a99abSHeiko Stübner *reg = RK2928_PULL_OFFSET; 1608a282926dSHeiko Stübner *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 1609a282926dSHeiko Stübner *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4; 1610a282926dSHeiko Stübner 1611a282926dSHeiko Stübner *bit = pin_num % RK2928_PULL_PINS_PER_REG; 161242573ab3SSebastian Reichel 161342573ab3SSebastian Reichel return 0; 1614a282926dSHeiko Stübner }; 1615a282926dSHeiko Stübner 1616d23c66dfSDavid Wu #define RK3128_PULL_OFFSET 0x118 1617d23c66dfSDavid Wu 161842573ab3SSebastian Reichel static int rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1619d23c66dfSDavid Wu int pin_num, struct regmap **regmap, 1620d23c66dfSDavid Wu int *reg, u8 *bit) 1621d23c66dfSDavid Wu { 1622d23c66dfSDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 1623d23c66dfSDavid Wu 1624d23c66dfSDavid Wu *regmap = info->regmap_base; 1625d23c66dfSDavid Wu *reg = RK3128_PULL_OFFSET; 1626d23c66dfSDavid Wu *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 1627d23c66dfSDavid Wu *reg += ((pin_num / RK2928_PULL_PINS_PER_REG) * 4); 1628d23c66dfSDavid Wu 1629d23c66dfSDavid Wu *bit = pin_num % RK2928_PULL_PINS_PER_REG; 163042573ab3SSebastian Reichel 163142573ab3SSebastian Reichel return 0; 1632d23c66dfSDavid Wu } 1633d23c66dfSDavid Wu 1634bfc7a42aSHeiko Stübner #define RK3188_PULL_OFFSET 0x164 16356ca5274dSHeiko Stübner #define RK3188_PULL_BITS_PER_PIN 2 16366ca5274dSHeiko Stübner #define RK3188_PULL_PINS_PER_REG 8 16376ca5274dSHeiko Stübner #define RK3188_PULL_BANK_STRIDE 16 163814dee867SHeiko Stübner #define RK3188_PULL_PMU_OFFSET 0x64 16396ca5274dSHeiko Stübner 164042573ab3SSebastian Reichel static int rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1641751a99abSHeiko Stübner int pin_num, struct regmap **regmap, 1642751a99abSHeiko Stübner int *reg, u8 *bit) 16436ca5274dSHeiko Stübner { 16446ca5274dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 16456ca5274dSHeiko Stübner 16466ca5274dSHeiko Stübner /* The first 12 pins of the first bank are located elsewhere */ 1647fc72c923SHeiko Stübner if (bank->bank_num == 0 && pin_num < 12) { 164814dee867SHeiko Stübner *regmap = info->regmap_pmu ? info->regmap_pmu 164914dee867SHeiko Stübner : bank->regmap_pull; 165014dee867SHeiko Stübner *reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0; 1651751a99abSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 16526ca5274dSHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 16536ca5274dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 16546ca5274dSHeiko Stübner } else { 1655751a99abSHeiko Stübner *regmap = info->regmap_pull ? info->regmap_pull 1656751a99abSHeiko Stübner : info->regmap_base; 1657751a99abSHeiko Stübner *reg = info->regmap_pull ? 0 : RK3188_PULL_OFFSET; 1658751a99abSHeiko Stübner 1659bfc7a42aSHeiko Stübner /* correct the offset, as it is the 2nd pull register */ 1660bfc7a42aSHeiko Stübner *reg -= 4; 16616ca5274dSHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 16626ca5274dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 16636ca5274dSHeiko Stübner 16646ca5274dSHeiko Stübner /* 16656ca5274dSHeiko Stübner * The bits in these registers have an inverse ordering 16666ca5274dSHeiko Stübner * with the lowest pin being in bits 15:14 and the highest 16676ca5274dSHeiko Stübner * pin in bits 1:0 16686ca5274dSHeiko Stübner */ 16696ca5274dSHeiko Stübner *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG); 16706ca5274dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 16716ca5274dSHeiko Stübner } 167242573ab3SSebastian Reichel 167342573ab3SSebastian Reichel return 0; 16746ca5274dSHeiko Stübner } 16756ca5274dSHeiko Stübner 1676304f077dSHeiko Stübner #define RK3288_PULL_OFFSET 0x140 167742573ab3SSebastian Reichel static int rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1678304f077dSHeiko Stübner int pin_num, struct regmap **regmap, 1679304f077dSHeiko Stübner int *reg, u8 *bit) 1680304f077dSHeiko Stübner { 1681304f077dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1682304f077dSHeiko Stübner 1683304f077dSHeiko Stübner /* The first 24 pins of the first bank are located in PMU */ 1684304f077dSHeiko Stübner if (bank->bank_num == 0) { 1685304f077dSHeiko Stübner *regmap = info->regmap_pmu; 1686304f077dSHeiko Stübner *reg = RK3188_PULL_PMU_OFFSET; 1687304f077dSHeiko Stübner 1688304f077dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1689304f077dSHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 1690304f077dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1691304f077dSHeiko Stübner } else { 1692304f077dSHeiko Stübner *regmap = info->regmap_base; 1693304f077dSHeiko Stübner *reg = RK3288_PULL_OFFSET; 1694304f077dSHeiko Stübner 1695304f077dSHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1696304f077dSHeiko Stübner *reg -= 0x10; 1697304f077dSHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1698304f077dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1699304f077dSHeiko Stübner 1700304f077dSHeiko Stübner *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1701304f077dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1702304f077dSHeiko Stübner } 170342573ab3SSebastian Reichel 170442573ab3SSebastian Reichel return 0; 1705304f077dSHeiko Stübner } 1706304f077dSHeiko Stübner 1707b547c800SHeiko Stübner #define RK3288_DRV_PMU_OFFSET 0x70 1708b547c800SHeiko Stübner #define RK3288_DRV_GRF_OFFSET 0x1c0 1709b547c800SHeiko Stübner #define RK3288_DRV_BITS_PER_PIN 2 1710b547c800SHeiko Stübner #define RK3288_DRV_PINS_PER_REG 8 1711b547c800SHeiko Stübner #define RK3288_DRV_BANK_STRIDE 16 1712b547c800SHeiko Stübner 171342573ab3SSebastian Reichel static int rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1714b547c800SHeiko Stübner int pin_num, struct regmap **regmap, 1715b547c800SHeiko Stübner int *reg, u8 *bit) 1716b547c800SHeiko Stübner { 1717b547c800SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1718b547c800SHeiko Stübner 1719b547c800SHeiko Stübner /* The first 24 pins of the first bank are located in PMU */ 1720b547c800SHeiko Stübner if (bank->bank_num == 0) { 1721b547c800SHeiko Stübner *regmap = info->regmap_pmu; 1722b547c800SHeiko Stübner *reg = RK3288_DRV_PMU_OFFSET; 1723b547c800SHeiko Stübner 1724b547c800SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1725b547c800SHeiko Stübner *bit = pin_num % RK3288_DRV_PINS_PER_REG; 1726b547c800SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1727b547c800SHeiko Stübner } else { 1728b547c800SHeiko Stübner *regmap = info->regmap_base; 1729b547c800SHeiko Stübner *reg = RK3288_DRV_GRF_OFFSET; 1730b547c800SHeiko Stübner 1731b547c800SHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1732b547c800SHeiko Stübner *reg -= 0x10; 1733b547c800SHeiko Stübner *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 1734b547c800SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1735b547c800SHeiko Stübner 1736b547c800SHeiko Stübner *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 1737b547c800SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1738b547c800SHeiko Stübner } 173942573ab3SSebastian Reichel 174042573ab3SSebastian Reichel return 0; 1741b547c800SHeiko Stübner } 1742b547c800SHeiko Stübner 1743fea0fe60SJeffy Chen #define RK3228_PULL_OFFSET 0x100 1744fea0fe60SJeffy Chen 174542573ab3SSebastian Reichel static int rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1746fea0fe60SJeffy Chen int pin_num, struct regmap **regmap, 1747fea0fe60SJeffy Chen int *reg, u8 *bit) 1748fea0fe60SJeffy Chen { 1749fea0fe60SJeffy Chen struct rockchip_pinctrl *info = bank->drvdata; 1750fea0fe60SJeffy Chen 1751fea0fe60SJeffy Chen *regmap = info->regmap_base; 1752fea0fe60SJeffy Chen *reg = RK3228_PULL_OFFSET; 1753fea0fe60SJeffy Chen *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1754fea0fe60SJeffy Chen *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1755fea0fe60SJeffy Chen 1756fea0fe60SJeffy Chen *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1757fea0fe60SJeffy Chen *bit *= RK3188_PULL_BITS_PER_PIN; 175842573ab3SSebastian Reichel 175942573ab3SSebastian Reichel return 0; 1760fea0fe60SJeffy Chen } 1761fea0fe60SJeffy Chen 1762fea0fe60SJeffy Chen #define RK3228_DRV_GRF_OFFSET 0x200 1763fea0fe60SJeffy Chen 176442573ab3SSebastian Reichel static int rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1765fea0fe60SJeffy Chen int pin_num, struct regmap **regmap, 1766fea0fe60SJeffy Chen int *reg, u8 *bit) 1767fea0fe60SJeffy Chen { 1768fea0fe60SJeffy Chen struct rockchip_pinctrl *info = bank->drvdata; 1769fea0fe60SJeffy Chen 1770fea0fe60SJeffy Chen *regmap = info->regmap_base; 1771fea0fe60SJeffy Chen *reg = RK3228_DRV_GRF_OFFSET; 1772fea0fe60SJeffy Chen *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 1773fea0fe60SJeffy Chen *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1774fea0fe60SJeffy Chen 1775fea0fe60SJeffy Chen *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 1776fea0fe60SJeffy Chen *bit *= RK3288_DRV_BITS_PER_PIN; 177742573ab3SSebastian Reichel 177842573ab3SSebastian Reichel return 0; 1779fea0fe60SJeffy Chen } 1780fea0fe60SJeffy Chen 17817825aeb7SJianqun Xu #define RK3308_PULL_OFFSET 0xa0 17827825aeb7SJianqun Xu 178342573ab3SSebastian Reichel static int rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 17847825aeb7SJianqun Xu int pin_num, struct regmap **regmap, 17857825aeb7SJianqun Xu int *reg, u8 *bit) 17867825aeb7SJianqun Xu { 17877825aeb7SJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 17887825aeb7SJianqun Xu 17897825aeb7SJianqun Xu *regmap = info->regmap_base; 17907825aeb7SJianqun Xu *reg = RK3308_PULL_OFFSET; 17917825aeb7SJianqun Xu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 17927825aeb7SJianqun Xu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 17937825aeb7SJianqun Xu 17947825aeb7SJianqun Xu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 17957825aeb7SJianqun Xu *bit *= RK3188_PULL_BITS_PER_PIN; 179642573ab3SSebastian Reichel 179742573ab3SSebastian Reichel return 0; 17987825aeb7SJianqun Xu } 17997825aeb7SJianqun Xu 18007825aeb7SJianqun Xu #define RK3308_DRV_GRF_OFFSET 0x100 18017825aeb7SJianqun Xu 180242573ab3SSebastian Reichel static int rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 18037825aeb7SJianqun Xu int pin_num, struct regmap **regmap, 18047825aeb7SJianqun Xu int *reg, u8 *bit) 18057825aeb7SJianqun Xu { 18067825aeb7SJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 18077825aeb7SJianqun Xu 18087825aeb7SJianqun Xu *regmap = info->regmap_base; 18097825aeb7SJianqun Xu *reg = RK3308_DRV_GRF_OFFSET; 18107825aeb7SJianqun Xu *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 18117825aeb7SJianqun Xu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 18127825aeb7SJianqun Xu 18137825aeb7SJianqun Xu *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 18147825aeb7SJianqun Xu *bit *= RK3288_DRV_BITS_PER_PIN; 181542573ab3SSebastian Reichel 181642573ab3SSebastian Reichel return 0; 18177825aeb7SJianqun Xu } 18187825aeb7SJianqun Xu 1819daecdc66SHeiko Stübner #define RK3368_PULL_GRF_OFFSET 0x100 1820daecdc66SHeiko Stübner #define RK3368_PULL_PMU_OFFSET 0x10 1821daecdc66SHeiko Stübner 182242573ab3SSebastian Reichel static int rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1823daecdc66SHeiko Stübner int pin_num, struct regmap **regmap, 1824daecdc66SHeiko Stübner int *reg, u8 *bit) 1825daecdc66SHeiko Stübner { 1826daecdc66SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1827daecdc66SHeiko Stübner 1828daecdc66SHeiko Stübner /* The first 32 pins of the first bank are located in PMU */ 1829daecdc66SHeiko Stübner if (bank->bank_num == 0) { 1830daecdc66SHeiko Stübner *regmap = info->regmap_pmu; 1831daecdc66SHeiko Stübner *reg = RK3368_PULL_PMU_OFFSET; 1832daecdc66SHeiko Stübner 1833daecdc66SHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1834daecdc66SHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 1835daecdc66SHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1836daecdc66SHeiko Stübner } else { 1837daecdc66SHeiko Stübner *regmap = info->regmap_base; 1838daecdc66SHeiko Stübner *reg = RK3368_PULL_GRF_OFFSET; 1839daecdc66SHeiko Stübner 1840daecdc66SHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1841daecdc66SHeiko Stübner *reg -= 0x10; 1842daecdc66SHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1843daecdc66SHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1844daecdc66SHeiko Stübner 1845daecdc66SHeiko Stübner *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1846daecdc66SHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1847daecdc66SHeiko Stübner } 184842573ab3SSebastian Reichel 184942573ab3SSebastian Reichel return 0; 1850daecdc66SHeiko Stübner } 1851daecdc66SHeiko Stübner 1852daecdc66SHeiko Stübner #define RK3368_DRV_PMU_OFFSET 0x20 1853daecdc66SHeiko Stübner #define RK3368_DRV_GRF_OFFSET 0x200 1854daecdc66SHeiko Stübner 185542573ab3SSebastian Reichel static int rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1856daecdc66SHeiko Stübner int pin_num, struct regmap **regmap, 1857daecdc66SHeiko Stübner int *reg, u8 *bit) 1858daecdc66SHeiko Stübner { 1859daecdc66SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1860daecdc66SHeiko Stübner 1861daecdc66SHeiko Stübner /* The first 32 pins of the first bank are located in PMU */ 1862daecdc66SHeiko Stübner if (bank->bank_num == 0) { 1863daecdc66SHeiko Stübner *regmap = info->regmap_pmu; 1864daecdc66SHeiko Stübner *reg = RK3368_DRV_PMU_OFFSET; 1865daecdc66SHeiko Stübner 1866daecdc66SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1867daecdc66SHeiko Stübner *bit = pin_num % RK3288_DRV_PINS_PER_REG; 1868daecdc66SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1869daecdc66SHeiko Stübner } else { 1870daecdc66SHeiko Stübner *regmap = info->regmap_base; 1871daecdc66SHeiko Stübner *reg = RK3368_DRV_GRF_OFFSET; 1872daecdc66SHeiko Stübner 1873daecdc66SHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1874daecdc66SHeiko Stübner *reg -= 0x10; 1875daecdc66SHeiko Stübner *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 1876daecdc66SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1877daecdc66SHeiko Stübner 1878daecdc66SHeiko Stübner *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 1879daecdc66SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1880daecdc66SHeiko Stübner } 188142573ab3SSebastian Reichel 188242573ab3SSebastian Reichel return 0; 1883daecdc66SHeiko Stübner } 1884daecdc66SHeiko Stübner 1885b6c23275SDavid Wu #define RK3399_PULL_GRF_OFFSET 0xe040 1886b6c23275SDavid Wu #define RK3399_PULL_PMU_OFFSET 0x40 1887b6c23275SDavid Wu #define RK3399_DRV_3BITS_PER_PIN 3 1888b6c23275SDavid Wu 188942573ab3SSebastian Reichel static int rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1890b6c23275SDavid Wu int pin_num, struct regmap **regmap, 1891b6c23275SDavid Wu int *reg, u8 *bit) 1892b6c23275SDavid Wu { 1893b6c23275SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 1894b6c23275SDavid Wu 1895b6c23275SDavid Wu /* The bank0:16 and bank1:32 pins are located in PMU */ 1896b6c23275SDavid Wu if ((bank->bank_num == 0) || (bank->bank_num == 1)) { 1897b6c23275SDavid Wu *regmap = info->regmap_pmu; 1898b6c23275SDavid Wu *reg = RK3399_PULL_PMU_OFFSET; 1899b6c23275SDavid Wu 1900b6c23275SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1901b6c23275SDavid Wu 1902b6c23275SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1903b6c23275SDavid Wu *bit = pin_num % RK3188_PULL_PINS_PER_REG; 1904b6c23275SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 1905b6c23275SDavid Wu } else { 1906b6c23275SDavid Wu *regmap = info->regmap_base; 1907b6c23275SDavid Wu *reg = RK3399_PULL_GRF_OFFSET; 1908b6c23275SDavid Wu 1909b6c23275SDavid Wu /* correct the offset, as we're starting with the 3rd bank */ 1910b6c23275SDavid Wu *reg -= 0x20; 1911b6c23275SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1912b6c23275SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1913b6c23275SDavid Wu 1914b6c23275SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1915b6c23275SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 1916b6c23275SDavid Wu } 191742573ab3SSebastian Reichel 191842573ab3SSebastian Reichel return 0; 1919b6c23275SDavid Wu } 1920b6c23275SDavid Wu 192142573ab3SSebastian Reichel static int rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1922b6c23275SDavid Wu int pin_num, struct regmap **regmap, 1923b6c23275SDavid Wu int *reg, u8 *bit) 1924b6c23275SDavid Wu { 1925b6c23275SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 1926b6c23275SDavid Wu int drv_num = (pin_num / 8); 1927b6c23275SDavid Wu 1928b6c23275SDavid Wu /* The bank0:16 and bank1:32 pins are located in PMU */ 1929b6c23275SDavid Wu if ((bank->bank_num == 0) || (bank->bank_num == 1)) 1930b6c23275SDavid Wu *regmap = info->regmap_pmu; 1931b6c23275SDavid Wu else 1932b6c23275SDavid Wu *regmap = info->regmap_base; 1933b6c23275SDavid Wu 1934b6c23275SDavid Wu *reg = bank->drv[drv_num].offset; 1935b6c23275SDavid Wu if ((bank->drv[drv_num].drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || 1936b6c23275SDavid Wu (bank->drv[drv_num].drv_type == DRV_TYPE_IO_3V3_ONLY)) 1937b6c23275SDavid Wu *bit = (pin_num % 8) * 3; 1938b6c23275SDavid Wu else 1939b6c23275SDavid Wu *bit = (pin_num % 8) * 2; 194042573ab3SSebastian Reichel 194142573ab3SSebastian Reichel return 0; 1942b6c23275SDavid Wu } 1943b6c23275SDavid Wu 1944c0dadc0eSJianqun Xu #define RK3568_PULL_PMU_OFFSET 0x20 1945c0dadc0eSJianqun Xu #define RK3568_PULL_GRF_OFFSET 0x80 1946c0dadc0eSJianqun Xu #define RK3568_PULL_BITS_PER_PIN 2 1947c0dadc0eSJianqun Xu #define RK3568_PULL_PINS_PER_REG 8 1948c0dadc0eSJianqun Xu #define RK3568_PULL_BANK_STRIDE 0x10 1949c0dadc0eSJianqun Xu 195042573ab3SSebastian Reichel static int rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1951c0dadc0eSJianqun Xu int pin_num, struct regmap **regmap, 1952c0dadc0eSJianqun Xu int *reg, u8 *bit) 1953c0dadc0eSJianqun Xu { 1954c0dadc0eSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 1955c0dadc0eSJianqun Xu 1956c0dadc0eSJianqun Xu if (bank->bank_num == 0) { 1957c0dadc0eSJianqun Xu *regmap = info->regmap_pmu; 1958c0dadc0eSJianqun Xu *reg = RK3568_PULL_PMU_OFFSET; 1959c0dadc0eSJianqun Xu *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; 1960c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); 1961c0dadc0eSJianqun Xu 1962c0dadc0eSJianqun Xu *bit = pin_num % RK3568_PULL_PINS_PER_REG; 1963c0dadc0eSJianqun Xu *bit *= RK3568_PULL_BITS_PER_PIN; 1964c0dadc0eSJianqun Xu } else { 1965c0dadc0eSJianqun Xu *regmap = info->regmap_base; 1966c0dadc0eSJianqun Xu *reg = RK3568_PULL_GRF_OFFSET; 1967c0dadc0eSJianqun Xu *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; 1968c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); 1969c0dadc0eSJianqun Xu 1970c0dadc0eSJianqun Xu *bit = (pin_num % RK3568_PULL_PINS_PER_REG); 1971c0dadc0eSJianqun Xu *bit *= RK3568_PULL_BITS_PER_PIN; 1972c0dadc0eSJianqun Xu } 197342573ab3SSebastian Reichel 197442573ab3SSebastian Reichel return 0; 1975c0dadc0eSJianqun Xu } 1976c0dadc0eSJianqun Xu 1977c0dadc0eSJianqun Xu #define RK3568_DRV_PMU_OFFSET 0x70 1978c0dadc0eSJianqun Xu #define RK3568_DRV_GRF_OFFSET 0x200 1979c0dadc0eSJianqun Xu #define RK3568_DRV_BITS_PER_PIN 8 1980c0dadc0eSJianqun Xu #define RK3568_DRV_PINS_PER_REG 2 1981c0dadc0eSJianqun Xu #define RK3568_DRV_BANK_STRIDE 0x40 1982c0dadc0eSJianqun Xu 198342573ab3SSebastian Reichel static int rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1984c0dadc0eSJianqun Xu int pin_num, struct regmap **regmap, 1985c0dadc0eSJianqun Xu int *reg, u8 *bit) 1986c0dadc0eSJianqun Xu { 1987c0dadc0eSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 1988c0dadc0eSJianqun Xu 1989c0dadc0eSJianqun Xu /* The first 32 pins of the first bank are located in PMU */ 1990c0dadc0eSJianqun Xu if (bank->bank_num == 0) { 1991c0dadc0eSJianqun Xu *regmap = info->regmap_pmu; 1992c0dadc0eSJianqun Xu *reg = RK3568_DRV_PMU_OFFSET; 1993c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); 1994c0dadc0eSJianqun Xu 1995c0dadc0eSJianqun Xu *bit = pin_num % RK3568_DRV_PINS_PER_REG; 1996c0dadc0eSJianqun Xu *bit *= RK3568_DRV_BITS_PER_PIN; 1997c0dadc0eSJianqun Xu } else { 1998c0dadc0eSJianqun Xu *regmap = info->regmap_base; 1999c0dadc0eSJianqun Xu *reg = RK3568_DRV_GRF_OFFSET; 2000c0dadc0eSJianqun Xu *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; 2001c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); 2002c0dadc0eSJianqun Xu 2003c0dadc0eSJianqun Xu *bit = (pin_num % RK3568_DRV_PINS_PER_REG); 2004c0dadc0eSJianqun Xu *bit *= RK3568_DRV_BITS_PER_PIN; 2005c0dadc0eSJianqun Xu } 200642573ab3SSebastian Reichel 200742573ab3SSebastian Reichel return 0; 2008c0dadc0eSJianqun Xu } 2009c0dadc0eSJianqun Xu 2010fdc33ebaSJianqun Xu #define RK3588_PMU1_IOC_REG (0x0000) 2011fdc33ebaSJianqun Xu #define RK3588_PMU2_IOC_REG (0x4000) 2012fdc33ebaSJianqun Xu #define RK3588_BUS_IOC_REG (0x8000) 2013fdc33ebaSJianqun Xu #define RK3588_VCCIO1_4_IOC_REG (0x9000) 2014fdc33ebaSJianqun Xu #define RK3588_VCCIO3_5_IOC_REG (0xA000) 2015fdc33ebaSJianqun Xu #define RK3588_VCCIO2_IOC_REG (0xB000) 2016fdc33ebaSJianqun Xu #define RK3588_VCCIO6_IOC_REG (0xC000) 2017fdc33ebaSJianqun Xu #define RK3588_EMMC_IOC_REG (0xD000) 2018fdc33ebaSJianqun Xu 2019fdc33ebaSJianqun Xu static const u32 rk3588_ds_regs[][2] = { 2020fdc33ebaSJianqun Xu {RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0010}, 2021fdc33ebaSJianqun Xu {RK_GPIO0_A4, RK3588_PMU1_IOC_REG + 0x0014}, 2022fdc33ebaSJianqun Xu {RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0018}, 2023fdc33ebaSJianqun Xu {RK_GPIO0_B4, RK3588_PMU2_IOC_REG + 0x0014}, 2024fdc33ebaSJianqun Xu {RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0018}, 2025fdc33ebaSJianqun Xu {RK_GPIO0_C4, RK3588_PMU2_IOC_REG + 0x001C}, 2026fdc33ebaSJianqun Xu {RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0020}, 2027fdc33ebaSJianqun Xu {RK_GPIO0_D4, RK3588_PMU2_IOC_REG + 0x0024}, 2028fdc33ebaSJianqun Xu {RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0020}, 2029fdc33ebaSJianqun Xu {RK_GPIO1_A4, RK3588_VCCIO1_4_IOC_REG + 0x0024}, 2030fdc33ebaSJianqun Xu {RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0028}, 2031fdc33ebaSJianqun Xu {RK_GPIO1_B4, RK3588_VCCIO1_4_IOC_REG + 0x002C}, 2032fdc33ebaSJianqun Xu {RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0030}, 2033fdc33ebaSJianqun Xu {RK_GPIO1_C4, RK3588_VCCIO1_4_IOC_REG + 0x0034}, 2034fdc33ebaSJianqun Xu {RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x0038}, 2035fdc33ebaSJianqun Xu {RK_GPIO1_D4, RK3588_VCCIO1_4_IOC_REG + 0x003C}, 2036fdc33ebaSJianqun Xu {RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0040}, 2037fdc33ebaSJianqun Xu {RK_GPIO2_A4, RK3588_VCCIO3_5_IOC_REG + 0x0044}, 2038fdc33ebaSJianqun Xu {RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0048}, 2039fdc33ebaSJianqun Xu {RK_GPIO2_B4, RK3588_VCCIO3_5_IOC_REG + 0x004C}, 2040fdc33ebaSJianqun Xu {RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0050}, 2041fdc33ebaSJianqun Xu {RK_GPIO2_C4, RK3588_VCCIO3_5_IOC_REG + 0x0054}, 2042fdc33ebaSJianqun Xu {RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x0058}, 2043fdc33ebaSJianqun Xu {RK_GPIO2_D4, RK3588_EMMC_IOC_REG + 0x005C}, 2044fdc33ebaSJianqun Xu {RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0060}, 2045fdc33ebaSJianqun Xu {RK_GPIO3_A4, RK3588_VCCIO3_5_IOC_REG + 0x0064}, 2046fdc33ebaSJianqun Xu {RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0068}, 2047fdc33ebaSJianqun Xu {RK_GPIO3_B4, RK3588_VCCIO3_5_IOC_REG + 0x006C}, 2048fdc33ebaSJianqun Xu {RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0070}, 2049fdc33ebaSJianqun Xu {RK_GPIO3_C4, RK3588_VCCIO3_5_IOC_REG + 0x0074}, 2050fdc33ebaSJianqun Xu {RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x0078}, 2051fdc33ebaSJianqun Xu {RK_GPIO3_D4, RK3588_VCCIO3_5_IOC_REG + 0x007C}, 2052fdc33ebaSJianqun Xu {RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0080}, 2053fdc33ebaSJianqun Xu {RK_GPIO4_A4, RK3588_VCCIO6_IOC_REG + 0x0084}, 2054fdc33ebaSJianqun Xu {RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0088}, 2055fdc33ebaSJianqun Xu {RK_GPIO4_B4, RK3588_VCCIO6_IOC_REG + 0x008C}, 2056fdc33ebaSJianqun Xu {RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0090}, 2057fdc33ebaSJianqun Xu {RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0090}, 2058fdc33ebaSJianqun Xu {RK_GPIO4_C4, RK3588_VCCIO3_5_IOC_REG + 0x0094}, 2059fdc33ebaSJianqun Xu {RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x0098}, 2060fdc33ebaSJianqun Xu {RK_GPIO4_D4, RK3588_VCCIO2_IOC_REG + 0x009C}, 2061fdc33ebaSJianqun Xu }; 2062fdc33ebaSJianqun Xu 2063fdc33ebaSJianqun Xu static const u32 rk3588_p_regs[][2] = { 2064fdc33ebaSJianqun Xu {RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0020}, 2065fdc33ebaSJianqun Xu {RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0024}, 2066fdc33ebaSJianqun Xu {RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0028}, 2067fdc33ebaSJianqun Xu {RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x002C}, 2068fdc33ebaSJianqun Xu {RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0030}, 2069fdc33ebaSJianqun Xu {RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0110}, 2070fdc33ebaSJianqun Xu {RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0114}, 2071fdc33ebaSJianqun Xu {RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0118}, 2072fdc33ebaSJianqun Xu {RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x011C}, 2073fdc33ebaSJianqun Xu {RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0120}, 2074fdc33ebaSJianqun Xu {RK_GPIO2_A6, RK3588_VCCIO3_5_IOC_REG + 0x0120}, 2075fdc33ebaSJianqun Xu {RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0124}, 2076fdc33ebaSJianqun Xu {RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0128}, 2077fdc33ebaSJianqun Xu {RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x012C}, 2078fdc33ebaSJianqun Xu {RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0130}, 2079fdc33ebaSJianqun Xu {RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0134}, 2080fdc33ebaSJianqun Xu {RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0138}, 2081fdc33ebaSJianqun Xu {RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x013C}, 2082fdc33ebaSJianqun Xu {RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0140}, 2083fdc33ebaSJianqun Xu {RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0144}, 2084fdc33ebaSJianqun Xu {RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0148}, 2085fdc33ebaSJianqun Xu {RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0148}, 2086fdc33ebaSJianqun Xu {RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x014C}, 2087fdc33ebaSJianqun Xu }; 2088fdc33ebaSJianqun Xu 2089fdc33ebaSJianqun Xu static const u32 rk3588_smt_regs[][2] = { 2090fdc33ebaSJianqun Xu {RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0030}, 2091fdc33ebaSJianqun Xu {RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0034}, 2092fdc33ebaSJianqun Xu {RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0040}, 2093fdc33ebaSJianqun Xu {RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0044}, 2094fdc33ebaSJianqun Xu {RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0048}, 2095fdc33ebaSJianqun Xu {RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0210}, 2096fdc33ebaSJianqun Xu {RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0214}, 2097fdc33ebaSJianqun Xu {RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0218}, 2098fdc33ebaSJianqun Xu {RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x021C}, 2099fdc33ebaSJianqun Xu {RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0220}, 2100fdc33ebaSJianqun Xu {RK_GPIO2_A6, RK3588_VCCIO3_5_IOC_REG + 0x0220}, 2101fdc33ebaSJianqun Xu {RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0224}, 2102fdc33ebaSJianqun Xu {RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0228}, 2103fdc33ebaSJianqun Xu {RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x022C}, 2104fdc33ebaSJianqun Xu {RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0230}, 2105fdc33ebaSJianqun Xu {RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0234}, 2106fdc33ebaSJianqun Xu {RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0238}, 2107fdc33ebaSJianqun Xu {RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x023C}, 2108fdc33ebaSJianqun Xu {RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0240}, 2109fdc33ebaSJianqun Xu {RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0244}, 2110fdc33ebaSJianqun Xu {RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0248}, 2111fdc33ebaSJianqun Xu {RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0248}, 2112fdc33ebaSJianqun Xu {RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x024C}, 2113fdc33ebaSJianqun Xu }; 2114fdc33ebaSJianqun Xu 2115fdc33ebaSJianqun Xu #define RK3588_PULL_BITS_PER_PIN 2 2116fdc33ebaSJianqun Xu #define RK3588_PULL_PINS_PER_REG 8 2117fdc33ebaSJianqun Xu 2118fdc33ebaSJianqun Xu static int rk3588_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 2119fdc33ebaSJianqun Xu int pin_num, struct regmap **regmap, 2120fdc33ebaSJianqun Xu int *reg, u8 *bit) 2121fdc33ebaSJianqun Xu { 2122fdc33ebaSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 2123fdc33ebaSJianqun Xu u8 bank_num = bank->bank_num; 2124fdc33ebaSJianqun Xu u32 pin = bank_num * 32 + pin_num; 2125fdc33ebaSJianqun Xu int i; 2126fdc33ebaSJianqun Xu 2127fdc33ebaSJianqun Xu for (i = ARRAY_SIZE(rk3588_p_regs) - 1; i >= 0; i--) { 2128fdc33ebaSJianqun Xu if (pin >= rk3588_p_regs[i][0]) { 2129fdc33ebaSJianqun Xu *reg = rk3588_p_regs[i][1]; 2130fdc33ebaSJianqun Xu *regmap = info->regmap_base; 2131fdc33ebaSJianqun Xu *bit = pin_num % RK3588_PULL_PINS_PER_REG; 2132fdc33ebaSJianqun Xu *bit *= RK3588_PULL_BITS_PER_PIN; 2133fdc33ebaSJianqun Xu return 0; 2134fdc33ebaSJianqun Xu } 2135fdc33ebaSJianqun Xu } 2136fdc33ebaSJianqun Xu 2137fdc33ebaSJianqun Xu return -EINVAL; 2138fdc33ebaSJianqun Xu } 2139fdc33ebaSJianqun Xu 2140fdc33ebaSJianqun Xu #define RK3588_DRV_BITS_PER_PIN 4 2141fdc33ebaSJianqun Xu #define RK3588_DRV_PINS_PER_REG 4 2142fdc33ebaSJianqun Xu 2143fdc33ebaSJianqun Xu static int rk3588_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 2144fdc33ebaSJianqun Xu int pin_num, struct regmap **regmap, 2145fdc33ebaSJianqun Xu int *reg, u8 *bit) 2146fdc33ebaSJianqun Xu { 2147fdc33ebaSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 2148fdc33ebaSJianqun Xu u8 bank_num = bank->bank_num; 2149fdc33ebaSJianqun Xu u32 pin = bank_num * 32 + pin_num; 2150fdc33ebaSJianqun Xu int i; 2151fdc33ebaSJianqun Xu 2152fdc33ebaSJianqun Xu for (i = ARRAY_SIZE(rk3588_ds_regs) - 1; i >= 0; i--) { 2153fdc33ebaSJianqun Xu if (pin >= rk3588_ds_regs[i][0]) { 2154fdc33ebaSJianqun Xu *reg = rk3588_ds_regs[i][1]; 2155fdc33ebaSJianqun Xu *regmap = info->regmap_base; 2156fdc33ebaSJianqun Xu *bit = pin_num % RK3588_DRV_PINS_PER_REG; 2157fdc33ebaSJianqun Xu *bit *= RK3588_DRV_BITS_PER_PIN; 2158fdc33ebaSJianqun Xu return 0; 2159fdc33ebaSJianqun Xu } 2160fdc33ebaSJianqun Xu } 2161fdc33ebaSJianqun Xu 2162fdc33ebaSJianqun Xu return -EINVAL; 2163fdc33ebaSJianqun Xu } 2164fdc33ebaSJianqun Xu 2165fdc33ebaSJianqun Xu #define RK3588_SMT_BITS_PER_PIN 1 2166fdc33ebaSJianqun Xu #define RK3588_SMT_PINS_PER_REG 8 2167fdc33ebaSJianqun Xu 2168fdc33ebaSJianqun Xu static int rk3588_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 2169fdc33ebaSJianqun Xu int pin_num, 2170fdc33ebaSJianqun Xu struct regmap **regmap, 2171fdc33ebaSJianqun Xu int *reg, u8 *bit) 2172fdc33ebaSJianqun Xu { 2173fdc33ebaSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 2174fdc33ebaSJianqun Xu u8 bank_num = bank->bank_num; 2175fdc33ebaSJianqun Xu u32 pin = bank_num * 32 + pin_num; 2176fdc33ebaSJianqun Xu int i; 2177fdc33ebaSJianqun Xu 2178fdc33ebaSJianqun Xu for (i = ARRAY_SIZE(rk3588_smt_regs) - 1; i >= 0; i--) { 2179fdc33ebaSJianqun Xu if (pin >= rk3588_smt_regs[i][0]) { 2180fdc33ebaSJianqun Xu *reg = rk3588_smt_regs[i][1]; 2181fdc33ebaSJianqun Xu *regmap = info->regmap_base; 2182fdc33ebaSJianqun Xu *bit = pin_num % RK3588_SMT_PINS_PER_REG; 2183fdc33ebaSJianqun Xu *bit *= RK3588_SMT_BITS_PER_PIN; 2184fdc33ebaSJianqun Xu return 0; 2185fdc33ebaSJianqun Xu } 2186fdc33ebaSJianqun Xu } 2187fdc33ebaSJianqun Xu 2188fdc33ebaSJianqun Xu return -EINVAL; 2189fdc33ebaSJianqun Xu } 2190fdc33ebaSJianqun Xu 2191b6c23275SDavid Wu static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { 2192b6c23275SDavid Wu { 2, 4, 8, 12, -1, -1, -1, -1 }, 2193b6c23275SDavid Wu { 3, 6, 9, 12, -1, -1, -1, -1 }, 2194b6c23275SDavid Wu { 5, 10, 15, 20, -1, -1, -1, -1 }, 2195b6c23275SDavid Wu { 4, 6, 8, 10, 12, 14, 16, 18 }, 2196b6c23275SDavid Wu { 4, 7, 10, 13, 16, 19, 22, 26 } 2197b6c23275SDavid Wu }; 2198ef17f69fSHeiko Stübner 2199ef17f69fSHeiko Stübner static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank, 2200ef17f69fSHeiko Stübner int pin_num) 2201b547c800SHeiko Stübner { 2202ef17f69fSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 2203ef17f69fSHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 2204e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2205b547c800SHeiko Stübner struct regmap *regmap; 2206b547c800SHeiko Stübner int reg, ret; 2207b6c23275SDavid Wu u32 data, temp, rmask_bits; 2208b547c800SHeiko Stübner u8 bit; 2209b6c23275SDavid Wu int drv_type = bank->drv[pin_num / 8].drv_type; 2210b547c800SHeiko Stübner 221142573ab3SSebastian Reichel ret = ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); 221242573ab3SSebastian Reichel if (ret) 221342573ab3SSebastian Reichel return ret; 2214b547c800SHeiko Stübner 2215b6c23275SDavid Wu switch (drv_type) { 2216b6c23275SDavid Wu case DRV_TYPE_IO_1V8_3V0_AUTO: 2217b6c23275SDavid Wu case DRV_TYPE_IO_3V3_ONLY: 2218b6c23275SDavid Wu rmask_bits = RK3399_DRV_3BITS_PER_PIN; 2219b6c23275SDavid Wu switch (bit) { 2220b6c23275SDavid Wu case 0 ... 12: 2221b6c23275SDavid Wu /* regular case, nothing to do */ 2222b6c23275SDavid Wu break; 2223b6c23275SDavid Wu case 15: 2224b6c23275SDavid Wu /* 2225b6c23275SDavid Wu * drive-strength offset is special, as it is 2226b6c23275SDavid Wu * spread over 2 registers 2227b6c23275SDavid Wu */ 2228b6c23275SDavid Wu ret = regmap_read(regmap, reg, &data); 2229b6c23275SDavid Wu if (ret) 2230b6c23275SDavid Wu return ret; 2231b6c23275SDavid Wu 2232b6c23275SDavid Wu ret = regmap_read(regmap, reg + 0x4, &temp); 2233b6c23275SDavid Wu if (ret) 2234b6c23275SDavid Wu return ret; 2235b6c23275SDavid Wu 2236b6c23275SDavid Wu /* 2237b6c23275SDavid Wu * the bit data[15] contains bit 0 of the value 2238b6c23275SDavid Wu * while temp[1:0] contains bits 2 and 1 2239b6c23275SDavid Wu */ 2240b6c23275SDavid Wu data >>= 15; 2241b6c23275SDavid Wu temp &= 0x3; 2242b6c23275SDavid Wu temp <<= 1; 2243b6c23275SDavid Wu data |= temp; 2244b6c23275SDavid Wu 2245b6c23275SDavid Wu return rockchip_perpin_drv_list[drv_type][data]; 2246b6c23275SDavid Wu case 18 ... 21: 2247b6c23275SDavid Wu /* setting fully enclosed in the second register */ 2248b6c23275SDavid Wu reg += 4; 2249b6c23275SDavid Wu bit -= 16; 2250b6c23275SDavid Wu break; 2251b6c23275SDavid Wu default: 2252e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n", 2253b6c23275SDavid Wu bit, drv_type); 2254b6c23275SDavid Wu return -EINVAL; 2255b6c23275SDavid Wu } 2256b6c23275SDavid Wu 2257b6c23275SDavid Wu break; 2258b6c23275SDavid Wu case DRV_TYPE_IO_DEFAULT: 2259b6c23275SDavid Wu case DRV_TYPE_IO_1V8_OR_3V0: 2260b6c23275SDavid Wu case DRV_TYPE_IO_1V8_ONLY: 2261b6c23275SDavid Wu rmask_bits = RK3288_DRV_BITS_PER_PIN; 2262b6c23275SDavid Wu break; 2263b6c23275SDavid Wu default: 2264e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type); 2265b6c23275SDavid Wu return -EINVAL; 2266b6c23275SDavid Wu } 2267b6c23275SDavid Wu 2268b547c800SHeiko Stübner ret = regmap_read(regmap, reg, &data); 2269b547c800SHeiko Stübner if (ret) 2270b547c800SHeiko Stübner return ret; 2271b547c800SHeiko Stübner 2272b547c800SHeiko Stübner data >>= bit; 2273b6c23275SDavid Wu data &= (1 << rmask_bits) - 1; 2274b547c800SHeiko Stübner 2275b6c23275SDavid Wu return rockchip_perpin_drv_list[drv_type][data]; 2276b547c800SHeiko Stübner } 2277b547c800SHeiko Stübner 2278ef17f69fSHeiko Stübner static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, 2279ef17f69fSHeiko Stübner int pin_num, int strength) 2280b547c800SHeiko Stübner { 2281b547c800SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 2282ef17f69fSHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 2283e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2284b547c800SHeiko Stübner struct regmap *regmap; 2285b547c800SHeiko Stübner int reg, ret, i; 2286b6c23275SDavid Wu u32 data, rmask, rmask_bits, temp; 2287b547c800SHeiko Stübner u8 bit; 2288b6c23275SDavid Wu int drv_type = bank->drv[pin_num / 8].drv_type; 2289b6c23275SDavid Wu 2290e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting drive of GPIO%d-%d to %d\n", 2291b6c23275SDavid Wu bank->bank_num, pin_num, strength); 2292b547c800SHeiko Stübner 229342573ab3SSebastian Reichel ret = ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); 229442573ab3SSebastian Reichel if (ret) 229542573ab3SSebastian Reichel return ret; 2296fdc33ebaSJianqun Xu if (ctrl->type == RK3588) { 2297fdc33ebaSJianqun Xu rmask_bits = RK3588_DRV_BITS_PER_PIN; 2298fdc33ebaSJianqun Xu ret = strength; 2299fdc33ebaSJianqun Xu goto config; 2300fdc33ebaSJianqun Xu } else if (ctrl->type == RK3568) { 2301c0dadc0eSJianqun Xu rmask_bits = RK3568_DRV_BITS_PER_PIN; 2302c0dadc0eSJianqun Xu ret = (1 << (strength + 1)) - 1; 2303c0dadc0eSJianqun Xu goto config; 2304c0dadc0eSJianqun Xu } 2305b547c800SHeiko Stübner 2306fd4ea486SJagan Teki if (ctrl->type == RV1126) { 2307fd4ea486SJagan Teki rmask_bits = RV1126_DRV_BITS_PER_PIN; 2308fd4ea486SJagan Teki ret = strength; 2309fd4ea486SJagan Teki goto config; 2310fd4ea486SJagan Teki } 2311fd4ea486SJagan Teki 2312b547c800SHeiko Stübner ret = -EINVAL; 2313b6c23275SDavid Wu for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) { 2314b6c23275SDavid Wu if (rockchip_perpin_drv_list[drv_type][i] == strength) { 2315b547c800SHeiko Stübner ret = i; 2316b547c800SHeiko Stübner break; 2317b6c23275SDavid Wu } else if (rockchip_perpin_drv_list[drv_type][i] < 0) { 2318b6c23275SDavid Wu ret = rockchip_perpin_drv_list[drv_type][i]; 2319b6c23275SDavid Wu break; 2320b547c800SHeiko Stübner } 2321b547c800SHeiko Stübner } 2322b547c800SHeiko Stübner 2323b547c800SHeiko Stübner if (ret < 0) { 2324e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported driver strength %d\n", strength); 2325b547c800SHeiko Stübner return ret; 2326b547c800SHeiko Stübner } 2327b547c800SHeiko Stübner 2328b6c23275SDavid Wu switch (drv_type) { 2329b6c23275SDavid Wu case DRV_TYPE_IO_1V8_3V0_AUTO: 2330b6c23275SDavid Wu case DRV_TYPE_IO_3V3_ONLY: 2331b6c23275SDavid Wu rmask_bits = RK3399_DRV_3BITS_PER_PIN; 2332b6c23275SDavid Wu switch (bit) { 2333b6c23275SDavid Wu case 0 ... 12: 2334b6c23275SDavid Wu /* regular case, nothing to do */ 2335b6c23275SDavid Wu break; 2336b6c23275SDavid Wu case 15: 2337b6c23275SDavid Wu /* 2338b6c23275SDavid Wu * drive-strength offset is special, as it is spread 2339b6c23275SDavid Wu * over 2 registers, the bit data[15] contains bit 0 2340b6c23275SDavid Wu * of the value while temp[1:0] contains bits 2 and 1 2341b6c23275SDavid Wu */ 2342b6c23275SDavid Wu data = (ret & 0x1) << 15; 2343b6c23275SDavid Wu temp = (ret >> 0x1) & 0x3; 2344b6c23275SDavid Wu 2345b6c23275SDavid Wu rmask = BIT(15) | BIT(31); 2346b6c23275SDavid Wu data |= BIT(31); 2347b6c23275SDavid Wu ret = regmap_update_bits(regmap, reg, rmask, data); 2348f07bedc3SJohn Keeping if (ret) 2349b6c23275SDavid Wu return ret; 2350b6c23275SDavid Wu 2351b6c23275SDavid Wu rmask = 0x3 | (0x3 << 16); 2352b6c23275SDavid Wu temp |= (0x3 << 16); 2353b6c23275SDavid Wu reg += 0x4; 2354b6c23275SDavid Wu ret = regmap_update_bits(regmap, reg, rmask, temp); 2355b6c23275SDavid Wu 2356b6c23275SDavid Wu return ret; 2357b6c23275SDavid Wu case 18 ... 21: 2358b6c23275SDavid Wu /* setting fully enclosed in the second register */ 2359b6c23275SDavid Wu reg += 4; 2360b6c23275SDavid Wu bit -= 16; 2361b6c23275SDavid Wu break; 2362b6c23275SDavid Wu default: 2363e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n", 2364b6c23275SDavid Wu bit, drv_type); 2365b6c23275SDavid Wu return -EINVAL; 2366b6c23275SDavid Wu } 2367b6c23275SDavid Wu break; 2368b6c23275SDavid Wu case DRV_TYPE_IO_DEFAULT: 2369b6c23275SDavid Wu case DRV_TYPE_IO_1V8_OR_3V0: 2370b6c23275SDavid Wu case DRV_TYPE_IO_1V8_ONLY: 2371b6c23275SDavid Wu rmask_bits = RK3288_DRV_BITS_PER_PIN; 2372b6c23275SDavid Wu break; 2373b6c23275SDavid Wu default: 2374e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type); 2375b6c23275SDavid Wu return -EINVAL; 2376b6c23275SDavid Wu } 2377b6c23275SDavid Wu 2378c0dadc0eSJianqun Xu config: 2379b547c800SHeiko Stübner /* enable the write to the equivalent lower bits */ 2380b6c23275SDavid Wu data = ((1 << rmask_bits) - 1) << (bit + 16); 238199e872d9SSonny Rao rmask = data | (data >> 16); 2382b547c800SHeiko Stübner data |= (ret << bit); 2383b547c800SHeiko Stübner 238499e872d9SSonny Rao ret = regmap_update_bits(regmap, reg, rmask, data); 2385b547c800SHeiko Stübner 2386b547c800SHeiko Stübner return ret; 2387b547c800SHeiko Stübner } 2388b547c800SHeiko Stübner 23893ba6767aSDavid Wu static int rockchip_pull_list[PULL_TYPE_MAX][4] = { 23903ba6767aSDavid Wu { 23913ba6767aSDavid Wu PIN_CONFIG_BIAS_DISABLE, 23923ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_UP, 23933ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_DOWN, 23943ba6767aSDavid Wu PIN_CONFIG_BIAS_BUS_HOLD 23953ba6767aSDavid Wu }, 23963ba6767aSDavid Wu { 23973ba6767aSDavid Wu PIN_CONFIG_BIAS_DISABLE, 23983ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_DOWN, 23993ba6767aSDavid Wu PIN_CONFIG_BIAS_DISABLE, 24003ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_UP 24013ba6767aSDavid Wu }, 24023ba6767aSDavid Wu }; 24033ba6767aSDavid Wu 2404d3e51161SHeiko Stübner static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) 2405d3e51161SHeiko Stübner { 2406d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 2407d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 2408e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2409751a99abSHeiko Stübner struct regmap *regmap; 24103ba6767aSDavid Wu int reg, ret, pull_type; 2411d3e51161SHeiko Stübner u8 bit; 24126ca5274dSHeiko Stübner u32 data; 2413d3e51161SHeiko Stübner 2414d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 2415a282926dSHeiko Stübner if (ctrl->type == RK3066B) 2416d3e51161SHeiko Stübner return PIN_CONFIG_BIAS_DISABLE; 2417d3e51161SHeiko Stübner 241842573ab3SSebastian Reichel ret = ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); 241942573ab3SSebastian Reichel if (ret) 242042573ab3SSebastian Reichel return ret; 2421751a99abSHeiko Stübner 2422751a99abSHeiko Stübner ret = regmap_read(regmap, reg, &data); 2423751a99abSHeiko Stübner if (ret) 2424751a99abSHeiko Stübner return ret; 24256ca5274dSHeiko Stübner 2426a282926dSHeiko Stübner switch (ctrl->type) { 2427a282926dSHeiko Stübner case RK2928: 2428d23c66dfSDavid Wu case RK3128: 2429751a99abSHeiko Stübner return !(data & BIT(bit)) 2430d3e51161SHeiko Stübner ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT 2431d3e51161SHeiko Stübner : PIN_CONFIG_BIAS_DISABLE; 243287065ca9SDavid Wu case PX30: 2433b9c6dcabSAndy Yan case RV1108: 2434a282926dSHeiko Stübner case RK3188: 243566d750e1SHeiko Stübner case RK3288: 24367825aeb7SJianqun Xu case RK3308: 2437daecdc66SHeiko Stübner case RK3368: 2438b6c23275SDavid Wu case RK3399: 2439fdc33ebaSJianqun Xu case RK3588: 24403ba6767aSDavid Wu pull_type = bank->pull_type[pin_num / 8]; 2441751a99abSHeiko Stübner data >>= bit; 24426ca5274dSHeiko Stübner data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; 24436ca5274dSHeiko Stübner 24443ba6767aSDavid Wu return rockchip_pull_list[pull_type][data]; 2445a282926dSHeiko Stübner default: 2446e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl type\n"); 2447a282926dSHeiko Stübner return -EINVAL; 2448a282926dSHeiko Stübner }; 2449d3e51161SHeiko Stübner } 2450d3e51161SHeiko Stübner 2451d3e51161SHeiko Stübner static int rockchip_set_pull(struct rockchip_pin_bank *bank, 2452d3e51161SHeiko Stübner int pin_num, int pull) 2453d3e51161SHeiko Stübner { 2454d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 2455d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 2456e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2457751a99abSHeiko Stübner struct regmap *regmap; 24583ba6767aSDavid Wu int reg, ret, i, pull_type; 2459d3e51161SHeiko Stübner u8 bit; 246099e872d9SSonny Rao u32 data, rmask; 2461d3e51161SHeiko Stübner 2462e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting pull of GPIO%d-%d to %d\n", bank->bank_num, pin_num, pull); 2463d3e51161SHeiko Stübner 2464d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 2465a282926dSHeiko Stübner if (ctrl->type == RK3066B) 2466d3e51161SHeiko Stübner return pull ? -EINVAL : 0; 2467d3e51161SHeiko Stübner 246842573ab3SSebastian Reichel ret = ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); 246942573ab3SSebastian Reichel if (ret) 247042573ab3SSebastian Reichel return ret; 2471d3e51161SHeiko Stübner 24726ca5274dSHeiko Stübner switch (ctrl->type) { 24736ca5274dSHeiko Stübner case RK2928: 2474d23c66dfSDavid Wu case RK3128: 2475d3e51161SHeiko Stübner data = BIT(bit + 16); 2476d3e51161SHeiko Stübner if (pull == PIN_CONFIG_BIAS_DISABLE) 2477d3e51161SHeiko Stübner data |= BIT(bit); 2478751a99abSHeiko Stübner ret = regmap_write(regmap, reg, data); 2479a282926dSHeiko Stübner break; 248087065ca9SDavid Wu case PX30: 2481b9c6dcabSAndy Yan case RV1108: 2482fd4ea486SJagan Teki case RV1126: 2483a282926dSHeiko Stübner case RK3188: 248466d750e1SHeiko Stübner case RK3288: 24857825aeb7SJianqun Xu case RK3308: 2486daecdc66SHeiko Stübner case RK3368: 2487b6c23275SDavid Wu case RK3399: 2488c0dadc0eSJianqun Xu case RK3568: 2489fdc33ebaSJianqun Xu case RK3588: 24903ba6767aSDavid Wu pull_type = bank->pull_type[pin_num / 8]; 24913ba6767aSDavid Wu ret = -EINVAL; 24923ba6767aSDavid Wu for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); 24933ba6767aSDavid Wu i++) { 24943ba6767aSDavid Wu if (rockchip_pull_list[pull_type][i] == pull) { 24953ba6767aSDavid Wu ret = i; 24963ba6767aSDavid Wu break; 24973ba6767aSDavid Wu } 24983ba6767aSDavid Wu } 2499c0dadc0eSJianqun Xu /* 2500c0dadc0eSJianqun Xu * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6, 2501c0dadc0eSJianqun Xu * where that pull up value becomes 3. 2502c0dadc0eSJianqun Xu */ 2503c0dadc0eSJianqun Xu if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { 2504c0dadc0eSJianqun Xu if (ret == 1) 2505c0dadc0eSJianqun Xu ret = 3; 2506c0dadc0eSJianqun Xu } 25073ba6767aSDavid Wu 25083ba6767aSDavid Wu if (ret < 0) { 2509e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pull setting %d\n", pull); 25103ba6767aSDavid Wu return ret; 25113ba6767aSDavid Wu } 25123ba6767aSDavid Wu 25136ca5274dSHeiko Stübner /* enable the write to the equivalent lower bits */ 25146ca5274dSHeiko Stübner data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); 251599e872d9SSonny Rao rmask = data | (data >> 16); 25163ba6767aSDavid Wu data |= (ret << bit); 25176ca5274dSHeiko Stübner 251899e872d9SSonny Rao ret = regmap_update_bits(regmap, reg, rmask, data); 25196ca5274dSHeiko Stübner break; 2520a282926dSHeiko Stübner default: 2521e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl type\n"); 2522a282926dSHeiko Stübner return -EINVAL; 2523d3e51161SHeiko Stübner } 2524d3e51161SHeiko Stübner 2525751a99abSHeiko Stübner return ret; 2526d3e51161SHeiko Stübner } 2527d3e51161SHeiko Stübner 2528728d3f5aSdavid.wu #define RK3328_SCHMITT_BITS_PER_PIN 1 2529728d3f5aSdavid.wu #define RK3328_SCHMITT_PINS_PER_REG 16 2530728d3f5aSdavid.wu #define RK3328_SCHMITT_BANK_STRIDE 8 2531728d3f5aSdavid.wu #define RK3328_SCHMITT_GRF_OFFSET 0x380 2532728d3f5aSdavid.wu 2533728d3f5aSdavid.wu static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 2534728d3f5aSdavid.wu int pin_num, 2535728d3f5aSdavid.wu struct regmap **regmap, 2536728d3f5aSdavid.wu int *reg, u8 *bit) 2537728d3f5aSdavid.wu { 2538728d3f5aSdavid.wu struct rockchip_pinctrl *info = bank->drvdata; 2539728d3f5aSdavid.wu 2540728d3f5aSdavid.wu *regmap = info->regmap_base; 2541728d3f5aSdavid.wu *reg = RK3328_SCHMITT_GRF_OFFSET; 2542728d3f5aSdavid.wu 2543728d3f5aSdavid.wu *reg += bank->bank_num * RK3328_SCHMITT_BANK_STRIDE; 2544728d3f5aSdavid.wu *reg += ((pin_num / RK3328_SCHMITT_PINS_PER_REG) * 4); 2545728d3f5aSdavid.wu *bit = pin_num % RK3328_SCHMITT_PINS_PER_REG; 2546728d3f5aSdavid.wu 2547728d3f5aSdavid.wu return 0; 2548728d3f5aSdavid.wu } 2549728d3f5aSdavid.wu 2550c0dadc0eSJianqun Xu #define RK3568_SCHMITT_BITS_PER_PIN 2 2551c0dadc0eSJianqun Xu #define RK3568_SCHMITT_PINS_PER_REG 8 2552c0dadc0eSJianqun Xu #define RK3568_SCHMITT_BANK_STRIDE 0x10 2553c0dadc0eSJianqun Xu #define RK3568_SCHMITT_GRF_OFFSET 0xc0 2554c0dadc0eSJianqun Xu #define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 2555c0dadc0eSJianqun Xu 2556c0dadc0eSJianqun Xu static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 2557c0dadc0eSJianqun Xu int pin_num, 2558c0dadc0eSJianqun Xu struct regmap **regmap, 2559c0dadc0eSJianqun Xu int *reg, u8 *bit) 2560c0dadc0eSJianqun Xu { 2561c0dadc0eSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 2562c0dadc0eSJianqun Xu 2563c0dadc0eSJianqun Xu if (bank->bank_num == 0) { 2564c0dadc0eSJianqun Xu *regmap = info->regmap_pmu; 2565c0dadc0eSJianqun Xu *reg = RK3568_SCHMITT_PMUGRF_OFFSET; 2566c0dadc0eSJianqun Xu } else { 2567c0dadc0eSJianqun Xu *regmap = info->regmap_base; 2568c0dadc0eSJianqun Xu *reg = RK3568_SCHMITT_GRF_OFFSET; 2569c0dadc0eSJianqun Xu *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; 2570c0dadc0eSJianqun Xu } 2571c0dadc0eSJianqun Xu 2572c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); 2573c0dadc0eSJianqun Xu *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; 2574c0dadc0eSJianqun Xu *bit *= RK3568_SCHMITT_BITS_PER_PIN; 2575c0dadc0eSJianqun Xu 2576c0dadc0eSJianqun Xu return 0; 2577c0dadc0eSJianqun Xu } 2578c0dadc0eSJianqun Xu 2579e3b357d7Sdavid.wu static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num) 2580e3b357d7Sdavid.wu { 2581e3b357d7Sdavid.wu struct rockchip_pinctrl *info = bank->drvdata; 2582e3b357d7Sdavid.wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 2583e3b357d7Sdavid.wu struct regmap *regmap; 2584e3b357d7Sdavid.wu int reg, ret; 2585e3b357d7Sdavid.wu u8 bit; 2586e3b357d7Sdavid.wu u32 data; 2587e3b357d7Sdavid.wu 2588e3b357d7Sdavid.wu ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit); 2589e3b357d7Sdavid.wu if (ret) 2590e3b357d7Sdavid.wu return ret; 2591e3b357d7Sdavid.wu 2592e3b357d7Sdavid.wu ret = regmap_read(regmap, reg, &data); 2593e3b357d7Sdavid.wu if (ret) 2594e3b357d7Sdavid.wu return ret; 2595e3b357d7Sdavid.wu 2596e3b357d7Sdavid.wu data >>= bit; 2597c0dadc0eSJianqun Xu switch (ctrl->type) { 2598c0dadc0eSJianqun Xu case RK3568: 2599c0dadc0eSJianqun Xu return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1); 2600c0dadc0eSJianqun Xu default: 2601c0dadc0eSJianqun Xu break; 2602c0dadc0eSJianqun Xu } 2603c0dadc0eSJianqun Xu 2604e3b357d7Sdavid.wu return data & 0x1; 2605e3b357d7Sdavid.wu } 2606e3b357d7Sdavid.wu 2607e3b357d7Sdavid.wu static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, 2608e3b357d7Sdavid.wu int pin_num, int enable) 2609e3b357d7Sdavid.wu { 2610e3b357d7Sdavid.wu struct rockchip_pinctrl *info = bank->drvdata; 2611e3b357d7Sdavid.wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 2612e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2613e3b357d7Sdavid.wu struct regmap *regmap; 2614e3b357d7Sdavid.wu int reg, ret; 2615e3b357d7Sdavid.wu u8 bit; 2616e3b357d7Sdavid.wu u32 data, rmask; 2617e3b357d7Sdavid.wu 2618e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting input schmitt of GPIO%d-%d to %d\n", 2619e3b357d7Sdavid.wu bank->bank_num, pin_num, enable); 2620e3b357d7Sdavid.wu 2621e3b357d7Sdavid.wu ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit); 2622e3b357d7Sdavid.wu if (ret) 2623e3b357d7Sdavid.wu return ret; 2624e3b357d7Sdavid.wu 2625e3b357d7Sdavid.wu /* enable the write to the equivalent lower bits */ 2626c0dadc0eSJianqun Xu switch (ctrl->type) { 2627c0dadc0eSJianqun Xu case RK3568: 2628c0dadc0eSJianqun Xu data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); 2629c0dadc0eSJianqun Xu rmask = data | (data >> 16); 2630c0dadc0eSJianqun Xu data |= ((enable ? 0x2 : 0x1) << bit); 2631c0dadc0eSJianqun Xu break; 2632c0dadc0eSJianqun Xu default: 2633e3b357d7Sdavid.wu data = BIT(bit + 16) | (enable << bit); 2634e3b357d7Sdavid.wu rmask = BIT(bit + 16) | BIT(bit); 2635c0dadc0eSJianqun Xu break; 2636c0dadc0eSJianqun Xu } 2637e3b357d7Sdavid.wu 2638f07bedc3SJohn Keeping return regmap_update_bits(regmap, reg, rmask, data); 2639e3b357d7Sdavid.wu } 2640e3b357d7Sdavid.wu 2641d3e51161SHeiko Stübner /* 2642d3e51161SHeiko Stübner * Pinmux_ops handling 2643d3e51161SHeiko Stübner */ 2644d3e51161SHeiko Stübner 2645d3e51161SHeiko Stübner static int rockchip_pmx_get_funcs_count(struct pinctrl_dev *pctldev) 2646d3e51161SHeiko Stübner { 2647d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2648d3e51161SHeiko Stübner 2649d3e51161SHeiko Stübner return info->nfunctions; 2650d3e51161SHeiko Stübner } 2651d3e51161SHeiko Stübner 2652d3e51161SHeiko Stübner static const char *rockchip_pmx_get_func_name(struct pinctrl_dev *pctldev, 2653d3e51161SHeiko Stübner unsigned selector) 2654d3e51161SHeiko Stübner { 2655d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2656d3e51161SHeiko Stübner 2657d3e51161SHeiko Stübner return info->functions[selector].name; 2658d3e51161SHeiko Stübner } 2659d3e51161SHeiko Stübner 2660d3e51161SHeiko Stübner static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev, 2661d3e51161SHeiko Stübner unsigned selector, const char * const **groups, 2662d3e51161SHeiko Stübner unsigned * const num_groups) 2663d3e51161SHeiko Stübner { 2664d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2665d3e51161SHeiko Stübner 2666d3e51161SHeiko Stübner *groups = info->functions[selector].groups; 2667d3e51161SHeiko Stübner *num_groups = info->functions[selector].ngroups; 2668d3e51161SHeiko Stübner 2669d3e51161SHeiko Stübner return 0; 2670d3e51161SHeiko Stübner } 2671d3e51161SHeiko Stübner 267203e9f0caSLinus Walleij static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, 2673d3e51161SHeiko Stübner unsigned group) 2674d3e51161SHeiko Stübner { 2675d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2676d3e51161SHeiko Stübner const unsigned int *pins = info->groups[group].pins; 2677d3e51161SHeiko Stübner const struct rockchip_pin_config *data = info->groups[group].data; 2678e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2679d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 268014797189SHeiko Stübner int cnt, ret = 0; 2681d3e51161SHeiko Stübner 2682e4dd7fd5SAndy Shevchenko dev_dbg(dev, "enable function %s group %s\n", 2683d3e51161SHeiko Stübner info->functions[selector].name, info->groups[group].name); 2684d3e51161SHeiko Stübner 2685d3e51161SHeiko Stübner /* 268685dc397aSMarkus Elfring * for each pin in the pin group selected, program the corresponding 2687d3e51161SHeiko Stübner * pin function number in the config register. 2688d3e51161SHeiko Stübner */ 2689d3e51161SHeiko Stübner for (cnt = 0; cnt < info->groups[group].npins; cnt++) { 2690d3e51161SHeiko Stübner bank = pin_to_bank(info, pins[cnt]); 269114797189SHeiko Stübner ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 2692d3e51161SHeiko Stübner data[cnt].func); 269314797189SHeiko Stübner if (ret) 269414797189SHeiko Stübner break; 269514797189SHeiko Stübner } 269614797189SHeiko Stübner 269714797189SHeiko Stübner if (ret) { 269814797189SHeiko Stübner /* revert the already done pin settings */ 269914797189SHeiko Stübner for (cnt--; cnt >= 0; cnt--) 270014797189SHeiko Stübner rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); 270114797189SHeiko Stübner 270214797189SHeiko Stübner return ret; 2703d3e51161SHeiko Stübner } 2704d3e51161SHeiko Stübner 2705d3e51161SHeiko Stübner return 0; 2706d3e51161SHeiko Stübner } 2707d3e51161SHeiko Stübner 27084635c0e2SQuentin Schulz static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, 27094635c0e2SQuentin Schulz struct pinctrl_gpio_range *range, 27104635c0e2SQuentin Schulz unsigned offset, 27114635c0e2SQuentin Schulz bool input) 27124635c0e2SQuentin Schulz { 27134635c0e2SQuentin Schulz struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 27144635c0e2SQuentin Schulz struct rockchip_pin_bank *bank; 27154635c0e2SQuentin Schulz 27164635c0e2SQuentin Schulz bank = pin_to_bank(info, offset); 27174635c0e2SQuentin Schulz return rockchip_set_mux(bank, offset - bank->pin_base, RK_FUNC_GPIO); 27184635c0e2SQuentin Schulz } 27194635c0e2SQuentin Schulz 2720d3e51161SHeiko Stübner static const struct pinmux_ops rockchip_pmx_ops = { 2721d3e51161SHeiko Stübner .get_functions_count = rockchip_pmx_get_funcs_count, 2722d3e51161SHeiko Stübner .get_function_name = rockchip_pmx_get_func_name, 2723d3e51161SHeiko Stübner .get_function_groups = rockchip_pmx_get_groups, 272403e9f0caSLinus Walleij .set_mux = rockchip_pmx_set, 27254635c0e2SQuentin Schulz .gpio_set_direction = rockchip_pmx_gpio_set_direction, 2726d3e51161SHeiko Stübner }; 2727d3e51161SHeiko Stübner 2728d3e51161SHeiko Stübner /* 2729d3e51161SHeiko Stübner * Pinconf_ops handling 2730d3e51161SHeiko Stübner */ 2731d3e51161SHeiko Stübner 273244b6d930SHeiko Stübner static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, 273344b6d930SHeiko Stübner enum pin_config_param pull) 273444b6d930SHeiko Stübner { 2735a282926dSHeiko Stübner switch (ctrl->type) { 2736a282926dSHeiko Stübner case RK2928: 2737d23c66dfSDavid Wu case RK3128: 2738a282926dSHeiko Stübner return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT || 2739a282926dSHeiko Stübner pull == PIN_CONFIG_BIAS_DISABLE); 2740a282926dSHeiko Stübner case RK3066B: 274144b6d930SHeiko Stübner return pull ? false : true; 274287065ca9SDavid Wu case PX30: 2743b9c6dcabSAndy Yan case RV1108: 2744fd4ea486SJagan Teki case RV1126: 2745a282926dSHeiko Stübner case RK3188: 274666d750e1SHeiko Stübner case RK3288: 27477825aeb7SJianqun Xu case RK3308: 2748daecdc66SHeiko Stübner case RK3368: 2749b6c23275SDavid Wu case RK3399: 2750c0dadc0eSJianqun Xu case RK3568: 2751fdc33ebaSJianqun Xu case RK3588: 2752a282926dSHeiko Stübner return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); 275344b6d930SHeiko Stübner } 275444b6d930SHeiko Stübner 2755a282926dSHeiko Stübner return false; 275644b6d930SHeiko Stübner } 275744b6d930SHeiko Stübner 27588ce5ef64SCaleb Connolly static int rockchip_pinconf_defer_pin(struct rockchip_pin_bank *bank, 27598ce5ef64SCaleb Connolly unsigned int pin, u32 param, u32 arg) 2760e7165b1dSHeiko Stuebner { 27618ce5ef64SCaleb Connolly struct rockchip_pin_deferred *cfg; 2762e7165b1dSHeiko Stuebner 2763e7165b1dSHeiko Stuebner cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 2764e7165b1dSHeiko Stuebner if (!cfg) 2765e7165b1dSHeiko Stuebner return -ENOMEM; 2766e7165b1dSHeiko Stuebner 2767e7165b1dSHeiko Stuebner cfg->pin = pin; 27688ce5ef64SCaleb Connolly cfg->param = param; 2769e7165b1dSHeiko Stuebner cfg->arg = arg; 2770e7165b1dSHeiko Stuebner 27718ce5ef64SCaleb Connolly list_add_tail(&cfg->head, &bank->deferred_pins); 2772e7165b1dSHeiko Stuebner 2773e7165b1dSHeiko Stuebner return 0; 2774e7165b1dSHeiko Stuebner } 2775e7165b1dSHeiko Stuebner 2776d3e51161SHeiko Stübner /* set the pin config settings for a specified pin */ 2777d3e51161SHeiko Stübner static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, 277803b054e9SSherman Yin unsigned long *configs, unsigned num_configs) 2779d3e51161SHeiko Stübner { 2780d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2781d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 27829ce9a020SJianqun Xu struct gpio_chip *gpio = &bank->gpio_chip; 278303b054e9SSherman Yin enum pin_config_param param; 278458957d2eSMika Westerberg u32 arg; 278503b054e9SSherman Yin int i; 278603b054e9SSherman Yin int rc; 278703b054e9SSherman Yin 278803b054e9SSherman Yin for (i = 0; i < num_configs; i++) { 278903b054e9SSherman Yin param = pinconf_to_config_param(configs[i]); 279003b054e9SSherman Yin arg = pinconf_to_config_argument(configs[i]); 2791d3e51161SHeiko Stübner 279242d90a1eSCaleb Connolly if (param == PIN_CONFIG_OUTPUT || param == PIN_CONFIG_INPUT_ENABLE) { 27938ce5ef64SCaleb Connolly /* 27948ce5ef64SCaleb Connolly * Check for gpio driver not being probed yet. 27958ce5ef64SCaleb Connolly * The lock makes sure that either gpio-probe has completed 27968ce5ef64SCaleb Connolly * or the gpio driver hasn't probed yet. 27978ce5ef64SCaleb Connolly */ 27988ce5ef64SCaleb Connolly mutex_lock(&bank->deferred_lock); 27998ce5ef64SCaleb Connolly if (!gpio || !gpio->direction_output) { 28008ce5ef64SCaleb Connolly rc = rockchip_pinconf_defer_pin(bank, pin - bank->pin_base, param, 28018ce5ef64SCaleb Connolly arg); 28028ce5ef64SCaleb Connolly mutex_unlock(&bank->deferred_lock); 28038ce5ef64SCaleb Connolly if (rc) 28048ce5ef64SCaleb Connolly return rc; 28058ce5ef64SCaleb Connolly 28068ce5ef64SCaleb Connolly break; 28078ce5ef64SCaleb Connolly } 28088ce5ef64SCaleb Connolly mutex_unlock(&bank->deferred_lock); 28098ce5ef64SCaleb Connolly } 28108ce5ef64SCaleb Connolly 2811d3e51161SHeiko Stübner switch (param) { 2812d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 281303b054e9SSherman Yin rc = rockchip_set_pull(bank, pin - bank->pin_base, 281403b054e9SSherman Yin param); 281503b054e9SSherman Yin if (rc) 281603b054e9SSherman Yin return rc; 281744b6d930SHeiko Stübner break; 2818d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 2819d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 2820d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 28216ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 282244b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 282344b6d930SHeiko Stübner return -ENOTSUPP; 282444b6d930SHeiko Stübner 282544b6d930SHeiko Stübner if (!arg) 282644b6d930SHeiko Stübner return -EINVAL; 282744b6d930SHeiko Stübner 282803b054e9SSherman Yin rc = rockchip_set_pull(bank, pin - bank->pin_base, 282903b054e9SSherman Yin param); 283003b054e9SSherman Yin if (rc) 283103b054e9SSherman Yin return rc; 2832d3e51161SHeiko Stübner break; 2833a076e2edSHeiko Stübner case PIN_CONFIG_OUTPUT: 28349ce9a020SJianqun Xu rc = rockchip_set_mux(bank, pin - bank->pin_base, 28359ce9a020SJianqun Xu RK_FUNC_GPIO); 28369ce9a020SJianqun Xu if (rc != RK_FUNC_GPIO) 28379ce9a020SJianqun Xu return -EINVAL; 28389ce9a020SJianqun Xu 28399ce9a020SJianqun Xu rc = gpio->direction_output(gpio, pin - bank->pin_base, 28409ce9a020SJianqun Xu arg); 2841a076e2edSHeiko Stübner if (rc) 2842a076e2edSHeiko Stübner return rc; 2843a076e2edSHeiko Stübner break; 284442d90a1eSCaleb Connolly case PIN_CONFIG_INPUT_ENABLE: 284542d90a1eSCaleb Connolly rc = rockchip_set_mux(bank, pin - bank->pin_base, 284642d90a1eSCaleb Connolly RK_FUNC_GPIO); 284742d90a1eSCaleb Connolly if (rc != RK_FUNC_GPIO) 284842d90a1eSCaleb Connolly return -EINVAL; 284942d90a1eSCaleb Connolly 285042d90a1eSCaleb Connolly rc = gpio->direction_input(gpio, pin - bank->pin_base); 285142d90a1eSCaleb Connolly if (rc) 285242d90a1eSCaleb Connolly return rc; 285342d90a1eSCaleb Connolly break; 2854b547c800SHeiko Stübner case PIN_CONFIG_DRIVE_STRENGTH: 2855b547c800SHeiko Stübner /* rk3288 is the first with per-pin drive-strength */ 2856ef17f69fSHeiko Stübner if (!info->ctrl->drv_calc_reg) 2857b547c800SHeiko Stübner return -ENOTSUPP; 2858b547c800SHeiko Stübner 2859ef17f69fSHeiko Stübner rc = rockchip_set_drive_perpin(bank, 2860ef17f69fSHeiko Stübner pin - bank->pin_base, arg); 2861b547c800SHeiko Stübner if (rc < 0) 2862b547c800SHeiko Stübner return rc; 2863b547c800SHeiko Stübner break; 2864e3b357d7Sdavid.wu case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 2865e3b357d7Sdavid.wu if (!info->ctrl->schmitt_calc_reg) 2866e3b357d7Sdavid.wu return -ENOTSUPP; 2867e3b357d7Sdavid.wu 2868e3b357d7Sdavid.wu rc = rockchip_set_schmitt(bank, 2869e3b357d7Sdavid.wu pin - bank->pin_base, arg); 2870e3b357d7Sdavid.wu if (rc < 0) 2871e3b357d7Sdavid.wu return rc; 2872e3b357d7Sdavid.wu break; 2873d3e51161SHeiko Stübner default: 2874d3e51161SHeiko Stübner return -ENOTSUPP; 2875d3e51161SHeiko Stübner break; 2876d3e51161SHeiko Stübner } 287703b054e9SSherman Yin } /* for each config */ 2878d3e51161SHeiko Stübner 2879d3e51161SHeiko Stübner return 0; 2880d3e51161SHeiko Stübner } 2881d3e51161SHeiko Stübner 2882d3e51161SHeiko Stübner /* get the pin config settings for a specified pin */ 2883d3e51161SHeiko Stübner static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, 2884d3e51161SHeiko Stübner unsigned long *config) 2885d3e51161SHeiko Stübner { 2886d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2887d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 28889ce9a020SJianqun Xu struct gpio_chip *gpio = &bank->gpio_chip; 2889d3e51161SHeiko Stübner enum pin_config_param param = pinconf_to_config_param(*config); 2890dab3eba7SHeiko Stübner u16 arg; 2891a076e2edSHeiko Stübner int rc; 2892d3e51161SHeiko Stübner 2893d3e51161SHeiko Stübner switch (param) { 2894d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 289544b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 2896d3e51161SHeiko Stübner return -EINVAL; 2897d3e51161SHeiko Stübner 2898dab3eba7SHeiko Stübner arg = 0; 2899d3e51161SHeiko Stübner break; 290044b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 290144b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 290244b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 29036ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 290444b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 290544b6d930SHeiko Stübner return -ENOTSUPP; 290644b6d930SHeiko Stübner 290744b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 290844b6d930SHeiko Stübner return -EINVAL; 290944b6d930SHeiko Stübner 2910dab3eba7SHeiko Stübner arg = 1; 291144b6d930SHeiko Stübner break; 2912a076e2edSHeiko Stübner case PIN_CONFIG_OUTPUT: 2913a076e2edSHeiko Stübner rc = rockchip_get_mux(bank, pin - bank->pin_base); 2914a076e2edSHeiko Stübner if (rc != RK_FUNC_GPIO) 2915a076e2edSHeiko Stübner return -EINVAL; 2916a076e2edSHeiko Stübner 2917e7165b1dSHeiko Stuebner if (!gpio || !gpio->get) { 2918e7165b1dSHeiko Stuebner arg = 0; 2919e7165b1dSHeiko Stuebner break; 2920e7165b1dSHeiko Stuebner } 2921e7165b1dSHeiko Stuebner 29229ce9a020SJianqun Xu rc = gpio->get(gpio, pin - bank->pin_base); 2923a076e2edSHeiko Stübner if (rc < 0) 2924a076e2edSHeiko Stübner return rc; 2925a076e2edSHeiko Stübner 2926a076e2edSHeiko Stübner arg = rc ? 1 : 0; 2927a076e2edSHeiko Stübner break; 2928b547c800SHeiko Stübner case PIN_CONFIG_DRIVE_STRENGTH: 2929b547c800SHeiko Stübner /* rk3288 is the first with per-pin drive-strength */ 2930ef17f69fSHeiko Stübner if (!info->ctrl->drv_calc_reg) 2931b547c800SHeiko Stübner return -ENOTSUPP; 2932b547c800SHeiko Stübner 2933ef17f69fSHeiko Stübner rc = rockchip_get_drive_perpin(bank, pin - bank->pin_base); 2934b547c800SHeiko Stübner if (rc < 0) 2935b547c800SHeiko Stübner return rc; 2936b547c800SHeiko Stübner 2937b547c800SHeiko Stübner arg = rc; 2938b547c800SHeiko Stübner break; 2939e3b357d7Sdavid.wu case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 2940e3b357d7Sdavid.wu if (!info->ctrl->schmitt_calc_reg) 2941e3b357d7Sdavid.wu return -ENOTSUPP; 2942e3b357d7Sdavid.wu 2943e3b357d7Sdavid.wu rc = rockchip_get_schmitt(bank, pin - bank->pin_base); 2944e3b357d7Sdavid.wu if (rc < 0) 2945e3b357d7Sdavid.wu return rc; 2946e3b357d7Sdavid.wu 2947e3b357d7Sdavid.wu arg = rc; 2948e3b357d7Sdavid.wu break; 2949d3e51161SHeiko Stübner default: 2950d3e51161SHeiko Stübner return -ENOTSUPP; 2951d3e51161SHeiko Stübner break; 2952d3e51161SHeiko Stübner } 2953d3e51161SHeiko Stübner 2954dab3eba7SHeiko Stübner *config = pinconf_to_config_packed(param, arg); 2955dab3eba7SHeiko Stübner 2956d3e51161SHeiko Stübner return 0; 2957d3e51161SHeiko Stübner } 2958d3e51161SHeiko Stübner 2959d3e51161SHeiko Stübner static const struct pinconf_ops rockchip_pinconf_ops = { 2960d3e51161SHeiko Stübner .pin_config_get = rockchip_pinconf_get, 2961d3e51161SHeiko Stübner .pin_config_set = rockchip_pinconf_set, 2962ed62f2f2SHeiko Stübner .is_generic = true, 2963d3e51161SHeiko Stübner }; 2964d3e51161SHeiko Stübner 296565fca613SHeiko Stübner static const struct of_device_id rockchip_bank_match[] = { 296665fca613SHeiko Stübner { .compatible = "rockchip,gpio-bank" }, 29676ca5274dSHeiko Stübner { .compatible = "rockchip,rk3188-gpio-bank0" }, 296865fca613SHeiko Stübner {}, 296965fca613SHeiko Stübner }; 2970d3e51161SHeiko Stübner 2971d3e51161SHeiko Stübner static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info, 2972d3e51161SHeiko Stübner struct device_node *np) 2973d3e51161SHeiko Stübner { 2974d3e51161SHeiko Stübner struct device_node *child; 2975d3e51161SHeiko Stübner 2976d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 297765fca613SHeiko Stübner if (of_match_node(rockchip_bank_match, child)) 2978d3e51161SHeiko Stübner continue; 2979d3e51161SHeiko Stübner 2980d3e51161SHeiko Stübner info->nfunctions++; 2981d3e51161SHeiko Stübner info->ngroups += of_get_child_count(child); 2982d3e51161SHeiko Stübner } 2983d3e51161SHeiko Stübner } 2984d3e51161SHeiko Stübner 2985d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_groups(struct device_node *np, 2986d3e51161SHeiko Stübner struct rockchip_pin_group *grp, 2987d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 2988d3e51161SHeiko Stübner u32 index) 2989d3e51161SHeiko Stübner { 2990e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2991d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 2992d3e51161SHeiko Stübner int size; 2993d3e51161SHeiko Stübner const __be32 *list; 2994d3e51161SHeiko Stübner int num; 2995d3e51161SHeiko Stübner int i, j; 2996d3e51161SHeiko Stübner int ret; 2997d3e51161SHeiko Stübner 2998e4dd7fd5SAndy Shevchenko dev_dbg(dev, "group(%d): %pOFn\n", index, np); 2999d3e51161SHeiko Stübner 3000d3e51161SHeiko Stübner /* Initialise group */ 3001d3e51161SHeiko Stübner grp->name = np->name; 3002d3e51161SHeiko Stübner 3003d3e51161SHeiko Stübner /* 3004d3e51161SHeiko Stübner * the binding format is rockchip,pins = <bank pin mux CONFIG>, 3005d3e51161SHeiko Stübner * do sanity check and calculate pins number 3006d3e51161SHeiko Stübner */ 3007d3e51161SHeiko Stübner list = of_get_property(np, "rockchip,pins", &size); 3008d3e51161SHeiko Stübner /* we do not check return since it's safe node passed down */ 3009d3e51161SHeiko Stübner size /= sizeof(*list); 30100045028fSAndy Shevchenko if (!size || size % 4) 30110045028fSAndy Shevchenko return dev_err_probe(dev, -EINVAL, "wrong pins number or pins and configs should be by 4\n"); 3012d3e51161SHeiko Stübner 3013d3e51161SHeiko Stübner grp->npins = size / 4; 3014d3e51161SHeiko Stübner 3015e4dd7fd5SAndy Shevchenko grp->pins = devm_kcalloc(dev, grp->npins, sizeof(*grp->pins), GFP_KERNEL); 3016e4dd7fd5SAndy Shevchenko grp->data = devm_kcalloc(dev, grp->npins, sizeof(*grp->data), GFP_KERNEL); 3017d3e51161SHeiko Stübner if (!grp->pins || !grp->data) 3018d3e51161SHeiko Stübner return -ENOMEM; 3019d3e51161SHeiko Stübner 3020d3e51161SHeiko Stübner for (i = 0, j = 0; i < size; i += 4, j++) { 3021d3e51161SHeiko Stübner const __be32 *phandle; 3022d3e51161SHeiko Stübner struct device_node *np_config; 3023d3e51161SHeiko Stübner 3024d3e51161SHeiko Stübner num = be32_to_cpu(*list++); 3025d3e51161SHeiko Stübner bank = bank_num_to_bank(info, num); 3026d3e51161SHeiko Stübner if (IS_ERR(bank)) 3027d3e51161SHeiko Stübner return PTR_ERR(bank); 3028d3e51161SHeiko Stübner 3029d3e51161SHeiko Stübner grp->pins[j] = bank->pin_base + be32_to_cpu(*list++); 3030d3e51161SHeiko Stübner grp->data[j].func = be32_to_cpu(*list++); 3031d3e51161SHeiko Stübner 3032d3e51161SHeiko Stübner phandle = list++; 3033d3e51161SHeiko Stübner if (!phandle) 3034d3e51161SHeiko Stübner return -EINVAL; 3035d3e51161SHeiko Stübner 3036d3e51161SHeiko Stübner np_config = of_find_node_by_phandle(be32_to_cpup(phandle)); 3037dd4d01f7SSoren Brinkmann ret = pinconf_generic_parse_dt_config(np_config, NULL, 3038d3e51161SHeiko Stübner &grp->data[j].configs, &grp->data[j].nconfigs); 3039d3e51161SHeiko Stübner if (ret) 3040d3e51161SHeiko Stübner return ret; 3041d3e51161SHeiko Stübner } 3042d3e51161SHeiko Stübner 3043d3e51161SHeiko Stübner return 0; 3044d3e51161SHeiko Stübner } 3045d3e51161SHeiko Stübner 3046d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_functions(struct device_node *np, 3047d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 3048d3e51161SHeiko Stübner u32 index) 3049d3e51161SHeiko Stübner { 3050e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 3051d3e51161SHeiko Stübner struct device_node *child; 3052d3e51161SHeiko Stübner struct rockchip_pmx_func *func; 3053d3e51161SHeiko Stübner struct rockchip_pin_group *grp; 3054d3e51161SHeiko Stübner int ret; 3055d3e51161SHeiko Stübner static u32 grp_index; 3056d3e51161SHeiko Stübner u32 i = 0; 3057d3e51161SHeiko Stübner 3058e4dd7fd5SAndy Shevchenko dev_dbg(dev, "parse function(%d): %pOFn\n", index, np); 3059d3e51161SHeiko Stübner 3060d3e51161SHeiko Stübner func = &info->functions[index]; 3061d3e51161SHeiko Stübner 3062d3e51161SHeiko Stübner /* Initialise function */ 3063d3e51161SHeiko Stübner func->name = np->name; 3064d3e51161SHeiko Stübner func->ngroups = of_get_child_count(np); 3065d3e51161SHeiko Stübner if (func->ngroups <= 0) 3066d3e51161SHeiko Stübner return 0; 3067d3e51161SHeiko Stübner 3068e4dd7fd5SAndy Shevchenko func->groups = devm_kcalloc(dev, func->ngroups, sizeof(*func->groups), GFP_KERNEL); 3069d3e51161SHeiko Stübner if (!func->groups) 3070d3e51161SHeiko Stübner return -ENOMEM; 3071d3e51161SHeiko Stübner 3072d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 3073d3e51161SHeiko Stübner func->groups[i] = child->name; 3074d3e51161SHeiko Stübner grp = &info->groups[grp_index++]; 3075d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_groups(child, grp, info, i++); 3076f7a81b7fSJulia Lawall if (ret) { 3077f7a81b7fSJulia Lawall of_node_put(child); 3078d3e51161SHeiko Stübner return ret; 3079d3e51161SHeiko Stübner } 3080f7a81b7fSJulia Lawall } 3081d3e51161SHeiko Stübner 3082d3e51161SHeiko Stübner return 0; 3083d3e51161SHeiko Stübner } 3084d3e51161SHeiko Stübner 3085d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_dt(struct platform_device *pdev, 3086d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 3087d3e51161SHeiko Stübner { 3088d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 3089d3e51161SHeiko Stübner struct device_node *np = dev->of_node; 3090d3e51161SHeiko Stübner struct device_node *child; 3091d3e51161SHeiko Stübner int ret; 3092d3e51161SHeiko Stübner int i; 3093d3e51161SHeiko Stübner 3094d3e51161SHeiko Stübner rockchip_pinctrl_child_count(info, np); 3095d3e51161SHeiko Stübner 3096e4dd7fd5SAndy Shevchenko dev_dbg(dev, "nfunctions = %d\n", info->nfunctions); 3097e4dd7fd5SAndy Shevchenko dev_dbg(dev, "ngroups = %d\n", info->ngroups); 3098d3e51161SHeiko Stübner 3099e4dd7fd5SAndy Shevchenko info->functions = devm_kcalloc(dev, info->nfunctions, sizeof(*info->functions), GFP_KERNEL); 310098c8ee73SMarkus Elfring if (!info->functions) 3101c4f333b7SDafna Hirschfeld return -ENOMEM; 3102d3e51161SHeiko Stübner 3103e4dd7fd5SAndy Shevchenko info->groups = devm_kcalloc(dev, info->ngroups, sizeof(*info->groups), GFP_KERNEL); 310498c8ee73SMarkus Elfring if (!info->groups) 3105c4f333b7SDafna Hirschfeld return -ENOMEM; 3106d3e51161SHeiko Stübner 3107d3e51161SHeiko Stübner i = 0; 3108d3e51161SHeiko Stübner 3109d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 311065fca613SHeiko Stübner if (of_match_node(rockchip_bank_match, child)) 3111d3e51161SHeiko Stübner continue; 311265fca613SHeiko Stübner 3113d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_functions(child, info, i++); 3114d3e51161SHeiko Stübner if (ret) { 3115e4dd7fd5SAndy Shevchenko dev_err(dev, "failed to parse function\n"); 3116f7a81b7fSJulia Lawall of_node_put(child); 3117d3e51161SHeiko Stübner return ret; 3118d3e51161SHeiko Stübner } 3119d3e51161SHeiko Stübner } 3120d3e51161SHeiko Stübner 3121d3e51161SHeiko Stübner return 0; 3122d3e51161SHeiko Stübner } 3123d3e51161SHeiko Stübner 3124d3e51161SHeiko Stübner static int rockchip_pinctrl_register(struct platform_device *pdev, 3125d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 3126d3e51161SHeiko Stübner { 3127d3e51161SHeiko Stübner struct pinctrl_desc *ctrldesc = &info->pctl; 3128d3e51161SHeiko Stübner struct pinctrl_pin_desc *pindesc, *pdesc; 3129d3e51161SHeiko Stübner struct rockchip_pin_bank *pin_bank; 3130e4dd7fd5SAndy Shevchenko struct device *dev = &pdev->dev; 3131069d7796SAndy Shevchenko char **pin_names; 3132d3e51161SHeiko Stübner int pin, bank, ret; 3133d3e51161SHeiko Stübner int k; 3134d3e51161SHeiko Stübner 3135d3e51161SHeiko Stübner ctrldesc->name = "rockchip-pinctrl"; 3136d3e51161SHeiko Stübner ctrldesc->owner = THIS_MODULE; 3137d3e51161SHeiko Stübner ctrldesc->pctlops = &rockchip_pctrl_ops; 3138d3e51161SHeiko Stübner ctrldesc->pmxops = &rockchip_pmx_ops; 3139d3e51161SHeiko Stübner ctrldesc->confops = &rockchip_pinconf_ops; 3140d3e51161SHeiko Stübner 3141e4dd7fd5SAndy Shevchenko pindesc = devm_kcalloc(dev, info->ctrl->nr_pins, sizeof(*pindesc), GFP_KERNEL); 314298c8ee73SMarkus Elfring if (!pindesc) 3143d3e51161SHeiko Stübner return -ENOMEM; 314498c8ee73SMarkus Elfring 3145d3e51161SHeiko Stübner ctrldesc->pins = pindesc; 3146d3e51161SHeiko Stübner ctrldesc->npins = info->ctrl->nr_pins; 3147d3e51161SHeiko Stübner 3148d3e51161SHeiko Stübner pdesc = pindesc; 3149d3e51161SHeiko Stübner for (bank = 0, k = 0; bank < info->ctrl->nr_banks; bank++) { 3150d3e51161SHeiko Stübner pin_bank = &info->ctrl->pin_banks[bank]; 3151069d7796SAndy Shevchenko 3152069d7796SAndy Shevchenko pin_names = devm_kasprintf_strarray(dev, pin_bank->name, pin_bank->nr_pins); 3153069d7796SAndy Shevchenko if (IS_ERR(pin_names)) 3154069d7796SAndy Shevchenko return PTR_ERR(pin_names); 3155069d7796SAndy Shevchenko 3156d3e51161SHeiko Stübner for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) { 3157d3e51161SHeiko Stübner pdesc->number = k; 3158069d7796SAndy Shevchenko pdesc->name = pin_names[pin]; 3159d3e51161SHeiko Stübner pdesc++; 3160d3e51161SHeiko Stübner } 3161e7165b1dSHeiko Stuebner 31628ce5ef64SCaleb Connolly INIT_LIST_HEAD(&pin_bank->deferred_pins); 3163e7165b1dSHeiko Stuebner mutex_init(&pin_bank->deferred_lock); 3164d3e51161SHeiko Stübner } 3165d3e51161SHeiko Stübner 31660fb7dcb1SDoug Anderson ret = rockchip_pinctrl_parse_dt(pdev, info); 31670fb7dcb1SDoug Anderson if (ret) 31680fb7dcb1SDoug Anderson return ret; 31690fb7dcb1SDoug Anderson 3170e4dd7fd5SAndy Shevchenko info->pctl_dev = devm_pinctrl_register(dev, ctrldesc, info); 31710045028fSAndy Shevchenko if (IS_ERR(info->pctl_dev)) 31720045028fSAndy Shevchenko return dev_err_probe(dev, PTR_ERR(info->pctl_dev), "could not register pinctrl driver\n"); 3173d3e51161SHeiko Stübner 3174d3e51161SHeiko Stübner return 0; 3175d3e51161SHeiko Stübner } 3176d3e51161SHeiko Stübner 3177d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[]; 3178d3e51161SHeiko Stübner 3179d3e51161SHeiko Stübner /* retrieve the soc specific data */ 3180d3e51161SHeiko Stübner static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( 3181d3e51161SHeiko Stübner struct rockchip_pinctrl *d, 3182d3e51161SHeiko Stübner struct platform_device *pdev) 3183d3e51161SHeiko Stübner { 3184e4dd7fd5SAndy Shevchenko struct device *dev = &pdev->dev; 3185e4dd7fd5SAndy Shevchenko struct device_node *node = dev->of_node; 3186d3e51161SHeiko Stübner const struct of_device_id *match; 3187d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 3188d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 3189b6c23275SDavid Wu int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j; 3190d3e51161SHeiko Stübner 3191d3e51161SHeiko Stübner match = of_match_node(rockchip_pinctrl_dt_match, node); 3192d3e51161SHeiko Stübner ctrl = (struct rockchip_pin_ctrl *)match->data; 3193d3e51161SHeiko Stübner 319495ec8ae4SHeiko Stübner grf_offs = ctrl->grf_mux_offset; 319595ec8ae4SHeiko Stübner pmu_offs = ctrl->pmu_mux_offset; 3196b6c23275SDavid Wu drv_pmu_offs = ctrl->pmu_drv_offset; 3197b6c23275SDavid Wu drv_grf_offs = ctrl->grf_drv_offset; 3198d3e51161SHeiko Stübner bank = ctrl->pin_banks; 3199d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 32006bc0d121SHeiko Stübner int bank_pins = 0; 32016bc0d121SHeiko Stübner 320270b7aa7aSJohn Keeping raw_spin_lock_init(&bank->slock); 3203d3e51161SHeiko Stübner bank->drvdata = d; 3204d3e51161SHeiko Stübner bank->pin_base = ctrl->nr_pins; 3205d3e51161SHeiko Stübner ctrl->nr_pins += bank->nr_pins; 32066bc0d121SHeiko Stübner 3207b6c23275SDavid Wu /* calculate iomux and drv offsets */ 32086bc0d121SHeiko Stübner for (j = 0; j < 4; j++) { 32096bc0d121SHeiko Stübner struct rockchip_iomux *iom = &bank->iomux[j]; 3210b6c23275SDavid Wu struct rockchip_drv *drv = &bank->drv[j]; 321103716e1dSHeiko Stübner int inc; 32126bc0d121SHeiko Stübner 32136bc0d121SHeiko Stübner if (bank_pins >= bank->nr_pins) 32146bc0d121SHeiko Stübner break; 32156bc0d121SHeiko Stübner 3216b6c23275SDavid Wu /* preset iomux offset value, set new start value */ 32176bc0d121SHeiko Stübner if (iom->offset >= 0) { 3218fd4ea486SJagan Teki if ((iom->type & IOMUX_SOURCE_PMU) || 3219fd4ea486SJagan Teki (iom->type & IOMUX_L_SOURCE_PMU)) 322095ec8ae4SHeiko Stübner pmu_offs = iom->offset; 322195ec8ae4SHeiko Stübner else 32226bc0d121SHeiko Stübner grf_offs = iom->offset; 3223b6c23275SDavid Wu } else { /* set current iomux offset */ 3224fd4ea486SJagan Teki iom->offset = ((iom->type & IOMUX_SOURCE_PMU) || 3225fd4ea486SJagan Teki (iom->type & IOMUX_L_SOURCE_PMU)) ? 322695ec8ae4SHeiko Stübner pmu_offs : grf_offs; 32276bc0d121SHeiko Stübner } 32286bc0d121SHeiko Stübner 3229b6c23275SDavid Wu /* preset drv offset value, set new start value */ 3230b6c23275SDavid Wu if (drv->offset >= 0) { 3231b6c23275SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 3232b6c23275SDavid Wu drv_pmu_offs = drv->offset; 3233b6c23275SDavid Wu else 3234b6c23275SDavid Wu drv_grf_offs = drv->offset; 3235b6c23275SDavid Wu } else { /* set current drv offset */ 3236b6c23275SDavid Wu drv->offset = (iom->type & IOMUX_SOURCE_PMU) ? 3237b6c23275SDavid Wu drv_pmu_offs : drv_grf_offs; 3238b6c23275SDavid Wu } 3239b6c23275SDavid Wu 3240e4dd7fd5SAndy Shevchenko dev_dbg(dev, "bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n", 3241b6c23275SDavid Wu i, j, iom->offset, drv->offset); 32426bc0d121SHeiko Stübner 32436bc0d121SHeiko Stübner /* 32446bc0d121SHeiko Stübner * Increase offset according to iomux width. 324503716e1dSHeiko Stübner * 4bit iomux'es are spread over two registers. 32466bc0d121SHeiko Stübner */ 32478b6c6f93Sdavid.wu inc = (iom->type & (IOMUX_WIDTH_4BIT | 32487825aeb7SJianqun Xu IOMUX_WIDTH_3BIT | 32497825aeb7SJianqun Xu IOMUX_WIDTH_2BIT)) ? 8 : 4; 3250fd4ea486SJagan Teki if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU)) 325195ec8ae4SHeiko Stübner pmu_offs += inc; 325295ec8ae4SHeiko Stübner else 325303716e1dSHeiko Stübner grf_offs += inc; 32546bc0d121SHeiko Stübner 3255b6c23275SDavid Wu /* 3256b6c23275SDavid Wu * Increase offset according to drv width. 3257b6c23275SDavid Wu * 3bit drive-strenth'es are spread over two registers. 3258b6c23275SDavid Wu */ 3259b6c23275SDavid Wu if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || 3260b6c23275SDavid Wu (drv->drv_type == DRV_TYPE_IO_3V3_ONLY)) 3261b6c23275SDavid Wu inc = 8; 3262b6c23275SDavid Wu else 3263b6c23275SDavid Wu inc = 4; 3264b6c23275SDavid Wu 3265b6c23275SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 3266b6c23275SDavid Wu drv_pmu_offs += inc; 3267b6c23275SDavid Wu else 3268b6c23275SDavid Wu drv_grf_offs += inc; 3269b6c23275SDavid Wu 32706bc0d121SHeiko Stübner bank_pins += 8; 32716bc0d121SHeiko Stübner } 3272bd35b9bfSDavid Wu 3273c04c3fa6SDavid Wu /* calculate the per-bank recalced_mask */ 3274c04c3fa6SDavid Wu for (j = 0; j < ctrl->niomux_recalced; j++) { 3275c04c3fa6SDavid Wu int pin = 0; 3276c04c3fa6SDavid Wu 3277c04c3fa6SDavid Wu if (ctrl->iomux_recalced[j].num == bank->bank_num) { 3278c04c3fa6SDavid Wu pin = ctrl->iomux_recalced[j].pin; 3279c04c3fa6SDavid Wu bank->recalced_mask |= BIT(pin); 3280c04c3fa6SDavid Wu } 3281c04c3fa6SDavid Wu } 3282c04c3fa6SDavid Wu 3283bd35b9bfSDavid Wu /* calculate the per-bank route_mask */ 3284bd35b9bfSDavid Wu for (j = 0; j < ctrl->niomux_routes; j++) { 3285bd35b9bfSDavid Wu int pin = 0; 3286bd35b9bfSDavid Wu 3287bd35b9bfSDavid Wu if (ctrl->iomux_routes[j].bank_num == bank->bank_num) { 3288bd35b9bfSDavid Wu pin = ctrl->iomux_routes[j].pin; 3289bd35b9bfSDavid Wu bank->route_mask |= BIT(pin); 3290bd35b9bfSDavid Wu } 3291bd35b9bfSDavid Wu } 3292d3e51161SHeiko Stübner } 3293d3e51161SHeiko Stübner 3294d3e51161SHeiko Stübner return ctrl; 3295d3e51161SHeiko Stübner } 3296d3e51161SHeiko Stübner 32978dca9331SChris Zhong #define RK3288_GRF_GPIO6C_IOMUX 0x64 32988dca9331SChris Zhong #define GPIO6C6_SEL_WRITE_ENABLE BIT(28) 32998dca9331SChris Zhong 33008dca9331SChris Zhong static u32 rk3288_grf_gpio6c_iomux; 33018dca9331SChris Zhong 33029198f509SChris Zhong static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev) 33039198f509SChris Zhong { 33049198f509SChris Zhong struct rockchip_pinctrl *info = dev_get_drvdata(dev); 33058dca9331SChris Zhong int ret = pinctrl_force_sleep(info->pctl_dev); 33069198f509SChris Zhong 33078dca9331SChris Zhong if (ret) 33088dca9331SChris Zhong return ret; 33098dca9331SChris Zhong 33108dca9331SChris Zhong /* 33118dca9331SChris Zhong * RK3288 GPIO6_C6 mux would be modified by Maskrom when resume, so save 33128dca9331SChris Zhong * the setting here, and restore it at resume. 33138dca9331SChris Zhong */ 33148dca9331SChris Zhong if (info->ctrl->type == RK3288) { 33158dca9331SChris Zhong ret = regmap_read(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, 33168dca9331SChris Zhong &rk3288_grf_gpio6c_iomux); 33178dca9331SChris Zhong if (ret) { 33188dca9331SChris Zhong pinctrl_force_default(info->pctl_dev); 33198dca9331SChris Zhong return ret; 33208dca9331SChris Zhong } 33218dca9331SChris Zhong } 33228dca9331SChris Zhong 33238dca9331SChris Zhong return 0; 33249198f509SChris Zhong } 33259198f509SChris Zhong 33269198f509SChris Zhong static int __maybe_unused rockchip_pinctrl_resume(struct device *dev) 33279198f509SChris Zhong { 33289198f509SChris Zhong struct rockchip_pinctrl *info = dev_get_drvdata(dev); 3329c971af25SWang Panzhenzhuan int ret; 3330c971af25SWang Panzhenzhuan 3331c971af25SWang Panzhenzhuan if (info->ctrl->type == RK3288) { 3332c971af25SWang Panzhenzhuan ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, 33338dca9331SChris Zhong rk3288_grf_gpio6c_iomux | 33348dca9331SChris Zhong GPIO6C6_SEL_WRITE_ENABLE); 33358dca9331SChris Zhong if (ret) 33368dca9331SChris Zhong return ret; 3337c971af25SWang Panzhenzhuan } 33389198f509SChris Zhong 33399198f509SChris Zhong return pinctrl_force_default(info->pctl_dev); 33409198f509SChris Zhong } 33419198f509SChris Zhong 33429198f509SChris Zhong static SIMPLE_DEV_PM_OPS(rockchip_pinctrl_dev_pm_ops, rockchip_pinctrl_suspend, 33439198f509SChris Zhong rockchip_pinctrl_resume); 33449198f509SChris Zhong 3345d3e51161SHeiko Stübner static int rockchip_pinctrl_probe(struct platform_device *pdev) 3346d3e51161SHeiko Stübner { 3347d3e51161SHeiko Stübner struct rockchip_pinctrl *info; 3348d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 3349e4dd7fd5SAndy Shevchenko struct device_node *np = dev->of_node, *node; 3350d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 3351d3e51161SHeiko Stübner struct resource *res; 3352751a99abSHeiko Stübner void __iomem *base; 3353d3e51161SHeiko Stübner int ret; 3354d3e51161SHeiko Stübner 33550045028fSAndy Shevchenko if (!dev->of_node) 33560045028fSAndy Shevchenko return dev_err_probe(dev, -ENODEV, "device tree node not found\n"); 3357d3e51161SHeiko Stübner 3358283b7ac9SMarkus Elfring info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 3359d3e51161SHeiko Stübner if (!info) 3360d3e51161SHeiko Stübner return -ENOMEM; 3361d3e51161SHeiko Stübner 3362622f3237SHeiko Stübner info->dev = dev; 3363622f3237SHeiko Stübner 3364d3e51161SHeiko Stübner ctrl = rockchip_pinctrl_get_soc_data(info, pdev); 33650045028fSAndy Shevchenko if (!ctrl) 33660045028fSAndy Shevchenko return dev_err_probe(dev, -EINVAL, "driver data not available\n"); 3367d3e51161SHeiko Stübner info->ctrl = ctrl; 3368d3e51161SHeiko Stübner 33691e747e59SHeiko Stübner node = of_parse_phandle(np, "rockchip,grf", 0); 33701e747e59SHeiko Stübner if (node) { 33711e747e59SHeiko Stübner info->regmap_base = syscon_node_to_regmap(node); 337289388f87SMiaoqian Lin of_node_put(node); 33731e747e59SHeiko Stübner if (IS_ERR(info->regmap_base)) 33741e747e59SHeiko Stübner return PTR_ERR(info->regmap_base); 33751e747e59SHeiko Stübner } else { 3376fb17dcd7SAndy Shevchenko base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 3377751a99abSHeiko Stübner if (IS_ERR(base)) 3378751a99abSHeiko Stübner return PTR_ERR(base); 3379751a99abSHeiko Stübner 3380751a99abSHeiko Stübner rockchip_regmap_config.max_register = resource_size(res) - 4; 3381751a99abSHeiko Stübner rockchip_regmap_config.name = "rockchip,pinctrl"; 3382e4dd7fd5SAndy Shevchenko info->regmap_base = 3383e4dd7fd5SAndy Shevchenko devm_regmap_init_mmio(dev, base, &rockchip_regmap_config); 3384d3e51161SHeiko Stübner 3385bfc7a42aSHeiko Stübner /* to check for the old dt-bindings */ 3386bfc7a42aSHeiko Stübner info->reg_size = resource_size(res); 3387bfc7a42aSHeiko Stübner 3388bfc7a42aSHeiko Stübner /* Honor the old binding, with pull registers as 2nd resource */ 3389bfc7a42aSHeiko Stübner if (ctrl->type == RK3188 && info->reg_size < 0x200) { 3390fb17dcd7SAndy Shevchenko base = devm_platform_get_and_ioremap_resource(pdev, 1, &res); 3391751a99abSHeiko Stübner if (IS_ERR(base)) 3392751a99abSHeiko Stübner return PTR_ERR(base); 3393751a99abSHeiko Stübner 3394e4dd7fd5SAndy Shevchenko rockchip_regmap_config.max_register = resource_size(res) - 4; 3395751a99abSHeiko Stübner rockchip_regmap_config.name = "rockchip,pinctrl-pull"; 3396e4dd7fd5SAndy Shevchenko info->regmap_pull = 3397e4dd7fd5SAndy Shevchenko devm_regmap_init_mmio(dev, base, &rockchip_regmap_config); 33986ca5274dSHeiko Stübner } 33991e747e59SHeiko Stübner } 34006ca5274dSHeiko Stübner 340114dee867SHeiko Stübner /* try to find the optional reference to the pmu syscon */ 340214dee867SHeiko Stübner node = of_parse_phandle(np, "rockchip,pmu", 0); 340314dee867SHeiko Stübner if (node) { 340414dee867SHeiko Stübner info->regmap_pmu = syscon_node_to_regmap(node); 340589388f87SMiaoqian Lin of_node_put(node); 340614dee867SHeiko Stübner if (IS_ERR(info->regmap_pmu)) 340714dee867SHeiko Stübner return PTR_ERR(info->regmap_pmu); 340814dee867SHeiko Stübner } 340914dee867SHeiko Stübner 34109ce9a020SJianqun Xu ret = rockchip_pinctrl_register(pdev, info); 3411d3e51161SHeiko Stübner if (ret) 3412d3e51161SHeiko Stübner return ret; 3413d3e51161SHeiko Stübner 34149ce9a020SJianqun Xu platform_set_drvdata(pdev, info); 34159ce9a020SJianqun Xu 3416bceb6732SJohn Keeping ret = of_platform_populate(np, NULL, NULL, &pdev->dev); 34170045028fSAndy Shevchenko if (ret) 34180045028fSAndy Shevchenko return dev_err_probe(dev, ret, "failed to register gpio device\n"); 3419d3e51161SHeiko Stübner 3420d3e51161SHeiko Stübner return 0; 3421d3e51161SHeiko Stübner } 3422d3e51161SHeiko Stübner 3423e7165b1dSHeiko Stuebner static int rockchip_pinctrl_remove(struct platform_device *pdev) 3424e7165b1dSHeiko Stuebner { 3425e7165b1dSHeiko Stuebner struct rockchip_pinctrl *info = platform_get_drvdata(pdev); 3426e7165b1dSHeiko Stuebner struct rockchip_pin_bank *bank; 34278ce5ef64SCaleb Connolly struct rockchip_pin_deferred *cfg; 3428e7165b1dSHeiko Stuebner int i; 3429e7165b1dSHeiko Stuebner 3430e7165b1dSHeiko Stuebner of_platform_depopulate(&pdev->dev); 3431e7165b1dSHeiko Stuebner 3432e7165b1dSHeiko Stuebner for (i = 0; i < info->ctrl->nr_banks; i++) { 3433e7165b1dSHeiko Stuebner bank = &info->ctrl->pin_banks[i]; 3434e7165b1dSHeiko Stuebner 3435e7165b1dSHeiko Stuebner mutex_lock(&bank->deferred_lock); 34368ce5ef64SCaleb Connolly while (!list_empty(&bank->deferred_pins)) { 34378ce5ef64SCaleb Connolly cfg = list_first_entry(&bank->deferred_pins, 34388ce5ef64SCaleb Connolly struct rockchip_pin_deferred, head); 3439e7165b1dSHeiko Stuebner list_del(&cfg->head); 3440e7165b1dSHeiko Stuebner kfree(cfg); 3441e7165b1dSHeiko Stuebner } 3442e7165b1dSHeiko Stuebner mutex_unlock(&bank->deferred_lock); 3443e7165b1dSHeiko Stuebner } 3444e7165b1dSHeiko Stuebner 3445e7165b1dSHeiko Stuebner return 0; 3446e7165b1dSHeiko Stuebner } 3447e7165b1dSHeiko Stuebner 344887065ca9SDavid Wu static struct rockchip_pin_bank px30_pin_banks[] = { 344987065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 345087065ca9SDavid Wu IOMUX_SOURCE_PMU, 345187065ca9SDavid Wu IOMUX_SOURCE_PMU, 345287065ca9SDavid Wu IOMUX_SOURCE_PMU 345387065ca9SDavid Wu ), 345487065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, 345587065ca9SDavid Wu IOMUX_WIDTH_4BIT, 345687065ca9SDavid Wu IOMUX_WIDTH_4BIT, 345787065ca9SDavid Wu IOMUX_WIDTH_4BIT 345887065ca9SDavid Wu ), 345987065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, 346087065ca9SDavid Wu IOMUX_WIDTH_4BIT, 346187065ca9SDavid Wu IOMUX_WIDTH_4BIT, 346287065ca9SDavid Wu IOMUX_WIDTH_4BIT 346387065ca9SDavid Wu ), 346487065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, 346587065ca9SDavid Wu IOMUX_WIDTH_4BIT, 346687065ca9SDavid Wu IOMUX_WIDTH_4BIT, 346787065ca9SDavid Wu IOMUX_WIDTH_4BIT 346887065ca9SDavid Wu ), 346987065ca9SDavid Wu }; 347087065ca9SDavid Wu 347187065ca9SDavid Wu static struct rockchip_pin_ctrl px30_pin_ctrl = { 347287065ca9SDavid Wu .pin_banks = px30_pin_banks, 347387065ca9SDavid Wu .nr_banks = ARRAY_SIZE(px30_pin_banks), 347487065ca9SDavid Wu .label = "PX30-GPIO", 347587065ca9SDavid Wu .type = PX30, 347687065ca9SDavid Wu .grf_mux_offset = 0x0, 347787065ca9SDavid Wu .pmu_mux_offset = 0x0, 347887065ca9SDavid Wu .iomux_routes = px30_mux_route_data, 347987065ca9SDavid Wu .niomux_routes = ARRAY_SIZE(px30_mux_route_data), 348087065ca9SDavid Wu .pull_calc_reg = px30_calc_pull_reg_and_bit, 348187065ca9SDavid Wu .drv_calc_reg = px30_calc_drv_reg_and_bit, 348287065ca9SDavid Wu .schmitt_calc_reg = px30_calc_schmitt_reg_and_bit, 348387065ca9SDavid Wu }; 348487065ca9SDavid Wu 3485b9c6dcabSAndy Yan static struct rockchip_pin_bank rv1108_pin_banks[] = { 3486688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 3487688daf23SAndy Yan IOMUX_SOURCE_PMU, 3488688daf23SAndy Yan IOMUX_SOURCE_PMU, 3489688daf23SAndy Yan IOMUX_SOURCE_PMU), 3490688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 3491688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0), 3492688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0), 3493688daf23SAndy Yan }; 3494688daf23SAndy Yan 3495b9c6dcabSAndy Yan static struct rockchip_pin_ctrl rv1108_pin_ctrl = { 3496b9c6dcabSAndy Yan .pin_banks = rv1108_pin_banks, 3497b9c6dcabSAndy Yan .nr_banks = ARRAY_SIZE(rv1108_pin_banks), 3498b9c6dcabSAndy Yan .label = "RV1108-GPIO", 3499b9c6dcabSAndy Yan .type = RV1108, 3500688daf23SAndy Yan .grf_mux_offset = 0x10, 3501688daf23SAndy Yan .pmu_mux_offset = 0x0, 350212b8f018SDavid Wu .iomux_recalced = rv1108_mux_recalced_data, 350312b8f018SDavid Wu .niomux_recalced = ARRAY_SIZE(rv1108_mux_recalced_data), 3504b9c6dcabSAndy Yan .pull_calc_reg = rv1108_calc_pull_reg_and_bit, 3505b9c6dcabSAndy Yan .drv_calc_reg = rv1108_calc_drv_reg_and_bit, 35065caff7eaSAndy Yan .schmitt_calc_reg = rv1108_calc_schmitt_reg_and_bit, 3507688daf23SAndy Yan }; 3508688daf23SAndy Yan 3509fd4ea486SJagan Teki static struct rockchip_pin_bank rv1126_pin_banks[] = { 3510fd4ea486SJagan Teki PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 3511fd4ea486SJagan Teki IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, 3512fd4ea486SJagan Teki IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, 3513fd4ea486SJagan Teki IOMUX_WIDTH_4BIT | IOMUX_L_SOURCE_PMU, 3514fd4ea486SJagan Teki IOMUX_WIDTH_4BIT), 3515fd4ea486SJagan Teki PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1", 3516fd4ea486SJagan Teki IOMUX_WIDTH_4BIT, 3517fd4ea486SJagan Teki IOMUX_WIDTH_4BIT, 3518fd4ea486SJagan Teki IOMUX_WIDTH_4BIT, 3519fd4ea486SJagan Teki IOMUX_WIDTH_4BIT, 3520fd4ea486SJagan Teki 0x10010, 0x10018, 0x10020, 0x10028), 3521fd4ea486SJagan Teki PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 3522fd4ea486SJagan Teki IOMUX_WIDTH_4BIT, 3523fd4ea486SJagan Teki IOMUX_WIDTH_4BIT, 3524fd4ea486SJagan Teki IOMUX_WIDTH_4BIT, 3525fd4ea486SJagan Teki IOMUX_WIDTH_4BIT), 3526fd4ea486SJagan Teki PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 3527fd4ea486SJagan Teki IOMUX_WIDTH_4BIT, 3528fd4ea486SJagan Teki IOMUX_WIDTH_4BIT, 3529fd4ea486SJagan Teki IOMUX_WIDTH_4BIT, 3530fd4ea486SJagan Teki IOMUX_WIDTH_4BIT), 3531fd4ea486SJagan Teki PIN_BANK_IOMUX_FLAGS(4, 2, "gpio4", 3532fd4ea486SJagan Teki IOMUX_WIDTH_4BIT, 0, 0, 0), 3533fd4ea486SJagan Teki }; 3534fd4ea486SJagan Teki 3535fd4ea486SJagan Teki static struct rockchip_pin_ctrl rv1126_pin_ctrl = { 3536fd4ea486SJagan Teki .pin_banks = rv1126_pin_banks, 3537fd4ea486SJagan Teki .nr_banks = ARRAY_SIZE(rv1126_pin_banks), 3538fd4ea486SJagan Teki .label = "RV1126-GPIO", 3539fd4ea486SJagan Teki .type = RV1126, 3540fd4ea486SJagan Teki .grf_mux_offset = 0x10004, /* mux offset from GPIO0_D0 */ 3541fd4ea486SJagan Teki .pmu_mux_offset = 0x0, 3542fd4ea486SJagan Teki .iomux_routes = rv1126_mux_route_data, 3543fd4ea486SJagan Teki .niomux_routes = ARRAY_SIZE(rv1126_mux_route_data), 3544fd4ea486SJagan Teki .iomux_recalced = rv1126_mux_recalced_data, 3545fd4ea486SJagan Teki .niomux_recalced = ARRAY_SIZE(rv1126_mux_recalced_data), 3546fd4ea486SJagan Teki .pull_calc_reg = rv1126_calc_pull_reg_and_bit, 3547fd4ea486SJagan Teki .drv_calc_reg = rv1126_calc_drv_reg_and_bit, 3548fd4ea486SJagan Teki .schmitt_calc_reg = rv1126_calc_schmitt_reg_and_bit, 3549fd4ea486SJagan Teki }; 3550fd4ea486SJagan Teki 3551d3e51161SHeiko Stübner static struct rockchip_pin_bank rk2928_pin_banks[] = { 3552d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 3553d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 3554d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 3555d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 3556d3e51161SHeiko Stübner }; 3557d3e51161SHeiko Stübner 3558d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk2928_pin_ctrl = { 3559d3e51161SHeiko Stübner .pin_banks = rk2928_pin_banks, 3560d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk2928_pin_banks), 3561d3e51161SHeiko Stübner .label = "RK2928-GPIO", 3562a282926dSHeiko Stübner .type = RK2928, 356395ec8ae4SHeiko Stübner .grf_mux_offset = 0xa8, 3564a282926dSHeiko Stübner .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 3565d3e51161SHeiko Stübner }; 3566d3e51161SHeiko Stübner 3567c5ce7670SXing Zheng static struct rockchip_pin_bank rk3036_pin_banks[] = { 3568c5ce7670SXing Zheng PIN_BANK(0, 32, "gpio0"), 3569c5ce7670SXing Zheng PIN_BANK(1, 32, "gpio1"), 3570c5ce7670SXing Zheng PIN_BANK(2, 32, "gpio2"), 3571c5ce7670SXing Zheng }; 3572c5ce7670SXing Zheng 3573c5ce7670SXing Zheng static struct rockchip_pin_ctrl rk3036_pin_ctrl = { 3574c5ce7670SXing Zheng .pin_banks = rk3036_pin_banks, 3575c5ce7670SXing Zheng .nr_banks = ARRAY_SIZE(rk3036_pin_banks), 3576c5ce7670SXing Zheng .label = "RK3036-GPIO", 3577c5ce7670SXing Zheng .type = RK2928, 3578c5ce7670SXing Zheng .grf_mux_offset = 0xa8, 3579c5ce7670SXing Zheng .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 3580c5ce7670SXing Zheng }; 3581c5ce7670SXing Zheng 3582d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066a_pin_banks[] = { 3583d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 3584d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 3585d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 3586d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 3587d3e51161SHeiko Stübner PIN_BANK(4, 32, "gpio4"), 3588d3e51161SHeiko Stübner PIN_BANK(6, 16, "gpio6"), 3589d3e51161SHeiko Stübner }; 3590d3e51161SHeiko Stübner 3591d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { 3592d3e51161SHeiko Stübner .pin_banks = rk3066a_pin_banks, 3593d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), 3594d3e51161SHeiko Stübner .label = "RK3066a-GPIO", 3595a282926dSHeiko Stübner .type = RK2928, 359695ec8ae4SHeiko Stübner .grf_mux_offset = 0xa8, 3597a282926dSHeiko Stübner .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 3598d3e51161SHeiko Stübner }; 3599d3e51161SHeiko Stübner 3600d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066b_pin_banks[] = { 3601d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 3602d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 3603d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 3604d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 3605d3e51161SHeiko Stübner }; 3606d3e51161SHeiko Stübner 3607d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { 3608d3e51161SHeiko Stübner .pin_banks = rk3066b_pin_banks, 3609d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), 3610d3e51161SHeiko Stübner .label = "RK3066b-GPIO", 3611a282926dSHeiko Stübner .type = RK3066B, 361295ec8ae4SHeiko Stübner .grf_mux_offset = 0x60, 3613d3e51161SHeiko Stübner }; 3614d3e51161SHeiko Stübner 3615d23c66dfSDavid Wu static struct rockchip_pin_bank rk3128_pin_banks[] = { 3616d23c66dfSDavid Wu PIN_BANK(0, 32, "gpio0"), 3617d23c66dfSDavid Wu PIN_BANK(1, 32, "gpio1"), 3618d23c66dfSDavid Wu PIN_BANK(2, 32, "gpio2"), 3619d23c66dfSDavid Wu PIN_BANK(3, 32, "gpio3"), 3620d23c66dfSDavid Wu }; 3621d23c66dfSDavid Wu 3622d23c66dfSDavid Wu static struct rockchip_pin_ctrl rk3128_pin_ctrl = { 3623d23c66dfSDavid Wu .pin_banks = rk3128_pin_banks, 3624d23c66dfSDavid Wu .nr_banks = ARRAY_SIZE(rk3128_pin_banks), 3625d23c66dfSDavid Wu .label = "RK3128-GPIO", 3626d23c66dfSDavid Wu .type = RK3128, 3627d23c66dfSDavid Wu .grf_mux_offset = 0xa8, 3628d23c66dfSDavid Wu .iomux_recalced = rk3128_mux_recalced_data, 3629d23c66dfSDavid Wu .niomux_recalced = ARRAY_SIZE(rk3128_mux_recalced_data), 3630d23c66dfSDavid Wu .iomux_routes = rk3128_mux_route_data, 3631d23c66dfSDavid Wu .niomux_routes = ARRAY_SIZE(rk3128_mux_route_data), 3632d23c66dfSDavid Wu .pull_calc_reg = rk3128_calc_pull_reg_and_bit, 3633d23c66dfSDavid Wu }; 3634d23c66dfSDavid Wu 3635d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3188_pin_banks[] = { 3636fc72c923SHeiko Stübner PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0), 3637d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 3638d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 3639d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 3640d3e51161SHeiko Stübner }; 3641d3e51161SHeiko Stübner 3642d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3188_pin_ctrl = { 3643d3e51161SHeiko Stübner .pin_banks = rk3188_pin_banks, 3644d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3188_pin_banks), 3645d3e51161SHeiko Stübner .label = "RK3188-GPIO", 3646a282926dSHeiko Stübner .type = RK3188, 364795ec8ae4SHeiko Stübner .grf_mux_offset = 0x60, 3648ada62b7cSHeiko Stuebner .iomux_routes = rk3188_mux_route_data, 3649ada62b7cSHeiko Stuebner .niomux_routes = ARRAY_SIZE(rk3188_mux_route_data), 36506ca5274dSHeiko Stübner .pull_calc_reg = rk3188_calc_pull_reg_and_bit, 3651d3e51161SHeiko Stübner }; 3652d3e51161SHeiko Stübner 3653fea0fe60SJeffy Chen static struct rockchip_pin_bank rk3228_pin_banks[] = { 3654fea0fe60SJeffy Chen PIN_BANK(0, 32, "gpio0"), 3655fea0fe60SJeffy Chen PIN_BANK(1, 32, "gpio1"), 3656fea0fe60SJeffy Chen PIN_BANK(2, 32, "gpio2"), 3657fea0fe60SJeffy Chen PIN_BANK(3, 32, "gpio3"), 3658fea0fe60SJeffy Chen }; 3659fea0fe60SJeffy Chen 3660fea0fe60SJeffy Chen static struct rockchip_pin_ctrl rk3228_pin_ctrl = { 3661fea0fe60SJeffy Chen .pin_banks = rk3228_pin_banks, 3662fea0fe60SJeffy Chen .nr_banks = ARRAY_SIZE(rk3228_pin_banks), 3663fea0fe60SJeffy Chen .label = "RK3228-GPIO", 3664fea0fe60SJeffy Chen .type = RK3288, 3665fea0fe60SJeffy Chen .grf_mux_offset = 0x0, 3666d4970ee0SDavid Wu .iomux_routes = rk3228_mux_route_data, 3667d4970ee0SDavid Wu .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), 3668fea0fe60SJeffy Chen .pull_calc_reg = rk3228_calc_pull_reg_and_bit, 3669fea0fe60SJeffy Chen .drv_calc_reg = rk3228_calc_drv_reg_and_bit, 3670fea0fe60SJeffy Chen }; 3671fea0fe60SJeffy Chen 3672304f077dSHeiko Stübner static struct rockchip_pin_bank rk3288_pin_banks[] = { 3673304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU, 3674304f077dSHeiko Stübner IOMUX_SOURCE_PMU, 3675304f077dSHeiko Stübner IOMUX_SOURCE_PMU, 3676304f077dSHeiko Stübner IOMUX_UNROUTED 3677304f077dSHeiko Stübner ), 3678304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED, 3679304f077dSHeiko Stübner IOMUX_UNROUTED, 3680304f077dSHeiko Stübner IOMUX_UNROUTED, 3681304f077dSHeiko Stübner 0 3682304f077dSHeiko Stübner ), 3683304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED), 3684304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT), 3685304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, 3686304f077dSHeiko Stübner IOMUX_WIDTH_4BIT, 3687304f077dSHeiko Stübner 0, 3688304f077dSHeiko Stübner 0 3689304f077dSHeiko Stübner ), 3690304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED, 3691304f077dSHeiko Stübner 0, 3692304f077dSHeiko Stübner 0, 3693304f077dSHeiko Stübner IOMUX_UNROUTED 3694304f077dSHeiko Stübner ), 3695304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED), 3696304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0, 3697304f077dSHeiko Stübner 0, 3698304f077dSHeiko Stübner IOMUX_WIDTH_4BIT, 3699304f077dSHeiko Stübner IOMUX_UNROUTED 3700304f077dSHeiko Stübner ), 3701304f077dSHeiko Stübner PIN_BANK(8, 16, "gpio8"), 3702304f077dSHeiko Stübner }; 3703304f077dSHeiko Stübner 3704304f077dSHeiko Stübner static struct rockchip_pin_ctrl rk3288_pin_ctrl = { 3705304f077dSHeiko Stübner .pin_banks = rk3288_pin_banks, 3706304f077dSHeiko Stübner .nr_banks = ARRAY_SIZE(rk3288_pin_banks), 3707304f077dSHeiko Stübner .label = "RK3288-GPIO", 370866d750e1SHeiko Stübner .type = RK3288, 3709304f077dSHeiko Stübner .grf_mux_offset = 0x0, 3710304f077dSHeiko Stübner .pmu_mux_offset = 0x84, 37114e96fd30SHeiko Stuebner .iomux_routes = rk3288_mux_route_data, 37124e96fd30SHeiko Stuebner .niomux_routes = ARRAY_SIZE(rk3288_mux_route_data), 3713304f077dSHeiko Stübner .pull_calc_reg = rk3288_calc_pull_reg_and_bit, 3714ef17f69fSHeiko Stübner .drv_calc_reg = rk3288_calc_drv_reg_and_bit, 3715304f077dSHeiko Stübner }; 3716304f077dSHeiko Stübner 37177825aeb7SJianqun Xu static struct rockchip_pin_bank rk3308_pin_banks[] = { 37187825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_WIDTH_2BIT, 37197825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 37207825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 37217825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 37227825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_2BIT, 37237825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 37247825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 37257825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 37267825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_2BIT, 37277825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 37287825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 37297825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 37307825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_2BIT, 37317825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 37327825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 37337825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 37347825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_2BIT, 37357825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 37367825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 37377825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 37387825aeb7SJianqun Xu }; 37397825aeb7SJianqun Xu 37407825aeb7SJianqun Xu static struct rockchip_pin_ctrl rk3308_pin_ctrl = { 37417825aeb7SJianqun Xu .pin_banks = rk3308_pin_banks, 37427825aeb7SJianqun Xu .nr_banks = ARRAY_SIZE(rk3308_pin_banks), 37437825aeb7SJianqun Xu .label = "RK3308-GPIO", 37447825aeb7SJianqun Xu .type = RK3308, 37457825aeb7SJianqun Xu .grf_mux_offset = 0x0, 37467825aeb7SJianqun Xu .iomux_recalced = rk3308_mux_recalced_data, 37477825aeb7SJianqun Xu .niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data), 37487825aeb7SJianqun Xu .iomux_routes = rk3308_mux_route_data, 37497825aeb7SJianqun Xu .niomux_routes = ARRAY_SIZE(rk3308_mux_route_data), 37507825aeb7SJianqun Xu .pull_calc_reg = rk3308_calc_pull_reg_and_bit, 37517825aeb7SJianqun Xu .drv_calc_reg = rk3308_calc_drv_reg_and_bit, 37527825aeb7SJianqun Xu .schmitt_calc_reg = rk3308_calc_schmitt_reg_and_bit, 37537825aeb7SJianqun Xu }; 37547825aeb7SJianqun Xu 37553818e4a7Sdavid.wu static struct rockchip_pin_bank rk3328_pin_banks[] = { 37563818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), 37573818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 37583818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 3759c04c3fa6SDavid Wu IOMUX_WIDTH_3BIT, 3760c04c3fa6SDavid Wu IOMUX_WIDTH_3BIT, 37613818e4a7Sdavid.wu 0), 37623818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 37633818e4a7Sdavid.wu IOMUX_WIDTH_3BIT, 3764c04c3fa6SDavid Wu IOMUX_WIDTH_3BIT, 37653818e4a7Sdavid.wu 0, 37663818e4a7Sdavid.wu 0), 37673818e4a7Sdavid.wu }; 37683818e4a7Sdavid.wu 37693818e4a7Sdavid.wu static struct rockchip_pin_ctrl rk3328_pin_ctrl = { 37703818e4a7Sdavid.wu .pin_banks = rk3328_pin_banks, 37713818e4a7Sdavid.wu .nr_banks = ARRAY_SIZE(rk3328_pin_banks), 37723818e4a7Sdavid.wu .label = "RK3328-GPIO", 37733818e4a7Sdavid.wu .type = RK3288, 37743818e4a7Sdavid.wu .grf_mux_offset = 0x0, 3775c04c3fa6SDavid Wu .iomux_recalced = rk3328_mux_recalced_data, 3776c04c3fa6SDavid Wu .niomux_recalced = ARRAY_SIZE(rk3328_mux_recalced_data), 3777cedc964aSDavid Wu .iomux_routes = rk3328_mux_route_data, 3778cedc964aSDavid Wu .niomux_routes = ARRAY_SIZE(rk3328_mux_route_data), 37793818e4a7Sdavid.wu .pull_calc_reg = rk3228_calc_pull_reg_and_bit, 37803818e4a7Sdavid.wu .drv_calc_reg = rk3228_calc_drv_reg_and_bit, 3781728d3f5aSdavid.wu .schmitt_calc_reg = rk3328_calc_schmitt_reg_and_bit, 37823818e4a7Sdavid.wu }; 37833818e4a7Sdavid.wu 3784daecdc66SHeiko Stübner static struct rockchip_pin_bank rk3368_pin_banks[] = { 3785daecdc66SHeiko Stübner PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 3786daecdc66SHeiko Stübner IOMUX_SOURCE_PMU, 3787daecdc66SHeiko Stübner IOMUX_SOURCE_PMU, 3788daecdc66SHeiko Stübner IOMUX_SOURCE_PMU 3789daecdc66SHeiko Stübner ), 3790daecdc66SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 3791daecdc66SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 3792daecdc66SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 3793daecdc66SHeiko Stübner }; 3794daecdc66SHeiko Stübner 3795daecdc66SHeiko Stübner static struct rockchip_pin_ctrl rk3368_pin_ctrl = { 3796daecdc66SHeiko Stübner .pin_banks = rk3368_pin_banks, 3797daecdc66SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3368_pin_banks), 3798daecdc66SHeiko Stübner .label = "RK3368-GPIO", 3799daecdc66SHeiko Stübner .type = RK3368, 3800daecdc66SHeiko Stübner .grf_mux_offset = 0x0, 3801daecdc66SHeiko Stübner .pmu_mux_offset = 0x0, 3802daecdc66SHeiko Stübner .pull_calc_reg = rk3368_calc_pull_reg_and_bit, 3803daecdc66SHeiko Stübner .drv_calc_reg = rk3368_calc_drv_reg_and_bit, 3804daecdc66SHeiko Stübner }; 3805daecdc66SHeiko Stübner 3806b6c23275SDavid Wu static struct rockchip_pin_bank rk3399_pin_banks[] = { 38073ba6767aSDavid Wu PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0", 38083ba6767aSDavid Wu IOMUX_SOURCE_PMU, 3809b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3810b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3811b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3812b6c23275SDavid Wu DRV_TYPE_IO_1V8_ONLY, 3813b6c23275SDavid Wu DRV_TYPE_IO_1V8_ONLY, 3814b6c23275SDavid Wu DRV_TYPE_IO_DEFAULT, 3815b6c23275SDavid Wu DRV_TYPE_IO_DEFAULT, 3816c437f65cSDavid Wu 0x80, 3817c437f65cSDavid Wu 0x88, 3818b6c23275SDavid Wu -1, 38193ba6767aSDavid Wu -1, 38203ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY, 38213ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY, 38223ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT, 38233ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT 3824b6c23275SDavid Wu ), 3825b6c23275SDavid Wu PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU, 3826b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3827b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3828b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3829b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3830b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3831b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3832b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3833c437f65cSDavid Wu 0xa0, 3834c437f65cSDavid Wu 0xa8, 3835c437f65cSDavid Wu 0xb0, 3836c437f65cSDavid Wu 0xb8 3837b6c23275SDavid Wu ), 38383ba6767aSDavid Wu PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0, 3839b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3840b6c23275SDavid Wu DRV_TYPE_IO_1V8_ONLY, 38413ba6767aSDavid Wu DRV_TYPE_IO_1V8_ONLY, 38423ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT, 38433ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT, 38443ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY, 38453ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY 3846b6c23275SDavid Wu ), 3847b6c23275SDavid Wu PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY, 3848b6c23275SDavid Wu DRV_TYPE_IO_3V3_ONLY, 3849b6c23275SDavid Wu DRV_TYPE_IO_3V3_ONLY, 3850b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0 3851b6c23275SDavid Wu ), 3852b6c23275SDavid Wu PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0, 3853b6c23275SDavid Wu DRV_TYPE_IO_1V8_3V0_AUTO, 3854b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3855b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0 3856b6c23275SDavid Wu ), 3857b6c23275SDavid Wu }; 3858b6c23275SDavid Wu 3859b6c23275SDavid Wu static struct rockchip_pin_ctrl rk3399_pin_ctrl = { 3860b6c23275SDavid Wu .pin_banks = rk3399_pin_banks, 3861b6c23275SDavid Wu .nr_banks = ARRAY_SIZE(rk3399_pin_banks), 3862b6c23275SDavid Wu .label = "RK3399-GPIO", 3863b6c23275SDavid Wu .type = RK3399, 3864b6c23275SDavid Wu .grf_mux_offset = 0xe000, 3865b6c23275SDavid Wu .pmu_mux_offset = 0x0, 3866b6c23275SDavid Wu .grf_drv_offset = 0xe100, 3867b6c23275SDavid Wu .pmu_drv_offset = 0x80, 3868accc1ce7SDavid Wu .iomux_routes = rk3399_mux_route_data, 3869accc1ce7SDavid Wu .niomux_routes = ARRAY_SIZE(rk3399_mux_route_data), 3870b6c23275SDavid Wu .pull_calc_reg = rk3399_calc_pull_reg_and_bit, 3871b6c23275SDavid Wu .drv_calc_reg = rk3399_calc_drv_reg_and_bit, 3872b6c23275SDavid Wu }; 3873daecdc66SHeiko Stübner 3874c0dadc0eSJianqun Xu static struct rockchip_pin_bank rk3568_pin_banks[] = { 3875c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, 3876c0dadc0eSJianqun Xu IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, 3877c0dadc0eSJianqun Xu IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, 3878c0dadc0eSJianqun Xu IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), 3879c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, 3880c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3881c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3882c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3883c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, 3884c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3885c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3886c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3887c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, 3888c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3889c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3890c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3891c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, 3892c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3893c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3894c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3895c0dadc0eSJianqun Xu }; 3896c0dadc0eSJianqun Xu 3897c0dadc0eSJianqun Xu static struct rockchip_pin_ctrl rk3568_pin_ctrl = { 3898c0dadc0eSJianqun Xu .pin_banks = rk3568_pin_banks, 3899c0dadc0eSJianqun Xu .nr_banks = ARRAY_SIZE(rk3568_pin_banks), 3900c0dadc0eSJianqun Xu .label = "RK3568-GPIO", 3901c0dadc0eSJianqun Xu .type = RK3568, 3902c0dadc0eSJianqun Xu .grf_mux_offset = 0x0, 3903c0dadc0eSJianqun Xu .pmu_mux_offset = 0x0, 3904c0dadc0eSJianqun Xu .grf_drv_offset = 0x0200, 3905c0dadc0eSJianqun Xu .pmu_drv_offset = 0x0070, 3906c0dadc0eSJianqun Xu .iomux_routes = rk3568_mux_route_data, 3907c0dadc0eSJianqun Xu .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), 3908c0dadc0eSJianqun Xu .pull_calc_reg = rk3568_calc_pull_reg_and_bit, 3909c0dadc0eSJianqun Xu .drv_calc_reg = rk3568_calc_drv_reg_and_bit, 3910c0dadc0eSJianqun Xu .schmitt_calc_reg = rk3568_calc_schmitt_reg_and_bit, 3911c0dadc0eSJianqun Xu }; 3912c0dadc0eSJianqun Xu 3913fdc33ebaSJianqun Xu static struct rockchip_pin_bank rk3588_pin_banks[] = { 3914fdc33ebaSJianqun Xu RK3588_PIN_BANK_FLAGS(0, 32, "gpio0", 3915fdc33ebaSJianqun Xu IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), 3916fdc33ebaSJianqun Xu RK3588_PIN_BANK_FLAGS(1, 32, "gpio1", 3917fdc33ebaSJianqun Xu IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), 3918fdc33ebaSJianqun Xu RK3588_PIN_BANK_FLAGS(2, 32, "gpio2", 3919fdc33ebaSJianqun Xu IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), 3920fdc33ebaSJianqun Xu RK3588_PIN_BANK_FLAGS(3, 32, "gpio3", 3921fdc33ebaSJianqun Xu IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), 3922fdc33ebaSJianqun Xu RK3588_PIN_BANK_FLAGS(4, 32, "gpio4", 3923fdc33ebaSJianqun Xu IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), 3924fdc33ebaSJianqun Xu }; 3925fdc33ebaSJianqun Xu 3926fdc33ebaSJianqun Xu static struct rockchip_pin_ctrl rk3588_pin_ctrl = { 3927fdc33ebaSJianqun Xu .pin_banks = rk3588_pin_banks, 3928fdc33ebaSJianqun Xu .nr_banks = ARRAY_SIZE(rk3588_pin_banks), 3929fdc33ebaSJianqun Xu .label = "RK3588-GPIO", 3930fdc33ebaSJianqun Xu .type = RK3588, 3931fdc33ebaSJianqun Xu .pull_calc_reg = rk3588_calc_pull_reg_and_bit, 3932fdc33ebaSJianqun Xu .drv_calc_reg = rk3588_calc_drv_reg_and_bit, 3933fdc33ebaSJianqun Xu .schmitt_calc_reg = rk3588_calc_schmitt_reg_and_bit, 3934fdc33ebaSJianqun Xu }; 3935fdc33ebaSJianqun Xu 3936d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[] = { 393787065ca9SDavid Wu { .compatible = "rockchip,px30-pinctrl", 393887065ca9SDavid Wu .data = &px30_pin_ctrl }, 3939b9c6dcabSAndy Yan { .compatible = "rockchip,rv1108-pinctrl", 3940cdbbd26fSMasahiro Yamada .data = &rv1108_pin_ctrl }, 3941fd4ea486SJagan Teki { .compatible = "rockchip,rv1126-pinctrl", 3942fd4ea486SJagan Teki .data = &rv1126_pin_ctrl }, 3943d3e51161SHeiko Stübner { .compatible = "rockchip,rk2928-pinctrl", 3944cdbbd26fSMasahiro Yamada .data = &rk2928_pin_ctrl }, 3945c5ce7670SXing Zheng { .compatible = "rockchip,rk3036-pinctrl", 3946cdbbd26fSMasahiro Yamada .data = &rk3036_pin_ctrl }, 3947d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066a-pinctrl", 3948cdbbd26fSMasahiro Yamada .data = &rk3066a_pin_ctrl }, 3949d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066b-pinctrl", 3950cdbbd26fSMasahiro Yamada .data = &rk3066b_pin_ctrl }, 3951d23c66dfSDavid Wu { .compatible = "rockchip,rk3128-pinctrl", 3952d23c66dfSDavid Wu .data = (void *)&rk3128_pin_ctrl }, 3953d3e51161SHeiko Stübner { .compatible = "rockchip,rk3188-pinctrl", 3954cdbbd26fSMasahiro Yamada .data = &rk3188_pin_ctrl }, 3955fea0fe60SJeffy Chen { .compatible = "rockchip,rk3228-pinctrl", 3956cdbbd26fSMasahiro Yamada .data = &rk3228_pin_ctrl }, 3957304f077dSHeiko Stübner { .compatible = "rockchip,rk3288-pinctrl", 3958cdbbd26fSMasahiro Yamada .data = &rk3288_pin_ctrl }, 39597825aeb7SJianqun Xu { .compatible = "rockchip,rk3308-pinctrl", 39607825aeb7SJianqun Xu .data = &rk3308_pin_ctrl }, 39613818e4a7Sdavid.wu { .compatible = "rockchip,rk3328-pinctrl", 3962cdbbd26fSMasahiro Yamada .data = &rk3328_pin_ctrl }, 3963daecdc66SHeiko Stübner { .compatible = "rockchip,rk3368-pinctrl", 3964cdbbd26fSMasahiro Yamada .data = &rk3368_pin_ctrl }, 3965b6c23275SDavid Wu { .compatible = "rockchip,rk3399-pinctrl", 3966cdbbd26fSMasahiro Yamada .data = &rk3399_pin_ctrl }, 3967c0dadc0eSJianqun Xu { .compatible = "rockchip,rk3568-pinctrl", 3968c0dadc0eSJianqun Xu .data = &rk3568_pin_ctrl }, 3969fdc33ebaSJianqun Xu { .compatible = "rockchip,rk3588-pinctrl", 3970fdc33ebaSJianqun Xu .data = &rk3588_pin_ctrl }, 3971d3e51161SHeiko Stübner {}, 3972d3e51161SHeiko Stübner }; 3973d3e51161SHeiko Stübner 3974d3e51161SHeiko Stübner static struct platform_driver rockchip_pinctrl_driver = { 3975d3e51161SHeiko Stübner .probe = rockchip_pinctrl_probe, 3976e7165b1dSHeiko Stuebner .remove = rockchip_pinctrl_remove, 3977d3e51161SHeiko Stübner .driver = { 3978d3e51161SHeiko Stübner .name = "rockchip-pinctrl", 39799198f509SChris Zhong .pm = &rockchip_pinctrl_dev_pm_ops, 39800be9e70dSAxel Lin .of_match_table = rockchip_pinctrl_dt_match, 3981d3e51161SHeiko Stübner }, 3982d3e51161SHeiko Stübner }; 3983d3e51161SHeiko Stübner 3984d3e51161SHeiko Stübner static int __init rockchip_pinctrl_drv_register(void) 3985d3e51161SHeiko Stübner { 3986d3e51161SHeiko Stübner return platform_driver_register(&rockchip_pinctrl_driver); 3987d3e51161SHeiko Stübner } 3988d3e51161SHeiko Stübner postcore_initcall(rockchip_pinctrl_drv_register); 3989be786ac5SJianqun Xu 3990be786ac5SJianqun Xu static void __exit rockchip_pinctrl_drv_unregister(void) 3991be786ac5SJianqun Xu { 3992be786ac5SJianqun Xu platform_driver_unregister(&rockchip_pinctrl_driver); 3993be786ac5SJianqun Xu } 3994be786ac5SJianqun Xu module_exit(rockchip_pinctrl_drv_unregister); 3995be786ac5SJianqun Xu 3996be786ac5SJianqun Xu MODULE_DESCRIPTION("ROCKCHIP Pin Controller Driver"); 3997be786ac5SJianqun Xu MODULE_LICENSE("GPL"); 3998be786ac5SJianqun Xu MODULE_ALIAS("platform:pinctrl-rockchip"); 3999be786ac5SJianqun Xu MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); 4000