1 /*
2  * Copyright (c) 2024 Silicon Laboratories Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/pinctrl.h>
8 #include <zephyr/arch/cpu.h>
9 
10 #include <em_gpio.h>
11 
12 #define DT_DRV_COMPAT silabs_dbus_pinctrl
13 #define PIN_MASK      0xF0000UL
14 #define ABUS_MASK(i)  GENMASK(((i) * 8) + 3, (i) * 8)
15 
pinctrl_configure_pins(const pinctrl_soc_pin_t * pins,uint8_t pin_cnt,uintptr_t reg)16 int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
17 {
18 	ARG_UNUSED(reg);
19 
20 	for (uint8_t i = 0U; i < pin_cnt; i++) {
21 		mem_addr_t enable_reg, route_reg;
22 
23 		/* Configure ABUS */
24 		if (pins[i].en_bit == SILABS_PINCTRL_ANALOG) {
25 			enable_reg = DT_INST_REG_ADDR_BY_NAME(0, abus) +
26 				     (pins[i].base_offset * sizeof(mem_addr_t));
27 			/* Read-modify-write. */
28 			uint32_t reg_val = sys_read32(enable_reg);
29 
30 			reg_val &= ~ABUS_MASK(pins[i].mode);
31 			reg_val |= FIELD_PREP(ABUS_MASK(pins[i].mode), pins[i].route_offset);
32 			sys_write32(reg_val, enable_reg);
33 			continue;
34 		}
35 
36 		/* Configure GPIO */
37 		GPIO_PinModeSet(pins[i].port, pins[i].pin, pins[i].mode, pins[i].dout);
38 
39 		/* Configure DBUS */
40 		enable_reg = DT_INST_REG_ADDR_BY_NAME(0, dbus) +
41 			     (pins[i].base_offset * sizeof(mem_addr_t));
42 		route_reg = enable_reg + (pins[i].route_offset * sizeof(mem_addr_t));
43 
44 		if (pins[i].route_offset != SILABS_PINCTRL_UNUSED) {
45 			sys_write32(pins[i].port | FIELD_PREP(PIN_MASK, pins[i].pin), route_reg);
46 		}
47 
48 		if (pins[i].en_bit != SILABS_PINCTRL_UNUSED) {
49 			if (pins[i].mode == gpioModeDisabled) {
50 				sys_clear_bit(enable_reg, pins[i].en_bit);
51 			} else {
52 				sys_set_bit(enable_reg, pins[i].en_bit);
53 			}
54 		}
55 	}
56 
57 	return 0;
58 }
59