1 /*
2  * Copyright (c) 2017 Intel Corporation
3  * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT espressif_esp32_gpio
9 
10 /* Include esp-idf headers first to avoid redefining BIT() macro */
11 #include <soc/gpio_reg.h>
12 #include <soc/io_mux_reg.h>
13 #include <soc/soc.h>
14 #include <hal/gpio_ll.h>
15 #include <esp_attr.h>
16 #include <hal/rtc_io_hal.h>
17 
18 #include <soc.h>
19 #include <errno.h>
20 #include <zephyr/device.h>
21 #include <zephyr/drivers/gpio.h>
22 #include <zephyr/dt-bindings/gpio/espressif-esp32-gpio.h>
23 #ifdef CONFIG_SOC_SERIES_ESP32C3
24 #include <zephyr/drivers/interrupt_controller/intc_esp32c3.h>
25 #else
26 #include <zephyr/drivers/interrupt_controller/intc_esp32.h>
27 #endif
28 #include <zephyr/kernel.h>
29 #include <zephyr/sys/util.h>
30 
31 #include <zephyr/drivers/gpio/gpio_utils.h>
32 
33 #include <zephyr/logging/log.h>
34 LOG_MODULE_REGISTER(gpio_esp32, CONFIG_LOG_DEFAULT_LEVEL);
35 
36 #ifdef CONFIG_SOC_SERIES_ESP32C3
37 /* gpio structs in esp32c3 series are different from xtensa ones */
38 #define out out.data
39 #define in in.data
40 #define out_w1ts out_w1ts.val
41 #define out_w1tc out_w1tc.val
42 /* arch_curr_cpu() is not available for riscv based chips */
43 #define CPU_ID()  0
44 #define ISR_HANDLER isr_handler_t
45 #else
46 #define CPU_ID() arch_curr_cpu()->id
47 #define ISR_HANDLER intr_handler_t
48 #endif
49 
50 #ifndef SOC_GPIO_SUPPORT_RTC_INDEPENDENT
51 #define SOC_GPIO_SUPPORT_RTC_INDEPENDENT 0
52 #endif
53 
54 struct gpio_esp32_config {
55 	/* gpio_driver_config needs to be first */
56 	struct gpio_driver_config drv_cfg;
57 	gpio_dev_t *const gpio_base;
58 	gpio_dev_t *const gpio_dev;
59 	const int gpio_port;
60 };
61 
62 struct gpio_esp32_data {
63 	/* gpio_driver_data needs to be first */
64 	struct gpio_driver_data common;
65 	sys_slist_t cb;
66 };
67 
rtc_gpio_is_valid_gpio(uint32_t gpio_num)68 static inline bool rtc_gpio_is_valid_gpio(uint32_t gpio_num)
69 {
70 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
71 	return (gpio_num < SOC_GPIO_PIN_COUNT && rtc_io_num_map[gpio_num] >= 0);
72 #else
73 	return false;
74 #endif
75 }
76 
gpio_pin_is_valid(uint32_t pin)77 static inline bool gpio_pin_is_valid(uint32_t pin)
78 {
79 	return ((BIT(pin) & SOC_GPIO_VALID_GPIO_MASK) != 0);
80 }
81 
gpio_pin_is_output_capable(uint32_t pin)82 static inline bool gpio_pin_is_output_capable(uint32_t pin)
83 {
84 	return ((BIT(pin) & SOC_GPIO_VALID_OUTPUT_GPIO_MASK) != 0);
85 }
86 
gpio_esp32_config(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)87 static int gpio_esp32_config(const struct device *dev,
88 			     gpio_pin_t pin,
89 			     gpio_flags_t flags)
90 {
91 	const struct gpio_esp32_config *const cfg = dev->config;
92 	struct gpio_esp32_data *data = dev->data;
93 	uint32_t io_pin = (uint32_t) pin + ((cfg->gpio_port == 1 && pin < 32) ? 32 : 0);
94 	uint32_t key;
95 	int ret = 0;
96 
97 	if (!gpio_pin_is_valid(io_pin)) {
98 		LOG_ERR("Selected IO pin is not valid.");
99 		return -EINVAL;
100 	}
101 
102 	key = irq_lock();
103 
104 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
105 	if (rtc_gpio_is_valid_gpio(io_pin)) {
106 		rtcio_hal_function_select(rtc_io_num_map[io_pin], RTCIO_FUNC_DIGITAL);
107 	}
108 #endif
109 
110 	if (io_pin >= GPIO_NUM_MAX) {
111 		LOG_ERR("Invalid pin.");
112 		ret = -EINVAL;
113 		goto end;
114 	}
115 
116 	/* Set pin function as GPIO */
117 	gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[io_pin], PIN_FUNC_GPIO);
118 
119 	if (flags & GPIO_PULL_UP) {
120 		if (!rtc_gpio_is_valid_gpio(io_pin) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
121 			gpio_ll_pullup_en(&GPIO, io_pin);
122 		} else {
123 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
124 			int rtcio_num = rtc_io_num_map[io_pin];
125 
126 			if (rtc_io_desc[rtcio_num].pullup) {
127 				rtcio_hal_pullup_enable(rtcio_num);
128 			} else {
129 				ret = -ENOTSUP;
130 				goto end;
131 			}
132 #endif
133 		}
134 	} else {
135 		if (!rtc_gpio_is_valid_gpio(io_pin) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
136 			gpio_ll_pullup_dis(&GPIO, io_pin);
137 		} else {
138 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
139 			int rtcio_num = rtc_io_num_map[io_pin];
140 
141 			if (rtc_io_desc[rtcio_num].pullup) {
142 				rtcio_hal_pullup_disable(rtcio_num);
143 			}
144 #else
145 			ret = -ENOTSUP;
146 			goto end;
147 #endif
148 		}
149 	}
150 
151 	if (flags & GPIO_SINGLE_ENDED) {
152 		if (flags & GPIO_LINE_OPEN_DRAIN) {
153 			gpio_ll_od_enable(cfg->gpio_base, io_pin);
154 		} else {
155 			LOG_ERR("GPIO configuration not supported");
156 			ret = -ENOTSUP;
157 			goto end;
158 		}
159 	} else {
160 		gpio_ll_od_disable(cfg->gpio_base, io_pin);
161 	}
162 
163 	if (flags & GPIO_PULL_DOWN) {
164 		if (!rtc_gpio_is_valid_gpio(io_pin) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
165 			gpio_ll_pulldown_en(&GPIO, io_pin);
166 		} else {
167 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
168 			int rtcio_num = rtc_io_num_map[io_pin];
169 
170 			if (rtc_io_desc[rtcio_num].pulldown) {
171 				rtcio_hal_pulldown_enable(rtcio_num);
172 			} else {
173 				ret = -ENOTSUP;
174 				goto end;
175 			}
176 #endif
177 		}
178 	} else {
179 		if (!rtc_gpio_is_valid_gpio(io_pin) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
180 			gpio_ll_pulldown_dis(&GPIO, io_pin);
181 		} else {
182 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
183 			int rtcio_num = rtc_io_num_map[io_pin];
184 
185 			if (rtc_io_desc[rtcio_num].pulldown) {
186 				rtcio_hal_pulldown_disable(rtcio_num);
187 			}
188 #else
189 			ret = -ENOTSUP;
190 			goto end;
191 #endif
192 		}
193 	}
194 
195 	if (flags & GPIO_OUTPUT) {
196 
197 		if (!gpio_pin_is_output_capable(pin)) {
198 			LOG_ERR("GPIO can only be used as input");
199 			ret = -EINVAL;
200 			goto end;
201 		}
202 
203 		/*
204 		 * By default, drive strength is set to its maximum value when the pin is set
205 		 * to either low or high states. Alternative drive strength is weak-only,
206 		 * while any other intermediary combination is considered invalid.
207 		 */
208 		switch (flags & ESP32_GPIO_DS_MASK) {
209 		case ESP32_GPIO_DS_DFLT:
210 			if (!rtc_gpio_is_valid_gpio(io_pin) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
211 				gpio_ll_set_drive_capability(cfg->gpio_base,
212 						io_pin,
213 						GPIO_DRIVE_CAP_3);
214 			} else {
215 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
216 				rtcio_hal_set_drive_capability(rtc_io_num_map[io_pin],
217 						GPIO_DRIVE_CAP_3);
218 #endif
219 			}
220 			break;
221 		case ESP32_GPIO_DS_ALT:
222 			if (!rtc_gpio_is_valid_gpio(io_pin) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
223 				gpio_ll_set_drive_capability(cfg->gpio_base,
224 						io_pin,
225 						GPIO_DRIVE_CAP_0);
226 			} else {
227 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
228 				rtcio_hal_set_drive_capability(rtc_io_num_map[io_pin],
229 						GPIO_DRIVE_CAP_0);
230 #endif
231 			}
232 			break;
233 		default:
234 			ret = -EINVAL;
235 			goto end;
236 		}
237 
238 		gpio_ll_output_enable(&GPIO, io_pin);
239 		esp_rom_gpio_matrix_out(io_pin, SIG_GPIO_OUT_IDX, false, false);
240 
241 		/* Set output pin initial value */
242 		if (flags & GPIO_OUTPUT_INIT_HIGH) {
243 			gpio_ll_set_level(cfg->gpio_base, io_pin, 1);
244 		} else if (flags & GPIO_OUTPUT_INIT_LOW) {
245 			gpio_ll_set_level(cfg->gpio_base, io_pin, 0);
246 		}
247 	} else {
248 		gpio_ll_output_disable(&GPIO, io_pin);
249 	}
250 
251 	if (flags & GPIO_INPUT) {
252 		gpio_ll_input_enable(&GPIO, io_pin);
253 	} else {
254 		gpio_ll_input_disable(&GPIO, io_pin);
255 	}
256 
257 end:
258 	irq_unlock(key);
259 
260 	return ret;
261 }
262 
gpio_esp32_port_get_raw(const struct device * port,uint32_t * value)263 static int gpio_esp32_port_get_raw(const struct device *port, uint32_t *value)
264 {
265 	const struct gpio_esp32_config *const cfg = port->config;
266 
267 	if (cfg->gpio_port == 0) {
268 		*value = cfg->gpio_dev->in;
269 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay)
270 	} else {
271 		*value = cfg->gpio_dev->in1.data;
272 #endif
273 	}
274 
275 	return 0;
276 }
277 
gpio_esp32_port_set_masked_raw(const struct device * port,uint32_t mask,uint32_t value)278 static int gpio_esp32_port_set_masked_raw(const struct device *port,
279 					  uint32_t mask, uint32_t value)
280 {
281 	const struct gpio_esp32_config *const cfg = port->config;
282 
283 	uint32_t key = irq_lock();
284 
285 	if (cfg->gpio_port == 0) {
286 		cfg->gpio_dev->out = (cfg->gpio_dev->out & ~mask) | (mask & value);
287 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay)
288 	} else {
289 		cfg->gpio_dev->out1.data = (cfg->gpio_dev->out1.data & ~mask) | (mask & value);
290 #endif
291 	}
292 
293 	irq_unlock(key);
294 
295 	return 0;
296 }
297 
gpio_esp32_port_set_bits_raw(const struct device * port,uint32_t pins)298 static int gpio_esp32_port_set_bits_raw(const struct device *port,
299 					uint32_t pins)
300 {
301 	const struct gpio_esp32_config *const cfg = port->config;
302 
303 	if (cfg->gpio_port == 0) {
304 		cfg->gpio_dev->out_w1ts = pins;
305 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay)
306 	} else {
307 		cfg->gpio_dev->out1_w1ts.data = pins;
308 #endif
309 	}
310 
311 	return 0;
312 }
313 
gpio_esp32_port_clear_bits_raw(const struct device * port,uint32_t pins)314 static int gpio_esp32_port_clear_bits_raw(const struct device *port,
315 					  uint32_t pins)
316 {
317 	const struct gpio_esp32_config *const cfg = port->config;
318 
319 	if (cfg->gpio_port == 0) {
320 		cfg->gpio_dev->out_w1tc = pins;
321 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay)
322 	} else {
323 		cfg->gpio_dev->out1_w1tc.data = pins;
324 #endif
325 	}
326 
327 	return 0;
328 }
329 
gpio_esp32_port_toggle_bits(const struct device * port,uint32_t pins)330 static int gpio_esp32_port_toggle_bits(const struct device *port,
331 				       uint32_t pins)
332 {
333 	const struct gpio_esp32_config *const cfg = port->config;
334 	uint32_t key = irq_lock();
335 
336 	if (cfg->gpio_port == 0) {
337 		cfg->gpio_dev->out ^= pins;
338 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay)
339 	} else {
340 		cfg->gpio_dev->out1.data ^= pins;
341 #endif
342 	}
343 
344 	irq_unlock(key);
345 
346 	return 0;
347 }
348 
convert_int_type(enum gpio_int_mode mode,enum gpio_int_trig trig)349 static int convert_int_type(enum gpio_int_mode mode,
350 			    enum gpio_int_trig trig)
351 {
352 	if (mode == GPIO_INT_MODE_DISABLED) {
353 		return GPIO_INTR_DISABLE;
354 	}
355 
356 	if (mode == GPIO_INT_MODE_LEVEL) {
357 		switch (trig) {
358 		case GPIO_INT_TRIG_LOW:
359 			return GPIO_INTR_LOW_LEVEL;
360 		case GPIO_INT_TRIG_HIGH:
361 			return GPIO_INTR_HIGH_LEVEL;
362 		default:
363 			return -EINVAL;
364 		}
365 	} else { /* edge interrupts */
366 		switch (trig) {
367 		case GPIO_INT_TRIG_HIGH:
368 			return GPIO_INTR_POSEDGE;
369 		case GPIO_INT_TRIG_LOW:
370 			return GPIO_INTR_NEGEDGE;
371 		case GPIO_INT_TRIG_BOTH:
372 			return GPIO_INTR_ANYEDGE;
373 		default:
374 			return -EINVAL;
375 		}
376 	}
377 
378 	/* Any other type of interrupt triggering is invalid. */
379 	return -EINVAL;
380 }
381 
gpio_esp32_pin_interrupt_configure(const struct device * port,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)382 static int gpio_esp32_pin_interrupt_configure(const struct device *port,
383 					      gpio_pin_t pin,
384 					      enum gpio_int_mode mode,
385 					      enum gpio_int_trig trig)
386 {
387 	const struct gpio_esp32_config *const cfg = port->config;
388 	uint32_t io_pin = (uint32_t) pin + ((cfg->gpio_port == 1 && pin < 32) ? 32 : 0);
389 	int intr_trig_mode = convert_int_type(mode, trig);
390 	uint32_t key;
391 
392 	if (intr_trig_mode < 0) {
393 		return intr_trig_mode;
394 	}
395 
396 	key = irq_lock();
397 	if (cfg->gpio_port == 0) {
398 		gpio_ll_clear_intr_status(cfg->gpio_base, BIT(pin));
399 	} else {
400 		gpio_ll_clear_intr_status_high(cfg->gpio_base, BIT(pin));
401 	}
402 
403 	gpio_ll_set_intr_type(cfg->gpio_base, io_pin, intr_trig_mode);
404 	gpio_ll_intr_enable_on_core(cfg->gpio_base, CPU_ID(), io_pin);
405 	irq_unlock(key);
406 
407 	return 0;
408 }
409 
gpio_esp32_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)410 static int gpio_esp32_manage_callback(const struct device *dev,
411 				      struct gpio_callback *callback,
412 				      bool set)
413 {
414 	struct gpio_esp32_data *data = dev->data;
415 
416 	return gpio_manage_callback(&data->cb, callback, set);
417 }
418 
gpio_esp32_get_pending_int(const struct device * dev)419 static uint32_t gpio_esp32_get_pending_int(const struct device *dev)
420 {
421 	const struct gpio_esp32_config *const cfg = dev->config;
422 	uint32_t irq_status;
423 	uint32_t const core_id = CPU_ID();
424 
425 	if (cfg->gpio_port == 0) {
426 		gpio_ll_get_intr_status(cfg->gpio_base, core_id, &irq_status);
427 	} else {
428 		gpio_ll_get_intr_status_high(cfg->gpio_base, core_id, &irq_status);
429 	}
430 
431 	return irq_status;
432 }
433 
gpio_esp32_fire_callbacks(const struct device * dev)434 static void IRAM_ATTR gpio_esp32_fire_callbacks(const struct device *dev)
435 {
436 	const struct gpio_esp32_config *const cfg = dev->config;
437 	struct gpio_esp32_data *data = dev->data;
438 	uint32_t irq_status;
439 	uint32_t const core_id = CPU_ID();
440 
441 	if (cfg->gpio_port == 0) {
442 		gpio_ll_get_intr_status(cfg->gpio_base, core_id, &irq_status);
443 		gpio_ll_clear_intr_status(cfg->gpio_base, irq_status);
444 	} else {
445 		gpio_ll_get_intr_status_high(cfg->gpio_base, core_id, &irq_status);
446 		gpio_ll_clear_intr_status_high(cfg->gpio_base, irq_status);
447 	}
448 
449 	if (irq_status != 0) {
450 		gpio_fire_callbacks(&data->cb, dev, irq_status);
451 	}
452 }
453 
454 static void gpio_esp32_isr(void *param);
455 
gpio_esp32_init(const struct device * dev)456 static int gpio_esp32_init(const struct device *dev)
457 {
458 	struct gpio_esp32_data *data = dev->data;
459 	static bool isr_connected;
460 
461 	if (!isr_connected) {
462 		esp_intr_alloc(DT_IRQN(DT_NODELABEL(gpio0)),
463 			0,
464 			(ISR_HANDLER)gpio_esp32_isr,
465 			(void *)dev,
466 			NULL);
467 
468 		isr_connected = true;
469 	}
470 
471 	return 0;
472 }
473 
474 static const struct gpio_driver_api gpio_esp32_driver_api = {
475 	.pin_configure = gpio_esp32_config,
476 	.port_get_raw = gpio_esp32_port_get_raw,
477 	.port_set_masked_raw = gpio_esp32_port_set_masked_raw,
478 	.port_set_bits_raw = gpio_esp32_port_set_bits_raw,
479 	.port_clear_bits_raw = gpio_esp32_port_clear_bits_raw,
480 	.port_toggle_bits = gpio_esp32_port_toggle_bits,
481 	.pin_interrupt_configure = gpio_esp32_pin_interrupt_configure,
482 	.manage_callback = gpio_esp32_manage_callback,
483 	.get_pending_int = gpio_esp32_get_pending_int
484 };
485 
486 #define ESP_SOC_GPIO_INIT(_id)							\
487 	static struct gpio_esp32_data gpio_data_##_id;	\
488 	static struct gpio_esp32_config gpio_config_##_id = {			\
489 		.drv_cfg = {							\
490 			.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(_id),	\
491 		},								\
492 		.gpio_base = (gpio_dev_t *)DT_REG_ADDR(DT_NODELABEL(gpio0)),	\
493 		.gpio_dev = (gpio_dev_t *)DT_REG_ADDR(DT_NODELABEL(gpio##_id)),	\
494 		.gpio_port = _id	\
495 	};									\
496 	DEVICE_DT_DEFINE(DT_NODELABEL(gpio##_id),				\
497 			&gpio_esp32_init,					\
498 			NULL,							\
499 			&gpio_data_##_id,					\
500 			&gpio_config_##_id,					\
501 			PRE_KERNEL_1,						\
502 			CONFIG_GPIO_INIT_PRIORITY,				\
503 			&gpio_esp32_driver_api);
504 
505 DT_INST_FOREACH_STATUS_OKAY(ESP_SOC_GPIO_INIT);
506 
gpio_esp32_isr(void * param)507 static void IRAM_ATTR gpio_esp32_isr(void *param)
508 {
509 	ARG_UNUSED(param);
510 
511 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio0), okay)
512 	gpio_esp32_fire_callbacks(DEVICE_DT_INST_GET(0));
513 #endif
514 
515 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay)
516 	gpio_esp32_fire_callbacks(DEVICE_DT_INST_GET(1));
517 #endif
518 }
519