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

pinctrl: Add pin controller driver for AAEON UP boards

This enables the pin control support of the onboard FPGA on AAEON UP
boards.

This FPGA acts as a level shifter between the Intel SoC pins and the pin
header, and also as a mux or switch.

+---------+ +--------------+ +---+
| | | | |
| PWM0 | \ | | H |
|----------|------ \-----|-------------| E |
| I2C0_SDA | | | A |
Intel SoC |----------|------\ | | D |
| GPIO0 | \------|-------------| E |
|----------|------ | | R |
| | FPGA | | |
----------+ +--------------+ +---+

For most of the pins, the FPGA opens/closes a switch to enable/disable
the access to the SoC pin from a pin header.
Each switch, has a direction flag that is set depending the status of the
SoC pin.

For some other pins, the FPGA acts as a mux, and routes one pin (or the
other one) to the header.

The driver also provides a GPIO chip. It requests SoC pins in GPIO mode,
and drives them in tandem with FPGA pins (switch/mux direction).

This commit adds support only for UP Squared board.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
Link: https://lore.kernel.org/20250811-aaeon-up-board-pinctrl-support-v9-10-29f0cbbdfb30@bootlin.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Thomas Richard and committed by
Linus Walleij
dca2f73c 236152dd

+1090
+19
drivers/pinctrl/Kconfig
··· 600 600 This driver is needed for RISC-V development boards like 601 601 the BeagleV Ahead and the LicheePi 4A. 602 602 603 + config PINCTRL_UPBOARD 604 + tristate "AAeon UP board FPGA pin controller" 605 + depends on MFD_UPBOARD_FPGA 606 + select PINMUX 607 + select GENERIC_PINCTRL_GROUPS 608 + select GENERIC_PINMUX_FUNCTIONS 609 + select GPIOLIB 610 + select GPIO_AGGREGATOR 611 + help 612 + Pin controller for the FPGA GPIO lines on UP boards. Due to the 613 + hardware layout, the driver controls the FPGA pins in tandem with 614 + their corresponding Intel SoC GPIOs. 615 + 616 + Currently supported: 617 + - UP Squared 618 + 619 + To compile this driver as a module, choose M here: the module 620 + will be called pinctrl-upboard. 621 + 603 622 config PINCTRL_ZYNQ 604 623 bool "Pinctrl driver for Xilinx Zynq" 605 624 depends on ARCH_ZYNQ || COMPILE_TEST
+1
drivers/pinctrl/Makefile
··· 59 59 obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o 60 60 obj-$(CONFIG_PINCTRL_TPS6594) += pinctrl-tps6594.o 61 61 obj-$(CONFIG_PINCTRL_TH1520) += pinctrl-th1520.o 62 + obj-$(CONFIG_PINCTRL_UPBOARD) += pinctrl-upboard.o 62 63 obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.o 63 64 obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o 64 65
+1070
drivers/pinctrl/pinctrl-upboard.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * UP board pin control driver. 4 + * 5 + * Copyright (C) 2025 Bootlin 6 + * 7 + * Author: Thomas Richard <thomas.richard@bootlin.com> 8 + */ 9 + 10 + #include <linux/array_size.h> 11 + #include <linux/container_of.h> 12 + #include <linux/device.h> 13 + #include <linux/dmi.h> 14 + #include <linux/err.h> 15 + #include <linux/gpio/forwarder.h> 16 + #include <linux/mfd/upboard-fpga.h> 17 + #include <linux/module.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/regmap.h> 20 + #include <linux/seq_file.h> 21 + #include <linux/stddef.h> 22 + #include <linux/string_choices.h> 23 + #include <linux/types.h> 24 + 25 + #include <linux/pinctrl/consumer.h> 26 + #include <linux/pinctrl/pinctrl.h> 27 + #include <linux/pinctrl/pinmux.h> 28 + 29 + #include <linux/gpio/driver.h> 30 + #include <linux/gpio/consumer.h> 31 + 32 + #include "core.h" 33 + #include "pinmux.h" 34 + 35 + enum upboard_pin_mode { 36 + UPBOARD_PIN_MODE_FUNCTION, 37 + UPBOARD_PIN_MODE_GPIO_IN, 38 + UPBOARD_PIN_MODE_GPIO_OUT, 39 + UPBOARD_PIN_MODE_DISABLED, 40 + }; 41 + 42 + struct upboard_pin { 43 + struct regmap_field *funcbit; 44 + struct regmap_field *enbit; 45 + struct regmap_field *dirbit; 46 + }; 47 + 48 + struct upboard_pingroup { 49 + struct pingroup grp; 50 + enum upboard_pin_mode mode; 51 + const enum upboard_pin_mode *modes; 52 + }; 53 + 54 + struct upboard_pinctrl_data { 55 + const struct upboard_pingroup *groups; 56 + size_t ngroups; 57 + const struct pinfunction *funcs; 58 + size_t nfuncs; 59 + const unsigned int *pin_header; 60 + size_t ngpio; 61 + }; 62 + 63 + struct upboard_pinctrl { 64 + struct device *dev; 65 + struct pinctrl_dev *pctldev; 66 + const struct upboard_pinctrl_data *pctrl_data; 67 + struct gpio_pin_range pin_range; 68 + struct upboard_pin *pins; 69 + }; 70 + 71 + struct upboard_pinctrl_map { 72 + const struct pinctrl_map *maps; 73 + size_t nmaps; 74 + }; 75 + 76 + enum upboard_func0_fpgabit { 77 + UPBOARD_FUNC_I2C0_EN = 8, 78 + UPBOARD_FUNC_I2C1_EN = 9, 79 + UPBOARD_FUNC_CEC0_EN = 12, 80 + UPBOARD_FUNC_ADC0_EN = 14, 81 + }; 82 + 83 + static const struct reg_field upboard_i2c0_reg = 84 + REG_FIELD(UPBOARD_REG_FUNC_EN0, UPBOARD_FUNC_I2C0_EN, UPBOARD_FUNC_I2C0_EN); 85 + 86 + static const struct reg_field upboard_i2c1_reg = 87 + REG_FIELD(UPBOARD_REG_FUNC_EN0, UPBOARD_FUNC_I2C1_EN, UPBOARD_FUNC_I2C1_EN); 88 + 89 + static const struct reg_field upboard_adc0_reg = 90 + REG_FIELD(UPBOARD_REG_FUNC_EN0, UPBOARD_FUNC_ADC0_EN, UPBOARD_FUNC_ADC0_EN); 91 + 92 + #define UPBOARD_UP_BIT_TO_PIN(bit) UPBOARD_UP_BIT_##bit 93 + 94 + #define UPBOARD_UP_PIN_NAME(id) \ 95 + { \ 96 + .number = UPBOARD_UP_BIT_##id, \ 97 + .name = #id, \ 98 + } 99 + 100 + #define UPBOARD_UP_PIN_MUX(bit, data) \ 101 + { \ 102 + .number = UPBOARD_UP_BIT_##bit, \ 103 + .name = "PINMUX_"#bit, \ 104 + .drv_data = (void *)(data), \ 105 + } 106 + 107 + #define UPBOARD_UP_PIN_FUNC(id, data) \ 108 + { \ 109 + .number = UPBOARD_UP_BIT_##id, \ 110 + .name = #id, \ 111 + .drv_data = (void *)(data), \ 112 + } 113 + 114 + enum upboard_up_fpgabit { 115 + UPBOARD_UP_BIT_I2C1_SDA, 116 + UPBOARD_UP_BIT_I2C1_SCL, 117 + UPBOARD_UP_BIT_ADC0, 118 + UPBOARD_UP_BIT_UART1_RTS, 119 + UPBOARD_UP_BIT_GPIO27, 120 + UPBOARD_UP_BIT_GPIO22, 121 + UPBOARD_UP_BIT_SPI_MOSI, 122 + UPBOARD_UP_BIT_SPI_MISO, 123 + UPBOARD_UP_BIT_SPI_CLK, 124 + UPBOARD_UP_BIT_I2C0_SDA, 125 + UPBOARD_UP_BIT_GPIO5, 126 + UPBOARD_UP_BIT_GPIO6, 127 + UPBOARD_UP_BIT_PWM1, 128 + UPBOARD_UP_BIT_I2S_FRM, 129 + UPBOARD_UP_BIT_GPIO26, 130 + UPBOARD_UP_BIT_UART1_TX, 131 + UPBOARD_UP_BIT_UART1_RX, 132 + UPBOARD_UP_BIT_I2S_CLK, 133 + UPBOARD_UP_BIT_GPIO23, 134 + UPBOARD_UP_BIT_GPIO24, 135 + UPBOARD_UP_BIT_GPIO25, 136 + UPBOARD_UP_BIT_SPI_CS0, 137 + UPBOARD_UP_BIT_SPI_CS1, 138 + UPBOARD_UP_BIT_I2C0_SCL, 139 + UPBOARD_UP_BIT_PWM0, 140 + UPBOARD_UP_BIT_UART1_CTS, 141 + UPBOARD_UP_BIT_I2S_DIN, 142 + UPBOARD_UP_BIT_I2S_DOUT, 143 + }; 144 + 145 + static const struct pinctrl_pin_desc upboard_up_pins[] = { 146 + UPBOARD_UP_PIN_FUNC(I2C1_SDA, &upboard_i2c1_reg), 147 + UPBOARD_UP_PIN_FUNC(I2C1_SCL, &upboard_i2c1_reg), 148 + UPBOARD_UP_PIN_FUNC(ADC0, &upboard_adc0_reg), 149 + UPBOARD_UP_PIN_NAME(UART1_RTS), 150 + UPBOARD_UP_PIN_NAME(GPIO27), 151 + UPBOARD_UP_PIN_NAME(GPIO22), 152 + UPBOARD_UP_PIN_NAME(SPI_MOSI), 153 + UPBOARD_UP_PIN_NAME(SPI_MISO), 154 + UPBOARD_UP_PIN_NAME(SPI_CLK), 155 + UPBOARD_UP_PIN_FUNC(I2C0_SDA, &upboard_i2c0_reg), 156 + UPBOARD_UP_PIN_NAME(GPIO5), 157 + UPBOARD_UP_PIN_NAME(GPIO6), 158 + UPBOARD_UP_PIN_NAME(PWM1), 159 + UPBOARD_UP_PIN_NAME(I2S_FRM), 160 + UPBOARD_UP_PIN_NAME(GPIO26), 161 + UPBOARD_UP_PIN_NAME(UART1_TX), 162 + UPBOARD_UP_PIN_NAME(UART1_RX), 163 + UPBOARD_UP_PIN_NAME(I2S_CLK), 164 + UPBOARD_UP_PIN_NAME(GPIO23), 165 + UPBOARD_UP_PIN_NAME(GPIO24), 166 + UPBOARD_UP_PIN_NAME(GPIO25), 167 + UPBOARD_UP_PIN_NAME(SPI_CS0), 168 + UPBOARD_UP_PIN_NAME(SPI_CS1), 169 + UPBOARD_UP_PIN_FUNC(I2C0_SCL, &upboard_i2c0_reg), 170 + UPBOARD_UP_PIN_NAME(PWM0), 171 + UPBOARD_UP_PIN_NAME(UART1_CTS), 172 + UPBOARD_UP_PIN_NAME(I2S_DIN), 173 + UPBOARD_UP_PIN_NAME(I2S_DOUT), 174 + }; 175 + 176 + static const unsigned int upboard_up_pin_header[] = { 177 + UPBOARD_UP_BIT_TO_PIN(I2C0_SDA), 178 + UPBOARD_UP_BIT_TO_PIN(I2C0_SCL), 179 + UPBOARD_UP_BIT_TO_PIN(I2C1_SDA), 180 + UPBOARD_UP_BIT_TO_PIN(I2C1_SCL), 181 + UPBOARD_UP_BIT_TO_PIN(ADC0), 182 + UPBOARD_UP_BIT_TO_PIN(GPIO5), 183 + UPBOARD_UP_BIT_TO_PIN(GPIO6), 184 + UPBOARD_UP_BIT_TO_PIN(SPI_CS1), 185 + UPBOARD_UP_BIT_TO_PIN(SPI_CS0), 186 + UPBOARD_UP_BIT_TO_PIN(SPI_MISO), 187 + UPBOARD_UP_BIT_TO_PIN(SPI_MOSI), 188 + UPBOARD_UP_BIT_TO_PIN(SPI_CLK), 189 + UPBOARD_UP_BIT_TO_PIN(PWM0), 190 + UPBOARD_UP_BIT_TO_PIN(PWM1), 191 + UPBOARD_UP_BIT_TO_PIN(UART1_TX), 192 + UPBOARD_UP_BIT_TO_PIN(UART1_RX), 193 + UPBOARD_UP_BIT_TO_PIN(UART1_CTS), 194 + UPBOARD_UP_BIT_TO_PIN(UART1_RTS), 195 + UPBOARD_UP_BIT_TO_PIN(I2S_CLK), 196 + UPBOARD_UP_BIT_TO_PIN(I2S_FRM), 197 + UPBOARD_UP_BIT_TO_PIN(I2S_DIN), 198 + UPBOARD_UP_BIT_TO_PIN(I2S_DOUT), 199 + UPBOARD_UP_BIT_TO_PIN(GPIO22), 200 + UPBOARD_UP_BIT_TO_PIN(GPIO23), 201 + UPBOARD_UP_BIT_TO_PIN(GPIO24), 202 + UPBOARD_UP_BIT_TO_PIN(GPIO25), 203 + UPBOARD_UP_BIT_TO_PIN(GPIO26), 204 + UPBOARD_UP_BIT_TO_PIN(GPIO27), 205 + }; 206 + 207 + static const unsigned int upboard_up_uart1_pins[] = { 208 + UPBOARD_UP_BIT_TO_PIN(UART1_TX), 209 + UPBOARD_UP_BIT_TO_PIN(UART1_RX), 210 + UPBOARD_UP_BIT_TO_PIN(UART1_RTS), 211 + UPBOARD_UP_BIT_TO_PIN(UART1_CTS), 212 + }; 213 + 214 + static const enum upboard_pin_mode upboard_up_uart1_modes[] = { 215 + UPBOARD_PIN_MODE_GPIO_OUT, 216 + UPBOARD_PIN_MODE_GPIO_IN, 217 + UPBOARD_PIN_MODE_GPIO_OUT, 218 + UPBOARD_PIN_MODE_GPIO_IN, 219 + }; 220 + 221 + static_assert(ARRAY_SIZE(upboard_up_uart1_modes) == ARRAY_SIZE(upboard_up_uart1_pins)); 222 + 223 + static const unsigned int upboard_up_i2c0_pins[] = { 224 + UPBOARD_UP_BIT_TO_PIN(I2C0_SCL), 225 + UPBOARD_UP_BIT_TO_PIN(I2C0_SDA), 226 + }; 227 + 228 + static const unsigned int upboard_up_i2c1_pins[] = { 229 + UPBOARD_UP_BIT_TO_PIN(I2C1_SCL), 230 + UPBOARD_UP_BIT_TO_PIN(I2C1_SDA), 231 + }; 232 + 233 + static const unsigned int upboard_up_spi2_pins[] = { 234 + UPBOARD_UP_BIT_TO_PIN(SPI_MOSI), 235 + UPBOARD_UP_BIT_TO_PIN(SPI_MISO), 236 + UPBOARD_UP_BIT_TO_PIN(SPI_CLK), 237 + UPBOARD_UP_BIT_TO_PIN(SPI_CS0), 238 + UPBOARD_UP_BIT_TO_PIN(SPI_CS1), 239 + }; 240 + 241 + static const enum upboard_pin_mode upboard_up_spi2_modes[] = { 242 + UPBOARD_PIN_MODE_GPIO_OUT, 243 + UPBOARD_PIN_MODE_GPIO_IN, 244 + UPBOARD_PIN_MODE_GPIO_OUT, 245 + UPBOARD_PIN_MODE_GPIO_OUT, 246 + UPBOARD_PIN_MODE_GPIO_OUT, 247 + }; 248 + 249 + static_assert(ARRAY_SIZE(upboard_up_spi2_modes) == ARRAY_SIZE(upboard_up_spi2_pins)); 250 + 251 + static const unsigned int upboard_up_i2s0_pins[] = { 252 + UPBOARD_UP_BIT_TO_PIN(I2S_FRM), 253 + UPBOARD_UP_BIT_TO_PIN(I2S_CLK), 254 + UPBOARD_UP_BIT_TO_PIN(I2S_DIN), 255 + UPBOARD_UP_BIT_TO_PIN(I2S_DOUT), 256 + }; 257 + 258 + static const enum upboard_pin_mode upboard_up_i2s0_modes[] = { 259 + UPBOARD_PIN_MODE_GPIO_OUT, 260 + UPBOARD_PIN_MODE_GPIO_OUT, 261 + UPBOARD_PIN_MODE_GPIO_IN, 262 + UPBOARD_PIN_MODE_GPIO_OUT, 263 + }; 264 + 265 + static_assert(ARRAY_SIZE(upboard_up_i2s0_pins) == ARRAY_SIZE(upboard_up_i2s0_modes)); 266 + 267 + static const unsigned int upboard_up_pwm0_pins[] = { 268 + UPBOARD_UP_BIT_TO_PIN(PWM0), 269 + }; 270 + 271 + static const unsigned int upboard_up_pwm1_pins[] = { 272 + UPBOARD_UP_BIT_TO_PIN(PWM1), 273 + }; 274 + 275 + static const unsigned int upboard_up_adc0_pins[] = { 276 + UPBOARD_UP_BIT_TO_PIN(ADC0), 277 + }; 278 + 279 + #define UPBOARD_PINGROUP(n, p, m) \ 280 + { \ 281 + .grp = PINCTRL_PINGROUP(n, p, ARRAY_SIZE(p)), \ 282 + .mode = __builtin_choose_expr( \ 283 + __builtin_types_compatible_p(typeof(m), const enum upboard_pin_mode *), \ 284 + 0, m), \ 285 + .modes = __builtin_choose_expr( \ 286 + __builtin_types_compatible_p(typeof(m), const enum upboard_pin_mode *), \ 287 + m, NULL), \ 288 + } 289 + 290 + static const struct upboard_pingroup upboard_up_pin_groups[] = { 291 + UPBOARD_PINGROUP("uart1_grp", upboard_up_uart1_pins, &upboard_up_uart1_modes[0]), 292 + UPBOARD_PINGROUP("i2c0_grp", upboard_up_i2c0_pins, UPBOARD_PIN_MODE_GPIO_OUT), 293 + UPBOARD_PINGROUP("i2c1_grp", upboard_up_i2c1_pins, UPBOARD_PIN_MODE_GPIO_OUT), 294 + UPBOARD_PINGROUP("spi2_grp", upboard_up_spi2_pins, &upboard_up_spi2_modes[0]), 295 + UPBOARD_PINGROUP("i2s0_grp", upboard_up_i2s0_pins, &upboard_up_i2s0_modes[0]), 296 + UPBOARD_PINGROUP("pwm0_grp", upboard_up_pwm0_pins, UPBOARD_PIN_MODE_GPIO_OUT), 297 + UPBOARD_PINGROUP("pwm1_grp", upboard_up_pwm1_pins, UPBOARD_PIN_MODE_GPIO_OUT), 298 + UPBOARD_PINGROUP("adc0_grp", upboard_up_adc0_pins, UPBOARD_PIN_MODE_GPIO_IN), 299 + }; 300 + 301 + static const char * const upboard_up_uart1_groups[] = { "uart1_grp" }; 302 + static const char * const upboard_up_i2c0_groups[] = { "i2c0_grp" }; 303 + static const char * const upboard_up_i2c1_groups[] = { "i2c1_grp" }; 304 + static const char * const upboard_up_spi2_groups[] = { "spi2_grp" }; 305 + static const char * const upboard_up_i2s0_groups[] = { "i2s0_grp" }; 306 + static const char * const upboard_up_pwm0_groups[] = { "pwm0_grp" }; 307 + static const char * const upboard_up_pwm1_groups[] = { "pwm1_grp" }; 308 + static const char * const upboard_up_adc0_groups[] = { "adc0_grp" }; 309 + 310 + #define UPBOARD_FUNCTION(func, groups) PINCTRL_PINFUNCTION(func, groups, ARRAY_SIZE(groups)) 311 + 312 + static const struct pinfunction upboard_up_pin_functions[] = { 313 + UPBOARD_FUNCTION("uart1", upboard_up_uart1_groups), 314 + UPBOARD_FUNCTION("i2c0", upboard_up_i2c0_groups), 315 + UPBOARD_FUNCTION("i2c1", upboard_up_i2c1_groups), 316 + UPBOARD_FUNCTION("spi2", upboard_up_spi2_groups), 317 + UPBOARD_FUNCTION("i2s0", upboard_up_i2s0_groups), 318 + UPBOARD_FUNCTION("pwm0", upboard_up_pwm0_groups), 319 + UPBOARD_FUNCTION("pwm1", upboard_up_pwm1_groups), 320 + UPBOARD_FUNCTION("adc0", upboard_up_adc0_groups), 321 + }; 322 + 323 + static const struct upboard_pinctrl_data upboard_up_pinctrl_data = { 324 + .groups = &upboard_up_pin_groups[0], 325 + .ngroups = ARRAY_SIZE(upboard_up_pin_groups), 326 + .funcs = &upboard_up_pin_functions[0], 327 + .nfuncs = ARRAY_SIZE(upboard_up_pin_functions), 328 + .pin_header = &upboard_up_pin_header[0], 329 + .ngpio = ARRAY_SIZE(upboard_up_pin_header), 330 + }; 331 + 332 + #define UPBOARD_UP2_BIT_TO_PIN(bit) UPBOARD_UP2_BIT_##bit 333 + 334 + #define UPBOARD_UP2_PIN_NAME(id) \ 335 + { \ 336 + .number = UPBOARD_UP2_BIT_##id, \ 337 + .name = #id, \ 338 + } 339 + 340 + #define UPBOARD_UP2_PIN_MUX(bit, data) \ 341 + { \ 342 + .number = UPBOARD_UP2_BIT_##bit, \ 343 + .name = "PINMUX_"#bit, \ 344 + .drv_data = (void *)(data), \ 345 + } 346 + 347 + #define UPBOARD_UP2_PIN_FUNC(id, data) \ 348 + { \ 349 + .number = UPBOARD_UP2_BIT_##id, \ 350 + .name = #id, \ 351 + .drv_data = (void *)(data), \ 352 + } 353 + 354 + enum upboard_up2_fpgabit { 355 + UPBOARD_UP2_BIT_UART1_TXD, 356 + UPBOARD_UP2_BIT_UART1_RXD, 357 + UPBOARD_UP2_BIT_UART1_RTS, 358 + UPBOARD_UP2_BIT_UART1_CTS, 359 + UPBOARD_UP2_BIT_GPIO3_ADC0, 360 + UPBOARD_UP2_BIT_GPIO5_ADC2, 361 + UPBOARD_UP2_BIT_GPIO6_ADC3, 362 + UPBOARD_UP2_BIT_GPIO11, 363 + UPBOARD_UP2_BIT_EXHAT_LVDS1n, 364 + UPBOARD_UP2_BIT_EXHAT_LVDS1p, 365 + UPBOARD_UP2_BIT_SPI2_TXD, 366 + UPBOARD_UP2_BIT_SPI2_RXD, 367 + UPBOARD_UP2_BIT_SPI2_FS1, 368 + UPBOARD_UP2_BIT_SPI2_FS0, 369 + UPBOARD_UP2_BIT_SPI2_CLK, 370 + UPBOARD_UP2_BIT_SPI1_TXD, 371 + UPBOARD_UP2_BIT_SPI1_RXD, 372 + UPBOARD_UP2_BIT_SPI1_FS1, 373 + UPBOARD_UP2_BIT_SPI1_FS0, 374 + UPBOARD_UP2_BIT_SPI1_CLK, 375 + UPBOARD_UP2_BIT_I2C0_SCL, 376 + UPBOARD_UP2_BIT_I2C0_SDA, 377 + UPBOARD_UP2_BIT_I2C1_SCL, 378 + UPBOARD_UP2_BIT_I2C1_SDA, 379 + UPBOARD_UP2_BIT_PWM1, 380 + UPBOARD_UP2_BIT_PWM0, 381 + UPBOARD_UP2_BIT_EXHAT_LVDS0n, 382 + UPBOARD_UP2_BIT_EXHAT_LVDS0p, 383 + UPBOARD_UP2_BIT_GPIO24, 384 + UPBOARD_UP2_BIT_GPIO10, 385 + UPBOARD_UP2_BIT_GPIO2, 386 + UPBOARD_UP2_BIT_GPIO1, 387 + UPBOARD_UP2_BIT_EXHAT_LVDS3n, 388 + UPBOARD_UP2_BIT_EXHAT_LVDS3p, 389 + UPBOARD_UP2_BIT_EXHAT_LVDS4n, 390 + UPBOARD_UP2_BIT_EXHAT_LVDS4p, 391 + UPBOARD_UP2_BIT_EXHAT_LVDS5n, 392 + UPBOARD_UP2_BIT_EXHAT_LVDS5p, 393 + UPBOARD_UP2_BIT_I2S_SDO, 394 + UPBOARD_UP2_BIT_I2S_SDI, 395 + UPBOARD_UP2_BIT_I2S_WS_SYNC, 396 + UPBOARD_UP2_BIT_I2S_BCLK, 397 + UPBOARD_UP2_BIT_EXHAT_LVDS6n, 398 + UPBOARD_UP2_BIT_EXHAT_LVDS6p, 399 + UPBOARD_UP2_BIT_EXHAT_LVDS7n, 400 + UPBOARD_UP2_BIT_EXHAT_LVDS7p, 401 + UPBOARD_UP2_BIT_EXHAT_LVDS2n, 402 + UPBOARD_UP2_BIT_EXHAT_LVDS2p, 403 + }; 404 + 405 + static const struct pinctrl_pin_desc upboard_up2_pins[] = { 406 + UPBOARD_UP2_PIN_NAME(UART1_TXD), 407 + UPBOARD_UP2_PIN_NAME(UART1_RXD), 408 + UPBOARD_UP2_PIN_NAME(UART1_RTS), 409 + UPBOARD_UP2_PIN_NAME(UART1_CTS), 410 + UPBOARD_UP2_PIN_NAME(GPIO3_ADC0), 411 + UPBOARD_UP2_PIN_NAME(GPIO5_ADC2), 412 + UPBOARD_UP2_PIN_NAME(GPIO6_ADC3), 413 + UPBOARD_UP2_PIN_NAME(GPIO11), 414 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS1n), 415 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS1p), 416 + UPBOARD_UP2_PIN_NAME(SPI2_TXD), 417 + UPBOARD_UP2_PIN_NAME(SPI2_RXD), 418 + UPBOARD_UP2_PIN_NAME(SPI2_FS1), 419 + UPBOARD_UP2_PIN_NAME(SPI2_FS0), 420 + UPBOARD_UP2_PIN_NAME(SPI2_CLK), 421 + UPBOARD_UP2_PIN_NAME(SPI1_TXD), 422 + UPBOARD_UP2_PIN_NAME(SPI1_RXD), 423 + UPBOARD_UP2_PIN_NAME(SPI1_FS1), 424 + UPBOARD_UP2_PIN_NAME(SPI1_FS0), 425 + UPBOARD_UP2_PIN_NAME(SPI1_CLK), 426 + UPBOARD_UP2_PIN_MUX(I2C0_SCL, &upboard_i2c0_reg), 427 + UPBOARD_UP2_PIN_MUX(I2C0_SDA, &upboard_i2c0_reg), 428 + UPBOARD_UP2_PIN_MUX(I2C1_SCL, &upboard_i2c1_reg), 429 + UPBOARD_UP2_PIN_MUX(I2C1_SDA, &upboard_i2c1_reg), 430 + UPBOARD_UP2_PIN_NAME(PWM1), 431 + UPBOARD_UP2_PIN_NAME(PWM0), 432 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS0n), 433 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS0p), 434 + UPBOARD_UP2_PIN_MUX(GPIO24, &upboard_i2c0_reg), 435 + UPBOARD_UP2_PIN_MUX(GPIO10, &upboard_i2c0_reg), 436 + UPBOARD_UP2_PIN_MUX(GPIO2, &upboard_i2c1_reg), 437 + UPBOARD_UP2_PIN_MUX(GPIO1, &upboard_i2c1_reg), 438 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS3n), 439 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS3p), 440 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS4n), 441 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS4p), 442 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS5n), 443 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS5p), 444 + UPBOARD_UP2_PIN_NAME(I2S_SDO), 445 + UPBOARD_UP2_PIN_NAME(I2S_SDI), 446 + UPBOARD_UP2_PIN_NAME(I2S_WS_SYNC), 447 + UPBOARD_UP2_PIN_NAME(I2S_BCLK), 448 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS6n), 449 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS6p), 450 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS7n), 451 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS7p), 452 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS2n), 453 + UPBOARD_UP2_PIN_NAME(EXHAT_LVDS2p), 454 + }; 455 + 456 + static const unsigned int upboard_up2_pin_header[] = { 457 + UPBOARD_UP2_BIT_TO_PIN(GPIO10), 458 + UPBOARD_UP2_BIT_TO_PIN(GPIO24), 459 + UPBOARD_UP2_BIT_TO_PIN(GPIO1), 460 + UPBOARD_UP2_BIT_TO_PIN(GPIO2), 461 + UPBOARD_UP2_BIT_TO_PIN(GPIO3_ADC0), 462 + UPBOARD_UP2_BIT_TO_PIN(GPIO11), 463 + UPBOARD_UP2_BIT_TO_PIN(SPI2_CLK), 464 + UPBOARD_UP2_BIT_TO_PIN(SPI1_FS1), 465 + UPBOARD_UP2_BIT_TO_PIN(SPI1_FS0), 466 + UPBOARD_UP2_BIT_TO_PIN(SPI1_RXD), 467 + UPBOARD_UP2_BIT_TO_PIN(SPI1_TXD), 468 + UPBOARD_UP2_BIT_TO_PIN(SPI1_CLK), 469 + UPBOARD_UP2_BIT_TO_PIN(PWM0), 470 + UPBOARD_UP2_BIT_TO_PIN(PWM1), 471 + UPBOARD_UP2_BIT_TO_PIN(UART1_TXD), 472 + UPBOARD_UP2_BIT_TO_PIN(UART1_RXD), 473 + UPBOARD_UP2_BIT_TO_PIN(UART1_CTS), 474 + UPBOARD_UP2_BIT_TO_PIN(UART1_RTS), 475 + UPBOARD_UP2_BIT_TO_PIN(I2S_BCLK), 476 + UPBOARD_UP2_BIT_TO_PIN(I2S_WS_SYNC), 477 + UPBOARD_UP2_BIT_TO_PIN(I2S_SDI), 478 + UPBOARD_UP2_BIT_TO_PIN(I2S_SDO), 479 + UPBOARD_UP2_BIT_TO_PIN(GPIO6_ADC3), 480 + UPBOARD_UP2_BIT_TO_PIN(SPI2_FS1), 481 + UPBOARD_UP2_BIT_TO_PIN(SPI2_RXD), 482 + UPBOARD_UP2_BIT_TO_PIN(SPI2_TXD), 483 + UPBOARD_UP2_BIT_TO_PIN(SPI2_FS0), 484 + UPBOARD_UP2_BIT_TO_PIN(GPIO5_ADC2), 485 + }; 486 + 487 + static const unsigned int upboard_up2_uart1_pins[] = { 488 + UPBOARD_UP2_BIT_TO_PIN(UART1_TXD), 489 + UPBOARD_UP2_BIT_TO_PIN(UART1_RXD), 490 + UPBOARD_UP2_BIT_TO_PIN(UART1_RTS), 491 + UPBOARD_UP2_BIT_TO_PIN(UART1_CTS), 492 + }; 493 + 494 + static const enum upboard_pin_mode upboard_up2_uart1_modes[] = { 495 + UPBOARD_PIN_MODE_GPIO_OUT, 496 + UPBOARD_PIN_MODE_GPIO_IN, 497 + UPBOARD_PIN_MODE_GPIO_OUT, 498 + UPBOARD_PIN_MODE_GPIO_IN, 499 + }; 500 + 501 + static_assert(ARRAY_SIZE(upboard_up2_uart1_modes) == ARRAY_SIZE(upboard_up2_uart1_pins)); 502 + 503 + static const unsigned int upboard_up2_i2c0_pins[] = { 504 + UPBOARD_UP2_BIT_TO_PIN(I2C0_SCL), 505 + UPBOARD_UP2_BIT_TO_PIN(I2C0_SDA), 506 + UPBOARD_UP2_BIT_TO_PIN(GPIO24), 507 + UPBOARD_UP2_BIT_TO_PIN(GPIO10), 508 + }; 509 + 510 + static const unsigned int upboard_up2_i2c1_pins[] = { 511 + UPBOARD_UP2_BIT_TO_PIN(I2C1_SCL), 512 + UPBOARD_UP2_BIT_TO_PIN(I2C1_SDA), 513 + UPBOARD_UP2_BIT_TO_PIN(GPIO2), 514 + UPBOARD_UP2_BIT_TO_PIN(GPIO1), 515 + }; 516 + 517 + static const unsigned int upboard_up2_spi1_pins[] = { 518 + UPBOARD_UP2_BIT_TO_PIN(SPI1_TXD), 519 + UPBOARD_UP2_BIT_TO_PIN(SPI1_RXD), 520 + UPBOARD_UP2_BIT_TO_PIN(SPI1_FS1), 521 + UPBOARD_UP2_BIT_TO_PIN(SPI1_FS0), 522 + UPBOARD_UP2_BIT_TO_PIN(SPI1_CLK), 523 + }; 524 + 525 + static const unsigned int upboard_up2_spi2_pins[] = { 526 + UPBOARD_UP2_BIT_TO_PIN(SPI2_TXD), 527 + UPBOARD_UP2_BIT_TO_PIN(SPI2_RXD), 528 + UPBOARD_UP2_BIT_TO_PIN(SPI2_FS1), 529 + UPBOARD_UP2_BIT_TO_PIN(SPI2_FS0), 530 + UPBOARD_UP2_BIT_TO_PIN(SPI2_CLK), 531 + }; 532 + 533 + static const enum upboard_pin_mode upboard_up2_spi_modes[] = { 534 + UPBOARD_PIN_MODE_GPIO_OUT, 535 + UPBOARD_PIN_MODE_GPIO_IN, 536 + UPBOARD_PIN_MODE_GPIO_OUT, 537 + UPBOARD_PIN_MODE_GPIO_OUT, 538 + UPBOARD_PIN_MODE_GPIO_OUT, 539 + }; 540 + 541 + static_assert(ARRAY_SIZE(upboard_up2_spi_modes) == ARRAY_SIZE(upboard_up2_spi1_pins)); 542 + 543 + static_assert(ARRAY_SIZE(upboard_up2_spi_modes) == ARRAY_SIZE(upboard_up2_spi2_pins)); 544 + 545 + static const unsigned int upboard_up2_i2s0_pins[] = { 546 + UPBOARD_UP2_BIT_TO_PIN(I2S_BCLK), 547 + UPBOARD_UP2_BIT_TO_PIN(I2S_WS_SYNC), 548 + UPBOARD_UP2_BIT_TO_PIN(I2S_SDI), 549 + UPBOARD_UP2_BIT_TO_PIN(I2S_SDO), 550 + }; 551 + 552 + static const enum upboard_pin_mode upboard_up2_i2s0_modes[] = { 553 + UPBOARD_PIN_MODE_GPIO_OUT, 554 + UPBOARD_PIN_MODE_GPIO_OUT, 555 + UPBOARD_PIN_MODE_GPIO_IN, 556 + UPBOARD_PIN_MODE_GPIO_OUT, 557 + }; 558 + 559 + static_assert(ARRAY_SIZE(upboard_up2_i2s0_modes) == ARRAY_SIZE(upboard_up2_i2s0_pins)); 560 + 561 + static const unsigned int upboard_up2_pwm0_pins[] = { 562 + UPBOARD_UP2_BIT_TO_PIN(PWM0), 563 + }; 564 + 565 + static const unsigned int upboard_up2_pwm1_pins[] = { 566 + UPBOARD_UP2_BIT_TO_PIN(PWM1), 567 + }; 568 + 569 + static const unsigned int upboard_up2_adc0_pins[] = { 570 + UPBOARD_UP2_BIT_TO_PIN(GPIO3_ADC0), 571 + }; 572 + 573 + static const unsigned int upboard_up2_adc2_pins[] = { 574 + UPBOARD_UP2_BIT_TO_PIN(GPIO5_ADC2), 575 + }; 576 + 577 + static const unsigned int upboard_up2_adc3_pins[] = { 578 + UPBOARD_UP2_BIT_TO_PIN(GPIO6_ADC3), 579 + }; 580 + 581 + static const struct upboard_pingroup upboard_up2_pin_groups[] = { 582 + UPBOARD_PINGROUP("uart1_grp", upboard_up2_uart1_pins, &upboard_up2_uart1_modes[0]), 583 + UPBOARD_PINGROUP("i2c0_grp", upboard_up2_i2c0_pins, UPBOARD_PIN_MODE_FUNCTION), 584 + UPBOARD_PINGROUP("i2c1_grp", upboard_up2_i2c1_pins, UPBOARD_PIN_MODE_FUNCTION), 585 + UPBOARD_PINGROUP("spi1_grp", upboard_up2_spi1_pins, &upboard_up2_spi_modes[0]), 586 + UPBOARD_PINGROUP("spi2_grp", upboard_up2_spi2_pins, &upboard_up2_spi_modes[0]), 587 + UPBOARD_PINGROUP("i2s0_grp", upboard_up2_i2s0_pins, &upboard_up2_i2s0_modes[0]), 588 + UPBOARD_PINGROUP("pwm0_grp", upboard_up2_pwm0_pins, UPBOARD_PIN_MODE_GPIO_OUT), 589 + UPBOARD_PINGROUP("pwm1_grp", upboard_up2_pwm1_pins, UPBOARD_PIN_MODE_GPIO_OUT), 590 + UPBOARD_PINGROUP("adc0_grp", upboard_up2_adc0_pins, UPBOARD_PIN_MODE_GPIO_IN), 591 + UPBOARD_PINGROUP("adc2_grp", upboard_up2_adc2_pins, UPBOARD_PIN_MODE_GPIO_IN), 592 + UPBOARD_PINGROUP("adc3_grp", upboard_up2_adc3_pins, UPBOARD_PIN_MODE_GPIO_IN), 593 + }; 594 + 595 + static const char * const upboard_up2_uart1_groups[] = { "uart1_grp" }; 596 + static const char * const upboard_up2_i2c0_groups[] = { "i2c0_grp" }; 597 + static const char * const upboard_up2_i2c1_groups[] = { "i2c1_grp" }; 598 + static const char * const upboard_up2_spi1_groups[] = { "spi1_grp" }; 599 + static const char * const upboard_up2_spi2_groups[] = { "spi2_grp" }; 600 + static const char * const upboard_up2_i2s0_groups[] = { "i2s0_grp" }; 601 + static const char * const upboard_up2_pwm0_groups[] = { "pwm0_grp" }; 602 + static const char * const upboard_up2_pwm1_groups[] = { "pwm1_grp" }; 603 + static const char * const upboard_up2_adc0_groups[] = { "adc0_grp" }; 604 + static const char * const upboard_up2_adc2_groups[] = { "adc2_grp" }; 605 + static const char * const upboard_up2_adc3_groups[] = { "adc3_grp" }; 606 + 607 + static const struct pinfunction upboard_up2_pin_functions[] = { 608 + UPBOARD_FUNCTION("uart1", upboard_up2_uart1_groups), 609 + UPBOARD_FUNCTION("i2c0", upboard_up2_i2c0_groups), 610 + UPBOARD_FUNCTION("i2c1", upboard_up2_i2c1_groups), 611 + UPBOARD_FUNCTION("spi1", upboard_up2_spi1_groups), 612 + UPBOARD_FUNCTION("spi2", upboard_up2_spi2_groups), 613 + UPBOARD_FUNCTION("i2s0", upboard_up2_i2s0_groups), 614 + UPBOARD_FUNCTION("pwm0", upboard_up2_pwm0_groups), 615 + UPBOARD_FUNCTION("pwm1", upboard_up2_pwm1_groups), 616 + UPBOARD_FUNCTION("adc0", upboard_up2_adc0_groups), 617 + UPBOARD_FUNCTION("adc2", upboard_up2_adc2_groups), 618 + UPBOARD_FUNCTION("adc3", upboard_up2_adc3_groups), 619 + }; 620 + 621 + static const struct upboard_pinctrl_data upboard_up2_pinctrl_data = { 622 + .groups = &upboard_up2_pin_groups[0], 623 + .ngroups = ARRAY_SIZE(upboard_up2_pin_groups), 624 + .funcs = &upboard_up2_pin_functions[0], 625 + .nfuncs = ARRAY_SIZE(upboard_up2_pin_functions), 626 + .pin_header = &upboard_up2_pin_header[0], 627 + .ngpio = ARRAY_SIZE(upboard_up2_pin_header), 628 + }; 629 + 630 + static int upboard_pinctrl_set_function(struct pinctrl_dev *pctldev, unsigned int offset) 631 + { 632 + struct upboard_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 633 + struct upboard_pin *p = &pctrl->pins[offset]; 634 + int ret; 635 + 636 + if (!p->funcbit) 637 + return -EPERM; 638 + 639 + ret = regmap_field_write(p->enbit, 0); 640 + if (ret) 641 + return ret; 642 + 643 + return regmap_field_write(p->funcbit, 1); 644 + } 645 + 646 + static int upboard_pinctrl_gpio_commit_enable(struct pinctrl_dev *pctldev, unsigned int offset) 647 + { 648 + struct upboard_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 649 + struct upboard_pin *p = &pctrl->pins[offset]; 650 + int ret; 651 + 652 + if (p->funcbit) { 653 + ret = regmap_field_write(p->funcbit, 0); 654 + if (ret) 655 + return ret; 656 + } 657 + 658 + return regmap_field_write(p->enbit, 1); 659 + } 660 + 661 + static int upboard_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev, 662 + struct pinctrl_gpio_range *range, 663 + unsigned int offset) 664 + { 665 + return upboard_pinctrl_gpio_commit_enable(pctldev, offset); 666 + } 667 + 668 + static void upboard_pinctrl_gpio_commit_disable(struct pinctrl_dev *pctldev, unsigned int offset) 669 + { 670 + struct upboard_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 671 + struct upboard_pin *p = &pctrl->pins[offset]; 672 + 673 + regmap_field_write(p->enbit, 0); 674 + }; 675 + 676 + static void upboard_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev, 677 + struct pinctrl_gpio_range *range, unsigned int offset) 678 + { 679 + return upboard_pinctrl_gpio_commit_disable(pctldev, offset); 680 + } 681 + 682 + static int upboard_pinctrl_gpio_commit_direction(struct pinctrl_dev *pctldev, unsigned int offset, 683 + bool input) 684 + { 685 + struct upboard_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 686 + struct upboard_pin *p = &pctrl->pins[offset]; 687 + 688 + return regmap_field_write(p->dirbit, input); 689 + } 690 + 691 + static int upboard_pinctrl_gpio_set_direction(struct pinctrl_dev *pctldev, 692 + struct pinctrl_gpio_range *range, 693 + unsigned int offset, bool input) 694 + { 695 + return upboard_pinctrl_gpio_commit_direction(pctldev, offset, input); 696 + } 697 + 698 + static int upboard_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, 699 + unsigned int group_selector) 700 + { 701 + struct upboard_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 702 + const struct upboard_pinctrl_data *pctrl_data = pctrl->pctrl_data; 703 + const struct upboard_pingroup *upgroups = pctrl_data->groups; 704 + struct group_desc *grp; 705 + unsigned int mode, i; 706 + int ret; 707 + 708 + grp = pinctrl_generic_get_group(pctldev, group_selector); 709 + if (!grp) 710 + return -EINVAL; 711 + 712 + for (i = 0; i < grp->grp.npins; i++) { 713 + mode = upgroups[group_selector].mode ?: upgroups[group_selector].modes[i]; 714 + if (mode == UPBOARD_PIN_MODE_FUNCTION) { 715 + ret = upboard_pinctrl_set_function(pctldev, grp->grp.pins[i]); 716 + if (ret) 717 + return ret; 718 + 719 + continue; 720 + } 721 + 722 + ret = upboard_pinctrl_gpio_commit_enable(pctldev, grp->grp.pins[i]); 723 + if (ret) 724 + return ret; 725 + 726 + ret = upboard_pinctrl_gpio_commit_direction(pctldev, grp->grp.pins[i], 727 + mode == UPBOARD_PIN_MODE_GPIO_IN); 728 + if (ret) 729 + return ret; 730 + } 731 + 732 + return 0; 733 + } 734 + 735 + static const struct pinmux_ops upboard_pinmux_ops = { 736 + .get_functions_count = pinmux_generic_get_function_count, 737 + .get_function_name = pinmux_generic_get_function_name, 738 + .get_function_groups = pinmux_generic_get_function_groups, 739 + .set_mux = upboard_pinctrl_set_mux, 740 + .gpio_request_enable = upboard_pinctrl_gpio_request_enable, 741 + .gpio_disable_free = upboard_pinctrl_gpio_disable_free, 742 + .gpio_set_direction = upboard_pinctrl_gpio_set_direction, 743 + }; 744 + 745 + static int upboard_pinctrl_pin_get_mode(struct pinctrl_dev *pctldev, unsigned int pin) 746 + { 747 + struct upboard_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 748 + struct upboard_pin *p = &pctrl->pins[pin]; 749 + unsigned int val; 750 + int ret; 751 + 752 + if (p->funcbit) { 753 + ret = regmap_field_read(p->funcbit, &val); 754 + if (ret) 755 + return ret; 756 + if (val) 757 + return UPBOARD_PIN_MODE_FUNCTION; 758 + } 759 + 760 + ret = regmap_field_read(p->enbit, &val); 761 + if (ret) 762 + return ret; 763 + if (!val) 764 + return UPBOARD_PIN_MODE_DISABLED; 765 + 766 + ret = regmap_field_read(p->dirbit, &val); 767 + if (ret) 768 + return ret; 769 + 770 + return val ? UPBOARD_PIN_MODE_GPIO_IN : UPBOARD_PIN_MODE_GPIO_OUT; 771 + } 772 + 773 + static void upboard_pinctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, 774 + unsigned int offset) 775 + { 776 + int ret; 777 + 778 + ret = upboard_pinctrl_pin_get_mode(pctldev, offset); 779 + if (ret == UPBOARD_PIN_MODE_FUNCTION) 780 + seq_puts(s, "mode function "); 781 + else if (ret == UPBOARD_PIN_MODE_DISABLED) 782 + seq_puts(s, "HIGH-Z "); 783 + else if (ret < 0) 784 + seq_puts(s, "N/A "); 785 + else 786 + seq_printf(s, "GPIO (%s) ", str_input_output(ret == UPBOARD_PIN_MODE_GPIO_IN)); 787 + } 788 + 789 + static const struct pinctrl_ops upboard_pinctrl_ops = { 790 + .get_groups_count = pinctrl_generic_get_group_count, 791 + .get_group_name = pinctrl_generic_get_group_name, 792 + .get_group_pins = pinctrl_generic_get_group_pins, 793 + .pin_dbg_show = upboard_pinctrl_dbg_show, 794 + }; 795 + 796 + static int upboard_gpio_request(struct gpio_chip *gc, unsigned int offset) 797 + { 798 + struct gpiochip_fwd *fwd = gpiochip_get_data(gc); 799 + struct upboard_pinctrl *pctrl = gpiochip_fwd_get_data(fwd); 800 + unsigned int pin = pctrl->pctrl_data->pin_header[offset]; 801 + struct gpio_desc *desc; 802 + int ret; 803 + 804 + ret = pinctrl_gpio_request(gc, offset); 805 + if (ret) 806 + return ret; 807 + 808 + desc = gpiod_get_index(pctrl->dev, "external", pin, 0); 809 + if (IS_ERR(desc)) { 810 + pinctrl_gpio_free(gc, offset); 811 + return PTR_ERR(desc); 812 + } 813 + 814 + return gpiochip_fwd_desc_add(fwd, desc, offset); 815 + } 816 + 817 + static void upboard_gpio_free(struct gpio_chip *gc, unsigned int offset) 818 + { 819 + struct gpiochip_fwd *fwd = gpiochip_get_data(gc); 820 + 821 + gpiochip_fwd_desc_free(fwd, offset); 822 + pinctrl_gpio_free(gc, offset); 823 + } 824 + 825 + static int upboard_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) 826 + { 827 + struct gpiochip_fwd *fwd = gpiochip_get_data(gc); 828 + struct upboard_pinctrl *pctrl = gpiochip_fwd_get_data(fwd); 829 + unsigned int pin = pctrl->pctrl_data->pin_header[offset]; 830 + int mode; 831 + 832 + /* If the pin is in function mode or high-z, input direction is returned */ 833 + mode = upboard_pinctrl_pin_get_mode(pctrl->pctldev, pin); 834 + if (mode < 0) 835 + return mode; 836 + 837 + if (mode == UPBOARD_PIN_MODE_GPIO_OUT) 838 + return GPIO_LINE_DIRECTION_OUT; 839 + 840 + return GPIO_LINE_DIRECTION_IN; 841 + } 842 + 843 + static int upboard_gpio_direction_input(struct gpio_chip *gc, unsigned int offset) 844 + { 845 + struct gpiochip_fwd *fwd = gpiochip_get_data(gc); 846 + int ret; 847 + 848 + ret = pinctrl_gpio_direction_input(gc, offset); 849 + if (ret) 850 + return ret; 851 + 852 + return gpiochip_fwd_gpio_direction_input(fwd, offset); 853 + } 854 + 855 + static int upboard_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, int value) 856 + { 857 + struct gpiochip_fwd *fwd = gpiochip_get_data(gc); 858 + int ret; 859 + 860 + ret = pinctrl_gpio_direction_output(gc, offset); 861 + if (ret) 862 + return ret; 863 + 864 + return gpiochip_fwd_gpio_direction_output(fwd, offset, value); 865 + } 866 + 867 + static int upboard_pinctrl_register_groups(struct upboard_pinctrl *pctrl) 868 + { 869 + const struct upboard_pingroup *groups = pctrl->pctrl_data->groups; 870 + size_t ngroups = pctrl->pctrl_data->ngroups; 871 + unsigned int i; 872 + int ret; 873 + 874 + for (i = 0; i < ngroups; i++) { 875 + ret = pinctrl_generic_add_group(pctrl->pctldev, groups[i].grp.name, 876 + groups[i].grp.pins, groups[i].grp.npins, pctrl); 877 + if (ret < 0) 878 + return ret; 879 + } 880 + 881 + return 0; 882 + } 883 + 884 + static int upboard_pinctrl_register_functions(struct upboard_pinctrl *pctrl) 885 + { 886 + const struct pinfunction *funcs = pctrl->pctrl_data->funcs; 887 + size_t nfuncs = pctrl->pctrl_data->nfuncs; 888 + unsigned int i; 889 + int ret; 890 + 891 + for (i = 0; i < nfuncs ; i++) { 892 + ret = pinmux_generic_add_function(pctrl->pctldev, funcs[i].name, 893 + funcs[i].groups, funcs[i].ngroups, NULL); 894 + if (ret < 0) 895 + return ret; 896 + } 897 + 898 + return 0; 899 + } 900 + 901 + static const struct pinctrl_map pinctrl_map_apl01[] = { 902 + PIN_MAP_MUX_GROUP_DEFAULT("upboard-pinctrl", "INT3452:00", "pwm0_grp", "pwm0"), 903 + PIN_MAP_MUX_GROUP_DEFAULT("upboard-pinctrl", "INT3452:00", "pwm1_grp", "pwm1"), 904 + PIN_MAP_MUX_GROUP_DEFAULT("upboard-pinctrl", "INT3452:00", "uart1_grp", "uart1"), 905 + PIN_MAP_MUX_GROUP_DEFAULT("upboard-pinctrl", "INT3452:02", "i2c0_grp", "i2c0"), 906 + PIN_MAP_MUX_GROUP_DEFAULT("upboard-pinctrl", "INT3452:02", "i2c1_grp", "i2c1"), 907 + PIN_MAP_MUX_GROUP_DEFAULT("upboard-pinctrl", "INT3452:01", "ssp0_grp", "ssp0"), 908 + }; 909 + 910 + static const struct upboard_pinctrl_map upboard_pinctrl_map_apl01 = { 911 + .maps = &pinctrl_map_apl01[0], 912 + .nmaps = ARRAY_SIZE(pinctrl_map_apl01), 913 + }; 914 + 915 + static const struct dmi_system_id dmi_platform_info[] = { 916 + { 917 + /* UP Squared */ 918 + .matches = { 919 + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 920 + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-APL01"), 921 + }, 922 + .driver_data = (void *)&upboard_pinctrl_map_apl01, 923 + }, 924 + { } 925 + }; 926 + 927 + static int upboard_pinctrl_probe(struct platform_device *pdev) 928 + { 929 + struct device *dev = &pdev->dev; 930 + struct upboard_fpga *fpga = dev_get_drvdata(dev->parent); 931 + const struct upboard_pinctrl_map *board_map; 932 + const struct dmi_system_id *dmi_id; 933 + struct pinctrl_desc *pctldesc; 934 + struct upboard_pinctrl *pctrl; 935 + struct upboard_pin *pins; 936 + struct gpiochip_fwd *fwd; 937 + struct pinctrl *pinctrl; 938 + struct gpio_chip *chip; 939 + unsigned int i; 940 + int ret; 941 + 942 + pctldesc = devm_kzalloc(dev, sizeof(*pctldesc), GFP_KERNEL); 943 + if (!pctldesc) 944 + return -ENOMEM; 945 + 946 + pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); 947 + if (!pctrl) 948 + return -ENOMEM; 949 + 950 + switch (fpga->fpga_data->type) { 951 + case UPBOARD_UP_FPGA: 952 + pctldesc->pins = upboard_up_pins; 953 + pctldesc->npins = ARRAY_SIZE(upboard_up_pins); 954 + pctrl->pctrl_data = &upboard_up_pinctrl_data; 955 + break; 956 + case UPBOARD_UP2_FPGA: 957 + pctldesc->pins = upboard_up2_pins; 958 + pctldesc->npins = ARRAY_SIZE(upboard_up2_pins); 959 + pctrl->pctrl_data = &upboard_up2_pinctrl_data; 960 + break; 961 + default: 962 + return dev_err_probe(dev, -ENODEV, "Unsupported device type %d\n", 963 + fpga->fpga_data->type); 964 + } 965 + 966 + dmi_id = dmi_first_match(dmi_platform_info); 967 + if (!dmi_id) 968 + return dev_err_probe(dev, -ENODEV, "Unsupported board\n"); 969 + 970 + board_map = (const struct upboard_pinctrl_map *)dmi_id->driver_data; 971 + 972 + pctldesc->name = dev_name(dev); 973 + pctldesc->owner = THIS_MODULE; 974 + pctldesc->pctlops = &upboard_pinctrl_ops; 975 + pctldesc->pmxops = &upboard_pinmux_ops; 976 + 977 + pctrl->dev = dev; 978 + 979 + pins = devm_kcalloc(dev, pctldesc->npins, sizeof(*pins), GFP_KERNEL); 980 + if (!pins) 981 + return -ENOMEM; 982 + 983 + /* Initialize pins */ 984 + for (i = 0; i < pctldesc->npins; i++) { 985 + const struct pinctrl_pin_desc *pin_desc = &pctldesc->pins[i]; 986 + unsigned int regoff = pin_desc->number / UPBOARD_REGISTER_SIZE; 987 + unsigned int lsb = pin_desc->number % UPBOARD_REGISTER_SIZE; 988 + struct reg_field * const fld_func = pin_desc->drv_data; 989 + struct upboard_pin *pin = &pins[i]; 990 + struct reg_field fldconf = {}; 991 + 992 + if (fld_func) { 993 + pin->funcbit = devm_regmap_field_alloc(dev, fpga->regmap, *fld_func); 994 + if (IS_ERR(pin->funcbit)) 995 + return PTR_ERR(pin->funcbit); 996 + } 997 + 998 + fldconf.reg = UPBOARD_REG_GPIO_EN0 + regoff; 999 + fldconf.lsb = lsb; 1000 + fldconf.msb = lsb; 1001 + pin->enbit = devm_regmap_field_alloc(dev, fpga->regmap, fldconf); 1002 + if (IS_ERR(pin->enbit)) 1003 + return PTR_ERR(pin->enbit); 1004 + 1005 + fldconf.reg = UPBOARD_REG_GPIO_DIR0 + regoff; 1006 + fldconf.lsb = lsb; 1007 + fldconf.msb = lsb; 1008 + pin->dirbit = devm_regmap_field_alloc(dev, fpga->regmap, fldconf); 1009 + if (IS_ERR(pin->dirbit)) 1010 + return PTR_ERR(pin->dirbit); 1011 + } 1012 + 1013 + pctrl->pins = pins; 1014 + 1015 + ret = devm_pinctrl_register_and_init(dev, pctldesc, pctrl, &pctrl->pctldev); 1016 + if (ret) 1017 + return dev_err_probe(dev, ret, "Failed to register pinctrl\n"); 1018 + 1019 + ret = upboard_pinctrl_register_groups(pctrl); 1020 + if (ret) 1021 + return dev_err_probe(dev, ret, "Failed to register groups\n"); 1022 + 1023 + ret = upboard_pinctrl_register_functions(pctrl); 1024 + if (ret) 1025 + return dev_err_probe(dev, ret, "Failed to register functions\n"); 1026 + 1027 + ret = devm_pinctrl_register_mappings(dev, board_map->maps, board_map->nmaps); 1028 + if (ret) 1029 + return ret; 1030 + 1031 + pinctrl = devm_pinctrl_get_select_default(dev); 1032 + if (IS_ERR(pinctrl)) 1033 + return dev_err_probe(dev, PTR_ERR(pinctrl), "Failed to select pinctrl\n"); 1034 + 1035 + ret = pinctrl_enable(pctrl->pctldev); 1036 + if (ret) 1037 + return ret; 1038 + 1039 + fwd = devm_gpiochip_fwd_alloc(dev, pctrl->pctrl_data->ngpio); 1040 + if (IS_ERR(fwd)) 1041 + return dev_err_probe(dev, PTR_ERR(fwd), "Failed to allocate the gpiochip forwarder\n"); 1042 + 1043 + chip = gpiochip_fwd_get_gpiochip(fwd); 1044 + chip->request = upboard_gpio_request; 1045 + chip->free = upboard_gpio_free; 1046 + chip->get_direction = upboard_gpio_get_direction; 1047 + chip->direction_output = upboard_gpio_direction_output; 1048 + chip->direction_input = upboard_gpio_direction_input; 1049 + 1050 + ret = gpiochip_fwd_register(fwd, pctrl); 1051 + if (ret) 1052 + return dev_err_probe(dev, ret, "Failed to register the gpiochip forwarder\n"); 1053 + 1054 + return gpiochip_add_sparse_pin_range(chip, dev_name(dev), 0, pctrl->pctrl_data->pin_header, 1055 + pctrl->pctrl_data->ngpio); 1056 + } 1057 + 1058 + static struct platform_driver upboard_pinctrl_driver = { 1059 + .driver = { 1060 + .name = "upboard-pinctrl", 1061 + }, 1062 + .probe = upboard_pinctrl_probe, 1063 + }; 1064 + module_platform_driver(upboard_pinctrl_driver); 1065 + 1066 + MODULE_AUTHOR("Thomas Richard <thomas.richard@bootlin.com"); 1067 + MODULE_DESCRIPTION("UP Board HAT pin controller driver"); 1068 + MODULE_LICENSE("GPL"); 1069 + MODULE_ALIAS("platform:upboard-pinctrl"); 1070 + MODULE_IMPORT_NS("GPIO_FORWARDER");