1 /*
2  * Copyright (c) 2023 ITE Corporation. All Rights Reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  */
7 
8 #define DT_DRV_COMPAT ite_it8xxx2_gpio_v2
9 
10 #include <errno.h>
11 #include <soc.h>
12 #include <soc_dt.h>
13 #include <string.h>
14 #include <zephyr/device.h>
15 #include <zephyr/drivers/gpio.h>
16 #include <zephyr/drivers/gpio/gpio_utils.h>
17 #include <zephyr/dt-bindings/gpio/ite-it8xxx2-gpio.h>
18 #include <zephyr/dt-bindings/interrupt-controller/ite-intc.h>
19 #include <zephyr/irq.h>
20 #include <zephyr/sys/util.h>
21 #include <zephyr/types.h>
22 #include <zephyr/logging/log.h>
23 LOG_MODULE_REGISTER(gpio_it8xxx2, LOG_LEVEL_ERR);
24 
25 /*
26  * Structure gpio_ite_cfg is about the setting of GPIO
27  * this config will be used at initial time
28  */
29 struct gpio_ite_cfg {
30 	/* gpio_driver_config needs to be first */
31 	struct gpio_driver_config common;
32 	/* GPIO port data register (bit mapping to pin) */
33 	uintptr_t reg_gpdr;
34 	/* GPIO port data mirror register (bit mapping to pin) */
35 	uintptr_t reg_gpdmr;
36 	/* GPIO port output type register (bit mapping to pin) */
37 	uintptr_t reg_gpotr;
38 	/* GPIO port 1.8V select register (bit mapping to pin) */
39 	uintptr_t reg_p18scr;
40 	/* GPIO port control register (byte mapping to pin) */
41 	uintptr_t reg_gpcr;
42 	/* Wake up control base register */
43 	uintptr_t wuc_base[8];
44 	/* Wake up control mask */
45 	uint8_t wuc_mask[8];
46 	/* GPIO's irq */
47 	uint8_t gpio_irq[8];
48 	/* Support input voltage selection */
49 	uint8_t has_volt_sel[8];
50 	/* Number of pins per group of GPIO */
51 	uint8_t num_pins;
52 };
53 
54 /* Structure gpio_ite_data is about callback function */
55 struct gpio_ite_data {
56 	struct gpio_driver_data common;
57 	sys_slist_t callbacks;
58 	uint8_t volt_default_set;
59 };
60 
61 /**
62  * Driver functions
63  */
gpio_ite_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)64 static int gpio_ite_configure(const struct device *dev,
65 			      gpio_pin_t pin,
66 			      gpio_flags_t flags)
67 {
68 	const struct gpio_ite_cfg *gpio_config = dev->config;
69 	volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr;
70 	volatile uint8_t *reg_gpotr = (uint8_t *)gpio_config->reg_gpotr;
71 	volatile uint8_t *reg_p18scr = (uint8_t *)gpio_config->reg_p18scr;
72 	volatile uint8_t *reg_gpcr = (uint8_t *)gpio_config->reg_gpcr + pin;
73 	struct gpio_ite_data *data = dev->data;
74 	uint8_t mask = BIT(pin);
75 
76 	/* Don't support "open source" mode */
77 	if (((flags & GPIO_SINGLE_ENDED) != 0) &&
78 	    ((flags & GPIO_LINE_OPEN_DRAIN) == 0)) {
79 		return -ENOTSUP;
80 	}
81 
82 	if (flags == GPIO_DISCONNECTED) {
83 		*reg_gpcr = GPCR_PORT_PIN_MODE_TRISTATE;
84 		/*
85 		 * Since not all GPIOs can be to configured as tri-state,
86 		 * prompt error if pin doesn't support the flag.
87 		 */
88 		if (*reg_gpcr != GPCR_PORT_PIN_MODE_TRISTATE) {
89 			/* Go back to default setting (input) */
90 			*reg_gpcr = GPCR_PORT_PIN_MODE_INPUT;
91 			LOG_ERR("Cannot config the node-gpio@%x, pin=%d as tri-state",
92 				(uint32_t)reg_gpdr, pin);
93 			return -ENOTSUP;
94 		}
95 		/*
96 		 * The following configuration isn't necessary because the pin
97 		 * was configured as disconnected.
98 		 */
99 		return 0;
100 	}
101 
102 	/*
103 	 * Select open drain first, so that we don't glitch the signal
104 	 * when changing the line to an output.
105 	 */
106 	if (flags & GPIO_OPEN_DRAIN) {
107 		*reg_gpotr |= mask;
108 	} else {
109 		*reg_gpotr &= ~mask;
110 	}
111 
112 	/* 1.8V or 3.3V */
113 	if (gpio_config->has_volt_sel[pin]) {
114 		gpio_flags_t volt = flags & IT8XXX2_GPIO_VOLTAGE_MASK;
115 
116 		if (volt == IT8XXX2_GPIO_VOLTAGE_1P8) {
117 			__ASSERT(!(flags & GPIO_PULL_UP),
118 			"Don't enable internal pullup if 1.8V voltage is used");
119 			*reg_p18scr |= mask;
120 			data->volt_default_set &= ~mask;
121 		} else if (volt == IT8XXX2_GPIO_VOLTAGE_3P3) {
122 			*reg_p18scr &= ~mask;
123 			/*
124 			 * A variable is needed to store the difference between
125 			 * 3.3V and default so that the flag can be distinguished
126 			 * between the two in gpio_ite_get_config.
127 			 */
128 			data->volt_default_set &= ~mask;
129 		} else if (volt == IT8XXX2_GPIO_VOLTAGE_DEFAULT) {
130 			*reg_p18scr &= ~mask;
131 			data->volt_default_set |= mask;
132 		} else {
133 			return -EINVAL;
134 		}
135 	}
136 
137 	/* If output, set level before changing type to an output. */
138 	if (flags & GPIO_OUTPUT) {
139 		if (flags & GPIO_OUTPUT_INIT_HIGH) {
140 			*reg_gpdr |= mask;
141 		} else if (flags & GPIO_OUTPUT_INIT_LOW) {
142 			*reg_gpdr &= ~mask;
143 		}
144 	}
145 
146 	/* Set input or output. */
147 	if (flags & GPIO_OUTPUT) {
148 		*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_OUTPUT) &
149 				~GPCR_PORT_PIN_MODE_INPUT;
150 	} else {
151 		*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_INPUT) &
152 				~GPCR_PORT_PIN_MODE_OUTPUT;
153 	}
154 
155 	/* Handle pullup / pulldown */
156 	if (flags & GPIO_PULL_UP) {
157 		*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_PULLUP) &
158 				~GPCR_PORT_PIN_MODE_PULLDOWN;
159 	} else if (flags & GPIO_PULL_DOWN) {
160 		*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_PULLDOWN) &
161 				~GPCR_PORT_PIN_MODE_PULLUP;
162 	} else {
163 		/* No pull up/down */
164 		*reg_gpcr &= ~(GPCR_PORT_PIN_MODE_PULLUP |
165 				GPCR_PORT_PIN_MODE_PULLDOWN);
166 	}
167 
168 	return 0;
169 }
170 
171 #ifdef CONFIG_GPIO_GET_CONFIG
gpio_ite_get_config(const struct device * dev,gpio_pin_t pin,gpio_flags_t * out_flags)172 static int gpio_ite_get_config(const struct device *dev,
173 			       gpio_pin_t pin,
174 			       gpio_flags_t *out_flags)
175 {
176 	const struct gpio_ite_cfg *gpio_config = dev->config;
177 	volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr;
178 	volatile uint8_t *reg_gpotr = (uint8_t *)gpio_config->reg_gpotr;
179 	volatile uint8_t *reg_p18scr = (uint8_t *)gpio_config->reg_p18scr;
180 	volatile uint8_t *reg_gpcr = (uint8_t *)gpio_config->reg_gpcr + pin;
181 	struct gpio_ite_data *data = dev->data;
182 	uint8_t mask = BIT(pin);
183 	gpio_flags_t flags = 0;
184 
185 	/* push-pull or open-drain */
186 	if (*reg_gpotr & mask) {
187 		flags |= GPIO_OPEN_DRAIN;
188 	}
189 
190 	/* 1.8V or 3.3V */
191 	if (gpio_config->has_volt_sel[pin]) {
192 		if (data->volt_default_set & mask) {
193 			flags |= IT8XXX2_GPIO_VOLTAGE_DEFAULT;
194 		} else {
195 			if (*reg_p18scr & mask) {
196 				flags |= IT8XXX2_GPIO_VOLTAGE_1P8;
197 			} else {
198 				flags |= IT8XXX2_GPIO_VOLTAGE_3P3;
199 			}
200 		}
201 	}
202 
203 	/* set input or output. */
204 	if (*reg_gpcr & GPCR_PORT_PIN_MODE_OUTPUT) {
205 		flags |= GPIO_OUTPUT;
206 
207 		/* set level */
208 		if (*reg_gpdr & mask) {
209 			flags |= GPIO_OUTPUT_HIGH;
210 		} else {
211 			flags |= GPIO_OUTPUT_LOW;
212 		}
213 	}
214 
215 	if (*reg_gpcr & GPCR_PORT_PIN_MODE_INPUT) {
216 		flags |= GPIO_INPUT;
217 
218 		/* pullup / pulldown */
219 		if (*reg_gpcr & GPCR_PORT_PIN_MODE_PULLUP) {
220 			flags |= GPIO_PULL_UP;
221 		}
222 
223 		if (*reg_gpcr & GPCR_PORT_PIN_MODE_PULLDOWN) {
224 			flags |= GPIO_PULL_DOWN;
225 		}
226 	}
227 
228 	*out_flags = flags;
229 
230 	return 0;
231 }
232 #endif
233 
gpio_ite_port_get_raw(const struct device * dev,gpio_port_value_t * value)234 static int gpio_ite_port_get_raw(const struct device *dev,
235 				 gpio_port_value_t *value)
236 {
237 	const struct gpio_ite_cfg *gpio_config = dev->config;
238 	volatile uint8_t *reg_gpdmr = (uint8_t *)gpio_config->reg_gpdmr;
239 
240 	/* Get raw bits of GPIO mirror register */
241 	*value = *reg_gpdmr;
242 
243 	return 0;
244 }
245 
gpio_ite_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)246 static int gpio_ite_port_set_masked_raw(const struct device *dev,
247 					gpio_port_pins_t mask,
248 					gpio_port_value_t value)
249 {
250 	const struct gpio_ite_cfg *gpio_config = dev->config;
251 	volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr;
252 	uint8_t out = *reg_gpdr;
253 
254 	*reg_gpdr = ((out & ~mask) | (value & mask));
255 
256 	return 0;
257 }
258 
gpio_ite_port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)259 static int gpio_ite_port_set_bits_raw(const struct device *dev,
260 				      gpio_port_pins_t pins)
261 {
262 	const struct gpio_ite_cfg *gpio_config = dev->config;
263 	volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr;
264 
265 	/* Set raw bits of GPIO data register */
266 	*reg_gpdr |= pins;
267 
268 	return 0;
269 }
270 
gpio_ite_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)271 static int gpio_ite_port_clear_bits_raw(const struct device *dev,
272 					gpio_port_pins_t pins)
273 {
274 	const struct gpio_ite_cfg *gpio_config = dev->config;
275 	volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr;
276 
277 	/* Clear raw bits of GPIO data register */
278 	*reg_gpdr &= ~pins;
279 
280 	return 0;
281 }
282 
gpio_ite_port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)283 static int gpio_ite_port_toggle_bits(const struct device *dev,
284 				     gpio_port_pins_t pins)
285 {
286 	const struct gpio_ite_cfg *gpio_config = dev->config;
287 	volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr;
288 
289 	/* Toggle raw bits of GPIO data register */
290 	*reg_gpdr ^= pins;
291 
292 	return 0;
293 }
294 
gpio_ite_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)295 static int gpio_ite_manage_callback(const struct device *dev,
296 				    struct gpio_callback *callback,
297 				    bool set)
298 {
299 	struct gpio_ite_data *data = dev->data;
300 
301 	return gpio_manage_callback(&data->callbacks, callback, set);
302 }
303 
gpio_ite_isr(const void * arg)304 static void gpio_ite_isr(const void *arg)
305 {
306 	const struct device *dev = arg;
307 	const struct gpio_ite_cfg *gpio_config = dev->config;
308 	struct gpio_ite_data *data = dev->data;
309 	uint8_t irq = ite_intc_get_irq_num();
310 	uint8_t num_pins = gpio_config->num_pins;
311 	uint8_t pin;
312 
313 	for (pin = 0; pin <= num_pins; pin++) {
314 		if (irq == gpio_config->gpio_irq[pin]) {
315 			volatile uint8_t *reg_base =
316 				(uint8_t *)gpio_config->wuc_base[pin];
317 			volatile uint8_t *reg_wuesr = reg_base + 1;
318 			uint8_t wuc_mask = gpio_config->wuc_mask[pin];
319 
320 			/* Clear the WUC status register. */
321 			*reg_wuesr = wuc_mask;
322 			gpio_fire_callbacks(&data->callbacks, dev, BIT(pin));
323 
324 			break;
325 		}
326 	}
327 }
328 
gpio_ite_pin_interrupt_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)329 static int gpio_ite_pin_interrupt_configure(const struct device *dev,
330 					    gpio_pin_t pin,
331 					    enum gpio_int_mode mode,
332 					    enum gpio_int_trig trig)
333 {
334 	const struct gpio_ite_cfg *gpio_config = dev->config;
335 	uint8_t gpio_irq = gpio_config->gpio_irq[pin];
336 
337 #ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
338 	if (mode == GPIO_INT_MODE_DISABLED || mode == GPIO_INT_MODE_DISABLE_ONLY) {
339 #else
340 	if (mode == GPIO_INT_MODE_DISABLED) {
341 #endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */
342 		/* Disable GPIO interrupt */
343 		irq_disable(gpio_irq);
344 		return 0;
345 #ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
346 	} else if (mode == GPIO_INT_MODE_ENABLE_ONLY) {
347 		/* Only enable GPIO interrupt */
348 		irq_enable(gpio_irq);
349 		return 0;
350 #endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */
351 	}
352 
353 	if (mode == GPIO_INT_MODE_LEVEL) {
354 		LOG_ERR("Level trigger mode not supported");
355 		return -ENOTSUP;
356 	}
357 
358 	/* Disable irq before configuring it */
359 	irq_disable(gpio_irq);
360 
361 	if (trig & GPIO_INT_TRIG_BOTH) {
362 		volatile uint8_t *reg_base = (uint8_t *)gpio_config->wuc_base[pin];
363 		volatile uint8_t *reg_wuemr = reg_base;
364 		volatile uint8_t *reg_wuesr = reg_base + 1;
365 		volatile uint8_t *reg_wubemr = reg_base + 3;
366 		uint8_t wuc_mask = gpio_config->wuc_mask[pin];
367 
368 		/* Set both edges interrupt. */
369 		if ((trig & GPIO_INT_TRIG_BOTH) == GPIO_INT_TRIG_BOTH) {
370 			*reg_wubemr |= wuc_mask;
371 		} else {
372 			*reg_wubemr &= ~wuc_mask;
373 		}
374 
375 		if (trig & GPIO_INT_TRIG_LOW) {
376 			*reg_wuemr |= wuc_mask;
377 		} else {
378 			*reg_wuemr &= ~wuc_mask;
379 		}
380 		/*
381 		 * Always write 1 to clear the WUC status register after
382 		 * modifying edge mode selection register (WUBEMR and WUEMR).
383 		 */
384 		*reg_wuesr = wuc_mask;
385 	}
386 
387 	/* Enable GPIO interrupt */
388 	irq_connect_dynamic(gpio_irq, 0, gpio_ite_isr, dev, 0);
389 	irq_enable(gpio_irq);
390 
391 	return 0;
392 }
393 
394 static const struct gpio_driver_api gpio_ite_driver_api = {
395 	.pin_configure = gpio_ite_configure,
396 #ifdef CONFIG_GPIO_GET_CONFIG
397 	.pin_get_config = gpio_ite_get_config,
398 #endif
399 	.port_get_raw = gpio_ite_port_get_raw,
400 	.port_set_masked_raw = gpio_ite_port_set_masked_raw,
401 	.port_set_bits_raw = gpio_ite_port_set_bits_raw,
402 	.port_clear_bits_raw = gpio_ite_port_clear_bits_raw,
403 	.port_toggle_bits = gpio_ite_port_toggle_bits,
404 	.pin_interrupt_configure = gpio_ite_pin_interrupt_configure,
405 	.manage_callback = gpio_ite_manage_callback,
406 };
407 
408 static int gpio_ite_init(const struct device *dev)
409 {
410 	return 0;
411 }
412 
413 #define GPIO_ITE_DEV_CFG_DATA(inst)                                \
414 static struct gpio_ite_data gpio_ite_data_##inst;                  \
415 static const struct gpio_ite_cfg gpio_ite_cfg_##inst = {           \
416 	.common = {                                                \
417 		.port_pin_mask =                                   \
418 			GPIO_PORT_PIN_MASK_FROM_DT_INST(inst)      \
419 	},                                                         \
420 	.reg_gpdr = DT_INST_REG_ADDR_BY_IDX(inst, 0),              \
421 	.reg_gpdmr = DT_INST_REG_ADDR_BY_IDX(inst, 1),             \
422 	.reg_gpotr = DT_INST_REG_ADDR_BY_IDX(inst, 2),             \
423 	.reg_p18scr = DT_INST_REG_ADDR_BY_IDX(inst, 3),            \
424 	.reg_gpcr = DT_INST_REG_ADDR_BY_IDX(inst, 4),              \
425 	.wuc_base = DT_INST_PROP_OR(inst, wuc_base, {0}),          \
426 	.wuc_mask = DT_INST_PROP_OR(inst, wuc_mask, {0}),          \
427 	.gpio_irq = IT8XXX2_DT_GPIO_IRQ_LIST(inst),                \
428 	.has_volt_sel = DT_INST_PROP_OR(inst, has_volt_sel, {0}),  \
429 	.num_pins = DT_INST_PROP(inst, ngpios),                    \
430 	};                                                         \
431 DEVICE_DT_INST_DEFINE(inst,                                        \
432 		      gpio_ite_init,                               \
433 		      NULL,                                        \
434 		      &gpio_ite_data_##inst,                       \
435 		      &gpio_ite_cfg_##inst,                        \
436 		      PRE_KERNEL_1,                                \
437 		      CONFIG_GPIO_INIT_PRIORITY,                   \
438 		      &gpio_ite_driver_api);
439 
440 DT_INST_FOREACH_STATUS_OKAY(GPIO_ITE_DEV_CFG_DATA)
441 
442 static int gpio_it8xxx2_init_set(void)
443 {
444 	if (IS_ENABLED(CONFIG_SOC_IT8XXX2_GPIO_GROUP_K_L_DEFAULT_PULL_DOWN)) {
445 		const struct device *const gpiok = DEVICE_DT_GET(DT_NODELABEL(gpiok));
446 		const struct device *const gpiol = DEVICE_DT_GET(DT_NODELABEL(gpiol));
447 
448 		for (int i = 0; i < 8; i++) {
449 			gpio_pin_configure(gpiok, i, GPIO_INPUT | GPIO_PULL_DOWN);
450 			gpio_pin_configure(gpiol, i, GPIO_INPUT | GPIO_PULL_DOWN);
451 		}
452 	}
453 
454 	return 0;
455 }
456 SYS_INIT(gpio_it8xxx2_init_set, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY);
457