1 /*
2  * Copyright (c) 2023 Antmicro <www.antmicro.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT quicklogic_eos_s3_pinctrl
8 
9 #include <zephyr/arch/cpu.h>
10 #include <zephyr/devicetree.h>
11 #include <zephyr/drivers/pinctrl.h>
12 #include <zephyr/logging/log.h>
13 #include <zephyr/dt-bindings/pinctrl/quicklogic-eos-s3-pinctrl.h>
14 #include <soc.h>
15 
16 LOG_MODULE_REGISTER(pinctrl_eos_s3, CONFIG_PINCTRL_LOG_LEVEL);
17 
18 #define FUNCTION_REGISTER(func)	(func >> 13)
19 #define PAD_FUNC_SEL_MASK	GENMASK(2, 0)
20 #define PAD_CTRL_SEL_BIT0	3
21 #define PAD_CTRL_SEL_BIT1	4
22 #define PAD_OUTPUT_EN_BIT	5
23 #define PAD_PULL_UP_BIT		6
24 #define PAD_PULL_DOWN_BIT	7
25 #define PAD_DRIVE_STRENGTH_BIT0	8
26 #define PAD_DRIVE_STRENGTH_BIT1	9
27 #define PAD_SLEW_RATE_BIT	10
28 #define PAD_INPUT_EN_BIT	11
29 #define PAD_SCHMITT_EN_BIT	12
30 
31 /*
32  * Program IOMUX_func_SEL register.
33  */
pinctrl_eos_s3_input_selection(uint32_t pin,uint32_t sel_reg)34 static int pinctrl_eos_s3_input_selection(uint32_t pin, uint32_t sel_reg)
35 {
36 	volatile uint32_t *reg = (uint32_t *)IO_MUX_BASE;
37 
38 	if (sel_reg <= IO_MUX_MAX_PAD_NR || sel_reg > IO_MUX_REG_MAX_OFFSET) {
39 		return -EINVAL;
40 	}
41 	reg += sel_reg;
42 	*reg = pin;
43 
44 	return 0;
45 }
46 
47 /*
48  * Program IOMUX_PAD_x_CTRL register.
49  */
pinctrl_eos_s3_set(uint32_t pin,uint32_t func)50 static int pinctrl_eos_s3_set(uint32_t pin, uint32_t func)
51 {
52 	volatile uint32_t *reg = (uint32_t *)IO_MUX_BASE;
53 
54 	if (pin > IO_MUX_REG_MAX_OFFSET) {
55 		return -EINVAL;
56 	}
57 	reg += pin;
58 	*reg = func;
59 
60 	return 0;
61 }
62 
pinctrl_eos_s3_configure_pin(const pinctrl_soc_pin_t * pin)63 static int pinctrl_eos_s3_configure_pin(const pinctrl_soc_pin_t *pin)
64 {
65 	uint32_t reg_value = 0;
66 
67 	/* Set function. */
68 	reg_value |= (pin->iof & PAD_FUNC_SEL_MASK);
69 
70 	/* Output enable is active low. */
71 	WRITE_BIT(reg_value, PAD_OUTPUT_EN_BIT, pin->output_enable ? 0 : 1);
72 
73 	/* These are active high. */
74 	WRITE_BIT(reg_value, PAD_INPUT_EN_BIT, pin->input_enable);
75 	WRITE_BIT(reg_value, PAD_SLEW_RATE_BIT, pin->slew_rate);
76 	WRITE_BIT(reg_value, PAD_SCHMITT_EN_BIT, pin->schmitt_enable);
77 	WRITE_BIT(reg_value, PAD_CTRL_SEL_BIT0, pin->control_selection & BIT(0));
78 	WRITE_BIT(reg_value, PAD_CTRL_SEL_BIT1, pin->control_selection & BIT(1));
79 
80 	switch (pin->drive_strength) {
81 	case 2:
82 		WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 0);
83 		WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 0);
84 		break;
85 	case 4:
86 		WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 1);
87 		WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 0);
88 		break;
89 	case 8:
90 		WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 0);
91 		WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 1);
92 		break;
93 	case 12:
94 		WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT0, 1);
95 		WRITE_BIT(reg_value, PAD_DRIVE_STRENGTH_BIT1, 1);
96 		break;
97 	default:
98 		LOG_ERR("Selected drive-strength is not supported: %d\n", pin->drive_strength);
99 	}
100 
101 	/* Enable pull-up by default; overwrite if any setting was chosen. */
102 	WRITE_BIT(reg_value, PAD_PULL_UP_BIT, 1);
103 	WRITE_BIT(reg_value, PAD_PULL_DOWN_BIT, 0);
104 	if (pin->high_impedance) {
105 		WRITE_BIT(reg_value, PAD_PULL_UP_BIT, 0);
106 	} else if (pin->pull_up | pin->pull_down) {
107 		WRITE_BIT(reg_value, PAD_PULL_UP_BIT, pin->pull_up);
108 		WRITE_BIT(reg_value, PAD_PULL_DOWN_BIT, pin->pull_down);
109 	}
110 
111 	/* Program registers. */
112 	pinctrl_eos_s3_set(pin->pin, reg_value);
113 	if (pin->input_enable && FUNCTION_REGISTER(pin->iof)) {
114 		pinctrl_eos_s3_input_selection(pin->pin, FUNCTION_REGISTER(pin->iof));
115 	}
116 	return 0;
117 }
118 
pinctrl_configure_pins(const pinctrl_soc_pin_t * pins,uint8_t pin_cnt,uintptr_t reg)119 int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
120 {
121 	ARG_UNUSED(reg);
122 
123 	for (int i = 0; i < pin_cnt; i++) {
124 		pinctrl_eos_s3_configure_pin(&pins[i]);
125 	}
126 
127 	return 0;
128 }
129