Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: Add driver for Sunplus SP7021

Add driver for Sunplus SP7021 SoC.

Signed-off-by: Wells Lu <wellslutw@gmail.com>
Link: https://lore.kernel.org/r/1642344734-27229-3-git-send-email-wellslutw@gmail.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Wells Lu and committed by
Linus Walleij
aa74c44b 340407d2

+1902
+1
MAINTAINERS
··· 15317 15317 S: Maintained 15318 15318 W: https://sunplus.atlassian.net/wiki/spaces/doc/overview 15319 15319 F: Documentation/devicetree/bindings/pinctrl/sunplus,* 15320 + F: drivers/pinctrl/sunplus/ 15320 15321 F: include/dt-bindings/pinctrl/sppctl*.h 15321 15322 15322 15323 PKTCDVD DRIVER
+1
drivers/pinctrl/Kconfig
··· 527 527 source "drivers/pinctrl/spear/Kconfig" 528 528 source "drivers/pinctrl/sprd/Kconfig" 529 529 source "drivers/pinctrl/stm32/Kconfig" 530 + source "drivers/pinctrl/sunplus/Kconfig" 530 531 source "drivers/pinctrl/sunxi/Kconfig" 531 532 source "drivers/pinctrl/tegra/Kconfig" 532 533 source "drivers/pinctrl/ti/Kconfig"
+1
drivers/pinctrl/Makefile
··· 71 71 obj-$(CONFIG_PINCTRL_SPEAR) += spear/ 72 72 obj-y += sprd/ 73 73 obj-$(CONFIG_PINCTRL_STM32) += stm32/ 74 + obj-y += sunplus/ 74 75 obj-$(CONFIG_PINCTRL_SUNXI) += sunxi/ 75 76 obj-$(CONFIG_ARCH_TEGRA) += tegra/ 76 77 obj-y += ti/
+22
drivers/pinctrl/sunplus/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # 3 + # Sunplus Pin control driver configuration 4 + # 5 + 6 + config PINCTRL_SPPCTL 7 + tristate "Sunplus SP7021 PinMux and GPIO driver" 8 + depends on SOC_SP7021 9 + depends on OF && HAS_IOMEM 10 + select GENERIC_PINCTRL_GROUPS 11 + select GENERIC_PINMUX_FUNCTIONS 12 + select GENERIC_PINCONF 13 + select PINCONF 14 + select PINMUX 15 + select GPIOLIB 16 + select OF_GPIO 17 + help 18 + Say Y here to support Sunplus SP7021 pinmux controller. 19 + This driver requires the pinctrl framework. 20 + GPIO is provided by the same driver. 21 + To compile this driver as a module, choose M here. 22 + The module will be called sppinctrl.
+6
drivers/pinctrl/sunplus/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # 3 + # Makefile for the Sunplus Pin control drivers. 4 + # 5 + obj-$(CONFIG_PINCTRL_SPPCTL) += sppinctrl.o 6 + sppinctrl-objs := sppctl.o sppctl_sp7021.o
+1118
drivers/pinctrl/sunplus/sppctl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * SP7021 Pin Controller Driver. 4 + * Copyright (C) Sunplus Tech / Tibbo Tech. 5 + */ 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/device.h> 9 + #include <linux/err.h> 10 + #include <linux/gpio/driver.h> 11 + #include <linux/init.h> 12 + #include <linux/module.h> 13 + #include <linux/of.h> 14 + #include <linux/of_device.h> 15 + #include <linux/overflow.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/seq_file.h> 18 + #include <linux/slab.h> 19 + 20 + #include <linux/pinctrl/pinconf.h> 21 + #include <linux/pinctrl/pinconf-generic.h> 22 + #include <linux/pinctrl/pinmux.h> 23 + 24 + #include <dt-bindings/pinctrl/sppctl-sp7021.h> 25 + 26 + #include "../core.h" 27 + #include "../pinctrl-utils.h" 28 + 29 + #include "sppctl.h" 30 + 31 + struct sppctl_gpio_chip { 32 + void __iomem *gpioxt_base; /* MASTER, OE, OUT, IN, I_INV, O_INV, OD */ 33 + void __iomem *first_base; /* GPIO_FIRST */ 34 + 35 + struct gpio_chip chip; 36 + spinlock_t lock; /* lock for accessing OE register */ 37 + }; 38 + 39 + static inline u32 sppctl_first_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) 40 + { 41 + return readl(spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST + off); 42 + } 43 + 44 + static inline void sppctl_first_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off) 45 + { 46 + writel(val, spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST + off); 47 + } 48 + 49 + static inline u32 sppctl_gpio_master_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) 50 + { 51 + return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + off); 52 + } 53 + 54 + static inline void sppctl_gpio_master_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, 55 + u32 off) 56 + { 57 + writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + off); 58 + } 59 + 60 + static inline u32 sppctl_gpio_oe_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) 61 + { 62 + return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OE + off); 63 + } 64 + 65 + static inline void sppctl_gpio_oe_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off) 66 + { 67 + writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OE + off); 68 + } 69 + 70 + static inline void sppctl_gpio_out_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off) 71 + { 72 + writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OUT + off); 73 + } 74 + 75 + static inline u32 sppctl_gpio_in_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) 76 + { 77 + return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IN + off); 78 + } 79 + 80 + static inline u32 sppctl_gpio_iinv_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) 81 + { 82 + return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IINV + off); 83 + } 84 + 85 + static inline void sppctl_gpio_iinv_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, 86 + u32 off) 87 + { 88 + writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IINV + off); 89 + } 90 + 91 + static inline u32 sppctl_gpio_oinv_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) 92 + { 93 + return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OINV + off); 94 + } 95 + 96 + static inline void sppctl_gpio_oinv_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, 97 + u32 off) 98 + { 99 + writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OINV + off); 100 + } 101 + 102 + static inline u32 sppctl_gpio_od_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) 103 + { 104 + return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OD + off); 105 + } 106 + 107 + static inline void sppctl_gpio_od_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off) 108 + { 109 + writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OD + off); 110 + } 111 + 112 + static inline u32 sppctl_get_reg_and_bit_offset(unsigned int offset, u32 *reg_off) 113 + { 114 + u32 bit_off; 115 + 116 + /* Each register has 32 bits. */ 117 + *reg_off = (offset / 32) * 4; 118 + bit_off = offset % 32; 119 + 120 + return bit_off; 121 + } 122 + 123 + static inline u32 sppctl_get_moon_reg_and_bit_offset(unsigned int offset, u32 *reg_off) 124 + { 125 + u32 bit_off; 126 + 127 + /* 128 + * Each MOON register has 32 bits. Upper 16-bit word are mask-fields. 129 + * The lower 16-bit word are the control-fields. The corresponding 130 + * bits in mask-field should be set then you can write something to 131 + * control-field. 132 + */ 133 + *reg_off = (offset / 16) * 4; 134 + bit_off = offset % 16; 135 + 136 + return bit_off; 137 + } 138 + 139 + static inline u32 sppctl_prep_moon_reg_and_offset(unsigned int offset, u32 *reg_off, int val) 140 + { 141 + u32 bit_off; 142 + 143 + bit_off = sppctl_get_moon_reg_and_bit_offset(offset, reg_off); 144 + if (val) 145 + return SPPCTL_SET_MOON_REG_BIT(bit_off); 146 + else 147 + return SPPCTL_CLR_MOON_REG_BIT(bit_off); 148 + } 149 + 150 + /** 151 + * sppctl_func_set() - Set pin of fully-pinmux function. 152 + * 153 + * Mask-fields and control-fields of fully-pinmux function of SP7021 are 154 + * arranged as shown below: 155 + * 156 + * func# | register | mask-field | control-field 157 + * -------+----------+--------------+--------------- 158 + * 0 | base[0] | (22 : 16) | ( 6 : 0) 159 + * 1 | base[0] | (30 : 24) | (14 : 8) 160 + * 2 | base[1] | (22 : 16) | ( 6 : 0) 161 + * 3 | baeg[1] | (30 : 24) | (14 : 8) 162 + * : | : | : | : 163 + * 164 + * where mask-fields are used to protect control-fields from write-in 165 + * accidentally. Set the corresponding bits in the mask-field before 166 + * you write a value into a control-field. 167 + * 168 + * Control-fields are used to set where the function pin is going to 169 + * be routed to. 170 + * 171 + * Note that mask-fields and control-fields of even number of 'func' 172 + * are located at bits (22:16) and (6:0), while odd number of 'func's 173 + * are located at bits (30:24) and (14:8). 174 + */ 175 + static void sppctl_func_set(struct sppctl_pdata *pctl, u8 func, u8 val) 176 + { 177 + u32 reg, offset; 178 + 179 + /* 180 + * Note that upper 16-bit word are mask-fields and lower 16-bit 181 + * word are the control-fields. Set corresponding bits in mask- 182 + * field before write to a control-field. 183 + */ 184 + reg = SPPCTL_FULLY_PINMUX_MASK_MASK | val; 185 + 186 + /* 187 + * MUXF_L2SW_CLK_OUT is the first fully-pinmux pin 188 + * and its register offset is 0. 189 + */ 190 + func -= MUXF_L2SW_CLK_OUT; 191 + 192 + /* 193 + * Check if 'func' is an odd number or not. Mask and control- 194 + * fields of odd number 'func' is located at upper portion of 195 + * a register. Extra shift is needed. 196 + */ 197 + if (func & BIT(0)) 198 + reg <<= SPPCTL_FULLY_PINMUX_UPPER_SHIFT; 199 + 200 + /* Convert func# to register offset w.r.t. base register. */ 201 + offset = func * 2; 202 + offset &= GENMASK(31, 2); 203 + 204 + writel(reg, pctl->moon2_base + offset); 205 + } 206 + 207 + /** 208 + * sppctl_gmx_set() - Set pin of group-pinmux. 209 + * 210 + * Mask-fields and control-fields of group-pinmux function of SP7021 are 211 + * arranged as shown below: 212 + * 213 + * register | mask-fields | control-fields 214 + * ----------+--------------+---------------- 215 + * base[0] | (31 : 16) | (15 : 0) 216 + * base[1] | (31 : 24) | (15 : 0) 217 + * base[2] | (31 : 24) | (15 : 0) 218 + * : | : | : 219 + * 220 + * where mask-fields are used to protect control-fields from write-in 221 + * accidentally. Set the corresponding bits in the mask-field before 222 + * you write a value into a control-field. 223 + * 224 + * Control-fields are used to set where the function pin is going to 225 + * be routed to. A control-field consists of one or more bits. 226 + */ 227 + static void sppctl_gmx_set(struct sppctl_pdata *pctl, u8 reg_off, u8 bit_off, u8 bit_sz, 228 + u8 val) 229 + { 230 + u32 mask, reg; 231 + 232 + /* 233 + * Note that upper 16-bit word are mask-fields and lower 16-bit 234 + * word are the control-fields. Set corresponding bits in mask- 235 + * field before write to a control-field. 236 + */ 237 + mask = GENMASK(bit_sz - 1, 0) << SPPCTL_MOON_REG_MASK_SHIFT; 238 + reg = (mask | val) << bit_off; 239 + 240 + writel(reg, pctl->moon1_base + reg_off * 4); 241 + } 242 + 243 + /** 244 + * sppctl_first_get() - get bit of FIRST register. 245 + * 246 + * There are 4 FIRST registers. Each has 32 control-bits. 247 + * Totally, there are 4 * 32 = 128 control-bits. 248 + * Control-bits are arranged as shown below: 249 + * 250 + * registers | control-bits 251 + * -----------+-------------- 252 + * first[0] | (31 : 0) 253 + * first[1] | (63 : 32) 254 + * first[2] | (95 : 64) 255 + * first[3] | (127 : 96) 256 + * 257 + * Each control-bit sets type of a GPIO pin. 258 + * 0: a fully-pinmux pin 259 + * 1: a GPIO or IOP pin 260 + */ 261 + static int sppctl_first_get(struct gpio_chip *chip, unsigned int offset) 262 + { 263 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 264 + u32 reg_off, bit_off, reg; 265 + 266 + bit_off = sppctl_get_reg_and_bit_offset(offset, &reg_off); 267 + reg = sppctl_first_readl(spp_gchip, reg_off); 268 + 269 + return (reg & BIT(bit_off)) ? 1 : 0; 270 + } 271 + 272 + /** 273 + * sppctl_master_get() - get bit of MASTER register. 274 + * 275 + * There are 8 MASTER registers. Each has 16 mask-bits and 16 control-bits. 276 + * Upper 16-bit of MASTER registers are mask-bits while lower 16-bit are 277 + * control-bits. Totally, there are 128 mask-bits and 128 control-bits. 278 + * They are arranged as shown below: 279 + * 280 + * register | mask-bits | control-bits 281 + * -----------+-------------+-------------- 282 + * master[0] | (15 : 0) | (15 : 0) 283 + * master[1] | (31 : 16) | (31 : 16) 284 + * master[2] | (47 : 32) | (47 : 32) 285 + * : | : | : 286 + * master[7] | (127 : 112) | (127 : 112) 287 + * 288 + * where mask-bits are used to protect control-bits from write-in 289 + * accidentally. Set the corresponding mask-bit before you write 290 + * a value into a control-bit. 291 + * 292 + * Each control-bit sets type of a GPIO pin when FIRST bit is 1. 293 + * 0: a IOP pin 294 + * 1: a GPIO pin 295 + */ 296 + static int sppctl_master_get(struct gpio_chip *chip, unsigned int offset) 297 + { 298 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 299 + u32 reg_off, bit_off, reg; 300 + 301 + bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off); 302 + reg = sppctl_gpio_master_readl(spp_gchip, reg_off); 303 + return (reg & BIT(bit_off)) ? 1 : 0; 304 + } 305 + 306 + static void sppctl_first_master_set(struct gpio_chip *chip, unsigned int offset, 307 + enum mux_first_reg first, enum mux_master_reg master) 308 + { 309 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 310 + u32 reg_off, bit_off, reg; 311 + enum mux_first_reg val; 312 + 313 + /* FIRST register */ 314 + if (first != mux_f_keep) { 315 + bit_off = sppctl_get_reg_and_bit_offset(offset, &reg_off); 316 + reg = sppctl_first_readl(spp_gchip, reg_off); 317 + val = (reg & BIT(bit_off)) ? mux_f_gpio : mux_f_mux; 318 + 319 + if (first != val) 320 + switch (first) { 321 + case mux_f_gpio: 322 + reg |= BIT(bit_off); 323 + sppctl_first_writel(spp_gchip, reg, reg_off); 324 + break; 325 + 326 + case mux_f_mux: 327 + reg &= ~BIT(bit_off); 328 + sppctl_first_writel(spp_gchip, reg, reg_off); 329 + break; 330 + 331 + case mux_f_keep: 332 + break; 333 + } 334 + } 335 + 336 + /* MASTER register */ 337 + if (master != mux_m_keep) { 338 + reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, (master == mux_m_gpio)); 339 + sppctl_gpio_master_writel(spp_gchip, reg, reg_off); 340 + } 341 + } 342 + 343 + static void sppctl_gpio_input_inv_set(struct gpio_chip *chip, unsigned int offset) 344 + { 345 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 346 + u32 reg_off, reg; 347 + 348 + reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1); 349 + sppctl_gpio_iinv_writel(spp_gchip, reg, reg_off); 350 + } 351 + 352 + static void sppctl_gpio_output_inv_set(struct gpio_chip *chip, unsigned int offset) 353 + { 354 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 355 + u32 reg_off, reg; 356 + 357 + reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1); 358 + sppctl_gpio_oinv_writel(spp_gchip, reg, reg_off); 359 + } 360 + 361 + static int sppctl_gpio_output_od_get(struct gpio_chip *chip, unsigned int offset) 362 + { 363 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 364 + u32 reg_off, bit_off, reg; 365 + 366 + bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off); 367 + reg = sppctl_gpio_od_readl(spp_gchip, reg_off); 368 + 369 + return (reg & BIT(bit_off)) ? 1 : 0; 370 + } 371 + 372 + static void sppctl_gpio_output_od_set(struct gpio_chip *chip, unsigned int offset, 373 + unsigned int val) 374 + { 375 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 376 + u32 reg_off, reg; 377 + 378 + reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, val); 379 + sppctl_gpio_od_writel(spp_gchip, reg, reg_off); 380 + } 381 + 382 + static int sppctl_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 383 + { 384 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 385 + u32 reg_off, bit_off, reg; 386 + 387 + bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off); 388 + reg = sppctl_gpio_oe_readl(spp_gchip, reg_off); 389 + 390 + return (reg & BIT(bit_off)) ? 0 : 1; 391 + } 392 + 393 + static int sppctl_gpio_inv_get(struct gpio_chip *chip, unsigned int offset) 394 + { 395 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 396 + u32 reg_off, bit_off, reg; 397 + unsigned long flags; 398 + 399 + bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off); 400 + 401 + spin_lock_irqsave(&spp_gchip->lock, flags); 402 + 403 + if (sppctl_gpio_get_direction(chip, offset)) 404 + reg = sppctl_gpio_iinv_readl(spp_gchip, reg_off); 405 + else 406 + reg = sppctl_gpio_oinv_readl(spp_gchip, reg_off); 407 + 408 + spin_unlock_irqrestore(&spp_gchip->lock, flags); 409 + 410 + return (reg & BIT(bit_off)) ? 1 : 0; 411 + } 412 + 413 + static int sppctl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) 414 + { 415 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 416 + unsigned long flags; 417 + u32 reg_off, reg; 418 + 419 + reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 0); 420 + 421 + spin_lock_irqsave(&spp_gchip->lock, flags); 422 + 423 + sppctl_gpio_oe_writel(spp_gchip, reg, reg_off); 424 + 425 + spin_unlock_irqrestore(&spp_gchip->lock, flags); 426 + return 0; 427 + } 428 + 429 + static int sppctl_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int val) 430 + { 431 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 432 + unsigned long flags; 433 + u32 reg_off, reg; 434 + 435 + reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1); 436 + 437 + spin_lock_irqsave(&spp_gchip->lock, flags); 438 + 439 + sppctl_gpio_oe_writel(spp_gchip, reg, reg_off); 440 + 441 + if (val < 0) { 442 + spin_unlock_irqrestore(&spp_gchip->lock, flags); 443 + return 0; 444 + } 445 + 446 + reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, val); 447 + sppctl_gpio_out_writel(spp_gchip, reg, reg_off); 448 + 449 + spin_unlock_irqrestore(&spp_gchip->lock, flags); 450 + return 0; 451 + } 452 + 453 + static int sppctl_gpio_get(struct gpio_chip *chip, unsigned int offset) 454 + { 455 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 456 + u32 reg_off, bit_off, reg; 457 + 458 + bit_off = sppctl_get_reg_and_bit_offset(offset, &reg_off); 459 + reg = sppctl_gpio_in_readl(spp_gchip, reg_off); 460 + 461 + return (reg & BIT(bit_off)) ? 1 : 0; 462 + } 463 + 464 + static void sppctl_gpio_set(struct gpio_chip *chip, unsigned int offset, int val) 465 + { 466 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 467 + u32 reg_off, reg; 468 + 469 + reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, val); 470 + sppctl_gpio_out_writel(spp_gchip, reg, reg_off); 471 + } 472 + 473 + static int sppctl_gpio_set_config(struct gpio_chip *chip, unsigned int offset, 474 + unsigned long config) 475 + { 476 + enum pin_config_param param = pinconf_to_config_param(config); 477 + struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip); 478 + u32 reg_off, reg; 479 + 480 + switch (param) { 481 + case PIN_CONFIG_DRIVE_OPEN_DRAIN: 482 + reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1); 483 + sppctl_gpio_od_writel(spp_gchip, reg, reg_off); 484 + break; 485 + 486 + case PIN_CONFIG_INPUT_ENABLE: 487 + break; 488 + 489 + case PIN_CONFIG_OUTPUT: 490 + return sppctl_gpio_direction_output(chip, offset, 0); 491 + 492 + case PIN_CONFIG_PERSIST_STATE: 493 + return -ENOTSUPP; 494 + 495 + default: 496 + return -EINVAL; 497 + } 498 + 499 + return 0; 500 + } 501 + 502 + #ifdef CONFIG_DEBUG_FS 503 + static void sppctl_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 504 + { 505 + const char *label; 506 + int i; 507 + 508 + for (i = 0; i < chip->ngpio; i++) { 509 + label = gpiochip_is_requested(chip, i); 510 + if (!label) 511 + label = ""; 512 + 513 + seq_printf(s, " gpio-%03d (%-16.16s | %-16.16s)", i + chip->base, 514 + chip->names[i], label); 515 + seq_printf(s, " %c", sppctl_gpio_get_direction(chip, i) ? 'I' : 'O'); 516 + seq_printf(s, ":%d", sppctl_gpio_get(chip, i)); 517 + seq_printf(s, " %s", sppctl_first_get(chip, i) ? "gpi" : "mux"); 518 + seq_printf(s, " %s", sppctl_master_get(chip, i) ? "gpi" : "iop"); 519 + seq_printf(s, " %s", sppctl_gpio_inv_get(chip, i) ? "inv" : " "); 520 + seq_printf(s, " %s", sppctl_gpio_output_od_get(chip, i) ? "oDr" : ""); 521 + seq_puts(s, "\n"); 522 + } 523 + } 524 + #endif 525 + 526 + static int sppctl_gpio_new(struct platform_device *pdev, struct sppctl_pdata *pctl) 527 + { 528 + struct sppctl_gpio_chip *spp_gchip; 529 + struct gpio_chip *gchip; 530 + int err; 531 + 532 + spp_gchip = devm_kzalloc(&pdev->dev, sizeof(*spp_gchip), GFP_KERNEL); 533 + if (!spp_gchip) 534 + return -ENOMEM; 535 + pctl->spp_gchip = spp_gchip; 536 + 537 + spp_gchip->gpioxt_base = pctl->gpioxt_base; 538 + spp_gchip->first_base = pctl->first_base; 539 + spin_lock_init(&spp_gchip->lock); 540 + 541 + gchip = &spp_gchip->chip; 542 + gchip->label = SPPCTL_MODULE_NAME; 543 + gchip->parent = &pdev->dev; 544 + gchip->owner = THIS_MODULE; 545 + gchip->request = gpiochip_generic_request; 546 + gchip->free = gpiochip_generic_free; 547 + gchip->get_direction = sppctl_gpio_get_direction; 548 + gchip->direction_input = sppctl_gpio_direction_input; 549 + gchip->direction_output = sppctl_gpio_direction_output; 550 + gchip->get = sppctl_gpio_get; 551 + gchip->set = sppctl_gpio_set; 552 + gchip->set_config = sppctl_gpio_set_config; 553 + #ifdef CONFIG_DEBUG_FS 554 + gchip->dbg_show = sppctl_gpio_dbg_show; 555 + #endif 556 + gchip->base = -1; 557 + gchip->ngpio = sppctl_gpio_list_sz; 558 + gchip->names = sppctl_gpio_list_s; 559 + gchip->of_gpio_n_cells = 2; 560 + 561 + pctl->pctl_grange.npins = gchip->ngpio; 562 + pctl->pctl_grange.name = gchip->label; 563 + pctl->pctl_grange.gc = gchip; 564 + 565 + err = devm_gpiochip_add_data(&pdev->dev, gchip, spp_gchip); 566 + if (err) 567 + return dev_err_probe(&pdev->dev, err, "Failed to add gpiochip!\n"); 568 + 569 + return 0; 570 + } 571 + 572 + static int sppctl_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin, 573 + unsigned long *config) 574 + { 575 + struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); 576 + unsigned int param = pinconf_to_config_param(*config); 577 + unsigned int arg; 578 + 579 + switch (param) { 580 + case PIN_CONFIG_DRIVE_OPEN_DRAIN: 581 + if (!sppctl_gpio_output_od_get(&pctl->spp_gchip->chip, pin)) 582 + return -EINVAL; 583 + arg = 0; 584 + break; 585 + 586 + case PIN_CONFIG_OUTPUT: 587 + if (!sppctl_first_get(&pctl->spp_gchip->chip, pin)) 588 + return -EINVAL; 589 + if (!sppctl_master_get(&pctl->spp_gchip->chip, pin)) 590 + return -EINVAL; 591 + if (sppctl_gpio_get_direction(&pctl->spp_gchip->chip, pin)) 592 + return -EINVAL; 593 + arg = sppctl_gpio_get(&pctl->spp_gchip->chip, pin); 594 + break; 595 + 596 + default: 597 + return -EOPNOTSUPP; 598 + } 599 + *config = pinconf_to_config_packed(param, arg); 600 + 601 + return 0; 602 + } 603 + 604 + static int sppctl_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin, 605 + unsigned long *configs, unsigned int num_configs) 606 + { 607 + struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); 608 + int i; 609 + 610 + /* Special handling for IOP pins */ 611 + if (configs[0] == SPPCTL_IOP_CONFIGS) { 612 + sppctl_first_master_set(&pctl->spp_gchip->chip, pin, mux_f_gpio, mux_m_iop); 613 + return 0; 614 + } 615 + 616 + for (i = 0; i < num_configs; i++) { 617 + if (configs[i] & SPPCTL_PCTL_L_OUT) 618 + sppctl_gpio_direction_output(&pctl->spp_gchip->chip, pin, 0); 619 + if (configs[i] & SPPCTL_PCTL_L_OU1) 620 + sppctl_gpio_direction_output(&pctl->spp_gchip->chip, pin, 1); 621 + if (configs[i] & SPPCTL_PCTL_L_INV) 622 + sppctl_gpio_input_inv_set(&pctl->spp_gchip->chip, pin); 623 + if (configs[i] & SPPCTL_PCTL_L_ONV) 624 + sppctl_gpio_output_inv_set(&pctl->spp_gchip->chip, pin); 625 + if (configs[i] & SPPCTL_PCTL_L_ODR) 626 + sppctl_gpio_output_od_set(&pctl->spp_gchip->chip, pin, 1); 627 + } 628 + 629 + return 0; 630 + } 631 + 632 + static const struct pinconf_ops sppctl_pconf_ops = { 633 + .is_generic = true, 634 + .pin_config_get = sppctl_pin_config_get, 635 + .pin_config_set = sppctl_pin_config_set, 636 + }; 637 + 638 + static int sppctl_get_functions_count(struct pinctrl_dev *pctldev) 639 + { 640 + return sppctl_list_funcs_sz; 641 + } 642 + 643 + static const char *sppctl_get_function_name(struct pinctrl_dev *pctldev, 644 + unsigned int selector) 645 + { 646 + return sppctl_list_funcs[selector].name; 647 + } 648 + 649 + static int sppctl_get_function_groups(struct pinctrl_dev *pctldev, unsigned int selector, 650 + const char * const **groups, unsigned int *num_groups) 651 + { 652 + struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); 653 + const struct sppctl_func *f = &sppctl_list_funcs[selector]; 654 + int i; 655 + 656 + *num_groups = 0; 657 + switch (f->type) { 658 + case pinmux_type_fpmx: 659 + *num_groups = sppctl_pmux_list_sz; 660 + *groups = sppctl_pmux_list_s; 661 + break; 662 + 663 + case pinmux_type_grp: 664 + if (!f->grps) 665 + break; 666 + 667 + *num_groups = f->gnum; 668 + for (i = 0; i < pctl->unq_grps_sz; i++) 669 + if (pctl->g2fp_maps[i].f_idx == selector) 670 + break; 671 + *groups = &pctl->unq_grps[i]; 672 + break; 673 + 674 + default: 675 + dev_err(pctldev->dev, "Unknown pinmux (selector: %d, type: %d)\n", 676 + selector, f->type); 677 + break; 678 + } 679 + 680 + return 0; 681 + } 682 + 683 + /** 684 + * sppctl_fully_pinmux_conv - Convert GPIO# to fully-pinmux control-field setting 685 + * 686 + * Each fully-pinmux function can be mapped to any of GPIO 8 ~ 71 by 687 + * settings its control-field. Refer to following table: 688 + * 689 + * control-field | GPIO 690 + * --------------+-------- 691 + * 0 | No map 692 + * 1 | 8 693 + * 2 | 9 694 + * 3 | 10 695 + * : | : 696 + * 65 | 71 697 + */ 698 + static inline int sppctl_fully_pinmux_conv(unsigned int offset) 699 + { 700 + return (offset < 8) ? 0 : offset - 7; 701 + } 702 + 703 + static int sppctl_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, 704 + unsigned int group_selector) 705 + { 706 + const struct sppctl_func *f = &sppctl_list_funcs[func_selector]; 707 + struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); 708 + struct grp2fp_map g2fpm = pctl->g2fp_maps[group_selector]; 709 + int i; 710 + 711 + switch (f->type) { 712 + case pinmux_type_fpmx: 713 + sppctl_first_master_set(&pctl->spp_gchip->chip, group_selector, 714 + mux_f_mux, mux_m_keep); 715 + sppctl_func_set(pctl, func_selector, sppctl_fully_pinmux_conv(group_selector)); 716 + break; 717 + 718 + case pinmux_type_grp: 719 + for (i = 0; i < f->grps[g2fpm.g_idx].pnum; i++) 720 + sppctl_first_master_set(&pctl->spp_gchip->chip, 721 + f->grps[g2fpm.g_idx].pins[i], 722 + mux_f_mux, mux_m_keep); 723 + sppctl_gmx_set(pctl, f->roff, f->boff, f->blen, f->grps[g2fpm.g_idx].gval); 724 + break; 725 + 726 + default: 727 + dev_err(pctldev->dev, "Unknown pinmux type (func_selector: %d, type: %d)\n", 728 + func_selector, f->type); 729 + break; 730 + } 731 + 732 + return 0; 733 + } 734 + 735 + static int sppctl_gpio_request_enable(struct pinctrl_dev *pctldev, 736 + struct pinctrl_gpio_range *range, unsigned int offset) 737 + { 738 + struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); 739 + int g_f, g_m; 740 + 741 + g_f = sppctl_first_get(&pctl->spp_gchip->chip, offset); 742 + g_m = sppctl_master_get(&pctl->spp_gchip->chip, offset); 743 + if (g_f == mux_f_gpio && g_m == mux_m_gpio) 744 + return 0; 745 + 746 + sppctl_first_master_set(&pctl->spp_gchip->chip, offset, mux_f_gpio, mux_m_gpio); 747 + return 0; 748 + } 749 + 750 + static const struct pinmux_ops sppctl_pinmux_ops = { 751 + .get_functions_count = sppctl_get_functions_count, 752 + .get_function_name = sppctl_get_function_name, 753 + .get_function_groups = sppctl_get_function_groups, 754 + .set_mux = sppctl_set_mux, 755 + .gpio_request_enable = sppctl_gpio_request_enable, 756 + .strict = true, 757 + }; 758 + 759 + static int sppctl_get_groups_count(struct pinctrl_dev *pctldev) 760 + { 761 + struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); 762 + 763 + return pctl->unq_grps_sz; 764 + } 765 + 766 + static const char *sppctl_get_group_name(struct pinctrl_dev *pctldev, unsigned int selector) 767 + { 768 + struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); 769 + 770 + return pctl->unq_grps[selector]; 771 + } 772 + 773 + static int sppctl_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector, 774 + const unsigned int **pins, unsigned int *num_pins) 775 + { 776 + struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); 777 + struct grp2fp_map g2fpm = pctl->g2fp_maps[selector]; 778 + const struct sppctl_func *f; 779 + 780 + f = &sppctl_list_funcs[g2fpm.f_idx]; 781 + *num_pins = 0; 782 + 783 + /* Except group-pinmux, each group has 1 pin. */ 784 + if (f->type != pinmux_type_grp) { 785 + *num_pins = 1; 786 + *pins = &sppctl_pins_gpio[selector]; 787 + return 0; 788 + } 789 + 790 + /* Group-pinmux may have more than one pin. */ 791 + if (!f->grps) 792 + return 0; 793 + 794 + if (f->gnum < 1) 795 + return 0; 796 + 797 + *num_pins = f->grps[g2fpm.g_idx].pnum; 798 + *pins = f->grps[g2fpm.g_idx].pins; 799 + 800 + return 0; 801 + } 802 + 803 + #ifdef CONFIG_DEBUG_FS 804 + static void sppctl_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, 805 + unsigned int offset) 806 + { 807 + struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); 808 + const char *pin_type; 809 + u8 first, master; 810 + 811 + first = sppctl_first_get(&pctl->spp_gchip->chip, offset); 812 + master = sppctl_master_get(&pctl->spp_gchip->chip, offset); 813 + if (first) 814 + if (master) 815 + pin_type = "GPIO"; 816 + else 817 + pin_type = " IOP"; 818 + else 819 + pin_type = " MUX"; 820 + seq_printf(s, " %s", pin_type); 821 + } 822 + #endif 823 + 824 + static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np_config, 825 + struct pinctrl_map **map, unsigned int *num_maps) 826 + { 827 + struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); 828 + int nmG = of_property_count_strings(np_config, "groups"); 829 + const struct sppctl_func *f = NULL; 830 + u8 pin_num, pin_type, pin_func; 831 + struct device_node *parent; 832 + unsigned long *configs; 833 + struct property *prop; 834 + const char *s_f, *s_g; 835 + 836 + const __be32 *list; 837 + u32 dt_pin, dt_fun; 838 + int i, size = 0; 839 + 840 + list = of_get_property(np_config, "sunplus,pins", &size); 841 + 842 + if (nmG <= 0) 843 + nmG = 0; 844 + 845 + parent = of_get_parent(np_config); 846 + *num_maps = size / sizeof(*list); 847 + 848 + /* 849 + * Process property: 850 + * sunplus,pins = < u32 u32 u32 ... >; 851 + * 852 + * Each 32-bit integer defines a individual pin in which: 853 + * 854 + * Bit 32~24: defines GPIO pin number. Its range is 0 ~ 98. 855 + * Bit 23~16: defines types: (1) fully-pinmux pins 856 + * (2) IO processor pins 857 + * (3) digital GPIO pins 858 + * Bit 15~8: defines pins of peripherals (which are defined in 859 + * 'include/dt-binging/pinctrl/sppctl.h'). 860 + * Bit 7~0: defines types or initial-state of digital GPIO pins. 861 + */ 862 + for (i = 0; i < (*num_maps); i++) { 863 + dt_pin = be32_to_cpu(list[i]); 864 + pin_num = FIELD_GET(GENMASK(31, 24), dt_pin); 865 + 866 + if (pin_num >= sppctl_pins_all_sz) { 867 + dev_err(pctldev->dev, "Invalid pin property at index %d (0x%08x)\n", 868 + i, dt_pin); 869 + return -EINVAL; 870 + } 871 + } 872 + 873 + *map = kcalloc(*num_maps + nmG, sizeof(**map), GFP_KERNEL); 874 + for (i = 0; i < (*num_maps); i++) { 875 + dt_pin = be32_to_cpu(list[i]); 876 + pin_num = FIELD_GET(GENMASK(31, 24), dt_pin); 877 + pin_type = FIELD_GET(GENMASK(23, 16), dt_pin); 878 + pin_func = FIELD_GET(GENMASK(15, 8), dt_pin); 879 + (*map)[i].name = parent->name; 880 + 881 + if (pin_type == SPPCTL_PCTL_G_GPIO) { 882 + /* A digital GPIO pin */ 883 + (*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN; 884 + (*map)[i].data.configs.num_configs = 1; 885 + (*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin_num); 886 + configs = kmalloc(sizeof(*configs), GFP_KERNEL); 887 + *configs = FIELD_GET(GENMASK(7, 0), dt_pin); 888 + (*map)[i].data.configs.configs = configs; 889 + 890 + dev_dbg(pctldev->dev, "%s: GPIO (%s)\n", 891 + (*map)[i].data.configs.group_or_pin, 892 + (*configs & (SPPCTL_PCTL_L_OUT | SPPCTL_PCTL_L_OU1)) ? 893 + "OUT" : "IN"); 894 + } else if (pin_type == SPPCTL_PCTL_G_IOPP) { 895 + /* A IO Processor (IOP) pin */ 896 + (*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN; 897 + (*map)[i].data.configs.num_configs = 1; 898 + (*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin_num); 899 + configs = kmalloc(sizeof(*configs), GFP_KERNEL); 900 + *configs = SPPCTL_IOP_CONFIGS; 901 + (*map)[i].data.configs.configs = configs; 902 + 903 + dev_dbg(pctldev->dev, "%s: IOP\n", 904 + (*map)[i].data.configs.group_or_pin); 905 + } else { 906 + /* A fully-pinmux pin */ 907 + (*map)[i].type = PIN_MAP_TYPE_MUX_GROUP; 908 + (*map)[i].data.mux.function = sppctl_list_funcs[pin_func].name; 909 + (*map)[i].data.mux.group = pin_get_name(pctldev, pin_num); 910 + 911 + dev_dbg(pctldev->dev, "%s: %s\n", (*map)[i].data.mux.group, 912 + (*map)[i].data.mux.function); 913 + } 914 + } 915 + 916 + /* 917 + * Process properties: 918 + * function = "xxx"; 919 + * groups = "yyy"; 920 + */ 921 + if (nmG > 0 && of_property_read_string(np_config, "function", &s_f) == 0) { 922 + of_property_for_each_string(np_config, "groups", prop, s_g) { 923 + (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP; 924 + (*map)[*num_maps].data.mux.function = s_f; 925 + (*map)[*num_maps].data.mux.group = s_g; 926 + (*num_maps)++; 927 + 928 + dev_dbg(pctldev->dev, "%s: %s\n", s_f, s_g); 929 + } 930 + } 931 + 932 + /* 933 + * Process property: 934 + * sunplus,zerofunc = < u32 u32 u32 ...> 935 + */ 936 + list = of_get_property(np_config, "sunplus,zerofunc", &size); 937 + if (list) { 938 + for (i = 0; i < (size / sizeof(*list)); i++) { 939 + dt_fun = be32_to_cpu(list[i]); 940 + if (dt_fun >= sppctl_list_funcs_sz) { 941 + dev_err(pctldev->dev, "Zero-func %d out of range!\n", 942 + dt_fun); 943 + continue; 944 + } 945 + 946 + f = &sppctl_list_funcs[dt_fun]; 947 + switch (f->type) { 948 + case pinmux_type_fpmx: 949 + sppctl_func_set(pctl, dt_fun, 0); 950 + dev_dbg(pctldev->dev, "%s: No map\n", f->name); 951 + break; 952 + 953 + case pinmux_type_grp: 954 + sppctl_gmx_set(pctl, f->roff, f->boff, f->blen, 0); 955 + dev_dbg(pctldev->dev, "%s: No map\n", f->name); 956 + break; 957 + 958 + default: 959 + dev_err(pctldev->dev, "Wrong zero-group: %d (%s)\n", 960 + dt_fun, f->name); 961 + break; 962 + } 963 + } 964 + } 965 + 966 + of_node_put(parent); 967 + dev_dbg(pctldev->dev, "%d pins mapped\n", *num_maps); 968 + return 0; 969 + } 970 + 971 + static const struct pinctrl_ops sppctl_pctl_ops = { 972 + .get_groups_count = sppctl_get_groups_count, 973 + .get_group_name = sppctl_get_group_name, 974 + .get_group_pins = sppctl_get_group_pins, 975 + #ifdef CONFIG_DEBUG_FS 976 + .pin_dbg_show = sppctl_pin_dbg_show, 977 + #endif 978 + .dt_node_to_map = sppctl_dt_node_to_map, 979 + .dt_free_map = pinctrl_utils_free_map, 980 + }; 981 + 982 + static int sppctl_group_groups(struct platform_device *pdev) 983 + { 984 + struct sppctl_pdata *sppctl = platform_get_drvdata(pdev); 985 + int i, k, j; 986 + 987 + /* Calculate number of total group (GPIO + group-pinmux group). */ 988 + sppctl->unq_grps_sz = sppctl_gpio_list_sz; 989 + for (i = 0; i < sppctl_list_funcs_sz; i++) 990 + if (sppctl_list_funcs[i].type == pinmux_type_grp) 991 + sppctl->unq_grps_sz += sppctl_list_funcs[i].gnum; 992 + 993 + sppctl->unq_grps = devm_kcalloc(&pdev->dev, sppctl->unq_grps_sz + 1, 994 + sizeof(*sppctl->unq_grps), GFP_KERNEL); 995 + if (!sppctl->unq_grps) 996 + return -ENOMEM; 997 + 998 + sppctl->g2fp_maps = devm_kcalloc(&pdev->dev, sppctl->unq_grps_sz + 1, 999 + sizeof(*sppctl->g2fp_maps), GFP_KERNEL); 1000 + if (!sppctl->g2fp_maps) 1001 + return -ENOMEM; 1002 + 1003 + /* Add GPIO pins. */ 1004 + for (i = 0; i < sppctl_gpio_list_sz; i++) { 1005 + sppctl->unq_grps[i] = sppctl_gpio_list_s[i]; 1006 + sppctl->g2fp_maps[i].f_idx = 0; 1007 + sppctl->g2fp_maps[i].g_idx = i; 1008 + } 1009 + 1010 + /* Add group-pinmux to end of GPIO pins. */ 1011 + j = sppctl_gpio_list_sz; 1012 + for (i = 0; i < sppctl_list_funcs_sz; i++) { 1013 + if (sppctl_list_funcs[i].type != pinmux_type_grp) 1014 + continue; 1015 + 1016 + for (k = 0; k < sppctl_list_funcs[i].gnum; k++) { 1017 + sppctl->unq_grps[j] = sppctl_list_funcs[i].grps[k].name; 1018 + sppctl->g2fp_maps[j].f_idx = i; 1019 + sppctl->g2fp_maps[j].g_idx = k; 1020 + j++; 1021 + } 1022 + } 1023 + 1024 + return 0; 1025 + } 1026 + 1027 + static int sppctl_pinctrl_init(struct platform_device *pdev) 1028 + { 1029 + struct sppctl_pdata *sppctl = platform_get_drvdata(pdev); 1030 + int err; 1031 + 1032 + sppctl->pctl_desc.owner = THIS_MODULE; 1033 + sppctl->pctl_desc.name = dev_name(&pdev->dev); 1034 + sppctl->pctl_desc.pins = sppctl_pins_all; 1035 + sppctl->pctl_desc.npins = sppctl_pins_all_sz; 1036 + sppctl->pctl_desc.pctlops = &sppctl_pctl_ops; 1037 + sppctl->pctl_desc.confops = &sppctl_pconf_ops; 1038 + sppctl->pctl_desc.pmxops = &sppctl_pinmux_ops; 1039 + 1040 + err = sppctl_group_groups(pdev); 1041 + if (err) 1042 + return err; 1043 + 1044 + err = devm_pinctrl_register_and_init(&pdev->dev, &sppctl->pctl_desc, 1045 + sppctl, &sppctl->pctl_dev); 1046 + if (err) 1047 + return dev_err_probe(&pdev->dev, err, "Failed to register pinctrl!\n"); 1048 + 1049 + pinctrl_enable(sppctl->pctl_dev); 1050 + return 0; 1051 + } 1052 + 1053 + static int sppctl_resource_map(struct platform_device *pdev, struct sppctl_pdata *sppctl) 1054 + { 1055 + sppctl->moon2_base = devm_platform_ioremap_resource_byname(pdev, "moon2"); 1056 + if (IS_ERR(sppctl->moon2_base)) 1057 + return PTR_ERR(sppctl->moon2_base); 1058 + 1059 + sppctl->gpioxt_base = devm_platform_ioremap_resource_byname(pdev, "gpioxt"); 1060 + if (IS_ERR(sppctl->gpioxt_base)) 1061 + return PTR_ERR(sppctl->gpioxt_base); 1062 + 1063 + sppctl->first_base = devm_platform_ioremap_resource_byname(pdev, "first"); 1064 + if (IS_ERR(sppctl->first_base)) 1065 + return PTR_ERR(sppctl->first_base); 1066 + 1067 + sppctl->moon1_base = devm_platform_ioremap_resource_byname(pdev, "moon1"); 1068 + if (IS_ERR(sppctl->moon1_base)) 1069 + return PTR_ERR(sppctl->moon1_base); 1070 + 1071 + return 0; 1072 + } 1073 + 1074 + static int sppctl_probe(struct platform_device *pdev) 1075 + { 1076 + struct sppctl_pdata *sppctl; 1077 + int ret; 1078 + 1079 + sppctl = devm_kzalloc(&pdev->dev, sizeof(*sppctl), GFP_KERNEL); 1080 + if (!sppctl) 1081 + return -ENOMEM; 1082 + platform_set_drvdata(pdev, sppctl); 1083 + 1084 + ret = sppctl_resource_map(pdev, sppctl); 1085 + if (ret) 1086 + return ret; 1087 + 1088 + ret = sppctl_gpio_new(pdev, sppctl); 1089 + if (ret) 1090 + return ret; 1091 + 1092 + ret = sppctl_pinctrl_init(pdev); 1093 + if (ret) 1094 + return ret; 1095 + 1096 + pinctrl_add_gpio_range(sppctl->pctl_dev, &sppctl->pctl_grange); 1097 + 1098 + return 0; 1099 + } 1100 + 1101 + static const struct of_device_id sppctl_match_table[] = { 1102 + { .compatible = "sunplus,sp7021-pctl" }, 1103 + { /* sentinel */ } 1104 + }; 1105 + 1106 + static struct platform_driver sppctl_pinctrl_driver = { 1107 + .driver = { 1108 + .name = SPPCTL_MODULE_NAME, 1109 + .of_match_table = sppctl_match_table, 1110 + }, 1111 + .probe = sppctl_probe, 1112 + }; 1113 + builtin_platform_driver(sppctl_pinctrl_driver) 1114 + 1115 + MODULE_AUTHOR("Dvorkin Dmitry <dvorkin@tibbo.com>"); 1116 + MODULE_AUTHOR("Wells Lu <wellslutw@gmail.com>"); 1117 + MODULE_DESCRIPTION("Sunplus SP7021 Pin Control and GPIO driver"); 1118 + MODULE_LICENSE("GPL v2");
+170
drivers/pinctrl/sunplus/sppctl.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * SP7021 Pin Controller Driver. 4 + * Copyright (C) Sunplus Tech / Tibbo Tech. 5 + */ 6 + 7 + #ifndef __SPPCTL_H__ 8 + #define __SPPCTL_H__ 9 + 10 + #include <linux/bits.h> 11 + #include <linux/gpio/driver.h> 12 + #include <linux/kernel.h> 13 + #include <linux/pinctrl/pinctrl.h> 14 + #include <linux/spinlock.h> 15 + #include <linux/types.h> 16 + 17 + #define SPPCTL_MODULE_NAME "sppctl_sp7021" 18 + 19 + #define SPPCTL_GPIO_OFF_FIRST 0x00 20 + #define SPPCTL_GPIO_OFF_MASTER 0x00 21 + #define SPPCTL_GPIO_OFF_OE 0x20 22 + #define SPPCTL_GPIO_OFF_OUT 0x40 23 + #define SPPCTL_GPIO_OFF_IN 0x60 24 + #define SPPCTL_GPIO_OFF_IINV 0x80 25 + #define SPPCTL_GPIO_OFF_OINV 0xa0 26 + #define SPPCTL_GPIO_OFF_OD 0xc0 27 + 28 + #define SPPCTL_FULLY_PINMUX_MASK_MASK GENMASK(22, 16) 29 + #define SPPCTL_FULLY_PINMUX_SEL_MASK GENMASK(6, 0) 30 + #define SPPCTL_FULLY_PINMUX_UPPER_SHIFT 8 31 + 32 + /* 33 + * Mask-fields and control-fields of MOON registers of SP7021 are 34 + * arranged as shown below: 35 + * 36 + * register | mask-fields | control-fields 37 + * ----------+--------------+---------------- 38 + * base[0] | (31 : 16) | (15 : 0) 39 + * base[1] | (31 : 24) | (15 : 0) 40 + * base[2] | (31 : 24) | (15 : 0) 41 + * : | : | : 42 + * 43 + * where mask-fields are used to protect control-fields from write-in 44 + * accidentally. Set the corresponding bits in the mask-field before 45 + * you write a value into a control-field. 46 + */ 47 + #define SPPCTL_MOON_REG_MASK_SHIFT 16 48 + #define SPPCTL_SET_MOON_REG_BIT(bit) (BIT((bit) + SPPCTL_MOON_REG_MASK_SHIFT) | BIT(bit)) 49 + #define SPPCTL_CLR_MOON_REG_BIT(bit) BIT((bit) + SPPCTL_MOON_REG_MASK_SHIFT) 50 + 51 + #define SPPCTL_IOP_CONFIGS 0xff 52 + 53 + #define FNCE(n, r, o, bo, bl, g) { \ 54 + .name = n, \ 55 + .type = r, \ 56 + .roff = o, \ 57 + .boff = bo, \ 58 + .blen = bl, \ 59 + .grps = (g), \ 60 + .gnum = ARRAY_SIZE(g), \ 61 + } 62 + 63 + #define FNCN(n, r, o, bo, bl) { \ 64 + .name = n, \ 65 + .type = r, \ 66 + .roff = o, \ 67 + .boff = bo, \ 68 + .blen = bl, \ 69 + .grps = NULL, \ 70 + .gnum = 0, \ 71 + } 72 + 73 + #define EGRP(n, v, p) { \ 74 + .name = n, \ 75 + .gval = (v), \ 76 + .pins = (p), \ 77 + .pnum = ARRAY_SIZE(p), \ 78 + } 79 + 80 + /** 81 + * enum mux_first_reg - Define modes of access of FIRST register 82 + * @mux_f_mux: Set the corresponding pin to a fully-pinmux pin 83 + * @mux_f_gpio: Set the corresponding pin to a GPIO or IOP pin 84 + * @mux_f_keep: Don't change (keep intact) 85 + */ 86 + enum mux_first_reg { 87 + mux_f_mux = 0, 88 + mux_f_gpio = 1, 89 + mux_f_keep = 2, 90 + }; 91 + 92 + /** 93 + * enum mux_master_reg - Define modes of access of MASTER register 94 + * @mux_m_iop: Set the corresponding pin to an IO processor (IOP) pin 95 + * @mux_m_gpio: Set the corresponding pin to a digital GPIO pin 96 + * @mux_m_keep: Don't change (keep intact) 97 + */ 98 + enum mux_master_reg { 99 + mux_m_iop = 0, 100 + mux_m_gpio = 1, 101 + mux_m_keep = 2, 102 + }; 103 + 104 + /** 105 + * enum pinmux_type - Define types of pinmux pins 106 + * @pinmux_type_fpmx: A fully-pinmux pin 107 + * @pinmux_type_grp: A group-pinmux pin 108 + */ 109 + enum pinmux_type { 110 + pinmux_type_fpmx, 111 + pinmux_type_grp, 112 + }; 113 + 114 + /** 115 + * struct grp2fp_map - A map storing indexes 116 + * @f_idx: an index to function table 117 + * @g_idx: an index to group table 118 + */ 119 + struct grp2fp_map { 120 + u16 f_idx; 121 + u16 g_idx; 122 + }; 123 + 124 + struct sppctl_gpio_chip; 125 + 126 + struct sppctl_pdata { 127 + void __iomem *moon2_base; /* MOON2 */ 128 + void __iomem *gpioxt_base; /* MASTER, OE, OUT, IN, I_INV, O_INV, OD */ 129 + void __iomem *first_base; /* FIRST */ 130 + void __iomem *moon1_base; /* MOON1 */ 131 + 132 + struct pinctrl_desc pctl_desc; 133 + struct pinctrl_dev *pctl_dev; 134 + struct pinctrl_gpio_range pctl_grange; 135 + struct sppctl_gpio_chip *spp_gchip; 136 + 137 + char const **unq_grps; 138 + size_t unq_grps_sz; 139 + struct grp2fp_map *g2fp_maps; 140 + }; 141 + 142 + struct sppctl_grp { 143 + const char * const name; 144 + const u8 gval; /* group number */ 145 + const unsigned * const pins; /* list of pins */ 146 + const unsigned int pnum; /* number of pins */ 147 + }; 148 + 149 + struct sppctl_func { 150 + const char * const name; 151 + const enum pinmux_type type; /* function type */ 152 + const u8 roff; /* register offset */ 153 + const u8 boff; /* bit offset */ 154 + const u8 blen; /* bit length */ 155 + const struct sppctl_grp * const grps; /* list of groups */ 156 + const unsigned int gnum; /* number of groups */ 157 + }; 158 + 159 + extern const struct sppctl_func sppctl_list_funcs[]; 160 + extern const char * const sppctl_pmux_list_s[]; 161 + extern const char * const sppctl_gpio_list_s[]; 162 + extern const struct pinctrl_pin_desc sppctl_pins_all[]; 163 + extern const unsigned int sppctl_pins_gpio[]; 164 + 165 + extern const size_t sppctl_list_funcs_sz; 166 + extern const size_t sppctl_pmux_list_sz; 167 + extern const size_t sppctl_gpio_list_sz; 168 + extern const size_t sppctl_pins_all_sz; 169 + 170 + #endif
+583
drivers/pinctrl/sunplus/sppctl_sp7021.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * SP7021 Pin Controller Driver. 4 + * Copyright (C) Sunplus Tech / Tibbo Tech. 5 + */ 6 + 7 + #include <linux/gpio/driver.h> 8 + #include <linux/kernel.h> 9 + #include <linux/pinctrl/pinctrl.h> 10 + 11 + #include "sppctl.h" 12 + 13 + #define D_PIS(x, y) "P" __stringify(x) "_0" __stringify(y) 14 + #define D(x, y) ((x) * 8 + (y)) 15 + #define P(x, y) PINCTRL_PIN(D(x, y), D_PIS(x, y)) 16 + 17 + const char * const sppctl_gpio_list_s[] = { 18 + D_PIS(0, 0), D_PIS(0, 1), D_PIS(0, 2), D_PIS(0, 3), 19 + D_PIS(0, 4), D_PIS(0, 5), D_PIS(0, 6), D_PIS(0, 7), 20 + D_PIS(1, 0), D_PIS(1, 1), D_PIS(1, 2), D_PIS(1, 3), 21 + D_PIS(1, 4), D_PIS(1, 5), D_PIS(1, 6), D_PIS(1, 7), 22 + D_PIS(2, 0), D_PIS(2, 1), D_PIS(2, 2), D_PIS(2, 3), 23 + D_PIS(2, 4), D_PIS(2, 5), D_PIS(2, 6), D_PIS(2, 7), 24 + D_PIS(3, 0), D_PIS(3, 1), D_PIS(3, 2), D_PIS(3, 3), 25 + D_PIS(3, 4), D_PIS(3, 5), D_PIS(3, 6), D_PIS(3, 7), 26 + D_PIS(4, 0), D_PIS(4, 1), D_PIS(4, 2), D_PIS(4, 3), 27 + D_PIS(4, 4), D_PIS(4, 5), D_PIS(4, 6), D_PIS(4, 7), 28 + D_PIS(5, 0), D_PIS(5, 1), D_PIS(5, 2), D_PIS(5, 3), 29 + D_PIS(5, 4), D_PIS(5, 5), D_PIS(5, 6), D_PIS(5, 7), 30 + D_PIS(6, 0), D_PIS(6, 1), D_PIS(6, 2), D_PIS(6, 3), 31 + D_PIS(6, 4), D_PIS(6, 5), D_PIS(6, 6), D_PIS(6, 7), 32 + D_PIS(7, 0), D_PIS(7, 1), D_PIS(7, 2), D_PIS(7, 3), 33 + D_PIS(7, 4), D_PIS(7, 5), D_PIS(7, 6), D_PIS(7, 7), 34 + D_PIS(8, 0), D_PIS(8, 1), D_PIS(8, 2), D_PIS(8, 3), 35 + D_PIS(8, 4), D_PIS(8, 5), D_PIS(8, 6), D_PIS(8, 7), 36 + D_PIS(9, 0), D_PIS(9, 1), D_PIS(9, 2), D_PIS(9, 3), 37 + D_PIS(9, 4), D_PIS(9, 5), D_PIS(9, 6), D_PIS(9, 7), 38 + D_PIS(10, 0), D_PIS(10, 1), D_PIS(10, 2), D_PIS(10, 3), 39 + D_PIS(10, 4), D_PIS(10, 5), D_PIS(10, 6), D_PIS(10, 7), 40 + D_PIS(11, 0), D_PIS(11, 1), D_PIS(11, 2), D_PIS(11, 3), 41 + D_PIS(11, 4), D_PIS(11, 5), D_PIS(11, 6), D_PIS(11, 7), 42 + D_PIS(12, 0), D_PIS(12, 1), D_PIS(12, 2), 43 + }; 44 + 45 + const size_t sppctl_gpio_list_sz = ARRAY_SIZE(sppctl_gpio_list_s); 46 + 47 + const unsigned int sppctl_pins_gpio[] = { 48 + D(0, 0), D(0, 1), D(0, 2), D(0, 3), D(0, 4), D(0, 5), D(0, 6), D(0, 7), 49 + D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6), D(1, 7), 50 + D(2, 0), D(2, 1), D(2, 2), D(2, 3), D(2, 4), D(2, 5), D(2, 6), D(2, 7), 51 + D(3, 0), D(3, 1), D(3, 2), D(3, 3), D(3, 4), D(3, 5), D(3, 6), D(3, 7), 52 + D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5), D(4, 6), D(4, 7), 53 + D(5, 0), D(5, 1), D(5, 2), D(5, 3), D(5, 4), D(5, 5), D(5, 6), D(5, 7), 54 + D(6, 0), D(6, 1), D(6, 2), D(6, 3), D(6, 4), D(6, 5), D(6, 6), D(6, 7), 55 + D(7, 0), D(7, 1), D(7, 2), D(7, 3), D(7, 4), D(7, 5), D(7, 6), D(7, 7), 56 + D(8, 0), D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5), D(8, 6), D(8, 7), 57 + D(9, 0), D(9, 1), D(9, 2), D(9, 3), D(9, 4), D(9, 5), D(9, 6), D(9, 7), 58 + D(10, 0), D(10, 1), D(10, 2), D(10, 3), D(10, 4), D(10, 5), D(10, 6), D(10, 7), 59 + D(11, 0), D(11, 1), D(11, 2), D(11, 3), D(11, 4), D(11, 5), D(11, 6), D(11, 7), 60 + D(12, 0), D(12, 1), D(12, 2), 61 + }; 62 + 63 + const struct pinctrl_pin_desc sppctl_pins_all[] = { 64 + /* gpio and iop only */ 65 + P(0, 0), P(0, 1), P(0, 2), P(0, 3), P(0, 4), P(0, 5), P(0, 6), P(0, 7), 66 + /* gpio, iop, muxable */ 67 + P(1, 0), P(1, 1), P(1, 2), P(1, 3), P(1, 4), P(1, 5), P(1, 6), P(1, 7), 68 + P(2, 0), P(2, 1), P(2, 2), P(2, 3), P(2, 4), P(2, 5), P(2, 6), P(2, 7), 69 + P(3, 0), P(3, 1), P(3, 2), P(3, 3), P(3, 4), P(3, 5), P(3, 6), P(3, 7), 70 + P(4, 0), P(4, 1), P(4, 2), P(4, 3), P(4, 4), P(4, 5), P(4, 6), P(4, 7), 71 + P(5, 0), P(5, 1), P(5, 2), P(5, 3), P(5, 4), P(5, 5), P(5, 6), P(5, 7), 72 + P(6, 0), P(6, 1), P(6, 2), P(6, 3), P(6, 4), P(6, 5), P(6, 6), P(6, 7), 73 + P(7, 0), P(7, 1), P(7, 2), P(7, 3), P(7, 4), P(7, 5), P(7, 6), P(7, 7), 74 + P(8, 0), P(8, 1), P(8, 2), P(8, 3), P(8, 4), P(8, 5), P(8, 6), P(8, 7), 75 + /* gpio and iop only */ 76 + P(9, 0), P(9, 1), P(9, 2), P(9, 3), P(9, 4), P(9, 5), P(9, 6), P(9, 7), 77 + P(10, 0), P(10, 1), P(10, 2), P(10, 3), P(10, 4), P(10, 5), P(10, 6), P(10, 7), 78 + P(11, 0), P(11, 1), P(11, 2), P(11, 3), P(11, 4), P(11, 5), P(11, 6), P(11, 7), 79 + P(12, 0), P(12, 1), P(12, 2), 80 + }; 81 + 82 + const size_t sppctl_pins_all_sz = ARRAY_SIZE(sppctl_pins_all); 83 + 84 + const char * const sppctl_pmux_list_s[] = { 85 + D_PIS(0, 0), 86 + D_PIS(1, 0), D_PIS(1, 1), D_PIS(1, 2), D_PIS(1, 3), 87 + D_PIS(1, 4), D_PIS(1, 5), D_PIS(1, 6), D_PIS(1, 7), 88 + D_PIS(2, 0), D_PIS(2, 1), D_PIS(2, 2), D_PIS(2, 3), 89 + D_PIS(2, 4), D_PIS(2, 5), D_PIS(2, 6), D_PIS(2, 7), 90 + D_PIS(3, 0), D_PIS(3, 1), D_PIS(3, 2), D_PIS(3, 3), 91 + D_PIS(3, 4), D_PIS(3, 5), D_PIS(3, 6), D_PIS(3, 7), 92 + D_PIS(4, 0), D_PIS(4, 1), D_PIS(4, 2), D_PIS(4, 3), 93 + D_PIS(4, 4), D_PIS(4, 5), D_PIS(4, 6), D_PIS(4, 7), 94 + D_PIS(5, 0), D_PIS(5, 1), D_PIS(5, 2), D_PIS(5, 3), 95 + D_PIS(5, 4), D_PIS(5, 5), D_PIS(5, 6), D_PIS(5, 7), 96 + D_PIS(6, 0), D_PIS(6, 1), D_PIS(6, 2), D_PIS(6, 3), 97 + D_PIS(6, 4), D_PIS(6, 5), D_PIS(6, 6), D_PIS(6, 7), 98 + D_PIS(7, 0), D_PIS(7, 1), D_PIS(7, 2), D_PIS(7, 3), 99 + D_PIS(7, 4), D_PIS(7, 5), D_PIS(7, 6), D_PIS(7, 7), 100 + D_PIS(8, 0), D_PIS(8, 1), D_PIS(8, 2), D_PIS(8, 3), 101 + D_PIS(8, 4), D_PIS(8, 5), D_PIS(8, 6), D_PIS(8, 7), 102 + }; 103 + 104 + const size_t sppctl_pmux_list_sz = ARRAY_SIZE(sppctl_pmux_list_s); 105 + 106 + static const unsigned int pins_spif1[] = { 107 + D(10, 3), D(10, 4), D(10, 6), D(10, 7), 108 + }; 109 + 110 + static const unsigned int pins_spif2[] = { 111 + D(9, 4), D(9, 6), D(9, 7), D(10, 1), 112 + }; 113 + 114 + static const struct sppctl_grp sp7021grps_spif[] = { 115 + EGRP("SPI_FLASH1", 1, pins_spif1), 116 + EGRP("SPI_FLASH2", 2, pins_spif2), 117 + }; 118 + 119 + static const unsigned int pins_spi41[] = { 120 + D(10, 2), D(10, 5), 121 + }; 122 + 123 + static const unsigned int pins_spi42[] = { 124 + D(9, 5), D(9, 8), 125 + }; 126 + 127 + static const struct sppctl_grp sp7021grps_spi4[] = { 128 + EGRP("SPI_FLASH_4BIT1", 1, pins_spi41), 129 + EGRP("SPI_FLASH_4BIT2", 2, pins_spi42), 130 + }; 131 + 132 + static const unsigned int pins_snan[] = { 133 + D(9, 4), D(9, 5), D(9, 6), D(9, 7), D(10, 0), D(10, 1), 134 + }; 135 + 136 + static const struct sppctl_grp sp7021grps_snan[] = { 137 + EGRP("SPI_NAND", 1, pins_snan), 138 + }; 139 + 140 + static const unsigned int pins_emmc[] = { 141 + D(9, 0), D(9, 1), D(9, 2), D(9, 3), D(9, 4), D(9, 5), 142 + D(9, 6), D(9, 7), D(10, 0), D(10, 1), 143 + }; 144 + 145 + static const struct sppctl_grp sp7021grps_emmc[] = { 146 + EGRP("CARD0_EMMC", 1, pins_emmc), 147 + }; 148 + 149 + static const unsigned int pins_sdsd[] = { 150 + D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5), D(8, 6), 151 + }; 152 + 153 + static const struct sppctl_grp sp7021grps_sdsd[] = { 154 + EGRP("SD_CARD", 1, pins_sdsd), 155 + }; 156 + 157 + static const unsigned int pins_uar0[] = { 158 + D(11, 0), D(11, 1), 159 + }; 160 + 161 + static const struct sppctl_grp sp7021grps_uar0[] = { 162 + EGRP("UA0", 1, pins_uar0), 163 + }; 164 + 165 + static const unsigned int pins_adbg1[] = { 166 + D(10, 2), D(10, 3), 167 + }; 168 + 169 + static const unsigned int pins_adbg2[] = { 170 + D(7, 1), D(7, 2), 171 + }; 172 + 173 + static const struct sppctl_grp sp7021grps_adbg[] = { 174 + EGRP("ACHIP_DEBUG1", 1, pins_adbg1), 175 + EGRP("ACHIP_DEBUG2", 2, pins_adbg2), 176 + }; 177 + 178 + static const unsigned int pins_aua2axi1[] = { 179 + D(2, 0), D(2, 1), D(2, 2), 180 + }; 181 + 182 + static const unsigned int pins_aua2axi2[] = { 183 + D(1, 0), D(1, 1), D(1, 2), 184 + }; 185 + 186 + static const struct sppctl_grp sp7021grps_au2x[] = { 187 + EGRP("ACHIP_UA2AXI1", 1, pins_aua2axi1), 188 + EGRP("ACHIP_UA2AXI2", 2, pins_aua2axi2), 189 + }; 190 + 191 + static const unsigned int pins_fpga[] = { 192 + D(0, 2), D(0, 3), D(0, 4), D(0, 5), D(0, 6), D(0, 7), 193 + D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), 194 + D(1, 6), D(1, 7), D(2, 0), D(2, 1), D(2, 2), D(2, 3), 195 + D(2, 4), D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1), 196 + D(3, 2), D(3, 3), D(3, 4), D(3, 5), D(3, 6), D(3, 7), 197 + D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5), 198 + D(4, 6), D(4, 7), D(5, 0), D(5, 1), D(5, 2), 199 + }; 200 + 201 + static const struct sppctl_grp sp7021grps_fpga[] = { 202 + EGRP("FPGA_IFX", 1, pins_fpga), 203 + }; 204 + 205 + static const unsigned int pins_hdmi1[] = { 206 + D(10, 6), D(12, 2), D(12, 1), 207 + }; 208 + 209 + static const unsigned int pins_hdmi2[] = { 210 + D(8, 3), D(8, 5), D(8, 6), 211 + }; 212 + 213 + static const unsigned int pins_hdmi3[] = { 214 + D(7, 4), D(7, 6), D(7, 7), 215 + }; 216 + 217 + static const struct sppctl_grp sp7021grps_hdmi[] = { 218 + EGRP("HDMI_TX1", 1, pins_hdmi1), 219 + EGRP("HDMI_TX2", 2, pins_hdmi2), 220 + EGRP("HDMI_TX3", 3, pins_hdmi3), 221 + }; 222 + 223 + static const unsigned int pins_eadc[] = { 224 + D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6), 225 + }; 226 + 227 + static const struct sppctl_grp sp7021grps_eadc[] = { 228 + EGRP("AUD_EXT_ADC_IFX0", 1, pins_eadc), 229 + }; 230 + 231 + static const unsigned int pins_edac[] = { 232 + D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1), D(3, 2), D(3, 4), 233 + }; 234 + 235 + static const struct sppctl_grp sp7021grps_edac[] = { 236 + EGRP("AUD_EXT_DAC_IFX0", 1, pins_edac), 237 + }; 238 + 239 + static const unsigned int pins_spdi[] = { 240 + D(2, 4), 241 + }; 242 + 243 + static const struct sppctl_grp sp7021grps_spdi[] = { 244 + EGRP("AUD_IEC_RX0", 1, pins_spdi), 245 + }; 246 + 247 + static const unsigned int pins_spdo[] = { 248 + D(3, 6), 249 + }; 250 + 251 + static const struct sppctl_grp sp7021grps_spdo[] = { 252 + EGRP("AUD_IEC_TX0", 1, pins_spdo), 253 + }; 254 + 255 + static const unsigned int pins_tdmt[] = { 256 + D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1), D(3, 2), 257 + }; 258 + 259 + static const struct sppctl_grp sp7021grps_tdmt[] = { 260 + EGRP("TDMTX_IFX0", 1, pins_tdmt), 261 + }; 262 + 263 + static const unsigned int pins_tdmr[] = { 264 + D(1, 7), D(2, 0), D(2, 1), D(2, 2), 265 + }; 266 + 267 + static const struct sppctl_grp sp7021grps_tdmr[] = { 268 + EGRP("TDMRX_IFX0", 1, pins_tdmr), 269 + }; 270 + 271 + static const unsigned int pins_pdmr[] = { 272 + D(1, 7), D(2, 0), D(2, 1), D(2, 2), D(2, 3), 273 + }; 274 + 275 + static const struct sppctl_grp sp7021grps_pdmr[] = { 276 + EGRP("PDMRX_IFX0", 1, pins_pdmr), 277 + }; 278 + 279 + static const unsigned int pins_pcmt[] = { 280 + D(3, 7), D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), 281 + }; 282 + 283 + static const struct sppctl_grp sp7021grps_pcmt[] = { 284 + EGRP("PCM_IEC_TX", 1, pins_pcmt), 285 + }; 286 + 287 + static const unsigned int pins_lcdi[] = { 288 + D(1, 4), D(1, 5), D(1, 6), D(1, 7), D(2, 0), D(2, 1), D(2, 2), D(2, 3), 289 + D(2, 4), D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1), D(3, 2), D(3, 3), 290 + D(3, 4), D(3, 5), D(3, 6), D(3, 7), D(4, 0), D(4, 1), D(4, 2), D(4, 3), 291 + D(4, 4), D(4, 5), D(4, 6), D(4, 7), 292 + }; 293 + 294 + static const struct sppctl_grp sp7021grps_lcdi[] = { 295 + EGRP("LCDIF", 1, pins_lcdi), 296 + }; 297 + 298 + static const unsigned int pins_dvdd[] = { 299 + D(7, 0), D(7, 1), D(7, 2), D(7, 3), D(7, 4), D(7, 5), D(7, 6), D(7, 7), 300 + D(8, 0), D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5), 301 + }; 302 + 303 + static const struct sppctl_grp sp7021grps_dvdd[] = { 304 + EGRP("DVD_DSP_DEBUG", 1, pins_dvdd), 305 + }; 306 + 307 + static const unsigned int pins_i2cd[] = { 308 + D(1, 0), D(1, 1), 309 + }; 310 + 311 + static const struct sppctl_grp sp7021grps_i2cd[] = { 312 + EGRP("I2C_DEBUG", 1, pins_i2cd), 313 + }; 314 + 315 + static const unsigned int pins_i2cs[] = { 316 + D(0, 0), D(0, 1), 317 + }; 318 + 319 + static const struct sppctl_grp sp7021grps_i2cs[] = { 320 + EGRP("I2C_SLAVE", 1, pins_i2cs), 321 + }; 322 + 323 + static const unsigned int pins_wakp[] = { 324 + D(10, 5), 325 + }; 326 + 327 + static const struct sppctl_grp sp7021grps_wakp[] = { 328 + EGRP("WAKEUP", 1, pins_wakp), 329 + }; 330 + 331 + static const unsigned int pins_u2ax[] = { 332 + D(2, 0), D(2, 1), D(3, 0), D(3, 1), 333 + }; 334 + 335 + static const struct sppctl_grp sp7021grps_u2ax[] = { 336 + EGRP("UART2AXI", 1, pins_u2ax), 337 + }; 338 + 339 + static const unsigned int pins_u0ic[] = { 340 + D(0, 0), D(0, 1), D(0, 4), D(0, 5), D(1, 0), D(1, 1), 341 + }; 342 + 343 + static const struct sppctl_grp sp7021grps_u0ic[] = { 344 + EGRP("USB0_I2C", 1, pins_u0ic), 345 + }; 346 + 347 + static const unsigned int pins_u1ic[] = { 348 + D(0, 2), D(0, 3), D(0, 6), D(0, 7), D(1, 2), D(1, 3), 349 + }; 350 + 351 + static const struct sppctl_grp sp7021grps_u1ic[] = { 352 + EGRP("USB1_I2C", 1, pins_u1ic), 353 + }; 354 + 355 + static const unsigned int pins_u0ot[] = { 356 + D(11, 2), 357 + }; 358 + 359 + static const struct sppctl_grp sp7021grps_u0ot[] = { 360 + EGRP("USB0_OTG", 1, pins_u0ot), 361 + }; 362 + 363 + static const unsigned int pins_u1ot[] = { 364 + D(11, 3), 365 + }; 366 + 367 + static const struct sppctl_grp sp7021grps_u1ot[] = { 368 + EGRP("USB1_OTG", 1, pins_u1ot), 369 + }; 370 + 371 + static const unsigned int pins_uphd[] = { 372 + D(0, 1), D(0, 2), D(0, 3), D(7, 4), D(7, 5), D(7, 6), 373 + D(7, 7), D(8, 0), D(8, 1), D(8, 2), D(8, 3), 374 + D(9, 7), D(10, 2), D(10, 3), D(10, 4), 375 + }; 376 + 377 + static const struct sppctl_grp sp7021grps_up0d[] = { 378 + EGRP("UPHY0_DEBUG", 1, pins_uphd), 379 + }; 380 + 381 + static const struct sppctl_grp sp7021grps_up1d[] = { 382 + EGRP("UPHY1_DEBUG", 1, pins_uphd), 383 + }; 384 + 385 + static const unsigned int pins_upex[] = { 386 + D(0, 0), D(0, 1), D(0, 2), D(0, 3), D(0, 4), D(0, 5), D(0, 6), D(0, 7), 387 + D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6), D(1, 7), 388 + D(2, 0), D(2, 1), D(2, 2), D(2, 3), D(2, 4), D(2, 5), D(2, 6), D(2, 7), 389 + D(3, 0), D(3, 1), D(3, 2), D(3, 3), D(3, 4), D(3, 5), D(3, 6), D(3, 7), 390 + D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5), D(4, 6), D(4, 7), 391 + D(5, 0), D(5, 1), D(5, 2), D(5, 3), D(5, 4), D(5, 5), D(5, 6), D(5, 7), 392 + D(6, 0), D(6, 1), D(6, 2), D(6, 3), D(6, 4), D(6, 5), D(6, 6), D(6, 7), 393 + D(7, 0), D(7, 1), D(7, 2), D(7, 3), D(7, 4), D(7, 5), D(7, 6), D(7, 7), 394 + D(8, 0), D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5), D(8, 6), D(8, 7), 395 + D(9, 0), D(9, 1), D(9, 2), D(9, 3), D(9, 4), D(9, 5), D(9, 6), D(9, 7), 396 + D(10, 0), D(10, 1), D(10, 2), D(10, 3), D(10, 4), D(10, 5), D(10, 6), D(10, 7), 397 + }; 398 + 399 + static const struct sppctl_grp sp7021grps_upex[] = { 400 + EGRP("UPHY0_EXT", 1, pins_upex), 401 + }; 402 + 403 + static const unsigned int pins_prp1[] = { 404 + D(0, 6), D(0, 7), 405 + D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6), D(1, 7), 406 + D(2, 1), D(2, 2), D(2, 3), D(2, 4), D(2, 5), D(2, 6), D(2, 7), 407 + D(3, 0), D(3, 1), D(3, 2), 408 + }; 409 + 410 + static const unsigned int pins_prp2[] = { 411 + D(3, 4), D(3, 6), D(3, 7), 412 + D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5), D(4, 6), D(4, 7), 413 + D(5, 0), D(5, 1), D(5, 2), D(5, 3), D(5, 4), D(5, 5), D(5, 6), D(5, 7), 414 + D(6, 4), 415 + }; 416 + 417 + static const struct sppctl_grp sp7021grps_prbp[] = { 418 + EGRP("PROBE_PORT1", 1, pins_prp1), 419 + EGRP("PROBE_PORT2", 2, pins_prp2), 420 + }; 421 + 422 + const struct sppctl_func sppctl_list_funcs[] = { 423 + FNCN("L2SW_CLK_OUT", pinmux_type_fpmx, 0x00, 0, 7), 424 + FNCN("L2SW_MAC_SMI_MDC", pinmux_type_fpmx, 0x00, 8, 7), 425 + FNCN("L2SW_LED_FLASH0", pinmux_type_fpmx, 0x01, 0, 7), 426 + FNCN("L2SW_LED_FLASH1", pinmux_type_fpmx, 0x01, 8, 7), 427 + FNCN("L2SW_LED_ON0", pinmux_type_fpmx, 0x02, 0, 7), 428 + FNCN("L2SW_LED_ON1", pinmux_type_fpmx, 0x02, 8, 7), 429 + FNCN("L2SW_MAC_SMI_MDIO", pinmux_type_fpmx, 0x03, 0, 7), 430 + FNCN("L2SW_P0_MAC_RMII_TXEN", pinmux_type_fpmx, 0x03, 8, 7), 431 + FNCN("L2SW_P0_MAC_RMII_TXD0", pinmux_type_fpmx, 0x04, 0, 7), 432 + FNCN("L2SW_P0_MAC_RMII_TXD1", pinmux_type_fpmx, 0x04, 8, 7), 433 + FNCN("L2SW_P0_MAC_RMII_CRSDV", pinmux_type_fpmx, 0x05, 0, 7), 434 + FNCN("L2SW_P0_MAC_RMII_RXD0", pinmux_type_fpmx, 0x05, 8, 7), 435 + FNCN("L2SW_P0_MAC_RMII_RXD1", pinmux_type_fpmx, 0x06, 0, 7), 436 + FNCN("L2SW_P0_MAC_RMII_RXER", pinmux_type_fpmx, 0x06, 8, 7), 437 + FNCN("L2SW_P1_MAC_RMII_TXEN", pinmux_type_fpmx, 0x07, 0, 7), 438 + FNCN("L2SW_P1_MAC_RMII_TXD0", pinmux_type_fpmx, 0x07, 8, 7), 439 + FNCN("L2SW_P1_MAC_RMII_TXD1", pinmux_type_fpmx, 0x08, 0, 7), 440 + FNCN("L2SW_P1_MAC_RMII_CRSDV", pinmux_type_fpmx, 0x08, 8, 7), 441 + FNCN("L2SW_P1_MAC_RMII_RXD0", pinmux_type_fpmx, 0x09, 0, 7), 442 + FNCN("L2SW_P1_MAC_RMII_RXD1", pinmux_type_fpmx, 0x09, 8, 7), 443 + FNCN("L2SW_P1_MAC_RMII_RXER", pinmux_type_fpmx, 0x0A, 0, 7), 444 + FNCN("DAISY_MODE", pinmux_type_fpmx, 0x0A, 8, 7), 445 + FNCN("SDIO_CLK", pinmux_type_fpmx, 0x0B, 0, 7), /* 1x SDIO */ 446 + FNCN("SDIO_CMD", pinmux_type_fpmx, 0x0B, 8, 7), 447 + FNCN("SDIO_D0", pinmux_type_fpmx, 0x0C, 0, 7), 448 + FNCN("SDIO_D1", pinmux_type_fpmx, 0x0C, 8, 7), 449 + FNCN("SDIO_D2", pinmux_type_fpmx, 0x0D, 0, 7), 450 + FNCN("SDIO_D3", pinmux_type_fpmx, 0x0D, 8, 7), 451 + FNCN("PWM0", pinmux_type_fpmx, 0x0E, 0, 7), /* 8x PWM */ 452 + FNCN("PWM1", pinmux_type_fpmx, 0x0E, 8, 7), 453 + FNCN("PWM2", pinmux_type_fpmx, 0x0F, 0, 7), 454 + FNCN("PWM3", pinmux_type_fpmx, 0x0F, 8, 7), 455 + 456 + FNCN("PWM4", pinmux_type_fpmx, 0x10, 0, 7), 457 + FNCN("PWM5", pinmux_type_fpmx, 0x10, 8, 7), 458 + FNCN("PWM6", pinmux_type_fpmx, 0x11, 0, 7), 459 + FNCN("PWM7", pinmux_type_fpmx, 0x11, 8, 7), 460 + FNCN("ICM0_D", pinmux_type_fpmx, 0x12, 0, 7), /* 4x Input captures */ 461 + FNCN("ICM1_D", pinmux_type_fpmx, 0x12, 8, 7), 462 + FNCN("ICM2_D", pinmux_type_fpmx, 0x13, 0, 7), 463 + FNCN("ICM3_D", pinmux_type_fpmx, 0x13, 8, 7), 464 + FNCN("ICM0_CLK", pinmux_type_fpmx, 0x14, 0, 7), 465 + FNCN("ICM1_CLK", pinmux_type_fpmx, 0x14, 8, 7), 466 + FNCN("ICM2_CLK", pinmux_type_fpmx, 0x15, 0, 7), 467 + FNCN("ICM3_CLK", pinmux_type_fpmx, 0x15, 8, 7), 468 + FNCN("SPIM0_INT", pinmux_type_fpmx, 0x16, 0, 7), /* 4x SPI masters */ 469 + FNCN("SPIM0_CLK", pinmux_type_fpmx, 0x16, 8, 7), 470 + FNCN("SPIM0_EN", pinmux_type_fpmx, 0x17, 0, 7), 471 + FNCN("SPIM0_DO", pinmux_type_fpmx, 0x17, 8, 7), 472 + FNCN("SPIM0_DI", pinmux_type_fpmx, 0x18, 0, 7), 473 + FNCN("SPIM1_INT", pinmux_type_fpmx, 0x18, 8, 7), 474 + FNCN("SPIM1_CLK", pinmux_type_fpmx, 0x19, 0, 7), 475 + FNCN("SPIM1_EN", pinmux_type_fpmx, 0x19, 8, 7), 476 + FNCN("SPIM1_DO", pinmux_type_fpmx, 0x1A, 0, 7), 477 + FNCN("SPIM1_DI", pinmux_type_fpmx, 0x1A, 8, 7), 478 + FNCN("SPIM2_INT", pinmux_type_fpmx, 0x1B, 0, 7), 479 + FNCN("SPIM2_CLK", pinmux_type_fpmx, 0x1B, 8, 7), 480 + FNCN("SPIM2_EN", pinmux_type_fpmx, 0x1C, 0, 7), 481 + FNCN("SPIM2_DO", pinmux_type_fpmx, 0x1C, 8, 7), 482 + FNCN("SPIM2_DI", pinmux_type_fpmx, 0x1D, 0, 7), 483 + FNCN("SPIM3_INT", pinmux_type_fpmx, 0x1D, 8, 7), 484 + FNCN("SPIM3_CLK", pinmux_type_fpmx, 0x1E, 0, 7), 485 + FNCN("SPIM3_EN", pinmux_type_fpmx, 0x1E, 8, 7), 486 + FNCN("SPIM3_DO", pinmux_type_fpmx, 0x1F, 0, 7), 487 + FNCN("SPIM3_DI", pinmux_type_fpmx, 0x1F, 8, 7), 488 + 489 + FNCN("SPI0S_INT", pinmux_type_fpmx, 0x20, 0, 7), /* 4x SPI slaves */ 490 + FNCN("SPI0S_CLK", pinmux_type_fpmx, 0x20, 8, 7), 491 + FNCN("SPI0S_EN", pinmux_type_fpmx, 0x21, 0, 7), 492 + FNCN("SPI0S_DO", pinmux_type_fpmx, 0x21, 8, 7), 493 + FNCN("SPI0S_DI", pinmux_type_fpmx, 0x22, 0, 7), 494 + FNCN("SPI1S_INT", pinmux_type_fpmx, 0x22, 8, 7), 495 + FNCN("SPI1S_CLK", pinmux_type_fpmx, 0x23, 0, 7), 496 + FNCN("SPI1S_EN", pinmux_type_fpmx, 0x23, 8, 7), 497 + FNCN("SPI1S_DO", pinmux_type_fpmx, 0x24, 0, 7), 498 + FNCN("SPI1S_DI", pinmux_type_fpmx, 0x24, 8, 7), 499 + FNCN("SPI2S_INT", pinmux_type_fpmx, 0x25, 0, 7), 500 + FNCN("SPI2S_CLK", pinmux_type_fpmx, 0x25, 8, 7), 501 + FNCN("SPI2S_EN", pinmux_type_fpmx, 0x26, 0, 7), 502 + FNCN("SPI2S_DO", pinmux_type_fpmx, 0x26, 8, 7), 503 + FNCN("SPI2S_DI", pinmux_type_fpmx, 0x27, 0, 7), 504 + FNCN("SPI3S_INT", pinmux_type_fpmx, 0x27, 8, 7), 505 + FNCN("SPI3S_CLK", pinmux_type_fpmx, 0x28, 0, 7), 506 + FNCN("SPI3S_EN", pinmux_type_fpmx, 0x28, 8, 7), 507 + FNCN("SPI3S_DO", pinmux_type_fpmx, 0x29, 0, 7), 508 + FNCN("SPI3S_DI", pinmux_type_fpmx, 0x29, 8, 7), 509 + FNCN("I2CM0_CLK", pinmux_type_fpmx, 0x2A, 0, 7), /* 4x I2C masters */ 510 + FNCN("I2CM0_DAT", pinmux_type_fpmx, 0x2A, 8, 7), 511 + FNCN("I2CM1_CLK", pinmux_type_fpmx, 0x2B, 0, 7), 512 + FNCN("I2CM1_DAT", pinmux_type_fpmx, 0x2B, 8, 7), 513 + FNCN("I2CM2_CLK", pinmux_type_fpmx, 0x2C, 0, 7), 514 + FNCN("I2CM2_DAT", pinmux_type_fpmx, 0x2C, 8, 7), 515 + FNCN("I2CM3_CLK", pinmux_type_fpmx, 0x2D, 0, 7), 516 + FNCN("I2CM3_DAT", pinmux_type_fpmx, 0x2D, 8, 7), 517 + FNCN("UA1_TX", pinmux_type_fpmx, 0x2E, 0, 7), /* 4x UARTS */ 518 + FNCN("UA1_RX", pinmux_type_fpmx, 0x2E, 8, 7), 519 + FNCN("UA1_CTS", pinmux_type_fpmx, 0x2F, 0, 7), 520 + FNCN("UA1_RTS", pinmux_type_fpmx, 0x2F, 8, 7), 521 + 522 + FNCN("UA2_TX", pinmux_type_fpmx, 0x30, 0, 7), 523 + FNCN("UA2_RX", pinmux_type_fpmx, 0x30, 8, 7), 524 + FNCN("UA2_CTS", pinmux_type_fpmx, 0x31, 0, 7), 525 + FNCN("UA2_RTS", pinmux_type_fpmx, 0x31, 8, 7), 526 + FNCN("UA3_TX", pinmux_type_fpmx, 0x32, 0, 7), 527 + FNCN("UA3_RX", pinmux_type_fpmx, 0x32, 8, 7), 528 + FNCN("UA3_CTS", pinmux_type_fpmx, 0x33, 0, 7), 529 + FNCN("UA3_RTS", pinmux_type_fpmx, 0x33, 8, 7), 530 + FNCN("UA4_TX", pinmux_type_fpmx, 0x34, 0, 7), 531 + FNCN("UA4_RX", pinmux_type_fpmx, 0x34, 8, 7), 532 + FNCN("UA4_CTS", pinmux_type_fpmx, 0x35, 0, 7), 533 + FNCN("UA4_RTS", pinmux_type_fpmx, 0x35, 8, 7), 534 + FNCN("TIMER0_INT", pinmux_type_fpmx, 0x36, 0, 7), /* 4x timer int. */ 535 + FNCN("TIMER1_INT", pinmux_type_fpmx, 0x36, 8, 7), 536 + FNCN("TIMER2_INT", pinmux_type_fpmx, 0x37, 0, 7), 537 + FNCN("TIMER3_INT", pinmux_type_fpmx, 0x37, 8, 7), 538 + FNCN("GPIO_INT0", pinmux_type_fpmx, 0x38, 0, 7), /* 8x GPIO int. */ 539 + FNCN("GPIO_INT1", pinmux_type_fpmx, 0x38, 8, 7), 540 + FNCN("GPIO_INT2", pinmux_type_fpmx, 0x39, 0, 7), 541 + FNCN("GPIO_INT3", pinmux_type_fpmx, 0x39, 8, 7), 542 + FNCN("GPIO_INT4", pinmux_type_fpmx, 0x3A, 0, 7), 543 + FNCN("GPIO_INT5", pinmux_type_fpmx, 0x3A, 8, 7), 544 + FNCN("GPIO_INT6", pinmux_type_fpmx, 0x3B, 0, 7), 545 + FNCN("GPIO_INT7", pinmux_type_fpmx, 0x3B, 8, 7), 546 + 547 + /* MOON1 register */ 548 + FNCE("SPI_FLASH", pinmux_type_grp, 0x01, 0, 2, sp7021grps_spif), 549 + FNCE("SPI_FLASH_4BIT", pinmux_type_grp, 0x01, 2, 2, sp7021grps_spi4), 550 + FNCE("SPI_NAND", pinmux_type_grp, 0x01, 4, 1, sp7021grps_snan), 551 + FNCE("CARD0_EMMC", pinmux_type_grp, 0x01, 5, 1, sp7021grps_emmc), 552 + FNCE("SD_CARD", pinmux_type_grp, 0x01, 6, 1, sp7021grps_sdsd), 553 + FNCE("UA0", pinmux_type_grp, 0x01, 7, 1, sp7021grps_uar0), 554 + FNCE("ACHIP_DEBUG", pinmux_type_grp, 0x01, 8, 2, sp7021grps_adbg), 555 + FNCE("ACHIP_UA2AXI", pinmux_type_grp, 0x01, 10, 2, sp7021grps_au2x), 556 + FNCE("FPGA_IFX", pinmux_type_grp, 0x01, 12, 1, sp7021grps_fpga), 557 + FNCE("HDMI_TX", pinmux_type_grp, 0x01, 13, 2, sp7021grps_hdmi), 558 + 559 + FNCE("AUD_EXT_ADC_IFX0", pinmux_type_grp, 0x01, 15, 1, sp7021grps_eadc), 560 + FNCE("AUD_EXT_DAC_IFX0", pinmux_type_grp, 0x02, 0, 1, sp7021grps_edac), 561 + FNCE("SPDIF_RX", pinmux_type_grp, 0x02, 2, 1, sp7021grps_spdi), 562 + FNCE("SPDIF_TX", pinmux_type_grp, 0x02, 3, 1, sp7021grps_spdo), 563 + FNCE("TDMTX_IFX0", pinmux_type_grp, 0x02, 4, 1, sp7021grps_tdmt), 564 + FNCE("TDMRX_IFX0", pinmux_type_grp, 0x02, 5, 1, sp7021grps_tdmr), 565 + FNCE("PDMRX_IFX0", pinmux_type_grp, 0x02, 6, 1, sp7021grps_pdmr), 566 + FNCE("PCM_IEC_TX", pinmux_type_grp, 0x02, 7, 1, sp7021grps_pcmt), 567 + FNCE("LCDIF", pinmux_type_grp, 0x04, 6, 1, sp7021grps_lcdi), 568 + FNCE("DVD_DSP_DEBUG", pinmux_type_grp, 0x02, 8, 1, sp7021grps_dvdd), 569 + FNCE("I2C_DEBUG", pinmux_type_grp, 0x02, 9, 1, sp7021grps_i2cd), 570 + FNCE("I2C_SLAVE", pinmux_type_grp, 0x02, 10, 1, sp7021grps_i2cs), 571 + FNCE("WAKEUP", pinmux_type_grp, 0x02, 11, 1, sp7021grps_wakp), 572 + FNCE("UART2AXI", pinmux_type_grp, 0x02, 12, 2, sp7021grps_u2ax), 573 + FNCE("USB0_I2C", pinmux_type_grp, 0x02, 14, 2, sp7021grps_u0ic), 574 + FNCE("USB1_I2C", pinmux_type_grp, 0x03, 0, 2, sp7021grps_u1ic), 575 + FNCE("USB0_OTG", pinmux_type_grp, 0x03, 2, 1, sp7021grps_u0ot), 576 + FNCE("USB1_OTG", pinmux_type_grp, 0x03, 3, 1, sp7021grps_u1ot), 577 + FNCE("UPHY0_DEBUG", pinmux_type_grp, 0x03, 4, 1, sp7021grps_up0d), 578 + FNCE("UPHY1_DEBUG", pinmux_type_grp, 0x03, 5, 1, sp7021grps_up1d), 579 + FNCE("UPHY0_EXT", pinmux_type_grp, 0x03, 6, 1, sp7021grps_upex), 580 + FNCE("PROBE_PORT", pinmux_type_grp, 0x03, 7, 2, sp7021grps_prbp), 581 + }; 582 + 583 + const size_t sppctl_list_funcs_sz = ARRAY_SIZE(sppctl_list_funcs);