1 /*
2  * Copyright (c) 2023 Bjarki Arge Andreasen
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/gpio.h>
10 #include <zephyr/modem/chat.h>
11 #include <zephyr/modem/cmux.h>
12 #include <zephyr/modem/pipe.h>
13 #include <zephyr/modem/ppp.h>
14 #include <zephyr/modem/backend/uart.h>
15 #include <zephyr/net/ppp.h>
16 #include <zephyr/pm/device.h>
17 #include <zephyr/sys/atomic.h>
18 
19 #include <zephyr/logging/log.h>
20 LOG_MODULE_REGISTER(modem_cellular, CONFIG_MODEM_LOG_LEVEL);
21 
22 #include <string.h>
23 #include <stdlib.h>
24 
25 enum modem_cellular_state {
26 	MODEM_CELLULAR_STATE_IDLE = 0,
27 	MODEM_CELLULAR_STATE_RESET_PULSE,
28 	MODEM_CELLULAR_STATE_POWER_ON_PULSE,
29 	MODEM_CELLULAR_STATE_AWAIT_POWER_ON,
30 	MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT,
31 	MODEM_CELLULAR_STATE_CONNECT_CMUX,
32 	MODEM_CELLULAR_STATE_OPEN_DLCI1,
33 	MODEM_CELLULAR_STATE_OPEN_DLCI2,
34 	MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT,
35 	MODEM_CELLULAR_STATE_AWAIT_REGISTERED,
36 	MODEM_CELLULAR_STATE_CARRIER_ON,
37 	MODEM_CELLULAR_STATE_INIT_POWER_OFF,
38 	MODEM_CELLULAR_STATE_POWER_OFF_PULSE,
39 	MODEM_CELLULAR_STATE_AWAIT_POWER_OFF,
40 };
41 
42 enum modem_cellular_event {
43 	MODEM_CELLULAR_EVENT_RESUME = 0,
44 	MODEM_CELLULAR_EVENT_SUSPEND,
45 	MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS,
46 	MODEM_CELLULAR_EVENT_SCRIPT_FAILED,
47 	MODEM_CELLULAR_EVENT_CMUX_CONNECTED,
48 	MODEM_CELLULAR_EVENT_DLCI1_OPENED,
49 	MODEM_CELLULAR_EVENT_DLCI2_OPENED,
50 	MODEM_CELLULAR_EVENT_TIMEOUT,
51 	MODEM_CELLULAR_EVENT_REGISTERED,
52 	MODEM_CELLULAR_EVENT_DEREGISTERED,
53 	MODEM_CELLULAR_EVENT_BUS_OPENED,
54 	MODEM_CELLULAR_EVENT_BUS_CLOSED,
55 };
56 
57 struct modem_cellular_data {
58 	/* UART backend */
59 	struct modem_pipe *uart_pipe;
60 	struct modem_backend_uart uart_backend;
61 	uint8_t uart_backend_receive_buf[512];
62 	uint8_t uart_backend_transmit_buf[512];
63 
64 	/* CMUX */
65 	struct modem_cmux cmux;
66 	uint8_t cmux_receive_buf[128];
67 	uint8_t cmux_transmit_buf[256];
68 	struct modem_cmux_dlci dlci1;
69 	struct modem_cmux_dlci dlci2;
70 	struct modem_pipe *dlci1_pipe;
71 	struct modem_pipe *dlci2_pipe;
72 	uint8_t dlci1_receive_buf[128];
73 	uint8_t dlci2_receive_buf[256];
74 
75 	/* Modem chat */
76 	struct modem_chat chat;
77 	uint8_t chat_receive_buf[128];
78 	uint8_t chat_delimiter[1];
79 	uint8_t chat_filter[1];
80 	uint8_t *chat_argv[32];
81 
82 	/* Status */
83 	uint8_t imei[15];
84 	uint8_t hwinfo[64];
85 	uint8_t registration_status_gsm;
86 	uint8_t registration_status_gprs;
87 	uint8_t registration_status_lte;
88 
89 	/* PPP */
90 	struct modem_ppp *ppp;
91 
92 	enum modem_cellular_state state;
93 	const struct device *dev;
94 	struct k_work_delayable timeout_work;
95 
96 	/* Power management */
97 	struct k_sem suspended_sem;
98 
99 	/* Event dispatcher */
100 	struct k_work event_dispatch_work;
101 	uint8_t event_buf[8];
102 	struct ring_buf event_rb;
103 	struct k_mutex event_rb_lock;
104 };
105 
106 struct modem_cellular_config {
107 	const struct device *uart;
108 	const struct gpio_dt_spec power_gpio;
109 	const struct gpio_dt_spec reset_gpio;
110 	const uint16_t power_pulse_duration_ms;
111 	const uint16_t reset_pulse_duration_ms;
112 	const uint16_t startup_time_ms;
113 	const uint16_t shutdown_time_ms;
114 	const struct modem_chat_script *init_chat_script;
115 	const struct modem_chat_script *dial_chat_script;
116 };
117 
modem_cellular_state_str(enum modem_cellular_state state)118 static const char *modem_cellular_state_str(enum modem_cellular_state state)
119 {
120 	switch (state) {
121 	case MODEM_CELLULAR_STATE_IDLE:
122 		return "idle";
123 	case MODEM_CELLULAR_STATE_RESET_PULSE:
124 		return "reset pulse";
125 	case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
126 		return "power pulse";
127 	case MODEM_CELLULAR_STATE_AWAIT_POWER_ON:
128 		return "await power on";
129 	case MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT:
130 		return "run init script";
131 	case MODEM_CELLULAR_STATE_CONNECT_CMUX:
132 		return "connect cmux";
133 	case MODEM_CELLULAR_STATE_OPEN_DLCI1:
134 		return "open dlci1";
135 	case MODEM_CELLULAR_STATE_OPEN_DLCI2:
136 		return "open dlci2";
137 	case MODEM_CELLULAR_STATE_AWAIT_REGISTERED:
138 		return "await registered";
139 	case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
140 		return "run dial script";
141 	case MODEM_CELLULAR_STATE_CARRIER_ON:
142 		return "carrier on";
143 	case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
144 		return "init power off";
145 	case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
146 		return "power off pulse";
147 	case MODEM_CELLULAR_STATE_AWAIT_POWER_OFF:
148 		return "await power off";
149 	}
150 
151 	return "";
152 }
153 
modem_cellular_event_str(enum modem_cellular_event event)154 static const char *modem_cellular_event_str(enum modem_cellular_event event)
155 {
156 	switch (event) {
157 	case MODEM_CELLULAR_EVENT_RESUME:
158 		return "resume";
159 	case MODEM_CELLULAR_EVENT_SUSPEND:
160 		return "suspend";
161 	case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
162 		return "script success";
163 	case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
164 		return "script failed";
165 	case MODEM_CELLULAR_EVENT_CMUX_CONNECTED:
166 		return "cmux connected";
167 	case MODEM_CELLULAR_EVENT_DLCI1_OPENED:
168 		return "dlci1 opened";
169 	case MODEM_CELLULAR_EVENT_DLCI2_OPENED:
170 		return "dlci2 opened";
171 	case MODEM_CELLULAR_EVENT_TIMEOUT:
172 		return "timeout";
173 	case MODEM_CELLULAR_EVENT_REGISTERED:
174 		return "registered";
175 	case MODEM_CELLULAR_EVENT_DEREGISTERED:
176 		return "deregistered";
177 	case MODEM_CELLULAR_EVENT_BUS_OPENED:
178 		return "bus opened";
179 	case MODEM_CELLULAR_EVENT_BUS_CLOSED:
180 		return "bus closed";
181 	}
182 
183 	return "";
184 }
185 
modem_cellular_gpio_is_enabled(const struct gpio_dt_spec * gpio)186 static bool modem_cellular_gpio_is_enabled(const struct gpio_dt_spec *gpio)
187 {
188 	return gpio->port != NULL;
189 }
190 
191 static void modem_cellular_enter_state(struct modem_cellular_data *data,
192 				       enum modem_cellular_state state);
193 
194 static void modem_cellular_delegate_event(struct modem_cellular_data *data,
195 					  enum modem_cellular_event evt);
196 
197 static void modem_cellular_event_handler(struct modem_cellular_data *data,
198 					 enum modem_cellular_event evt);
199 
modem_cellular_bus_pipe_handler(struct modem_pipe * pipe,enum modem_pipe_event event,void * user_data)200 static void modem_cellular_bus_pipe_handler(struct modem_pipe *pipe,
201 					    enum modem_pipe_event event,
202 					    void *user_data)
203 {
204 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
205 
206 	switch (event) {
207 	case MODEM_PIPE_EVENT_OPENED:
208 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_BUS_OPENED);
209 		break;
210 
211 	case MODEM_PIPE_EVENT_CLOSED:
212 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_BUS_CLOSED);
213 		break;
214 
215 	default:
216 		break;
217 	}
218 }
219 
modem_cellular_dlci1_pipe_handler(struct modem_pipe * pipe,enum modem_pipe_event event,void * user_data)220 static void modem_cellular_dlci1_pipe_handler(struct modem_pipe *pipe,
221 					      enum modem_pipe_event event,
222 					      void *user_data)
223 {
224 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
225 
226 	switch (event) {
227 	case MODEM_PIPE_EVENT_OPENED:
228 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_DLCI1_OPENED);
229 		break;
230 
231 	default:
232 		break;
233 	}
234 }
235 
modem_cellular_dlci2_pipe_handler(struct modem_pipe * pipe,enum modem_pipe_event event,void * user_data)236 static void modem_cellular_dlci2_pipe_handler(struct modem_pipe *pipe,
237 					      enum modem_pipe_event event,
238 					      void *user_data)
239 {
240 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
241 
242 	switch (event) {
243 	case MODEM_PIPE_EVENT_OPENED:
244 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_DLCI2_OPENED);
245 		break;
246 
247 	default:
248 		break;
249 	}
250 }
251 
modem_cellular_chat_callback_handler(struct modem_chat * chat,enum modem_chat_script_result result,void * user_data)252 static void modem_cellular_chat_callback_handler(struct modem_chat *chat,
253 						 enum modem_chat_script_result result,
254 						 void *user_data)
255 {
256 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
257 
258 	if (result == MODEM_CHAT_SCRIPT_RESULT_SUCCESS) {
259 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS);
260 	} else {
261 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_SCRIPT_FAILED);
262 	}
263 }
264 
modem_cellular_chat_on_imei(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)265 static void modem_cellular_chat_on_imei(struct modem_chat *chat, char **argv, uint16_t argc,
266 					void *user_data)
267 {
268 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
269 
270 	if (argc != 2) {
271 		return;
272 	}
273 
274 	if (strlen(argv[1]) != 15) {
275 		return;
276 	}
277 
278 	for (uint8_t i = 0; i < 15; i++) {
279 		data->imei[i] = argv[1][i] - '0';
280 	}
281 }
282 
modem_cellular_chat_on_cgmm(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)283 static void modem_cellular_chat_on_cgmm(struct modem_chat *chat, char **argv, uint16_t argc,
284 					void *user_data)
285 {
286 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
287 
288 	if (argc != 2) {
289 		return;
290 	}
291 
292 	strncpy(data->hwinfo, argv[1], sizeof(data->hwinfo) - 1);
293 }
294 
modem_cellular_is_registered(struct modem_cellular_data * data)295 static bool modem_cellular_is_registered(struct modem_cellular_data *data)
296 {
297 	return (data->registration_status_gsm == 1)
298 		|| (data->registration_status_gsm == 5)
299 		|| (data->registration_status_gprs == 1)
300 		|| (data->registration_status_gprs == 5)
301 		|| (data->registration_status_lte == 1)
302 		|| (data->registration_status_lte == 5);
303 }
304 
modem_cellular_chat_on_cxreg(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)305 static void modem_cellular_chat_on_cxreg(struct modem_chat *chat, char **argv, uint16_t argc,
306 					void *user_data)
307 {
308 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
309 	uint8_t registration_status;
310 	bool is_registered;
311 
312 	is_registered = modem_cellular_is_registered(data);
313 
314 	if (argc == 2) {
315 		registration_status = atoi(argv[1]);
316 	} else if (argc == 3) {
317 		registration_status = atoi(argv[2]);
318 	} else {
319 		return;
320 	}
321 
322 	if (strcmp(argv[0], "+CREG: ") == 0) {
323 		data->registration_status_gsm = registration_status;
324 	} else if (strcmp(argv[0], "+CGREG: ") == 0) {
325 		data->registration_status_gprs = registration_status;
326 	} else {
327 		data->registration_status_lte = registration_status;
328 	}
329 
330 	if (modem_cellular_is_registered(data)) {
331 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_REGISTERED);
332 	} else {
333 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_DEREGISTERED);
334 	}
335 }
336 
337 MODEM_CHAT_MATCH_DEFINE(ok_match, "OK", "", NULL);
338 MODEM_CHAT_MATCHES_DEFINE(allow_match,
339 			  MODEM_CHAT_MATCH("OK", "", NULL),
340 			  MODEM_CHAT_MATCH("ERROR", "", NULL));
341 
342 MODEM_CHAT_MATCH_DEFINE(imei_match, "", "", modem_cellular_chat_on_imei);
343 MODEM_CHAT_MATCH_DEFINE(cgmm_match, "", "", modem_cellular_chat_on_cgmm);
344 
345 MODEM_CHAT_MATCHES_DEFINE(unsol_matches,
346 			  MODEM_CHAT_MATCH("+CREG: ", ",", modem_cellular_chat_on_cxreg),
347 			  MODEM_CHAT_MATCH("+CEREG: ", ",", modem_cellular_chat_on_cxreg),
348 			  MODEM_CHAT_MATCH("+CGREG: ", ",", modem_cellular_chat_on_cxreg));
349 
350 MODEM_CHAT_MATCHES_DEFINE(abort_matches, MODEM_CHAT_MATCH("ERROR", "", NULL));
351 
352 MODEM_CHAT_MATCHES_DEFINE(dial_abort_matches,
353 			  MODEM_CHAT_MATCH("ERROR", "", NULL),
354 			  MODEM_CHAT_MATCH("BUSY", "", NULL),
355 			  MODEM_CHAT_MATCH("NO ANSWER", "", NULL),
356 			  MODEM_CHAT_MATCH("NO CARRIER", "", NULL),
357 			  MODEM_CHAT_MATCH("NO DIALTONE", "", NULL));
358 
modem_cellular_log_state_changed(enum modem_cellular_state last_state,enum modem_cellular_state new_state)359 static void modem_cellular_log_state_changed(enum modem_cellular_state last_state,
360 					     enum modem_cellular_state new_state)
361 {
362 	LOG_INF("switch from %s to %s", modem_cellular_state_str(last_state),
363 		modem_cellular_state_str(new_state));
364 }
365 
modem_cellular_log_event(enum modem_cellular_event evt)366 static void modem_cellular_log_event(enum modem_cellular_event evt)
367 {
368 	LOG_INF("event %s", modem_cellular_event_str(evt));
369 }
370 
modem_cellular_start_timer(struct modem_cellular_data * data,k_timeout_t timeout)371 static void modem_cellular_start_timer(struct modem_cellular_data *data, k_timeout_t timeout)
372 {
373 	k_work_schedule(&data->timeout_work, timeout);
374 }
375 
modem_cellular_stop_timer(struct modem_cellular_data * data)376 static void modem_cellular_stop_timer(struct modem_cellular_data *data)
377 {
378 	k_work_cancel_delayable(&data->timeout_work);
379 }
380 
modem_cellular_timeout_handler(struct k_work * item)381 static void modem_cellular_timeout_handler(struct k_work *item)
382 {
383 	struct k_work_delayable *dwork = k_work_delayable_from_work(item);
384 	struct modem_cellular_data *data =
385 		CONTAINER_OF(dwork, struct modem_cellular_data, timeout_work);
386 
387 	modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_TIMEOUT);
388 }
389 
modem_cellular_event_dispatch_handler(struct k_work * item)390 static void modem_cellular_event_dispatch_handler(struct k_work *item)
391 {
392 	struct modem_cellular_data *data =
393 		CONTAINER_OF(item, struct modem_cellular_data, event_dispatch_work);
394 
395 	uint8_t events[sizeof(data->event_buf)];
396 	uint8_t events_cnt;
397 
398 	k_mutex_lock(&data->event_rb_lock, K_FOREVER);
399 
400 	events_cnt = (uint8_t)ring_buf_get(&data->event_rb, events, sizeof(data->event_buf));
401 
402 	k_mutex_unlock(&data->event_rb_lock);
403 
404 	for (uint8_t i = 0; i < events_cnt; i++) {
405 		modem_cellular_event_handler(data, (enum modem_cellular_event)events[i]);
406 	}
407 }
408 
modem_cellular_delegate_event(struct modem_cellular_data * data,enum modem_cellular_event evt)409 static void modem_cellular_delegate_event(struct modem_cellular_data *data,
410 					  enum modem_cellular_event evt)
411 {
412 	k_mutex_lock(&data->event_rb_lock, K_FOREVER);
413 	ring_buf_put(&data->event_rb, (uint8_t *)&evt, 1);
414 	k_mutex_unlock(&data->event_rb_lock);
415 	k_work_submit(&data->event_dispatch_work);
416 }
417 
modem_cellular_on_idle_state_enter(struct modem_cellular_data * data)418 static int modem_cellular_on_idle_state_enter(struct modem_cellular_data *data)
419 {
420 	const struct modem_cellular_config *config =
421 		(const struct modem_cellular_config *)data->dev->config;
422 
423 	if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
424 		gpio_pin_set_dt(&config->reset_gpio, 1);
425 	}
426 
427 	modem_chat_release(&data->chat);
428 	modem_ppp_release(data->ppp);
429 	modem_cmux_release(&data->cmux);
430 	modem_pipe_close_async(data->uart_pipe);
431 	k_sem_give(&data->suspended_sem);
432 	return 0;
433 }
434 
modem_cellular_idle_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)435 static void modem_cellular_idle_event_handler(struct modem_cellular_data *data,
436 					      enum modem_cellular_event evt)
437 {
438 	const struct modem_cellular_config *config =
439 		(const struct modem_cellular_config *)data->dev->config;
440 
441 	switch (evt) {
442 	case MODEM_CELLULAR_EVENT_RESUME:
443 		if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
444 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_POWER_ON_PULSE);
445 			break;
446 		}
447 
448 		if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
449 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON);
450 			break;
451 		}
452 
453 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT);
454 		break;
455 
456 	case MODEM_CELLULAR_EVENT_SUSPEND:
457 		k_sem_give(&data->suspended_sem);
458 		break;
459 
460 	default:
461 		break;
462 	}
463 }
464 
modem_cellular_on_idle_state_leave(struct modem_cellular_data * data)465 static int modem_cellular_on_idle_state_leave(struct modem_cellular_data *data)
466 {
467 	const struct modem_cellular_config *config =
468 		(const struct modem_cellular_config *)data->dev->config;
469 
470 	k_sem_take(&data->suspended_sem, K_NO_WAIT);
471 
472 	if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
473 		gpio_pin_set_dt(&config->reset_gpio, 0);
474 	}
475 
476 	return 0;
477 }
478 
modem_cellular_on_reset_pulse_state_enter(struct modem_cellular_data * data)479 static int modem_cellular_on_reset_pulse_state_enter(struct modem_cellular_data *data)
480 {
481 	const struct modem_cellular_config *config =
482 		(const struct modem_cellular_config *)data->dev->config;
483 
484 	gpio_pin_set_dt(&config->reset_gpio, 1);
485 	modem_cellular_start_timer(data, K_MSEC(config->reset_pulse_duration_ms));
486 	return 0;
487 }
488 
modem_cellular_reset_pulse_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)489 static void modem_cellular_reset_pulse_event_handler(struct modem_cellular_data *data,
490 							enum modem_cellular_event evt)
491 {
492 	switch (evt) {
493 	case MODEM_CELLULAR_EVENT_TIMEOUT:
494 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON);
495 		break;
496 
497 	case MODEM_CELLULAR_EVENT_SUSPEND:
498 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
499 		break;
500 
501 	default:
502 		break;
503 	}
504 }
505 
modem_cellular_on_reset_pulse_state_leave(struct modem_cellular_data * data)506 static int modem_cellular_on_reset_pulse_state_leave(struct modem_cellular_data *data)
507 {
508 	const struct modem_cellular_config *config =
509 		(const struct modem_cellular_config *)data->dev->config;
510 
511 	gpio_pin_set_dt(&config->reset_gpio, 0);
512 	modem_cellular_stop_timer(data);
513 	return 0;
514 }
515 
modem_cellular_on_power_on_pulse_state_enter(struct modem_cellular_data * data)516 static int modem_cellular_on_power_on_pulse_state_enter(struct modem_cellular_data *data)
517 {
518 	const struct modem_cellular_config *config =
519 		(const struct modem_cellular_config *)data->dev->config;
520 
521 	gpio_pin_set_dt(&config->power_gpio, 1);
522 	modem_cellular_start_timer(data, K_MSEC(config->power_pulse_duration_ms));
523 	return 0;
524 }
525 
modem_cellular_power_on_pulse_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)526 static void modem_cellular_power_on_pulse_event_handler(struct modem_cellular_data *data,
527 							enum modem_cellular_event evt)
528 {
529 	switch (evt) {
530 	case MODEM_CELLULAR_EVENT_TIMEOUT:
531 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON);
532 		break;
533 
534 	case MODEM_CELLULAR_EVENT_SUSPEND:
535 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
536 		break;
537 
538 	default:
539 		break;
540 	}
541 }
542 
modem_cellular_on_power_on_pulse_state_leave(struct modem_cellular_data * data)543 static int modem_cellular_on_power_on_pulse_state_leave(struct modem_cellular_data *data)
544 {
545 	const struct modem_cellular_config *config =
546 		(const struct modem_cellular_config *)data->dev->config;
547 
548 	gpio_pin_set_dt(&config->power_gpio, 0);
549 	modem_cellular_stop_timer(data);
550 	return 0;
551 }
552 
modem_cellular_on_await_power_on_state_enter(struct modem_cellular_data * data)553 static int modem_cellular_on_await_power_on_state_enter(struct modem_cellular_data *data)
554 {
555 	const struct modem_cellular_config *config =
556 		(const struct modem_cellular_config *)data->dev->config;
557 
558 	modem_cellular_start_timer(data, K_MSEC(config->startup_time_ms));
559 	return 0;
560 }
561 
modem_cellular_await_power_on_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)562 static void modem_cellular_await_power_on_event_handler(struct modem_cellular_data *data,
563 							enum modem_cellular_event evt)
564 {
565 	switch (evt) {
566 	case MODEM_CELLULAR_EVENT_TIMEOUT:
567 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT);
568 		break;
569 
570 	case MODEM_CELLULAR_EVENT_SUSPEND:
571 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
572 		break;
573 
574 	default:
575 		break;
576 	}
577 }
578 
modem_cellular_on_run_init_script_state_enter(struct modem_cellular_data * data)579 static int modem_cellular_on_run_init_script_state_enter(struct modem_cellular_data *data)
580 {
581 	modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
582 	return modem_pipe_open_async(data->uart_pipe);
583 }
584 
modem_cellular_run_init_script_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)585 static void modem_cellular_run_init_script_event_handler(struct modem_cellular_data *data,
586 							 enum modem_cellular_event evt)
587 {
588 	const struct modem_cellular_config *config =
589 		(const struct modem_cellular_config *)data->dev->config;
590 
591 	switch (evt) {
592 	case MODEM_CELLULAR_EVENT_BUS_OPENED:
593 		modem_chat_attach(&data->chat, data->uart_pipe);
594 		modem_chat_run_script_async(&data->chat, config->init_chat_script);
595 		break;
596 
597 	case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
598 		net_if_set_link_addr(modem_ppp_get_iface(data->ppp), data->imei,
599 				     ARRAY_SIZE(data->imei), NET_LINK_UNKNOWN);
600 
601 		modem_chat_release(&data->chat);
602 		modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
603 		modem_pipe_close_async(data->uart_pipe);
604 		break;
605 
606 	case MODEM_CELLULAR_EVENT_BUS_CLOSED:
607 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_CONNECT_CMUX);
608 		break;
609 
610 	case MODEM_CELLULAR_EVENT_SUSPEND:
611 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
612 		break;
613 
614 	case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
615 		if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
616 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_POWER_ON_PULSE);
617 			break;
618 		}
619 
620 		if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
621 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RESET_PULSE);
622 			break;
623 		}
624 
625 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
626 		break;
627 
628 	default:
629 		break;
630 	}
631 }
632 
modem_cellular_on_connect_cmux_state_enter(struct modem_cellular_data * data)633 static int modem_cellular_on_connect_cmux_state_enter(struct modem_cellular_data *data)
634 {
635 	/*
636 	 * Allow modem to switch bus into CMUX mode. Some modems disable UART RX while
637 	 * switching, resulting in UART RX errors as bus is no longer pulled up by modem.
638 	 */
639 	modem_cellular_start_timer(data, K_MSEC(100));
640 	return 0;
641 }
642 
modem_cellular_connect_cmux_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)643 static void modem_cellular_connect_cmux_event_handler(struct modem_cellular_data *data,
644 						      enum modem_cellular_event evt)
645 {
646 	switch (evt) {
647 	case MODEM_CELLULAR_EVENT_TIMEOUT:
648 		modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
649 		modem_pipe_open_async(data->uart_pipe);
650 		break;
651 
652 	case MODEM_CELLULAR_EVENT_BUS_OPENED:
653 		modem_cmux_attach(&data->cmux, data->uart_pipe);
654 		modem_cmux_connect_async(&data->cmux);
655 		break;
656 
657 	case MODEM_CELLULAR_EVENT_CMUX_CONNECTED:
658 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_OPEN_DLCI1);
659 		break;
660 
661 	case MODEM_CELLULAR_EVENT_SUSPEND:
662 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
663 		break;
664 
665 	default:
666 		break;
667 	}
668 }
669 
modem_cellular_on_open_dlci1_state_enter(struct modem_cellular_data * data)670 static int modem_cellular_on_open_dlci1_state_enter(struct modem_cellular_data *data)
671 {
672 	modem_pipe_attach(data->dlci1_pipe, modem_cellular_dlci1_pipe_handler, data);
673 	return modem_pipe_open_async(data->dlci1_pipe);
674 }
675 
modem_cellular_open_dlci1_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)676 static void modem_cellular_open_dlci1_event_handler(struct modem_cellular_data *data,
677 						    enum modem_cellular_event evt)
678 {
679 	switch (evt) {
680 	case MODEM_CELLULAR_EVENT_DLCI1_OPENED:
681 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_OPEN_DLCI2);
682 		break;
683 
684 	case MODEM_CELLULAR_EVENT_SUSPEND:
685 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
686 		break;
687 
688 	default:
689 		break;
690 	}
691 }
692 
modem_cellular_on_open_dlci1_state_leave(struct modem_cellular_data * data)693 static int modem_cellular_on_open_dlci1_state_leave(struct modem_cellular_data *data)
694 {
695 	modem_pipe_release(data->dlci1_pipe);
696 	return 0;
697 }
698 
modem_cellular_on_open_dlci2_state_enter(struct modem_cellular_data * data)699 static int modem_cellular_on_open_dlci2_state_enter(struct modem_cellular_data *data)
700 {
701 	modem_pipe_attach(data->dlci2_pipe, modem_cellular_dlci2_pipe_handler, data);
702 	return modem_pipe_open_async(data->dlci2_pipe);
703 }
704 
modem_cellular_open_dlci2_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)705 static void modem_cellular_open_dlci2_event_handler(struct modem_cellular_data *data,
706 						    enum modem_cellular_event evt)
707 {
708 	switch (evt) {
709 	case MODEM_CELLULAR_EVENT_DLCI2_OPENED:
710 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT);
711 		break;
712 
713 	case MODEM_CELLULAR_EVENT_SUSPEND:
714 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
715 		break;
716 
717 	default:
718 		break;
719 	}
720 }
721 
modem_cellular_on_open_dlci2_state_leave(struct modem_cellular_data * data)722 static int modem_cellular_on_open_dlci2_state_leave(struct modem_cellular_data *data)
723 {
724 	modem_pipe_release(data->dlci2_pipe);
725 	return 0;
726 }
727 
modem_cellular_on_run_dial_script_state_enter(struct modem_cellular_data * data)728 static int modem_cellular_on_run_dial_script_state_enter(struct modem_cellular_data *data)
729 {
730 	/* Allow modem time to enter command mode before running dial script */
731 	modem_cellular_start_timer(data, K_MSEC(100));
732 	return 0;
733 }
734 
modem_cellular_run_dial_script_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)735 static void modem_cellular_run_dial_script_event_handler(struct modem_cellular_data *data,
736 							 enum modem_cellular_event evt)
737 {
738 	const struct modem_cellular_config *config =
739 		(const struct modem_cellular_config *)data->dev->config;
740 
741 	switch (evt) {
742 	case MODEM_CELLULAR_EVENT_TIMEOUT:
743 		modem_chat_attach(&data->chat, data->dlci1_pipe);
744 		modem_chat_run_script_async(&data->chat, config->dial_chat_script);
745 		break;
746 
747 	case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
748 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_REGISTERED);
749 		break;
750 
751 	case MODEM_CELLULAR_EVENT_SUSPEND:
752 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
753 		break;
754 
755 	default:
756 		break;
757 	}
758 }
759 
modem_cellular_on_run_dial_script_state_leave(struct modem_cellular_data * data)760 static int modem_cellular_on_run_dial_script_state_leave(struct modem_cellular_data *data)
761 {
762 	modem_chat_release(&data->chat);
763 	return 0;
764 }
765 
modem_cellular_on_await_registered_state_enter(struct modem_cellular_data * data)766 static int modem_cellular_on_await_registered_state_enter(struct modem_cellular_data *data)
767 {
768 	if (modem_ppp_attach(data->ppp, data->dlci1_pipe) < 0) {
769 		return -EAGAIN;
770 	}
771 
772 	return modem_chat_attach(&data->chat, data->dlci2_pipe);
773 }
774 
modem_cellular_await_registered_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)775 static void modem_cellular_await_registered_event_handler(struct modem_cellular_data *data,
776 						  enum modem_cellular_event evt)
777 {
778 	switch (evt) {
779 	case MODEM_CELLULAR_EVENT_REGISTERED:
780 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_CARRIER_ON);
781 		break;
782 
783 	case MODEM_CELLULAR_EVENT_SUSPEND:
784 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
785 		break;
786 
787 	default:
788 		break;
789 	}
790 }
791 
modem_cellular_on_carrier_on_state_enter(struct modem_cellular_data * data)792 static int modem_cellular_on_carrier_on_state_enter(struct modem_cellular_data *data)
793 {
794 	net_if_carrier_on(modem_ppp_get_iface(data->ppp));
795 	return 0;
796 }
797 
modem_cellular_carrier_on_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)798 static void modem_cellular_carrier_on_event_handler(struct modem_cellular_data *data,
799 						    enum modem_cellular_event evt)
800 {
801 	switch (evt) {
802 	case MODEM_CELLULAR_EVENT_DEREGISTERED:
803 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT);
804 		break;
805 
806 	case MODEM_CELLULAR_EVENT_SUSPEND:
807 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
808 		break;
809 
810 	default:
811 		break;
812 	}
813 }
814 
modem_cellular_on_carrier_on_state_leave(struct modem_cellular_data * data)815 static int modem_cellular_on_carrier_on_state_leave(struct modem_cellular_data *data)
816 {
817 	net_if_carrier_off(modem_ppp_get_iface(data->ppp));
818 	modem_chat_release(&data->chat);
819 	modem_ppp_release(data->ppp);
820 	return 0;
821 }
822 
modem_cellular_on_init_power_off_state_enter(struct modem_cellular_data * data)823 static int modem_cellular_on_init_power_off_state_enter(struct modem_cellular_data *data)
824 {
825 	modem_pipe_close_async(data->uart_pipe);
826 	modem_cellular_start_timer(data, K_MSEC(2000));
827 	return 0;
828 }
829 
modem_cellular_init_power_off_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)830 static void modem_cellular_init_power_off_event_handler(struct modem_cellular_data *data,
831 							enum modem_cellular_event evt)
832 {
833 	const struct modem_cellular_config *config =
834 		(const struct modem_cellular_config *)data->dev->config;
835 
836 	switch (evt) {
837 	case MODEM_CELLULAR_EVENT_TIMEOUT:
838 		if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
839 			modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_POWER_OFF_PULSE);
840 			break;
841 		}
842 
843 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
844 		break;
845 
846 	default:
847 		break;
848 	}
849 }
850 
modem_cellular_on_init_power_off_state_leave(struct modem_cellular_data * data)851 static int modem_cellular_on_init_power_off_state_leave(struct modem_cellular_data *data)
852 {
853 	modem_chat_release(&data->chat);
854 	modem_ppp_release(data->ppp);
855 	return 0;
856 }
857 
modem_cellular_on_power_off_pulse_state_enter(struct modem_cellular_data * data)858 static int modem_cellular_on_power_off_pulse_state_enter(struct modem_cellular_data *data)
859 {
860 	const struct modem_cellular_config *config =
861 		(const struct modem_cellular_config *)data->dev->config;
862 
863 	gpio_pin_set_dt(&config->power_gpio, 1);
864 	modem_cellular_start_timer(data, K_MSEC(config->power_pulse_duration_ms));
865 	return 0;
866 }
867 
modem_cellular_power_off_pulse_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)868 static void modem_cellular_power_off_pulse_event_handler(struct modem_cellular_data *data,
869 							enum modem_cellular_event evt)
870 {
871 	switch (evt) {
872 	case MODEM_CELLULAR_EVENT_TIMEOUT:
873 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_OFF);
874 		break;
875 
876 	default:
877 		break;
878 	}
879 }
880 
modem_cellular_on_power_off_pulse_state_leave(struct modem_cellular_data * data)881 static int modem_cellular_on_power_off_pulse_state_leave(struct modem_cellular_data *data)
882 {
883 	const struct modem_cellular_config *config =
884 		(const struct modem_cellular_config *)data->dev->config;
885 
886 	gpio_pin_set_dt(&config->power_gpio, 0);
887 	modem_cellular_stop_timer(data);
888 	return 0;
889 }
890 
modem_cellular_on_await_power_off_state_enter(struct modem_cellular_data * data)891 static int modem_cellular_on_await_power_off_state_enter(struct modem_cellular_data *data)
892 {
893 	const struct modem_cellular_config *config =
894 		(const struct modem_cellular_config *)data->dev->config;
895 
896 	modem_cellular_start_timer(data, K_MSEC(config->shutdown_time_ms));
897 	return 0;
898 }
899 
modem_cellular_await_power_off_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)900 static void modem_cellular_await_power_off_event_handler(struct modem_cellular_data *data,
901 							enum modem_cellular_event evt)
902 {
903 	switch (evt) {
904 	case MODEM_CELLULAR_EVENT_TIMEOUT:
905 		modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
906 		break;
907 
908 	default:
909 		break;
910 	}
911 }
912 
modem_cellular_on_state_enter(struct modem_cellular_data * data)913 static int modem_cellular_on_state_enter(struct modem_cellular_data *data)
914 {
915 	int ret;
916 
917 	switch (data->state) {
918 	case MODEM_CELLULAR_STATE_IDLE:
919 		ret = modem_cellular_on_idle_state_enter(data);
920 		break;
921 
922 	case MODEM_CELLULAR_STATE_RESET_PULSE:
923 		ret = modem_cellular_on_reset_pulse_state_enter(data);
924 		break;
925 
926 	case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
927 		ret = modem_cellular_on_power_on_pulse_state_enter(data);
928 		break;
929 
930 	case MODEM_CELLULAR_STATE_AWAIT_POWER_ON:
931 		ret = modem_cellular_on_await_power_on_state_enter(data);
932 		break;
933 
934 	case MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT:
935 		ret = modem_cellular_on_run_init_script_state_enter(data);
936 		break;
937 
938 	case MODEM_CELLULAR_STATE_CONNECT_CMUX:
939 		ret = modem_cellular_on_connect_cmux_state_enter(data);
940 		break;
941 
942 	case MODEM_CELLULAR_STATE_OPEN_DLCI1:
943 		ret = modem_cellular_on_open_dlci1_state_enter(data);
944 		break;
945 
946 	case MODEM_CELLULAR_STATE_OPEN_DLCI2:
947 		ret = modem_cellular_on_open_dlci2_state_enter(data);
948 		break;
949 
950 	case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
951 		ret = modem_cellular_on_run_dial_script_state_enter(data);
952 		break;
953 
954 	case MODEM_CELLULAR_STATE_AWAIT_REGISTERED:
955 		ret = modem_cellular_on_await_registered_state_enter(data);
956 		break;
957 
958 	case MODEM_CELLULAR_STATE_CARRIER_ON:
959 		ret = modem_cellular_on_carrier_on_state_enter(data);
960 		break;
961 
962 	case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
963 		ret = modem_cellular_on_init_power_off_state_enter(data);
964 		break;
965 
966 	case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
967 		ret = modem_cellular_on_power_off_pulse_state_enter(data);
968 		break;
969 
970 	case MODEM_CELLULAR_STATE_AWAIT_POWER_OFF:
971 		ret = modem_cellular_on_await_power_off_state_enter(data);
972 		break;
973 
974 	default:
975 		ret = 0;
976 		break;
977 	}
978 
979 	return ret;
980 }
981 
modem_cellular_on_state_leave(struct modem_cellular_data * data)982 static int modem_cellular_on_state_leave(struct modem_cellular_data *data)
983 {
984 	int ret;
985 
986 	switch (data->state) {
987 	case MODEM_CELLULAR_STATE_IDLE:
988 		ret = modem_cellular_on_idle_state_leave(data);
989 		break;
990 
991 	case MODEM_CELLULAR_STATE_RESET_PULSE:
992 		ret = modem_cellular_on_reset_pulse_state_leave(data);
993 		break;
994 
995 	case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
996 		ret = modem_cellular_on_power_on_pulse_state_leave(data);
997 		break;
998 
999 	case MODEM_CELLULAR_STATE_OPEN_DLCI1:
1000 		ret = modem_cellular_on_open_dlci1_state_leave(data);
1001 		break;
1002 
1003 	case MODEM_CELLULAR_STATE_OPEN_DLCI2:
1004 		ret = modem_cellular_on_open_dlci2_state_leave(data);
1005 		break;
1006 
1007 	case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
1008 		ret = modem_cellular_on_run_dial_script_state_leave(data);
1009 		break;
1010 
1011 	case MODEM_CELLULAR_STATE_CARRIER_ON:
1012 		ret = modem_cellular_on_carrier_on_state_leave(data);
1013 		break;
1014 
1015 	case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
1016 		ret = modem_cellular_on_init_power_off_state_leave(data);
1017 		break;
1018 
1019 	case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
1020 		ret = modem_cellular_on_power_off_pulse_state_leave(data);
1021 		break;
1022 
1023 	default:
1024 		ret = 0;
1025 		break;
1026 	}
1027 
1028 	return ret;
1029 }
1030 
modem_cellular_enter_state(struct modem_cellular_data * data,enum modem_cellular_state state)1031 static void modem_cellular_enter_state(struct modem_cellular_data *data,
1032 				       enum modem_cellular_state state)
1033 {
1034 	int ret;
1035 
1036 	ret = modem_cellular_on_state_leave(data);
1037 
1038 	if (ret < 0) {
1039 		LOG_WRN("failed to leave state, error: %i", ret);
1040 
1041 		return;
1042 	}
1043 
1044 	data->state = state;
1045 	ret = modem_cellular_on_state_enter(data);
1046 
1047 	if (ret < 0) {
1048 		LOG_WRN("failed to enter state error: %i", ret);
1049 	}
1050 }
1051 
modem_cellular_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1052 static void modem_cellular_event_handler(struct modem_cellular_data *data,
1053 					 enum modem_cellular_event evt)
1054 {
1055 	enum modem_cellular_state state;
1056 
1057 	state = data->state;
1058 
1059 	modem_cellular_log_event(evt);
1060 
1061 	switch (data->state) {
1062 	case MODEM_CELLULAR_STATE_IDLE:
1063 		modem_cellular_idle_event_handler(data, evt);
1064 		break;
1065 
1066 	case MODEM_CELLULAR_STATE_RESET_PULSE:
1067 		modem_cellular_reset_pulse_event_handler(data, evt);
1068 		break;
1069 
1070 	case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
1071 		modem_cellular_power_on_pulse_event_handler(data, evt);
1072 		break;
1073 
1074 	case MODEM_CELLULAR_STATE_AWAIT_POWER_ON:
1075 		modem_cellular_await_power_on_event_handler(data, evt);
1076 		break;
1077 
1078 	case MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT:
1079 		modem_cellular_run_init_script_event_handler(data, evt);
1080 		break;
1081 
1082 	case MODEM_CELLULAR_STATE_CONNECT_CMUX:
1083 		modem_cellular_connect_cmux_event_handler(data, evt);
1084 		break;
1085 
1086 	case MODEM_CELLULAR_STATE_OPEN_DLCI1:
1087 		modem_cellular_open_dlci1_event_handler(data, evt);
1088 		break;
1089 
1090 	case MODEM_CELLULAR_STATE_OPEN_DLCI2:
1091 		modem_cellular_open_dlci2_event_handler(data, evt);
1092 		break;
1093 
1094 	case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
1095 		modem_cellular_run_dial_script_event_handler(data, evt);
1096 		break;
1097 
1098 	case MODEM_CELLULAR_STATE_AWAIT_REGISTERED:
1099 		modem_cellular_await_registered_event_handler(data, evt);
1100 		break;
1101 
1102 	case MODEM_CELLULAR_STATE_CARRIER_ON:
1103 		modem_cellular_carrier_on_event_handler(data, evt);
1104 		break;
1105 
1106 	case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
1107 		modem_cellular_init_power_off_event_handler(data, evt);
1108 		break;
1109 
1110 	case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
1111 		modem_cellular_power_off_pulse_event_handler(data, evt);
1112 		break;
1113 
1114 	case MODEM_CELLULAR_STATE_AWAIT_POWER_OFF:
1115 		modem_cellular_await_power_off_event_handler(data, evt);
1116 		break;
1117 	}
1118 
1119 	if (state != data->state) {
1120 		modem_cellular_log_state_changed(state, data->state);
1121 	}
1122 }
1123 
modem_cellular_cmux_handler(struct modem_cmux * cmux,enum modem_cmux_event event,void * user_data)1124 static void modem_cellular_cmux_handler(struct modem_cmux *cmux, enum modem_cmux_event event,
1125 					void *user_data)
1126 {
1127 	struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
1128 
1129 	switch (event) {
1130 	case MODEM_CMUX_EVENT_CONNECTED:
1131 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_CMUX_CONNECTED);
1132 		break;
1133 
1134 	default:
1135 		break;
1136 	}
1137 }
1138 
1139 #ifdef CONFIG_PM_DEVICE
modem_cellular_pm_action(const struct device * dev,enum pm_device_action action)1140 static int modem_cellular_pm_action(const struct device *dev, enum pm_device_action action)
1141 {
1142 	struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1143 	int ret;
1144 
1145 	switch (action) {
1146 	case PM_DEVICE_ACTION_RESUME:
1147 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_RESUME);
1148 		ret = 0;
1149 		break;
1150 
1151 	case PM_DEVICE_ACTION_SUSPEND:
1152 		modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_SUSPEND);
1153 		ret = k_sem_take(&data->suspended_sem, K_SECONDS(30));
1154 		break;
1155 
1156 	default:
1157 		ret = -ENOTSUP;
1158 		break;
1159 	}
1160 
1161 	return ret;
1162 }
1163 #endif /* CONFIG_PM_DEVICE */
1164 
modem_cellular_init(const struct device * dev)1165 static int modem_cellular_init(const struct device *dev)
1166 {
1167 	struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1168 	struct modem_cellular_config *config = (struct modem_cellular_config *)dev->config;
1169 
1170 	data->dev = dev;
1171 
1172 	k_work_init_delayable(&data->timeout_work, modem_cellular_timeout_handler);
1173 
1174 	k_work_init(&data->event_dispatch_work, modem_cellular_event_dispatch_handler);
1175 	ring_buf_init(&data->event_rb, sizeof(data->event_buf), data->event_buf);
1176 
1177 	k_sem_init(&data->suspended_sem, 0, 1);
1178 
1179 	if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
1180 		gpio_pin_configure_dt(&config->power_gpio, GPIO_OUTPUT_INACTIVE);
1181 	}
1182 
1183 	if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
1184 		gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE);
1185 	}
1186 
1187 	{
1188 		const struct modem_backend_uart_config uart_backend_config = {
1189 			.uart = config->uart,
1190 			.receive_buf = data->uart_backend_receive_buf,
1191 			.receive_buf_size = ARRAY_SIZE(data->uart_backend_receive_buf),
1192 			.transmit_buf = data->uart_backend_transmit_buf,
1193 			.transmit_buf_size = ARRAY_SIZE(data->uart_backend_transmit_buf),
1194 		};
1195 
1196 		data->uart_pipe = modem_backend_uart_init(&data->uart_backend,
1197 							  &uart_backend_config);
1198 	}
1199 
1200 	{
1201 		const struct modem_cmux_config cmux_config = {
1202 			.callback = modem_cellular_cmux_handler,
1203 			.user_data = data,
1204 			.receive_buf = data->cmux_receive_buf,
1205 			.receive_buf_size = ARRAY_SIZE(data->cmux_receive_buf),
1206 			.transmit_buf = data->cmux_transmit_buf,
1207 			.transmit_buf_size = ARRAY_SIZE(data->cmux_transmit_buf),
1208 		};
1209 
1210 		modem_cmux_init(&data->cmux, &cmux_config);
1211 	}
1212 
1213 	{
1214 		const struct modem_cmux_dlci_config dlci1_config = {
1215 			.dlci_address = 1,
1216 			.receive_buf = data->dlci1_receive_buf,
1217 			.receive_buf_size = ARRAY_SIZE(data->dlci1_receive_buf),
1218 		};
1219 
1220 		data->dlci1_pipe = modem_cmux_dlci_init(&data->cmux, &data->dlci1,
1221 							&dlci1_config);
1222 	}
1223 
1224 	{
1225 		const struct modem_cmux_dlci_config dlci2_config = {
1226 			.dlci_address = 2,
1227 			.receive_buf = data->dlci2_receive_buf,
1228 			.receive_buf_size = ARRAY_SIZE(data->dlci2_receive_buf),
1229 		};
1230 
1231 		data->dlci2_pipe = modem_cmux_dlci_init(&data->cmux, &data->dlci2,
1232 							&dlci2_config);
1233 	}
1234 
1235 	{
1236 		const struct modem_chat_config chat_config = {
1237 			.user_data = data,
1238 			.receive_buf = data->chat_receive_buf,
1239 			.receive_buf_size = ARRAY_SIZE(data->chat_receive_buf),
1240 			.delimiter = data->chat_delimiter,
1241 			.delimiter_size = ARRAY_SIZE(data->chat_delimiter),
1242 			.filter = data->chat_filter,
1243 			.filter_size = ARRAY_SIZE(data->chat_filter),
1244 			.argv = data->chat_argv,
1245 			.argv_size = ARRAY_SIZE(data->chat_argv),
1246 			.unsol_matches = unsol_matches,
1247 			.unsol_matches_size = ARRAY_SIZE(unsol_matches),
1248 			.process_timeout = K_MSEC(2),
1249 		};
1250 
1251 		modem_chat_init(&data->chat, &chat_config);
1252 	}
1253 
1254 #ifndef CONFIG_PM_DEVICE
1255 	modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_RESUME);
1256 #else
1257 	pm_device_init_suspended(dev);
1258 #endif /* CONFIG_PM_DEVICE */
1259 
1260 	return 0;
1261 }
1262 
1263 /*
1264  * Every modem uses two custom scripts to initialize the modem and dial out.
1265  *
1266  * The first script is named <dt driver compatible>_init_chat_script, with its
1267  * script commands named <dt driver compatible>_init_chat_script_cmds. This
1268  * script is sent to the modem after it has started up, and must configure the
1269  * modem to use CMUX.
1270  *
1271  * The second script is named <dt driver compatible>_dial_chat_script, with its
1272  * script commands named <dt driver compatible>_dial_chat_script_cmds. This
1273  * script is sent on a DLCI channel in command mode, and must request the modem
1274  * dial out and put the DLCI channel into data mode.
1275  */
1276 
1277 #if DT_HAS_COMPAT_STATUS_OKAY(quectel_bg95)
1278 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_init_chat_script_cmds,
1279 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1280 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1281 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1282 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1283 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1284 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1285 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1286 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1287 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1288 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1289 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1290 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1291 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2",
1292 							      0));
1293 
1294 MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_init_chat_script, quectel_bg95_init_chat_script_cmds,
1295 			 abort_matches, modem_cellular_chat_callback_handler, 10);
1296 
1297 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_dial_chat_script_cmds,
1298 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1299 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1300 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1301 							 ok_match),
1302 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1303 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1304 
1305 MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_dial_chat_script, quectel_bg95_dial_chat_script_cmds,
1306 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1307 #endif
1308 
1309 #if DT_HAS_COMPAT_STATUS_OKAY(zephyr_gsm_ppp)
1310 MODEM_CHAT_SCRIPT_CMDS_DEFINE(zephyr_gsm_ppp_init_chat_script_cmds,
1311 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1312 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1313 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1314 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1315 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1316 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1317 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1318 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1319 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1320 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1321 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1322 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1323 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1324 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1325 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1326 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1327 			      /* The 300ms delay after sending the AT+CMUX command is required
1328 			       * for some modems to ensure they get enough time to enter CMUX
1329 			       * mode before sending the first CMUX command. If this delay is
1330 			       * too short, modems have been observed to simply deadlock,
1331 			       * refusing to respond to any CMUX command.
1332 			       */
1333 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300));
1334 
1335 MODEM_CHAT_SCRIPT_DEFINE(zephyr_gsm_ppp_init_chat_script, zephyr_gsm_ppp_init_chat_script_cmds,
1336 			 abort_matches, modem_cellular_chat_callback_handler, 10);
1337 
1338 MODEM_CHAT_SCRIPT_CMDS_DEFINE(zephyr_gsm_ppp_dial_chat_script_cmds,
1339 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1340 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1341 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1342 							 ok_match),
1343 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1344 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1345 
1346 MODEM_CHAT_SCRIPT_DEFINE(zephyr_gsm_ppp_dial_chat_script, zephyr_gsm_ppp_dial_chat_script_cmds,
1347 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1348 #endif
1349 
1350 #if DT_HAS_COMPAT_STATUS_OKAY(simcom_sim7080)
1351 MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_init_chat_script_cmds,
1352 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1353 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1354 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1355 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1356 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1357 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1358 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1359 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1360 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1361 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1362 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1363 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1364 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1365 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1366 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1367 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1368 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300));
1369 
1370 MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_init_chat_script, simcom_sim7080_init_chat_script_cmds,
1371 			 abort_matches, modem_cellular_chat_callback_handler, 10);
1372 
1373 MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_dial_chat_script_cmds,
1374 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1375 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1376 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1377 							 ok_match),
1378 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1379 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1380 
1381 MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_dial_chat_script, simcom_sim7080_dial_chat_script_cmds,
1382 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1383 #endif
1384 
1385 #if DT_HAS_COMPAT_STATUS_OKAY(u_blox_sara_r4)
1386 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_init_chat_script_cmds,
1387 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1388 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1389 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1390 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1391 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1392 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1393 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1394 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1395 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1396 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1397 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1398 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1399 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1400 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1401 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1402 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1403 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2",
1404 							      0));
1405 
1406 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_init_chat_script, u_blox_sara_r4_init_chat_script_cmds,
1407 			 abort_matches, modem_cellular_chat_callback_handler, 10);
1408 
1409 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_dial_chat_script_cmds,
1410 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1411 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1412 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1413 							 ok_match),
1414 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1415 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1416 
1417 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_dial_chat_script, u_blox_sara_r4_dial_chat_script_cmds,
1418 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1419 #endif
1420 
1421 #if DT_HAS_COMPAT_STATUS_OKAY(swir_hl7800)
1422 MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_init_chat_script_cmds,
1423 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1424 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1425 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1426 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1427 			      MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1428 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1429 			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0", allow_match),
1430 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1431 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1432 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1433 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1434 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1435 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1436 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1437 			      MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1438 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1439 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2",
1440 							      0));
1441 
1442 MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_init_chat_script, swir_hl7800_init_chat_script_cmds,
1443 			 abort_matches, modem_cellular_chat_callback_handler, 10);
1444 
1445 MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_dial_chat_script_cmds,
1446 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1447 							 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1448 							 ok_match),
1449 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+KCNXCFG=1,\"GPRS\",\""
1450 							 CONFIG_MODEM_CELLULAR_APN
1451 							 "\",,,\"IPV4\"",
1452 							 ok_match),
1453 			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1454 			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0));
1455 
1456 MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_dial_chat_script, swir_hl7800_dial_chat_script_cmds,
1457 			 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1458 #endif
1459 
1460 #define MODEM_CELLULAR_INST_NAME(name, inst) \
1461 	_CONCAT(_CONCAT(_CONCAT(name, _), DT_DRV_COMPAT), inst)
1462 
1463 #define MODEM_CELLULAR_DEVICE(inst)								\
1464 	MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64);		\
1465 												\
1466 	static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = {		\
1467 		.chat_delimiter = {'\r'},							\
1468 		.chat_filter = {'\n'},								\
1469 		.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst),					\
1470 	};											\
1471 												\
1472 	static struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = {		\
1473 		.uart = DEVICE_DT_GET(DT_INST_BUS(inst)),					\
1474 		.power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}),		\
1475 		.reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}),		\
1476 		.power_pulse_duration_ms = 1500,						\
1477 		.reset_pulse_duration_ms = 100,							\
1478 		.startup_time_ms = 10000,							\
1479 		.shutdown_time_ms = 5000,							\
1480 		.init_chat_script = &_CONCAT(DT_DRV_COMPAT, _init_chat_script),			\
1481 		.dial_chat_script = &_CONCAT(DT_DRV_COMPAT, _dial_chat_script),			\
1482 	};											\
1483 												\
1484 	PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action);				\
1485 												\
1486 	DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst),		\
1487 			      &MODEM_CELLULAR_INST_NAME(data, inst),				\
1488 			      &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, NULL);
1489 
1490 #define DT_DRV_COMPAT quectel_bg95
1491 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE)
1492 #undef DT_DRV_COMPAT
1493 
1494 #define DT_DRV_COMPAT zephyr_gsm_ppp
1495 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE)
1496 #undef DT_DRV_COMPAT
1497 
1498 #define DT_DRV_COMPAT simcom_sim7080
1499 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE)
1500 #undef DT_DRV_COMPAT
1501 
1502 #define DT_DRV_COMPAT u_blox_sara_r4
1503 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE)
1504 #undef DT_DRV_COMPAT
1505 
1506 #define DT_DRV_COMPAT swir_hl7800
1507 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE)
1508 #undef DT_DRV_COMPAT
1509