1*cb703792SJia Wang // SPDX-License-Identifier: GPL-2.0 2*cb703792SJia Wang /* 3*cb703792SJia Wang * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd. 4*cb703792SJia Wang * 5*cb703792SJia Wang * Author: Jia Wang <wangjia@ultrarisc.com> 6*cb703792SJia Wang */ 7*cb703792SJia Wang 8*cb703792SJia Wang #include <linux/module.h> 9*cb703792SJia Wang #include <linux/of.h> 10*cb703792SJia Wang #include <linux/platform_device.h> 11*cb703792SJia Wang 12*cb703792SJia Wang #include "pinctrl-ultrarisc.h" 13*cb703792SJia Wang 14*cb703792SJia Wang /* Port indices. */ 15*cb703792SJia Wang #define UR_DP1000_PORT_A_IDX 0 16*cb703792SJia Wang #define UR_DP1000_PORT_B_IDX 1 17*cb703792SJia Wang #define UR_DP1000_PORT_C_IDX 2 18*cb703792SJia Wang #define UR_DP1000_PORT_D_IDX 3 19*cb703792SJia Wang #define UR_DP1000_PORT_LPC_IDX 4 20*cb703792SJia Wang 21*cb703792SJia Wang /* Port mux register offsets. */ 22*cb703792SJia Wang #define UR_DP1000_PORTA_FUNC_OFFSET 0x2c0 23*cb703792SJia Wang #define UR_DP1000_PORTB_FUNC_OFFSET 0x2c4 24*cb703792SJia Wang #define UR_DP1000_PORTC_FUNC_OFFSET 0x2c8 25*cb703792SJia Wang #define UR_DP1000_PORTD_FUNC_OFFSET 0x2cc 26*cb703792SJia Wang #define UR_DP1000_PORTLPC_FUNC_OFFSET 0x2d0 27*cb703792SJia Wang 28*cb703792SJia Wang /* Port pinconf register offsets. */ 29*cb703792SJia Wang #define UR_DP1000_PORTA_CONF_OFFSET 0x310 30*cb703792SJia Wang #define UR_DP1000_PORTB_CONF_OFFSET 0x318 31*cb703792SJia Wang #define UR_DP1000_PORTC_CONF_OFFSET 0x31c 32*cb703792SJia Wang #define UR_DP1000_PORTD_CONF_OFFSET 0x320 33*cb703792SJia Wang #define UR_DP1000_PORTLPC_CONF_OFFSET 0x324 34*cb703792SJia Wang 35*cb703792SJia Wang /* Pin ranges for function descriptors. */ 36*cb703792SJia Wang #define UR_DP1000_PINS_ABCD GENMASK_ULL(39, 0) 37*cb703792SJia Wang #define UR_DP1000_PINS_LPC GENMASK_ULL(52, 40) 38*cb703792SJia Wang 39*cb703792SJia Wang /* Static table entry helpers. */ 40*cb703792SJia Wang #define UR_DP1000_PORT(_base, _npins, _func, _conf, _modes, _gpio) \ 41*cb703792SJia Wang { .pin_base = (_base), .npins = (_npins), .func_offset = (_func), \ 42*cb703792SJia Wang .conf_offset = (_conf), .supported_modes = (_modes), \ 43*cb703792SJia Wang .supports_gpio = (_gpio) } 44*cb703792SJia Wang 45*cb703792SJia Wang #define UR_DP1000_PIN(_nr, _name, _port) \ 46*cb703792SJia Wang { .number = (_nr), .name = (_name), .drv_data = (void *)&ur_dp1000_ports[_port] } 47*cb703792SJia Wang 48*cb703792SJia Wang static const struct ur_func_route ur_dp1000_routes[] = { 49*cb703792SJia Wang { "gpio", UR_FUNC_DEFAULT, UR_DP1000_PINS_ABCD }, 50*cb703792SJia Wang { "i2c", UR_FUNC_0, GENMASK_ULL(13, 12) }, 51*cb703792SJia Wang { "i2c", UR_FUNC_0, GENMASK_ULL(23, 22) }, 52*cb703792SJia Wang { "i2c", UR_FUNC_0, GENMASK_ULL(25, 24) }, 53*cb703792SJia Wang { "i2c", UR_FUNC_0, GENMASK_ULL(27, 26) }, 54*cb703792SJia Wang { "pwm", UR_FUNC_0, GENMASK_ULL(19, 16) }, 55*cb703792SJia Wang { "spi", UR_FUNC_1, GENMASK_ULL(39, 32) }, 56*cb703792SJia Wang { "spi", UR_FUNC_0, GENMASK_ULL(6, 0) }, 57*cb703792SJia Wang { "uart", UR_FUNC_1, GENMASK_ULL(9, 8) }, 58*cb703792SJia Wang { "uart", UR_FUNC_0, GENMASK_ULL(21, 20) }, 59*cb703792SJia Wang { "uart", UR_FUNC_0, GENMASK_ULL(29, 28) }, 60*cb703792SJia Wang { "uart", UR_FUNC_0, GENMASK_ULL(31, 30) }, 61*cb703792SJia Wang { "lpc", UR_FUNC_DEFAULT, UR_DP1000_PINS_LPC }, 62*cb703792SJia Wang { "espi", UR_FUNC_0, UR_DP1000_PINS_LPC }, 63*cb703792SJia Wang }; 64*cb703792SJia Wang 65*cb703792SJia Wang static const struct ur_port_desc ur_dp1000_ports[] = { 66*cb703792SJia Wang UR_DP1000_PORT(0, 16, UR_DP1000_PORTA_FUNC_OFFSET, 67*cb703792SJia Wang UR_DP1000_PORTA_CONF_OFFSET, 68*cb703792SJia Wang UR_FUNC_0 | UR_FUNC_1, true), 69*cb703792SJia Wang UR_DP1000_PORT(16, 8, UR_DP1000_PORTB_FUNC_OFFSET, 70*cb703792SJia Wang UR_DP1000_PORTB_CONF_OFFSET, 71*cb703792SJia Wang UR_FUNC_0 | UR_FUNC_1, true), 72*cb703792SJia Wang UR_DP1000_PORT(24, 8, UR_DP1000_PORTC_FUNC_OFFSET, 73*cb703792SJia Wang UR_DP1000_PORTC_CONF_OFFSET, 74*cb703792SJia Wang UR_FUNC_0 | UR_FUNC_1, true), 75*cb703792SJia Wang UR_DP1000_PORT(32, 8, UR_DP1000_PORTD_FUNC_OFFSET, 76*cb703792SJia Wang UR_DP1000_PORTD_CONF_OFFSET, 77*cb703792SJia Wang UR_FUNC_0 | UR_FUNC_1, true), 78*cb703792SJia Wang UR_DP1000_PORT(40, 13, UR_DP1000_PORTLPC_FUNC_OFFSET, 79*cb703792SJia Wang UR_DP1000_PORTLPC_CONF_OFFSET, 80*cb703792SJia Wang UR_FUNC_0, false), 81*cb703792SJia Wang }; 82*cb703792SJia Wang 83*cb703792SJia Wang static const struct pinctrl_pin_desc ur_dp1000_pins[] = { 84*cb703792SJia Wang UR_DP1000_PIN(0, "PA0", UR_DP1000_PORT_A_IDX), 85*cb703792SJia Wang UR_DP1000_PIN(1, "PA1", UR_DP1000_PORT_A_IDX), 86*cb703792SJia Wang UR_DP1000_PIN(2, "PA2", UR_DP1000_PORT_A_IDX), 87*cb703792SJia Wang UR_DP1000_PIN(3, "PA3", UR_DP1000_PORT_A_IDX), 88*cb703792SJia Wang UR_DP1000_PIN(4, "PA4", UR_DP1000_PORT_A_IDX), 89*cb703792SJia Wang UR_DP1000_PIN(5, "PA5", UR_DP1000_PORT_A_IDX), 90*cb703792SJia Wang UR_DP1000_PIN(6, "PA6", UR_DP1000_PORT_A_IDX), 91*cb703792SJia Wang UR_DP1000_PIN(7, "PA7", UR_DP1000_PORT_A_IDX), 92*cb703792SJia Wang UR_DP1000_PIN(8, "PA8", UR_DP1000_PORT_A_IDX), 93*cb703792SJia Wang UR_DP1000_PIN(9, "PA9", UR_DP1000_PORT_A_IDX), 94*cb703792SJia Wang UR_DP1000_PIN(10, "PA10", UR_DP1000_PORT_A_IDX), 95*cb703792SJia Wang UR_DP1000_PIN(11, "PA11", UR_DP1000_PORT_A_IDX), 96*cb703792SJia Wang UR_DP1000_PIN(12, "PA12", UR_DP1000_PORT_A_IDX), 97*cb703792SJia Wang UR_DP1000_PIN(13, "PA13", UR_DP1000_PORT_A_IDX), 98*cb703792SJia Wang UR_DP1000_PIN(14, "PA14", UR_DP1000_PORT_A_IDX), 99*cb703792SJia Wang UR_DP1000_PIN(15, "PA15", UR_DP1000_PORT_A_IDX), 100*cb703792SJia Wang UR_DP1000_PIN(16, "PB0", UR_DP1000_PORT_B_IDX), 101*cb703792SJia Wang UR_DP1000_PIN(17, "PB1", UR_DP1000_PORT_B_IDX), 102*cb703792SJia Wang UR_DP1000_PIN(18, "PB2", UR_DP1000_PORT_B_IDX), 103*cb703792SJia Wang UR_DP1000_PIN(19, "PB3", UR_DP1000_PORT_B_IDX), 104*cb703792SJia Wang UR_DP1000_PIN(20, "PB4", UR_DP1000_PORT_B_IDX), 105*cb703792SJia Wang UR_DP1000_PIN(21, "PB5", UR_DP1000_PORT_B_IDX), 106*cb703792SJia Wang UR_DP1000_PIN(22, "PB6", UR_DP1000_PORT_B_IDX), 107*cb703792SJia Wang UR_DP1000_PIN(23, "PB7", UR_DP1000_PORT_B_IDX), 108*cb703792SJia Wang UR_DP1000_PIN(24, "PC0", UR_DP1000_PORT_C_IDX), 109*cb703792SJia Wang UR_DP1000_PIN(25, "PC1", UR_DP1000_PORT_C_IDX), 110*cb703792SJia Wang UR_DP1000_PIN(26, "PC2", UR_DP1000_PORT_C_IDX), 111*cb703792SJia Wang UR_DP1000_PIN(27, "PC3", UR_DP1000_PORT_C_IDX), 112*cb703792SJia Wang UR_DP1000_PIN(28, "PC4", UR_DP1000_PORT_C_IDX), 113*cb703792SJia Wang UR_DP1000_PIN(29, "PC5", UR_DP1000_PORT_C_IDX), 114*cb703792SJia Wang UR_DP1000_PIN(30, "PC6", UR_DP1000_PORT_C_IDX), 115*cb703792SJia Wang UR_DP1000_PIN(31, "PC7", UR_DP1000_PORT_C_IDX), 116*cb703792SJia Wang UR_DP1000_PIN(32, "PD0", UR_DP1000_PORT_D_IDX), 117*cb703792SJia Wang UR_DP1000_PIN(33, "PD1", UR_DP1000_PORT_D_IDX), 118*cb703792SJia Wang UR_DP1000_PIN(34, "PD2", UR_DP1000_PORT_D_IDX), 119*cb703792SJia Wang UR_DP1000_PIN(35, "PD3", UR_DP1000_PORT_D_IDX), 120*cb703792SJia Wang UR_DP1000_PIN(36, "PD4", UR_DP1000_PORT_D_IDX), 121*cb703792SJia Wang UR_DP1000_PIN(37, "PD5", UR_DP1000_PORT_D_IDX), 122*cb703792SJia Wang UR_DP1000_PIN(38, "PD6", UR_DP1000_PORT_D_IDX), 123*cb703792SJia Wang UR_DP1000_PIN(39, "PD7", UR_DP1000_PORT_D_IDX), 124*cb703792SJia Wang UR_DP1000_PIN(40, "LPC0", UR_DP1000_PORT_LPC_IDX), 125*cb703792SJia Wang UR_DP1000_PIN(41, "LPC1", UR_DP1000_PORT_LPC_IDX), 126*cb703792SJia Wang UR_DP1000_PIN(42, "LPC2", UR_DP1000_PORT_LPC_IDX), 127*cb703792SJia Wang UR_DP1000_PIN(43, "LPC3", UR_DP1000_PORT_LPC_IDX), 128*cb703792SJia Wang UR_DP1000_PIN(44, "LPC4", UR_DP1000_PORT_LPC_IDX), 129*cb703792SJia Wang UR_DP1000_PIN(45, "LPC5", UR_DP1000_PORT_LPC_IDX), 130*cb703792SJia Wang UR_DP1000_PIN(46, "LPC6", UR_DP1000_PORT_LPC_IDX), 131*cb703792SJia Wang UR_DP1000_PIN(47, "LPC7", UR_DP1000_PORT_LPC_IDX), 132*cb703792SJia Wang UR_DP1000_PIN(48, "LPC8", UR_DP1000_PORT_LPC_IDX), 133*cb703792SJia Wang UR_DP1000_PIN(49, "LPC9", UR_DP1000_PORT_LPC_IDX), 134*cb703792SJia Wang UR_DP1000_PIN(50, "LPC10", UR_DP1000_PORT_LPC_IDX), 135*cb703792SJia Wang UR_DP1000_PIN(51, "LPC11", UR_DP1000_PORT_LPC_IDX), 136*cb703792SJia Wang UR_DP1000_PIN(52, "LPC12", UR_DP1000_PORT_LPC_IDX), 137*cb703792SJia Wang }; 138*cb703792SJia Wang 139*cb703792SJia Wang static const struct ur_pinctrl_data ur_dp1000_pinctrl_data = { 140*cb703792SJia Wang .pins = ur_dp1000_pins, 141*cb703792SJia Wang .npins = ARRAY_SIZE(ur_dp1000_pins), 142*cb703792SJia Wang .routes = ur_dp1000_routes, 143*cb703792SJia Wang .num_routes = ARRAY_SIZE(ur_dp1000_routes), 144*cb703792SJia Wang }; 145*cb703792SJia Wang 146*cb703792SJia Wang static const struct of_device_id ur_pinctrl_of_match[] = { 147*cb703792SJia Wang { .compatible = "ultrarisc,dp1000-pinctrl" }, 148*cb703792SJia Wang { } 149*cb703792SJia Wang }; 150*cb703792SJia Wang MODULE_DEVICE_TABLE(of, ur_pinctrl_of_match); 151*cb703792SJia Wang 152*cb703792SJia Wang static int ur_dp1000_pinctrl_probe(struct platform_device *pdev) 153*cb703792SJia Wang { 154*cb703792SJia Wang return ur_pinctrl_probe(pdev, &ur_dp1000_pinctrl_data); 155*cb703792SJia Wang } 156*cb703792SJia Wang 157*cb703792SJia Wang static struct platform_driver ur_pinctrl_driver = { 158*cb703792SJia Wang .driver = { 159*cb703792SJia Wang .name = "ultrarisc-pinctrl-dp1000", 160*cb703792SJia Wang .of_match_table = ur_pinctrl_of_match, 161*cb703792SJia Wang }, 162*cb703792SJia Wang .probe = ur_dp1000_pinctrl_probe, 163*cb703792SJia Wang }; 164*cb703792SJia Wang 165*cb703792SJia Wang module_platform_driver(ur_pinctrl_driver); 166*cb703792SJia Wang 167*cb703792SJia Wang MODULE_DESCRIPTION("UltraRISC DP1000 pinctrl driver"); 168*cb703792SJia Wang MODULE_LICENSE("GPL"); 169