1 /*
2  * Copyright (c) 2022 ITE Corporation. All Rights Reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT ite_it8xxx2_pinctrl_func
8 
9 #include <zephyr/drivers/pinctrl.h>
10 #include <zephyr/logging/log.h>
11 
12 #include <chip_chipregs.h>
13 
14 LOG_MODULE_REGISTER(pinctrl_ite_it8xxx2, LOG_LEVEL_ERR);
15 
16 #define GPIO_IT8XXX2_REG_BASE \
17 	((struct gpio_it8xxx2_regs *)DT_REG_ADDR(DT_NODELABEL(gpiogcr)))
18 #define GPIO_GROUP_MEMBERS  8
19 
20 struct pinctrl_it8xxx2_gpio {
21 	/* gpio port control register (byte mapping to pin) */
22 	uint8_t *reg_gpcr;
23 	/* function 3 general control register */
24 	uintptr_t func3_gcr[GPIO_GROUP_MEMBERS];
25 	/* function 3 enable mask */
26 	uint8_t func3_en_mask[GPIO_GROUP_MEMBERS];
27 	/* function 3 external control register */
28 	uintptr_t func3_ext[GPIO_GROUP_MEMBERS];
29 	/* function 3 external mask */
30 	uint8_t func3_ext_mask[GPIO_GROUP_MEMBERS];
31 	/* function 4 general control register */
32 	uintptr_t func4_gcr[GPIO_GROUP_MEMBERS];
33 	/* function 4 enable mask */
34 	uint8_t func4_en_mask[GPIO_GROUP_MEMBERS];
35 	/* Input voltage selection */
36 	uintptr_t volt_sel[GPIO_GROUP_MEMBERS];
37 	/* Input voltage selection mask */
38 	uint8_t volt_sel_mask[GPIO_GROUP_MEMBERS];
39 };
40 
41 struct pinctrl_it8xxx2_ksi_kso {
42 	/*
43 	 * KSI[7:0]/KSO[15:8]/KSO[7:0] port gpio control register
44 	 * (bit mapping to pin)
45 	 */
46 	uint8_t *reg_gctrl;
47 	/* KSI[7:0]/KSO[15:8]/KSO[7:0] port control register */
48 	uint8_t *reg_ctrl;
49 	/*
50 	 * KSO push-pull/open-drain bit of KSO[15:0] control register
51 	 * (this bit apply to all pins)
52 	 */
53 	int pp_od_mask;
54 	/*
55 	 * KSI/KSO pullup bit of KSI[7:0]/KSO[15:0] control register
56 	 * (this bit apply to all pins)
57 	 */
58 	int pullup_mask;
59 };
60 
61 struct pinctrl_it8xxx2_config {
62 	bool gpio_group;
63 	union {
64 		struct pinctrl_it8xxx2_gpio gpio;
65 		struct pinctrl_it8xxx2_ksi_kso ksi_kso;
66 	};
67 };
68 
pinctrl_it8xxx2_set(const pinctrl_soc_pin_t * pins)69 static int pinctrl_it8xxx2_set(const pinctrl_soc_pin_t *pins)
70 {
71 	const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
72 	const struct pinctrl_it8xxx2_gpio *gpio = &(pinctrl_config->gpio);
73 	uint32_t pincfg = pins->pincfg;
74 	uint8_t pin = pins->pin;
75 	volatile uint8_t *reg_gpcr = (uint8_t *)gpio->reg_gpcr + pin;
76 	volatile uint8_t *reg_volt_sel = (uint8_t *)(gpio->volt_sel[pin]);
77 
78 	/* Setting pull-up or pull-down. */
79 	switch (IT8XXX2_DT_PINCFG_PUPDR(pincfg)) {
80 	case IT8XXX2_PULL_PIN_DEFAULT:
81 		/* No pull-up or pull-down */
82 		*reg_gpcr &= ~(GPCR_PORT_PIN_MODE_PULLUP |
83 			       GPCR_PORT_PIN_MODE_PULLDOWN);
84 		break;
85 	case IT8XXX2_PULL_UP:
86 		*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_PULLUP) &
87 			     ~GPCR_PORT_PIN_MODE_PULLDOWN;
88 		break;
89 	case IT8XXX2_PULL_DOWN:
90 		*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_PULLDOWN) &
91 			     ~GPCR_PORT_PIN_MODE_PULLUP;
92 		break;
93 	default:
94 		LOG_ERR("This pull level is not supported.");
95 		return -EINVAL;
96 	}
97 
98 	/*
99 	 * Since not all GPIOs support voltage selection, configure voltage
100 	 * selection register only if it is present.
101 	 */
102 	if (reg_volt_sel != NULL) {
103 		/* Setting voltage 3.3V or 1.8V. */
104 		switch (IT8XXX2_DT_PINCFG_VOLTAGE(pincfg)) {
105 		case IT8XXX2_VOLTAGE_3V3:
106 			/* Input voltage selection 3.3V. */
107 			*reg_volt_sel &= ~gpio->volt_sel_mask[pin];
108 			break;
109 		case IT8XXX2_VOLTAGE_1V8:
110 			__ASSERT(!(IT8XXX2_DT_PINCFG_PUPDR(pincfg)
111 				   == IT8XXX2_PULL_UP),
112 			"Don't enable internal pullup if 1.8V voltage is used");
113 			/* Input voltage selection 1.8V. */
114 			*reg_volt_sel |= gpio->volt_sel_mask[pin];
115 			break;
116 		default:
117 			LOG_ERR("The voltage selection is not supported");
118 			return -EINVAL;
119 		}
120 	}
121 
122 	/* Setting tri-state mode. */
123 	if (IT8XXX2_DT_PINCFG_IMPEDANCE(pincfg)) {
124 		*reg_gpcr |= (GPCR_PORT_PIN_MODE_PULLUP |
125 			      GPCR_PORT_PIN_MODE_PULLDOWN);
126 	}
127 
128 	return 0;
129 }
130 
pinctrl_gpio_it8xxx2_configure_pins(const pinctrl_soc_pin_t * pins)131 static int pinctrl_gpio_it8xxx2_configure_pins(const pinctrl_soc_pin_t *pins)
132 {
133 	const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
134 	const struct pinctrl_it8xxx2_gpio *gpio = &(pinctrl_config->gpio);
135 	uint8_t pin = pins->pin;
136 	volatile uint8_t *reg_gpcr = (uint8_t *)gpio->reg_gpcr + pin;
137 	volatile uint8_t *reg_func3_gcr = (uint8_t *)(gpio->func3_gcr[pin]);
138 	volatile uint8_t *reg_func4_gcr = (uint8_t *)(gpio->func4_gcr[pin]);
139 	volatile uint8_t *reg_func3_ext = (uint8_t *)(gpio->func3_ext[pin]);
140 
141 	/* Handle PIN configuration. */
142 	if (pinctrl_it8xxx2_set(pins)) {
143 		LOG_ERR("Pin configuration is invalid.");
144 		return -EINVAL;
145 	}
146 
147 	/*
148 	 * Default input mode prevents leakage during changes to extended
149 	 * setting (e.g. enabling i2c functionality on GPIO E1/E2 on IT82002)
150 	 */
151 	*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_INPUT) &
152 		     ~GPCR_PORT_PIN_MODE_OUTPUT;
153 
154 	/*
155 	 * If pincfg is input, we don't need to handle
156 	 * alternate function.
157 	 */
158 	if (IT8XXX2_DT_PINCFG_INPUT(pins->pincfg)) {
159 		return 0;
160 	}
161 
162 	/*
163 	 * Handle alternate function.
164 	 */
165 	if (reg_func3_gcr != NULL) {
166 		*reg_func3_gcr &= ~gpio->func3_en_mask[pin];
167 	}
168 	/* Ensure that func3-ext setting is in default state. */
169 	if (reg_func3_ext != NULL) {
170 		*reg_func3_ext &= ~gpio->func3_ext_mask[pin];
171 	}
172 
173 	switch (pins->alt_func) {
174 	case IT8XXX2_ALT_FUNC_1:
175 		/* Func1: Alternate function will be set below. */
176 		break;
177 	case IT8XXX2_ALT_FUNC_2:
178 		/* Func2: WUI function: pin has been set as input above.*/
179 		return 0;
180 	case IT8XXX2_ALT_FUNC_3:
181 		/*
182 		 * Func3: In addition to the alternate setting above,
183 		 *        Func3 also need to set the general control.
184 		 */
185 		if (reg_func3_gcr != NULL) {
186 			*reg_func3_gcr |= gpio->func3_en_mask[pin];
187 		}
188 		/* Func3-external: Some pins require external setting. */
189 		if (reg_func3_ext != NULL) {
190 			*reg_func3_ext |= gpio->func3_ext_mask[pin];
191 		}
192 		break;
193 	case IT8XXX2_ALT_FUNC_4:
194 		/*
195 		 * Func4: In addition to the alternate setting above,
196 		 *        Func4 also need to set the general control.
197 		 */
198 		*reg_func4_gcr |= gpio->func4_en_mask[pin];
199 		break;
200 	case IT8XXX2_ALT_DEFAULT:
201 		*reg_func3_gcr &= ~gpio->func3_en_mask[pin];
202 		*reg_func4_gcr &= ~gpio->func4_en_mask[pin];
203 		return 0;
204 	default:
205 		LOG_ERR("This function is not supported.");
206 		return -EINVAL;
207 	}
208 
209 	/* Common settings for alternate function. */
210 	*reg_gpcr &= ~(GPCR_PORT_PIN_MODE_INPUT |
211 		       GPCR_PORT_PIN_MODE_OUTPUT);
212 
213 	return 0;
214 }
215 
pinctrl_kscan_it8xxx2_set(const pinctrl_soc_pin_t * pins)216 static int pinctrl_kscan_it8xxx2_set(const pinctrl_soc_pin_t *pins)
217 {
218 	const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
219 	const struct pinctrl_it8xxx2_ksi_kso *ksi_kso = &(pinctrl_config->ksi_kso);
220 	volatile uint8_t *reg_ctrl = ksi_kso->reg_ctrl;
221 	uint8_t pullup_mask = ksi_kso->pullup_mask;
222 	uint8_t pp_od_mask = ksi_kso->pp_od_mask;
223 	uint32_t pincfg = pins->pincfg;
224 
225 	/*
226 	 * Enable or disable internal pull-up (this bit apply to all pins):
227 	 * If KSI[7:0]/KSO[15:0] is in KBS mode , setting 1 enables the internal
228 	 * pull-up (KSO[17:16] setting internal pull-up by GPIO port GPCR register).
229 	 * If KSI[7:0]/KSO[15:0] is in GPIO mode, then this bit is always disabled.
230 	 */
231 	switch (IT8XXX2_DT_PINCFG_PULLUP(pincfg)) {
232 	case IT8XXX2_PULL_PIN_DEFAULT:
233 		/* Disable internal pulll-up */
234 		*reg_ctrl &= ~pullup_mask;
235 		break;
236 	case IT8XXX2_PULL_UP:
237 		*reg_ctrl |= pullup_mask;
238 		break;
239 	default:
240 		LOG_ERR("This pull level is not supported.");
241 		return -EINVAL;
242 	}
243 
244 	/*
245 	 * Set push-pull or open-drain mode (this bit apply to all pins):
246 	 * KSI[7:0] doesn't support push-pull and open-drain settings in kbs mode.
247 	 * If KSO[17:0] is in KBS mode, setting 1 selects open-drain mode,
248 	 * setting 0 selects push-pull mode.
249 	 * If KSO[15:0] is in GPIO mode, then this bit is always disabled.
250 	 */
251 	if (pp_od_mask != NO_FUNC) {
252 		switch (IT8XXX2_DT_PINCFG_PP_OD(pincfg)) {
253 		case IT8XXX2_PUSH_PULL:
254 			*reg_ctrl &= ~pp_od_mask;
255 			break;
256 		case IT8XXX2_OPEN_DRAIN:
257 			*reg_ctrl |= pp_od_mask;
258 			break;
259 		default:
260 			LOG_ERR("This pull mode is not supported.");
261 			return -EINVAL;
262 		}
263 	}
264 
265 	return 0;
266 }
267 
pinctrl_kscan_it8xxx2_configure_pins(const pinctrl_soc_pin_t * pins)268 static int pinctrl_kscan_it8xxx2_configure_pins(const pinctrl_soc_pin_t *pins)
269 {
270 	const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
271 	const struct pinctrl_it8xxx2_ksi_kso *ksi_kso = &(pinctrl_config->ksi_kso);
272 
273 	/* Set a pin of KSI[7:0]/KSO[15:0] to pullup, push-pull/open-drain */
274 	if (pinctrl_kscan_it8xxx2_set(pins)) {
275 		return -EINVAL;
276 	}
277 
278 #ifdef CONFIG_SOC_IT8XXX2_REG_SET_V1
279 	uint8_t pin_mask = BIT(pins->pin);
280 	volatile uint8_t *reg_gctrl = ksi_kso->reg_gctrl;
281 
282 	switch (pins->alt_func) {
283 	case IT8XXX2_ALT_FUNC_1:
284 		/* Set a pin of KSI[7:0]/KSO[15:0] to kbs mode */
285 		*reg_gctrl &= ~pin_mask;
286 		break;
287 	case IT8XXX2_ALT_DEFAULT:
288 		/* Set a pin of KSI[7:0]/KSO[15:0] to gpio mode */
289 		*reg_gctrl |= pin_mask;
290 		break;
291 #elif CONFIG_SOC_IT8XXX2_REG_SET_V2
292 	uint8_t pin = pins->pin;
293 	volatile uint8_t *reg_gctrl = ksi_kso->reg_gctrl + pin;
294 
295 	switch (pins->alt_func) {
296 	case IT8XXX2_ALT_FUNC_1:
297 		/* Set a pin of KSI[7:0]/KSO[15:0] to kbs mode */
298 		*reg_gctrl &= ~(GPCR_PORT_PIN_MODE_INPUT |
299 				GPCR_PORT_PIN_MODE_OUTPUT);
300 		break;
301 	case IT8XXX2_ALT_DEFAULT:
302 		/* Set a pin of KSI[7:0]/KSO[15:0] to gpio mode */
303 		*reg_gctrl = (*reg_gctrl | GPCR_PORT_PIN_MODE_INPUT) &
304 			      ~GPCR_PORT_PIN_MODE_OUTPUT;
305 		break;
306 #endif
307 	default:
308 		LOG_ERR("Alternate function not supported");
309 		return -ENOTSUP;
310 	}
311 
312 	return 0;
313 }
314 
315 int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
316 			   uintptr_t reg)
317 {
318 	ARG_UNUSED(reg);
319 	const struct pinctrl_it8xxx2_config *pinctrl_config;
320 	int status;
321 
322 	for (uint8_t i = 0U; i < pin_cnt; i++) {
323 		pinctrl_config = pins[i].pinctrls->config;
324 
325 		if (pinctrl_config->gpio_group) {
326 			status = pinctrl_gpio_it8xxx2_configure_pins(&pins[i]);
327 		} else {
328 			status = pinctrl_kscan_it8xxx2_configure_pins(&pins[i]);
329 		}
330 
331 		if (status < 0) {
332 			LOG_ERR("%s pin%d configuration is invalid.",
333 				pins[i].pinctrls->name, pins[i].pin);
334 			return status;
335 		}
336 	}
337 
338 	return 0;
339 }
340 
341 static int pinctrl_it8xxx2_init(const struct device *dev)
342 {
343 	struct gpio_it8xxx2_regs *const gpio_base = GPIO_IT8XXX2_REG_BASE;
344 
345 	/*
346 	 * The default value of LPCRSTEN is bit2:1 = 10b(GPD2) in GCR.
347 	 * If LPC reset is enabled on GPB7, we have to clear bit2:1
348 	 * to 00b.
349 	 */
350 	gpio_base->GPIO_GCR &= ~IT8XXX2_GPIO_LPCRSTEN;
351 
352 #ifdef CONFIG_SOC_IT8XXX2_REG_SET_V2
353 	/*
354 	 * Swap the default I2C2 SMCLK2/SMDAT2 pins from GPC7/GPD0 to GPF6/GPF7,
355 	 * and I2C3 SMCLK3/SMDAT3 pins from GPB2/GPB5 to GPH1/GPH2,
356 	 * and I2C5 SMCLK5/SMDAT5 pins from GPE1/GPE2 to GPA4/GPA5,
357 	 */
358 	gpio_base->GPIO_GCR7 &= ~(IT8XXX2_GPIO_SMB2PS |
359 				  IT8XXX2_GPIO_SMB3PS |
360 				  IT8XXX2_GPIO_SMB5PS);
361 #endif
362 	return 0;
363 }
364 
365 #define INIT_UNION_CONFIG(inst)                                                        \
366 	COND_CODE_1(DT_INST_PROP(inst, gpio_group),                                    \
367 		(.gpio = {                                                             \
368 			 .reg_gpcr = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 0),      \
369 			 .func3_gcr = DT_INST_PROP(inst, func3_gcr),                   \
370 			 .func3_en_mask = DT_INST_PROP(inst, func3_en_mask),           \
371 			 .func3_ext = DT_INST_PROP_OR(inst, func3_ext, {0}),           \
372 			 .func3_ext_mask = DT_INST_PROP_OR(inst, func3_ext_mask, {0}), \
373 			 .func4_gcr = DT_INST_PROP(inst, func4_gcr),                   \
374 			 .func4_en_mask = DT_INST_PROP(inst, func4_en_mask),           \
375 			 .volt_sel = DT_INST_PROP(inst, volt_sel),                     \
376 			 .volt_sel_mask = DT_INST_PROP(inst, volt_sel_mask),           \
377 		}),                                                                    \
378 		(.ksi_kso = {                                                          \
379 			 .reg_gctrl = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 0),     \
380 			 .reg_ctrl = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 1),      \
381 			 .pp_od_mask = (uint8_t)DT_INST_PROP(inst, pp_od_mask),        \
382 			 .pullup_mask = (uint8_t)DT_INST_PROP(inst, pullup_mask),      \
383 		})                                                                     \
384 	)
385 
386 #define PINCTRL_ITE_INIT(inst)                                                     \
387 	static const struct pinctrl_it8xxx2_config pinctrl_it8xxx2_cfg_##inst = {  \
388 		.gpio_group = DT_INST_PROP(inst, gpio_group),                      \
389 		{                                                                  \
390 			INIT_UNION_CONFIG(inst)                                    \
391 		}                                                                  \
392 	};                                                                         \
393 										   \
394 	DEVICE_DT_INST_DEFINE(inst, &pinctrl_it8xxx2_init,                         \
395 			      NULL,                                                \
396 			      NULL,                                                \
397 			      &pinctrl_it8xxx2_cfg_##inst,                         \
398 			      PRE_KERNEL_1,                                        \
399 			      CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,                 \
400 			      NULL);
401 DT_INST_FOREACH_STATUS_OKAY(PINCTRL_ITE_INIT)
402