1 // SPDX-License-Identifier: GPL-2.0-only
3 #include <linux/gpio/driver.h>
4 #include <linux/module.h>
5 #include <linux/platform_device.h>
6 #include <linux/delay.h>
7 #include <asm/mach-rtl838x/mach-rtl83xx.h>
9 /* RTL8231 registers for LED control */
10 #define RTL8231_LED_FUNC0 0x0000
11 #define RTL8231_GPIO_PIN_SEL(gpio) ((0x0002) + ((gpio) >> 4))
12 #define RTL8231_GPIO_DIR(gpio) ((0x0005) + ((gpio) >> 4))
13 #define RTL8231_GPIO_DATA(gpio) ((0x001C) + ((gpio) >> 4))
15 struct rtl838x_gpios
{
26 int (*led_sw_p_ctrl
)(int port
);
27 int (*led_sw_p_en_ctrl
)(int port
);
28 int (*ext_gpio_dir
)(int i
);
29 int (*ext_gpio_data
)(int i
);
32 inline int rtl838x_ext_gpio_dir(int i
)
34 return RTL838X_EXT_GPIO_DIR
+ ((i
>>5) << 2);
37 inline int rtl839x_ext_gpio_dir(int i
)
39 return RTL839X_EXT_GPIO_DIR
+ ((i
>>5) << 2);
42 inline int rtl838x_ext_gpio_data(int i
)
44 return RTL838X_EXT_GPIO_DATA
+ ((i
>>5) << 2);
47 inline int rtl839x_ext_gpio_data(int i
)
49 return RTL839X_EXT_GPIO_DATA
+ ((i
>>5) << 2);
52 inline int rtl838x_led_sw_p_ctrl(int p
)
54 return RTL838X_LED_SW_P_CTRL
+ (p
<< 2);
57 inline int rtl839x_led_sw_p_ctrl(int p
)
59 return RTL839X_LED_SW_P_CTRL
+ (p
<< 2);
62 inline int rtl838x_led_sw_p_en_ctrl(int p
)
64 return RTL838X_LED_SW_P_EN_CTRL
+ ((p
/ 10) << 2);
67 inline int rtl839x_led_sw_p_en_ctrl(int p
)
69 return RTL839X_LED_SW_P_EN_CTRL
+ ((p
/ 10) << 2);
72 extern struct mutex smi_lock
;
73 extern struct rtl83xx_soc_info soc_info
;
76 void rtl838x_gpio_set(struct gpio_chip
*gc
, unsigned int offset
, int value
)
79 struct rtl838x_gpios
*gpios
= gpiochip_get_data(gc
);
81 pr_debug("rtl838x_set: %d, value: %d\n", offset
, value
);
82 /* Internal GPIO of the RTL8380 */
85 rtl83xx_w32_mask(0, BIT(offset
), RTL838X_GPIO_PABC_DATA
);
87 rtl83xx_w32_mask(BIT(offset
), 0, RTL838X_GPIO_PABC_DATA
);
90 /* LED driver for PWR and SYS */
91 if (offset
>= 32 && offset
< 64) {
94 sw_w32_mask(0, BIT(bit
), gpios
->led_glb_ctrl
);
96 sw_w32_mask(BIT(bit
), 0, gpios
->led_glb_ctrl
);
100 bit
= (offset
- 64) % 32;
102 if (offset
>= 64 && offset
< 96
103 && offset
>= (64 + gpios
->min_led
)
104 && offset
< (64 + gpios
->min_led
+ gpios
->num_leds
)) {
106 sw_w32_mask(7, 5, gpios
->led_sw_p_ctrl(bit
));
108 sw_w32_mask(7, 0, gpios
->led_sw_p_ctrl(bit
));
110 if (offset
>= 96 && offset
< 128
111 && offset
>= (96 + gpios
->min_led
)
112 && offset
< (96 + gpios
->min_led
+ gpios
->num_leds
)) {
114 sw_w32_mask(7 << 3, 5 << 3, gpios
->led_sw_p_ctrl(bit
));
116 sw_w32_mask(7 << 3, 0, gpios
->led_sw_p_ctrl(bit
));
118 if (offset
>= 128 && offset
< 160
119 && offset
>= (128 + gpios
->min_led
)
120 && offset
< (128 + gpios
->min_led
+ gpios
->num_leds
)) {
122 sw_w32_mask(7 << 6, 5 << 6, gpios
->led_sw_p_ctrl(bit
));
124 sw_w32_mask(7 << 6, 0, gpios
->led_sw_p_ctrl(bit
));
126 __asm__
volatile ("sync");
129 static int rtl838x_direction_input(struct gpio_chip
*gc
, unsigned int offset
)
131 pr_debug("%s: %d\n", __func__
, offset
);
134 rtl83xx_w32_mask(BIT(offset
), 0, RTL838X_GPIO_PABC_DIR
);
138 /* Internal LED driver does not support input */
142 static int rtl838x_direction_output(struct gpio_chip
*gc
, unsigned int offset
, int value
)
144 pr_debug("%s: %d\n", __func__
, offset
);
146 rtl83xx_w32_mask(0, BIT(offset
), RTL838X_GPIO_PABC_DIR
);
147 rtl838x_gpio_set(gc
, offset
, value
);
149 /* LED for PWR and SYS driver is direction output by default */
153 static int rtl838x_get_direction(struct gpio_chip
*gc
, unsigned int offset
)
157 pr_debug("%s: %d\n", __func__
, offset
);
159 v
= rtl83xx_r32(RTL838X_GPIO_PABC_DIR
);
165 /* LED driver for PWR and SYS is direction output by default */
166 if (offset
>= 32 && offset
< 64)
172 static int rtl838x_gpio_get(struct gpio_chip
*gc
, unsigned int offset
)
175 struct rtl838x_gpios
*gpios
= gpiochip_get_data(gc
);
177 pr_debug("%s: %d\n", __func__
, offset
);
179 /* Internal GPIO of the RTL8380 */
181 v
= rtl83xx_r32(RTL838X_GPIO_PABC_DATA
);
187 /* LED driver for PWR and SYS */
188 if (offset
>= 32 && offset
< 64) {
189 v
= sw_r32(gpios
->led_glb_ctrl
);
190 if (v
& BIT(offset
-32))
196 bit = (offset - 64) % 32;
197 if (offset >= 64 && offset < 96) {
198 if (sw_r32(RTL838X_LED1_SW_P_EN_CTRL) & BIT(bit))
202 if (offset >= 96 && offset < 128) {
203 if (sw_r32(RTL838X_LED1_SW_P_EN_CTRL) & BIT(bit))
207 if (offset >= 128 && offset < 160) {
208 if (sw_r32(RTL838X_LED1_SW_P_EN_CTRL) & BIT(bit))
216 void rtl8380_led_test(struct rtl838x_gpios
*gpios
, u32 mask
)
219 u32 led_gbl
= sw_r32(gpios
->led_glb_ctrl
);
220 u32 mode_sel
, led_p_en
;
222 if (soc_info
.family
== RTL8380_FAMILY_ID
) {
223 mode_sel
= sw_r32(RTL838X_LED_MODE_SEL
);
224 led_p_en
= sw_r32(RTL838X_LED_P_EN_CTRL
);
227 /* 2 Leds for ports 0-23 and 24-27, 3 would be 0x7 */
228 sw_w32_mask(0x3f, 0x3 | (0x3 << 3), gpios
->led_glb_ctrl
);
230 if(soc_info
.family
== RTL8380_FAMILY_ID
) {
231 /* Enable all leds */
232 sw_w32(0xFFFFFFF, RTL838X_LED_P_EN_CTRL
);
234 /* Enable software control of all leds */
235 sw_w32(0xFFFFFFF, gpios
->led_sw_ctrl
);
236 sw_w32(0xFFFFFFF, gpios
->led_sw_p_en_ctrl(0));
237 sw_w32(0xFFFFFFF, gpios
->led_sw_p_en_ctrl(10));
238 sw_w32(0x0000000, gpios
->led_sw_p_en_ctrl(20));
240 for (i
= 0; i
< 28; i
++) {
242 sw_w32(5 | (5 << 3) | (5 << 6), gpios
->led_sw_p_ctrl(i
));
246 if (soc_info
.family
== RTL8380_FAMILY_ID
)
247 sw_w32(led_p_en
, RTL838X_LED_P_EN_CTRL
);
248 /* Disable software control of all leds */
249 sw_w32(0x0000000, gpios
->led_sw_ctrl
);
250 sw_w32(0x0000000, gpios
->led_sw_p_en_ctrl(0));
251 sw_w32(0x0000000, gpios
->led_sw_p_en_ctrl(10));
252 sw_w32(0x0000000, gpios
->led_sw_p_en_ctrl(20));
254 sw_w32(led_gbl
, gpios
->led_glb_ctrl
);
255 if (soc_info
.family
== RTL8380_FAMILY_ID
)
256 sw_w32(mode_sel
, RTL838X_LED_MODE_SEL
);
259 void take_port_leds(struct rtl838x_gpios
*gpios
)
261 int leds_per_port
= gpios
->leds_per_port
;
262 int mode
= gpios
->led_mode
;
264 pr_info("%s, %d, %x\n", __func__
, leds_per_port
, mode
);
265 pr_debug("Bootloader settings: %x %x %x\n",
266 sw_r32(gpios
->led_sw_p_en_ctrl(0)),
267 sw_r32(gpios
->led_sw_p_en_ctrl(10)),
268 sw_r32(gpios
->led_sw_p_en_ctrl(20))
271 if (soc_info
.family
== RTL8380_FAMILY_ID
) {
272 pr_debug("led glb: %x, sel %x\n",
273 sw_r32(gpios
->led_glb_ctrl
), sw_r32(RTL838X_LED_MODE_SEL
));
274 pr_debug("RTL838X_LED_P_EN_CTRL: %x", sw_r32(RTL838X_LED_P_EN_CTRL
));
275 pr_debug("RTL838X_LED_MODE_CTRL: %x", sw_r32(RTL838X_LED_MODE_CTRL
));
276 sw_w32_mask(3, 0, RTL838X_LED_MODE_SEL
);
277 sw_w32(mode
, RTL838X_LED_MODE_CTRL
);
280 /* Enable software control of all leds */
281 sw_w32(0xFFFFFFF, gpios
->led_sw_ctrl
);
282 if (soc_info
.family
== RTL8380_FAMILY_ID
)
283 sw_w32(0xFFFFFFF, RTL838X_LED_P_EN_CTRL
);
285 sw_w32(0x0000000, gpios
->led_sw_p_en_ctrl(0));
286 sw_w32(0x0000000, gpios
->led_sw_p_en_ctrl(10));
287 sw_w32(0x0000000, gpios
->led_sw_p_en_ctrl(20));
289 sw_w32_mask(0x3f, 0, gpios
->led_glb_ctrl
);
290 switch (leds_per_port
) {
292 sw_w32_mask(0, 0x7 | (0x7 << 3), gpios
->led_glb_ctrl
);
293 sw_w32(0xFFFFFFF, gpios
->led_sw_p_en_ctrl(20));
296 sw_w32_mask(0, 0x3 | (0x3 << 3), gpios
->led_glb_ctrl
);
297 sw_w32(0xFFFFFFF, gpios
->led_sw_p_en_ctrl(10));
300 sw_w32_mask(0, 0x1 | (0x1 << 3), gpios
->led_glb_ctrl
);
301 sw_w32(0xFFFFFFF, gpios
->led_sw_p_en_ctrl(0));
304 pr_err("No LEDS configured for software control\n");
308 static const struct of_device_id rtl838x_gpio_of_match
[] = {
309 { .compatible
= "realtek,rtl838x-gpio" },
313 MODULE_DEVICE_TABLE(of
, rtl838x_gpio_of_match
);
315 static int rtl838x_gpio_probe(struct platform_device
*pdev
)
317 struct device
*dev
= &pdev
->dev
;
318 struct device_node
*np
= dev
->of_node
;
319 struct rtl838x_gpios
*gpios
;
322 pr_info("Probing RTL838X GPIOs\n");
325 dev_err(&pdev
->dev
, "No DT found\n");
329 gpios
= devm_kzalloc(dev
, sizeof(*gpios
), GFP_KERNEL
);
333 gpios
->id
= soc_info
.id
;
337 pr_debug("Found RTL8332M GPIO\n");
340 pr_debug("Found RTL8380M GPIO\n");
343 pr_debug("Found RTL8381M GPIO\n");
346 pr_debug("Found RTL8382M GPIO\n");
349 pr_debug("Found RTL8391 GPIO\n");
352 pr_debug("Found RTL8393 GPIO\n");
355 pr_err("Unknown GPIO chip id (%04x)\n", gpios
->id
);
359 if (soc_info
.family
== RTL8380_FAMILY_ID
) {
360 gpios
->led_glb_ctrl
= gpios
->led_glb_ctrl
;
361 gpios
->led_sw_ctrl
= RTL838X_LED_SW_CTRL
;
362 gpios
->led_sw_p_ctrl
= rtl838x_led_sw_p_ctrl
;
363 gpios
->led_sw_p_en_ctrl
= rtl838x_led_sw_p_en_ctrl
;
364 gpios
->ext_gpio_dir
= rtl838x_ext_gpio_dir
;
365 gpios
->ext_gpio_data
= rtl838x_ext_gpio_data
;
368 if (soc_info
.family
== RTL8390_FAMILY_ID
) {
369 gpios
->led_glb_ctrl
= RTL839X_LED_GLB_CTRL
;
370 gpios
->led_sw_ctrl
= RTL839X_LED_SW_CTRL
;
371 gpios
->led_sw_p_ctrl
= rtl839x_led_sw_p_ctrl
;
372 gpios
->led_sw_p_en_ctrl
= rtl839x_led_sw_p_en_ctrl
;
373 gpios
->ext_gpio_dir
= rtl839x_ext_gpio_dir
;
374 gpios
->ext_gpio_data
= rtl839x_ext_gpio_data
;
380 * 32-63, LED control register
383 * 128-159: PORT-LED 2
385 gpios
->gc
.ngpio
= 160;
386 gpios
->gc
.label
= "rtl838x";
387 gpios
->gc
.parent
= dev
;
388 gpios
->gc
.owner
= THIS_MODULE
;
389 gpios
->gc
.can_sleep
= true;
392 gpios
->gc
.direction_input
= rtl838x_direction_input
;
393 gpios
->gc
.direction_output
= rtl838x_direction_output
;
394 gpios
->gc
.set
= rtl838x_gpio_set
;
395 gpios
->gc
.get
= rtl838x_gpio_get
;
396 gpios
->gc
.get_direction
= rtl838x_get_direction
;
398 if (of_property_read_bool(np
, "take-port-leds")) {
399 if (of_property_read_u32(np
, "leds-per-port", &gpios
->leds_per_port
))
400 gpios
->leds_per_port
= 2;
401 if (of_property_read_u32(np
, "led-mode", &gpios
->led_mode
))
402 gpios
->led_mode
= (0x1ea << 15) | 0x1ea;
403 if (of_property_read_u32(np
, "num-leds", &gpios
->num_leds
))
404 gpios
->num_leds
= 32;
405 if (of_property_read_u32(np
, "min-led", &gpios
->min_led
))
407 take_port_leds(gpios
);
410 err
= devm_gpiochip_add_data(dev
, &gpios
->gc
, gpios
);
414 static struct platform_driver rtl838x_gpio_driver
= {
416 .name
= "rtl838x-gpio",
417 .of_match_table
= rtl838x_gpio_of_match
,
419 .probe
= rtl838x_gpio_probe
,
422 module_platform_driver(rtl838x_gpio_driver
);
424 MODULE_DESCRIPTION("Realtek RTL838X GPIO API support");
425 MODULE_LICENSE("GPL v2");