xref: /linux/drivers/pinctrl/ultrarisc/pinctrl-dp1000.c (revision 3d5e48944e824bddc20d7b874e784f7b279636fe)
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