1 /*
2  * Copyright (c) 2021, Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #define DT_DRV_COMPAT nordic_nrf_gpio
7 
8 #include <nrfx_gpiote.h>
9 #include <string.h>
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h>
12 #include <zephyr/irq.h>
13 
14 #include <zephyr/drivers/gpio/gpio_utils.h>
15 
16 struct gpio_nrfx_data {
17 	/* gpio_driver_data needs to be first */
18 	struct gpio_driver_data common;
19 	sys_slist_t callbacks;
20 };
21 
22 struct gpio_nrfx_cfg {
23 	/* gpio_driver_config needs to be first */
24 	struct gpio_driver_config common;
25 	NRF_GPIO_Type *port;
26 	uint32_t edge_sense;
27 	uint8_t port_num;
28 };
29 
get_port_data(const struct device * port)30 static inline struct gpio_nrfx_data *get_port_data(const struct device *port)
31 {
32 	return port->data;
33 }
34 
get_port_cfg(const struct device * port)35 static inline const struct gpio_nrfx_cfg *get_port_cfg(const struct device *port)
36 {
37 	return port->config;
38 }
39 
get_drive(gpio_flags_t flags,nrf_gpio_pin_drive_t * drive)40 static int get_drive(gpio_flags_t flags, nrf_gpio_pin_drive_t *drive)
41 {
42 	switch (flags & (NRF_GPIO_DRIVE_MSK | GPIO_OPEN_DRAIN)) {
43 	case NRF_GPIO_DRIVE_S0S1:
44 		*drive = NRF_GPIO_PIN_S0S1;
45 		break;
46 	case NRF_GPIO_DRIVE_S0H1:
47 		*drive = NRF_GPIO_PIN_S0H1;
48 		break;
49 	case NRF_GPIO_DRIVE_H0S1:
50 		*drive = NRF_GPIO_PIN_H0S1;
51 		break;
52 	case NRF_GPIO_DRIVE_H0H1:
53 		*drive = NRF_GPIO_PIN_H0H1;
54 		break;
55 	case NRF_GPIO_DRIVE_S0 | GPIO_OPEN_DRAIN:
56 		*drive = NRF_GPIO_PIN_S0D1;
57 		break;
58 	case NRF_GPIO_DRIVE_H0 | GPIO_OPEN_DRAIN:
59 		*drive = NRF_GPIO_PIN_H0D1;
60 		break;
61 	case NRF_GPIO_DRIVE_S1 | GPIO_OPEN_SOURCE:
62 		*drive = NRF_GPIO_PIN_D0S1;
63 		break;
64 	case NRF_GPIO_DRIVE_H1 | GPIO_OPEN_SOURCE:
65 		*drive = NRF_GPIO_PIN_D0H1;
66 		break;
67 	default:
68 		return -EINVAL;
69 	}
70 
71 	return 0;
72 }
73 
get_pull(gpio_flags_t flags)74 static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags)
75 {
76 	if (flags & GPIO_PULL_UP) {
77 		return NRF_GPIO_PIN_PULLUP;
78 	} else if (flags & GPIO_PULL_DOWN) {
79 		return NRF_GPIO_PIN_PULLDOWN;
80 	}
81 
82 	return NRF_GPIO_PIN_NOPULL;
83 }
84 
gpio_nrfx_pin_configure(const struct device * port,gpio_pin_t pin,gpio_flags_t flags)85 static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
86 				   gpio_flags_t flags)
87 {
88 	nrfx_err_t err = NRFX_SUCCESS;
89 	uint8_t ch;
90 	bool free_ch = false;
91 	const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
92 	nrfx_gpiote_pin_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin);
93 
94 	/* Get the GPIOTE channel associated with this pin, if any. It needs
95 	 * to be freed when the pin is reconfigured or disconnected.
96 	 */
97 	if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) {
98 		err = nrfx_gpiote_channel_get(abs_pin, &ch);
99 		free_ch = (err == NRFX_SUCCESS);
100 	}
101 
102 	if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == GPIO_DISCONNECTED) {
103 		/* Ignore the error code. The pin may not have been used. */
104 		(void)nrfx_gpiote_pin_uninit(abs_pin);
105 
106 		if (free_ch) {
107 			err = nrfx_gpiote_channel_free(ch);
108 			__ASSERT_NO_MSG(err == NRFX_SUCCESS);
109 		}
110 
111 		return 0;
112 	}
113 
114 	if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) {
115 		nrfx_gpiote_trigger_config_t trigger_config = {
116 			.trigger = NRFX_GPIOTE_TRIGGER_NONE
117 		};
118 
119 		/* Remove previously configured trigger when pin is reconfigured. */
120 		err = nrfx_gpiote_input_configure(abs_pin, NULL, &trigger_config, NULL);
121 		if (err != NRFX_SUCCESS) {
122 			return -EINVAL;
123 		}
124 
125 		if (free_ch) {
126 			err = nrfx_gpiote_channel_free(ch);
127 			__ASSERT_NO_MSG(err == NRFX_SUCCESS);
128 		}
129 	}
130 
131 	if (flags & GPIO_OUTPUT) {
132 		nrf_gpio_pin_drive_t drive;
133 		int rv = get_drive(flags, &drive);
134 
135 		if (rv != 0) {
136 			return rv;
137 		}
138 
139 		nrfx_gpiote_output_config_t output_config = {
140 			.drive = drive,
141 			.input_connect = (flags & GPIO_INPUT) ?
142 				NRF_GPIO_PIN_INPUT_CONNECT :
143 				NRF_GPIO_PIN_INPUT_DISCONNECT,
144 			.pull = get_pull(flags)
145 		};
146 
147 
148 		if (flags & GPIO_OUTPUT_INIT_HIGH) {
149 			nrf_gpio_port_out_set(cfg->port, BIT(pin));
150 		} else if (flags & GPIO_OUTPUT_INIT_LOW) {
151 			nrf_gpio_port_out_clear(cfg->port, BIT(pin));
152 		}
153 
154 		err = nrfx_gpiote_output_configure(abs_pin, &output_config, NULL);
155 		return (err != NRFX_SUCCESS) ? -EINVAL : 0;
156 	}
157 
158 	nrfx_gpiote_input_config_t input_config = {
159 		.pull = get_pull(flags)
160 	};
161 
162 	err = nrfx_gpiote_input_configure(abs_pin, &input_config, NULL, NULL);
163 
164 	return (err != NRFX_SUCCESS) ? -EINVAL : 0;
165 }
166 
gpio_nrfx_port_get_raw(const struct device * port,gpio_port_value_t * value)167 static int gpio_nrfx_port_get_raw(const struct device *port,
168 				  gpio_port_value_t *value)
169 {
170 	NRF_GPIO_Type *reg = get_port_cfg(port)->port;
171 
172 	*value = nrf_gpio_port_in_read(reg);
173 
174 	return 0;
175 }
176 
gpio_nrfx_port_set_masked_raw(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t value)177 static int gpio_nrfx_port_set_masked_raw(const struct device *port,
178 					 gpio_port_pins_t mask,
179 					 gpio_port_value_t value)
180 {
181 	NRF_GPIO_Type *reg = get_port_cfg(port)->port;
182 
183 	const uint32_t set_mask = value & mask;
184 	const uint32_t clear_mask = (~set_mask) & mask;
185 
186 	nrf_gpio_port_out_set(reg, set_mask);
187 	nrf_gpio_port_out_clear(reg, clear_mask);
188 
189 	return 0;
190 }
191 
gpio_nrfx_port_set_bits_raw(const struct device * port,gpio_port_pins_t mask)192 static int gpio_nrfx_port_set_bits_raw(const struct device *port,
193 				       gpio_port_pins_t mask)
194 {
195 	NRF_GPIO_Type *reg = get_port_cfg(port)->port;
196 
197 	nrf_gpio_port_out_set(reg, mask);
198 
199 	return 0;
200 }
201 
gpio_nrfx_port_clear_bits_raw(const struct device * port,gpio_port_pins_t mask)202 static int gpio_nrfx_port_clear_bits_raw(const struct device *port,
203 					 gpio_port_pins_t mask)
204 {
205 	NRF_GPIO_Type *reg = get_port_cfg(port)->port;
206 
207 	nrf_gpio_port_out_clear(reg, mask);
208 
209 	return 0;
210 }
211 
gpio_nrfx_port_toggle_bits(const struct device * port,gpio_port_pins_t mask)212 static int gpio_nrfx_port_toggle_bits(const struct device *port,
213 				      gpio_port_pins_t mask)
214 {
215 	NRF_GPIO_Type *reg = get_port_cfg(port)->port;
216 	const uint32_t value = nrf_gpio_port_out_read(reg) ^ mask;
217 	const uint32_t set_mask = value & mask;
218 	const uint32_t clear_mask = (~value) & mask;
219 
220 	nrf_gpio_port_out_set(reg, set_mask);
221 	nrf_gpio_port_out_clear(reg, clear_mask);
222 
223 	return 0;
224 }
225 
226 #ifdef CONFIG_GPIO_NRFX_INTERRUPT
get_trigger(enum gpio_int_mode mode,enum gpio_int_trig trig)227 static nrfx_gpiote_trigger_t get_trigger(enum gpio_int_mode mode,
228 					 enum gpio_int_trig trig)
229 {
230 	if (mode == GPIO_INT_MODE_LEVEL) {
231 		return trig == GPIO_INT_TRIG_LOW ? NRFX_GPIOTE_TRIGGER_LOW :
232 						   NRFX_GPIOTE_TRIGGER_HIGH;
233 	}
234 
235 	return trig == GPIO_INT_TRIG_BOTH ? NRFX_GPIOTE_TRIGGER_TOGGLE :
236 	       trig == GPIO_INT_TRIG_LOW  ? NRFX_GPIOTE_TRIGGER_HITOLO :
237 					    NRFX_GPIOTE_TRIGGER_LOTOHI;
238 }
239 
gpio_nrfx_pin_interrupt_configure(const struct device * port,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)240 static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
241 					     gpio_pin_t pin,
242 					     enum gpio_int_mode mode,
243 					     enum gpio_int_trig trig)
244 {
245 	uint32_t abs_pin = NRF_GPIO_PIN_MAP(get_port_cfg(port)->port_num, pin);
246 	nrfx_err_t err;
247 	uint8_t ch;
248 
249 	if (mode == GPIO_INT_MODE_DISABLED) {
250 		nrfx_gpiote_trigger_disable(abs_pin);
251 
252 		return 0;
253 	}
254 
255 	nrfx_gpiote_trigger_config_t trigger_config = {
256 		.trigger = get_trigger(mode, trig),
257 	};
258 
259 	/* If edge mode is to be used and pin is not configured to use sense for
260 	 * edge use IN event.
261 	 */
262 	if (!(BIT(pin) & get_port_cfg(port)->edge_sense) &&
263 	    (mode == GPIO_INT_MODE_EDGE) &&
264 	    (nrf_gpio_pin_dir_get(abs_pin) == NRF_GPIO_PIN_DIR_INPUT)) {
265 		err = nrfx_gpiote_channel_get(abs_pin, &ch);
266 		if (err == NRFX_ERROR_INVALID_PARAM) {
267 			err = nrfx_gpiote_channel_alloc(&ch);
268 			if (err != NRFX_SUCCESS) {
269 				return -ENOMEM;
270 			}
271 		}
272 
273 		trigger_config.p_in_channel = &ch;
274 	}
275 
276 	err = nrfx_gpiote_input_configure(abs_pin, NULL, &trigger_config, NULL);
277 	if (err != NRFX_SUCCESS) {
278 		return -EINVAL;
279 	}
280 
281 	nrfx_gpiote_trigger_enable(abs_pin, true);
282 
283 	return 0;
284 }
285 
gpio_nrfx_manage_callback(const struct device * port,struct gpio_callback * callback,bool set)286 static int gpio_nrfx_manage_callback(const struct device *port,
287 				     struct gpio_callback *callback,
288 				     bool set)
289 {
290 	return gpio_manage_callback(&get_port_data(port)->callbacks,
291 				     callback, set);
292 }
293 #endif /* CONFIG_GPIO_NRFX_INTERRUPT */
294 
295 #ifdef CONFIG_GPIO_GET_DIRECTION
gpio_nrfx_port_get_direction(const struct device * port,gpio_port_pins_t map,gpio_port_pins_t * inputs,gpio_port_pins_t * outputs)296 static int gpio_nrfx_port_get_direction(const struct device *port,
297 					gpio_port_pins_t map,
298 					gpio_port_pins_t *inputs,
299 					gpio_port_pins_t *outputs)
300 {
301 	const struct gpio_nrfx_cfg *cfg = get_port_cfg(port);
302 	NRF_GPIO_Type *reg = cfg->port;
303 
304 	map &= cfg->common.port_pin_mask;
305 
306 	if (outputs != NULL) {
307 		*outputs = map & nrf_gpio_port_dir_read(cfg->port);
308 	}
309 
310 	if (inputs != NULL) {
311 		*inputs = 0;
312 		while (map) {
313 			uint32_t pin = NRF_CTZ(map);
314 			uint32_t pin_cnf = reg->PIN_CNF[pin];
315 
316 			/* Check if the pin has its input buffer connected. */
317 			if (((pin_cnf & GPIO_PIN_CNF_INPUT_Msk) >>
318 			     GPIO_PIN_CNF_INPUT_Pos) ==
319 			    GPIO_PIN_CNF_INPUT_Connect) {
320 				*inputs |= BIT(pin);
321 			}
322 
323 			map &= ~BIT(pin);
324 		}
325 	}
326 
327 	return 0;
328 }
329 #endif /* CONFIG_GPIO_GET_DIRECTION */
330 
331 #ifdef CONFIG_GPIO_NRFX_INTERRUPT
332 /* Get port device from port id. */
get_dev(uint32_t port_id)333 static const struct device *get_dev(uint32_t port_id)
334 {
335 	const struct device *dev = NULL;
336 
337 	#define GPIO_NRF_GET_DEV(i) \
338 		else if (DT_INST_PROP(i, port) == port_id) { \
339 			dev = DEVICE_DT_INST_GET(i); \
340 		}
341 
342 	if (0) {
343 	} /* Followed by else if from FOREACH macro. Done to avoid return statement in macro.  */
344 	DT_INST_FOREACH_STATUS_OKAY(GPIO_NRF_GET_DEV)
345 	#undef GPIO_NRF_GET_DEV
346 
347 	return dev;
348 }
349 
nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin,nrfx_gpiote_trigger_t trigger,void * context)350 static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin,
351 			      nrfx_gpiote_trigger_t trigger,
352 			      void *context)
353 {
354 	uint32_t pin = abs_pin;
355 	uint32_t port_id = nrf_gpio_pin_port_number_extract(&pin);
356 	const struct device *port = get_dev(port_id);
357 
358 	/* If given port is handled directly by nrfx driver it might not be enabled in DT. */
359 	if (port == NULL) {
360 		return;
361 	}
362 
363 	struct gpio_nrfx_data *data = get_port_data(port);
364 	sys_slist_t *list = &data->callbacks;
365 
366 	gpio_fire_callbacks(list, port, BIT(pin));
367 }
368 #endif /* CONFIG_GPIO_NRFX_INTERRUPT */
369 
370 #define GPIOTE_NODE DT_INST(0, nordic_nrf_gpiote)
371 
gpio_nrfx_init(const struct device * port)372 static int gpio_nrfx_init(const struct device *port)
373 {
374 	nrfx_err_t err;
375 
376 	if (nrfx_gpiote_is_init()) {
377 		return 0;
378 	}
379 
380 	err = nrfx_gpiote_init(0/*not used*/);
381 	if (err != NRFX_SUCCESS) {
382 		return -EIO;
383 	}
384 
385 #ifdef CONFIG_GPIO_NRFX_INTERRUPT
386 	nrfx_gpiote_global_callback_set(nrfx_gpio_handler, NULL);
387 
388 	IRQ_CONNECT(DT_IRQN(GPIOTE_NODE), DT_IRQ(GPIOTE_NODE, priority),
389 		    nrfx_isr, nrfx_gpiote_irq_handler, 0);
390 #endif /* CONFIG_GPIO_NRFX_INTERRUPT */
391 
392 	return 0;
393 }
394 
395 static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = {
396 	.pin_configure = gpio_nrfx_pin_configure,
397 	.port_get_raw = gpio_nrfx_port_get_raw,
398 	.port_set_masked_raw = gpio_nrfx_port_set_masked_raw,
399 	.port_set_bits_raw = gpio_nrfx_port_set_bits_raw,
400 	.port_clear_bits_raw = gpio_nrfx_port_clear_bits_raw,
401 	.port_toggle_bits = gpio_nrfx_port_toggle_bits,
402 #ifdef CONFIG_GPIO_NRFX_INTERRUPT
403 	.pin_interrupt_configure = gpio_nrfx_pin_interrupt_configure,
404 	.manage_callback = gpio_nrfx_manage_callback,
405 #endif
406 #ifdef CONFIG_GPIO_GET_DIRECTION
407 	.port_get_direction = gpio_nrfx_port_get_direction,
408 #endif
409 };
410 
411 /* Device instantiation is done with node labels because 'port_num' is
412  * the peripheral number by SoC numbering. We therefore cannot use
413  * DT_INST APIs here without wider changes.
414  */
415 
416 #define GPIO_NRF_DEVICE(id)						\
417 	static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = {	\
418 		.common = {						\
419 			.port_pin_mask =				\
420 			GPIO_PORT_PIN_MASK_FROM_DT_INST(id),		\
421 		},							\
422 		.port = _CONCAT(NRF_P, DT_INST_PROP(id, port)),		\
423 		.port_num = DT_INST_PROP(id, port),			\
424 		.edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0)	\
425 	};								\
426 									\
427 	static struct gpio_nrfx_data gpio_nrfx_p##id##_data;		\
428 									\
429 	DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init,			\
430 			 NULL,						\
431 			 &gpio_nrfx_p##id##_data,			\
432 			 &gpio_nrfx_p##id##_cfg,			\
433 			 PRE_KERNEL_1,					\
434 			 CONFIG_GPIO_INIT_PRIORITY,			\
435 			 &gpio_nrfx_drv_api_funcs);
436 
437 DT_INST_FOREACH_STATUS_OKAY(GPIO_NRF_DEVICE)
438