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/drivers/cellular.h>
11 #include <zephyr/modem/chat.h>
12 #include <zephyr/modem/cmux.h>
13 #include <zephyr/modem/pipe.h>
14 #include <zephyr/modem/pipelink.h>
15 #include <zephyr/modem/ppp.h>
16 #include <zephyr/modem/backend/uart.h>
17 #include <zephyr/net/ppp.h>
18 #include <zephyr/pm/device.h>
19 #include <zephyr/sys/atomic.h>
20
21 #include <zephyr/logging/log.h>
22 LOG_MODULE_REGISTER(modem_cellular, CONFIG_MODEM_LOG_LEVEL);
23
24 #include <string.h>
25 #include <stdlib.h>
26
27 #define MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT \
28 K_MSEC(CONFIG_MODEM_CELLULAR_PERIODIC_SCRIPT_MS)
29
30 #define MODEM_CELLULAR_DATA_IMEI_LEN (16)
31 #define MODEM_CELLULAR_DATA_MODEL_ID_LEN (65)
32 #define MODEM_CELLULAR_DATA_IMSI_LEN (23)
33 #define MODEM_CELLULAR_DATA_ICCID_LEN (22)
34 #define MODEM_CELLULAR_DATA_MANUFACTURER_LEN (65)
35 #define MODEM_CELLULAR_DATA_FW_VERSION_LEN (65)
36
37 #define MODEM_CELLULAR_RESERVED_DLCIS (2)
38
39 /* Magic constants */
40 #define CSQ_RSSI_UNKNOWN (99)
41 #define CESQ_RSRP_UNKNOWN (255)
42 #define CESQ_RSRQ_UNKNOWN (255)
43
44 /* Magic numbers to units conversions */
45 #define CSQ_RSSI_TO_DB(v) (-113 + (2 * (rssi)))
46 #define CESQ_RSRP_TO_DB(v) (-140 + (v))
47 #define CESQ_RSRQ_TO_DB(v) (-20 + ((v) / 2))
48
49 enum modem_cellular_state {
50 MODEM_CELLULAR_STATE_IDLE = 0,
51 MODEM_CELLULAR_STATE_RESET_PULSE,
52 MODEM_CELLULAR_STATE_POWER_ON_PULSE,
53 MODEM_CELLULAR_STATE_AWAIT_POWER_ON,
54 MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT,
55 MODEM_CELLULAR_STATE_CONNECT_CMUX,
56 MODEM_CELLULAR_STATE_OPEN_DLCI1,
57 MODEM_CELLULAR_STATE_OPEN_DLCI2,
58 MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT,
59 MODEM_CELLULAR_STATE_AWAIT_REGISTERED,
60 MODEM_CELLULAR_STATE_CARRIER_ON,
61 MODEM_CELLULAR_STATE_INIT_POWER_OFF,
62 MODEM_CELLULAR_STATE_POWER_OFF_PULSE,
63 MODEM_CELLULAR_STATE_AWAIT_POWER_OFF,
64 };
65
66 enum modem_cellular_event {
67 MODEM_CELLULAR_EVENT_RESUME = 0,
68 MODEM_CELLULAR_EVENT_SUSPEND,
69 MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS,
70 MODEM_CELLULAR_EVENT_SCRIPT_FAILED,
71 MODEM_CELLULAR_EVENT_CMUX_CONNECTED,
72 MODEM_CELLULAR_EVENT_DLCI1_OPENED,
73 MODEM_CELLULAR_EVENT_DLCI2_OPENED,
74 MODEM_CELLULAR_EVENT_TIMEOUT,
75 MODEM_CELLULAR_EVENT_REGISTERED,
76 MODEM_CELLULAR_EVENT_DEREGISTERED,
77 MODEM_CELLULAR_EVENT_BUS_OPENED,
78 MODEM_CELLULAR_EVENT_BUS_CLOSED,
79 };
80
81 struct modem_cellular_data {
82 /* UART backend */
83 struct modem_pipe *uart_pipe;
84 struct modem_backend_uart uart_backend;
85 uint8_t uart_backend_receive_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES];
86 uint8_t uart_backend_transmit_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES];
87
88 /* CMUX */
89 struct modem_cmux cmux;
90 uint8_t cmux_receive_buf[CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE];
91 uint8_t cmux_transmit_buf[2 * CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE];
92
93 struct modem_cmux_dlci dlci1;
94 struct modem_cmux_dlci dlci2;
95 struct modem_pipe *dlci1_pipe;
96 struct modem_pipe *dlci2_pipe;
97 uint8_t dlci1_receive_buf[CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE];
98 /* DLCI 2 is only used for chat scripts. */
99 uint8_t dlci2_receive_buf[CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZES];
100
101 /* Modem chat */
102 struct modem_chat chat;
103 uint8_t chat_receive_buf[CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZES];
104 uint8_t *chat_delimiter;
105 uint8_t *chat_filter;
106 uint8_t *chat_argv[32];
107
108 /* Status */
109 enum cellular_registration_status registration_status_gsm;
110 enum cellular_registration_status registration_status_gprs;
111 enum cellular_registration_status registration_status_lte;
112 uint8_t rssi;
113 uint8_t rsrp;
114 uint8_t rsrq;
115 uint8_t imei[MODEM_CELLULAR_DATA_IMEI_LEN];
116 uint8_t model_id[MODEM_CELLULAR_DATA_MODEL_ID_LEN];
117 uint8_t imsi[MODEM_CELLULAR_DATA_IMSI_LEN];
118 uint8_t iccid[MODEM_CELLULAR_DATA_ICCID_LEN];
119 uint8_t manufacturer[MODEM_CELLULAR_DATA_MANUFACTURER_LEN];
120 uint8_t fw_version[MODEM_CELLULAR_DATA_FW_VERSION_LEN];
121
122 /* PPP */
123 struct modem_ppp *ppp;
124
125 enum modem_cellular_state state;
126 const struct device *dev;
127 struct k_work_delayable timeout_work;
128
129 /* Power management */
130 struct k_sem suspended_sem;
131
132 /* Event dispatcher */
133 struct k_work event_dispatch_work;
134 uint8_t event_buf[8];
135 struct ring_buf event_rb;
136 struct k_mutex event_rb_lock;
137 };
138
139 struct modem_cellular_user_pipe {
140 struct modem_cmux_dlci dlci;
141 uint8_t dlci_address;
142 uint8_t *dlci_receive_buf;
143 uint16_t dlci_receive_buf_size;
144 struct modem_pipe *pipe;
145 struct modem_pipelink *pipelink;
146 };
147
148 struct modem_cellular_config {
149 const struct device *uart;
150 struct gpio_dt_spec power_gpio;
151 struct gpio_dt_spec reset_gpio;
152 uint16_t power_pulse_duration_ms;
153 uint16_t reset_pulse_duration_ms;
154 uint16_t startup_time_ms;
155 uint16_t shutdown_time_ms;
156 bool autostarts;
157 const struct modem_chat_script *init_chat_script;
158 const struct modem_chat_script *dial_chat_script;
159 const struct modem_chat_script *periodic_chat_script;
160 struct modem_cellular_user_pipe *user_pipes;
161 uint8_t user_pipes_size;
162 };
163
modem_cellular_state_str(enum modem_cellular_state state)164 static const char *modem_cellular_state_str(enum modem_cellular_state state)
165 {
166 switch (state) {
167 case MODEM_CELLULAR_STATE_IDLE:
168 return "idle";
169 case MODEM_CELLULAR_STATE_RESET_PULSE:
170 return "reset pulse";
171 case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
172 return "power pulse";
173 case MODEM_CELLULAR_STATE_AWAIT_POWER_ON:
174 return "await power on";
175 case MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT:
176 return "run init script";
177 case MODEM_CELLULAR_STATE_CONNECT_CMUX:
178 return "connect cmux";
179 case MODEM_CELLULAR_STATE_OPEN_DLCI1:
180 return "open dlci1";
181 case MODEM_CELLULAR_STATE_OPEN_DLCI2:
182 return "open dlci2";
183 case MODEM_CELLULAR_STATE_AWAIT_REGISTERED:
184 return "await registered";
185 case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
186 return "run dial script";
187 case MODEM_CELLULAR_STATE_CARRIER_ON:
188 return "carrier on";
189 case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
190 return "init power off";
191 case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
192 return "power off pulse";
193 case MODEM_CELLULAR_STATE_AWAIT_POWER_OFF:
194 return "await power off";
195 }
196
197 return "";
198 }
199
modem_cellular_event_str(enum modem_cellular_event event)200 static const char *modem_cellular_event_str(enum modem_cellular_event event)
201 {
202 switch (event) {
203 case MODEM_CELLULAR_EVENT_RESUME:
204 return "resume";
205 case MODEM_CELLULAR_EVENT_SUSPEND:
206 return "suspend";
207 case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
208 return "script success";
209 case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
210 return "script failed";
211 case MODEM_CELLULAR_EVENT_CMUX_CONNECTED:
212 return "cmux connected";
213 case MODEM_CELLULAR_EVENT_DLCI1_OPENED:
214 return "dlci1 opened";
215 case MODEM_CELLULAR_EVENT_DLCI2_OPENED:
216 return "dlci2 opened";
217 case MODEM_CELLULAR_EVENT_TIMEOUT:
218 return "timeout";
219 case MODEM_CELLULAR_EVENT_REGISTERED:
220 return "registered";
221 case MODEM_CELLULAR_EVENT_DEREGISTERED:
222 return "deregistered";
223 case MODEM_CELLULAR_EVENT_BUS_OPENED:
224 return "bus opened";
225 case MODEM_CELLULAR_EVENT_BUS_CLOSED:
226 return "bus closed";
227 }
228
229 return "";
230 }
231
modem_cellular_gpio_is_enabled(const struct gpio_dt_spec * gpio)232 static bool modem_cellular_gpio_is_enabled(const struct gpio_dt_spec *gpio)
233 {
234 return gpio->port != NULL;
235 }
236
modem_cellular_notify_user_pipes_connected(struct modem_cellular_data * data)237 static void modem_cellular_notify_user_pipes_connected(struct modem_cellular_data *data)
238 {
239 const struct modem_cellular_config *config =
240 (const struct modem_cellular_config *)data->dev->config;
241 struct modem_cellular_user_pipe *user_pipe;
242 struct modem_pipelink *pipelink;
243
244 for (uint8_t i = 0; i < config->user_pipes_size; i++) {
245 user_pipe = &config->user_pipes[i];
246 pipelink = user_pipe->pipelink;
247 modem_pipelink_notify_connected(pipelink);
248 }
249 }
250
modem_cellular_notify_user_pipes_disconnected(struct modem_cellular_data * data)251 static void modem_cellular_notify_user_pipes_disconnected(struct modem_cellular_data *data)
252 {
253 const struct modem_cellular_config *config =
254 (const struct modem_cellular_config *)data->dev->config;
255 struct modem_cellular_user_pipe *user_pipe;
256 struct modem_pipelink *pipelink;
257
258 for (uint8_t i = 0; i < config->user_pipes_size; i++) {
259 user_pipe = &config->user_pipes[i];
260 pipelink = user_pipe->pipelink;
261 modem_pipelink_notify_disconnected(pipelink);
262 }
263 }
264
265 static void modem_cellular_enter_state(struct modem_cellular_data *data,
266 enum modem_cellular_state state);
267
268 static void modem_cellular_delegate_event(struct modem_cellular_data *data,
269 enum modem_cellular_event evt);
270
271 static void modem_cellular_event_handler(struct modem_cellular_data *data,
272 enum modem_cellular_event evt);
273
modem_cellular_bus_pipe_handler(struct modem_pipe * pipe,enum modem_pipe_event event,void * user_data)274 static void modem_cellular_bus_pipe_handler(struct modem_pipe *pipe,
275 enum modem_pipe_event event,
276 void *user_data)
277 {
278 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
279
280 switch (event) {
281 case MODEM_PIPE_EVENT_OPENED:
282 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_BUS_OPENED);
283 break;
284
285 case MODEM_PIPE_EVENT_CLOSED:
286 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_BUS_CLOSED);
287 break;
288
289 default:
290 break;
291 }
292 }
293
modem_cellular_dlci1_pipe_handler(struct modem_pipe * pipe,enum modem_pipe_event event,void * user_data)294 static void modem_cellular_dlci1_pipe_handler(struct modem_pipe *pipe,
295 enum modem_pipe_event event,
296 void *user_data)
297 {
298 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
299
300 switch (event) {
301 case MODEM_PIPE_EVENT_OPENED:
302 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_DLCI1_OPENED);
303 break;
304
305 default:
306 break;
307 }
308 }
309
modem_cellular_dlci2_pipe_handler(struct modem_pipe * pipe,enum modem_pipe_event event,void * user_data)310 static void modem_cellular_dlci2_pipe_handler(struct modem_pipe *pipe,
311 enum modem_pipe_event event,
312 void *user_data)
313 {
314 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
315
316 switch (event) {
317 case MODEM_PIPE_EVENT_OPENED:
318 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_DLCI2_OPENED);
319 break;
320
321 default:
322 break;
323 }
324 }
325
modem_cellular_chat_callback_handler(struct modem_chat * chat,enum modem_chat_script_result result,void * user_data)326 static void modem_cellular_chat_callback_handler(struct modem_chat *chat,
327 enum modem_chat_script_result result,
328 void *user_data)
329 {
330 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
331
332 if (result == MODEM_CHAT_SCRIPT_RESULT_SUCCESS) {
333 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS);
334 } else {
335 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_SCRIPT_FAILED);
336 }
337 }
338
modem_cellular_chat_on_imei(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)339 static void modem_cellular_chat_on_imei(struct modem_chat *chat, char **argv, uint16_t argc,
340 void *user_data)
341 {
342 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
343
344 if (argc != 2) {
345 return;
346 }
347
348 strncpy(data->imei, argv[1], sizeof(data->imei) - 1);
349 }
350
modem_cellular_chat_on_cgmm(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)351 static void modem_cellular_chat_on_cgmm(struct modem_chat *chat, char **argv, uint16_t argc,
352 void *user_data)
353 {
354 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
355
356 if (argc != 2) {
357 return;
358 }
359
360 strncpy(data->model_id, argv[1], sizeof(data->model_id) - 1);
361 }
362
modem_cellular_chat_on_cgmi(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)363 static void modem_cellular_chat_on_cgmi(struct modem_chat *chat, char **argv, uint16_t argc,
364 void *user_data)
365 {
366 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
367
368 if (argc != 2) {
369 return;
370 }
371
372 strncpy(data->manufacturer, argv[1], sizeof(data->manufacturer) - 1);
373 }
374
modem_cellular_chat_on_cgmr(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)375 static void modem_cellular_chat_on_cgmr(struct modem_chat *chat, char **argv, uint16_t argc,
376 void *user_data)
377 {
378 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
379
380 if (argc != 2) {
381 return;
382 }
383
384 strncpy(data->fw_version, argv[1], sizeof(data->fw_version) - 1);
385 }
386
modem_cellular_chat_on_csq(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)387 static void modem_cellular_chat_on_csq(struct modem_chat *chat, char **argv, uint16_t argc,
388 void *user_data)
389 {
390 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
391
392 if (argc != 3) {
393 return;
394 }
395
396 data->rssi = (uint8_t)atoi(argv[1]);
397 }
398
modem_cellular_chat_on_cesq(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)399 static void modem_cellular_chat_on_cesq(struct modem_chat *chat, char **argv, uint16_t argc,
400 void *user_data)
401 {
402 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
403
404 if (argc != 7) {
405 return;
406 }
407
408 data->rsrq = (uint8_t)atoi(argv[5]);
409 data->rsrp = (uint8_t)atoi(argv[6]);
410 }
411
modem_cellular_chat_on_iccid(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)412 static void modem_cellular_chat_on_iccid(struct modem_chat *chat, char **argv, uint16_t argc,
413 void *user_data)
414 {
415 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
416
417 if (argc != 2) {
418 return;
419 }
420
421 strncpy(data->iccid, argv[1], sizeof(data->iccid) - 1);
422 }
423
modem_cellular_chat_on_imsi(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)424 static void modem_cellular_chat_on_imsi(struct modem_chat *chat, char **argv, uint16_t argc,
425 void *user_data)
426 {
427 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
428
429 if (argc != 2) {
430 return;
431 }
432
433 strncpy(data->imsi, argv[1], sizeof(data->imsi) - 1);
434 }
435
modem_cellular_is_registered(struct modem_cellular_data * data)436 static bool modem_cellular_is_registered(struct modem_cellular_data *data)
437 {
438 return (data->registration_status_gsm == CELLULAR_REGISTRATION_REGISTERED_HOME)
439 || (data->registration_status_gsm == CELLULAR_REGISTRATION_REGISTERED_ROAMING)
440 || (data->registration_status_gprs == CELLULAR_REGISTRATION_REGISTERED_HOME)
441 || (data->registration_status_gprs == CELLULAR_REGISTRATION_REGISTERED_ROAMING)
442 || (data->registration_status_lte == CELLULAR_REGISTRATION_REGISTERED_HOME)
443 || (data->registration_status_lte == CELLULAR_REGISTRATION_REGISTERED_ROAMING);
444 }
445
modem_cellular_chat_on_cxreg(struct modem_chat * chat,char ** argv,uint16_t argc,void * user_data)446 static void modem_cellular_chat_on_cxreg(struct modem_chat *chat, char **argv, uint16_t argc,
447 void *user_data)
448 {
449 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
450 enum cellular_registration_status registration_status = 0;
451
452 if (argc == 2) {
453 registration_status = atoi(argv[1]);
454 } else if (argc == 3 || argc == 6) {
455 registration_status = atoi(argv[2]);
456 } else {
457 return;
458 }
459
460 if (strcmp(argv[0], "+CREG: ") == 0) {
461 data->registration_status_gsm = registration_status;
462 } else if (strcmp(argv[0], "+CGREG: ") == 0) {
463 data->registration_status_gprs = registration_status;
464 } else {
465 data->registration_status_lte = registration_status;
466 }
467
468 if (modem_cellular_is_registered(data)) {
469 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_REGISTERED);
470 } else {
471 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_DEREGISTERED);
472 }
473 }
474
475 MODEM_CHAT_MATCH_DEFINE(ok_match, "OK", "", NULL);
476 MODEM_CHAT_MATCHES_DEFINE(allow_match,
477 MODEM_CHAT_MATCH("OK", "", NULL),
478 MODEM_CHAT_MATCH("ERROR", "", NULL));
479
480 MODEM_CHAT_MATCH_DEFINE(imei_match, "", "", modem_cellular_chat_on_imei);
481 MODEM_CHAT_MATCH_DEFINE(cgmm_match, "", "", modem_cellular_chat_on_cgmm);
482 MODEM_CHAT_MATCH_DEFINE(csq_match, "+CSQ: ", ",", modem_cellular_chat_on_csq);
483 MODEM_CHAT_MATCH_DEFINE(cesq_match, "+CESQ: ", ",", modem_cellular_chat_on_cesq);
484 MODEM_CHAT_MATCH_DEFINE(qccid_match __maybe_unused, "+QCCID: ", "", modem_cellular_chat_on_iccid);
485 MODEM_CHAT_MATCH_DEFINE(iccid_match __maybe_unused, "+ICCID: ", "", modem_cellular_chat_on_iccid);
486 MODEM_CHAT_MATCH_DEFINE(cimi_match __maybe_unused, "", "", modem_cellular_chat_on_imsi);
487 MODEM_CHAT_MATCH_DEFINE(cgmi_match __maybe_unused, "", "", modem_cellular_chat_on_cgmi);
488 MODEM_CHAT_MATCH_DEFINE(cgmr_match __maybe_unused, "", "", modem_cellular_chat_on_cgmr);
489
490 MODEM_CHAT_MATCHES_DEFINE(unsol_matches,
491 MODEM_CHAT_MATCH("+CREG: ", ",", modem_cellular_chat_on_cxreg),
492 MODEM_CHAT_MATCH("+CEREG: ", ",", modem_cellular_chat_on_cxreg),
493 MODEM_CHAT_MATCH("+CGREG: ", ",", modem_cellular_chat_on_cxreg));
494
495 MODEM_CHAT_MATCHES_DEFINE(abort_matches, MODEM_CHAT_MATCH("ERROR", "", NULL));
496
497 MODEM_CHAT_MATCHES_DEFINE(dial_abort_matches,
498 MODEM_CHAT_MATCH("ERROR", "", NULL),
499 MODEM_CHAT_MATCH("BUSY", "", NULL),
500 MODEM_CHAT_MATCH("NO ANSWER", "", NULL),
501 MODEM_CHAT_MATCH("NO CARRIER", "", NULL),
502 MODEM_CHAT_MATCH("NO DIALTONE", "", NULL));
503
504 #if DT_HAS_COMPAT_STATUS_OKAY(swir_hl7800) || DT_HAS_COMPAT_STATUS_OKAY(sqn_gm02s)
505 MODEM_CHAT_MATCH_DEFINE(connect_match, "CONNECT", "", NULL);
506 #endif
507
modem_cellular_log_state_changed(enum modem_cellular_state last_state,enum modem_cellular_state new_state)508 static void modem_cellular_log_state_changed(enum modem_cellular_state last_state,
509 enum modem_cellular_state new_state)
510 {
511 LOG_DBG("switch from %s to %s", modem_cellular_state_str(last_state),
512 modem_cellular_state_str(new_state));
513 }
514
modem_cellular_log_event(enum modem_cellular_event evt)515 static void modem_cellular_log_event(enum modem_cellular_event evt)
516 {
517 LOG_DBG("event %s", modem_cellular_event_str(evt));
518 }
519
modem_cellular_start_timer(struct modem_cellular_data * data,k_timeout_t timeout)520 static void modem_cellular_start_timer(struct modem_cellular_data *data, k_timeout_t timeout)
521 {
522 k_work_schedule(&data->timeout_work, timeout);
523 }
524
modem_cellular_stop_timer(struct modem_cellular_data * data)525 static void modem_cellular_stop_timer(struct modem_cellular_data *data)
526 {
527 k_work_cancel_delayable(&data->timeout_work);
528 }
529
modem_cellular_timeout_handler(struct k_work * item)530 static void modem_cellular_timeout_handler(struct k_work *item)
531 {
532 struct k_work_delayable *dwork = k_work_delayable_from_work(item);
533 struct modem_cellular_data *data =
534 CONTAINER_OF(dwork, struct modem_cellular_data, timeout_work);
535
536 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_TIMEOUT);
537 }
538
modem_cellular_event_dispatch_handler(struct k_work * item)539 static void modem_cellular_event_dispatch_handler(struct k_work *item)
540 {
541 struct modem_cellular_data *data =
542 CONTAINER_OF(item, struct modem_cellular_data, event_dispatch_work);
543
544 uint8_t events[sizeof(data->event_buf)];
545 uint8_t events_cnt;
546
547 k_mutex_lock(&data->event_rb_lock, K_FOREVER);
548
549 events_cnt = (uint8_t)ring_buf_get(&data->event_rb, events, sizeof(data->event_buf));
550
551 k_mutex_unlock(&data->event_rb_lock);
552
553 for (uint8_t i = 0; i < events_cnt; i++) {
554 modem_cellular_event_handler(data, (enum modem_cellular_event)events[i]);
555 }
556 }
557
modem_cellular_delegate_event(struct modem_cellular_data * data,enum modem_cellular_event evt)558 static void modem_cellular_delegate_event(struct modem_cellular_data *data,
559 enum modem_cellular_event evt)
560 {
561 k_mutex_lock(&data->event_rb_lock, K_FOREVER);
562 ring_buf_put(&data->event_rb, (uint8_t *)&evt, 1);
563 k_mutex_unlock(&data->event_rb_lock);
564 k_work_submit(&data->event_dispatch_work);
565 }
566
modem_cellular_on_idle_state_enter(struct modem_cellular_data * data)567 static int modem_cellular_on_idle_state_enter(struct modem_cellular_data *data)
568 {
569 const struct modem_cellular_config *config =
570 (const struct modem_cellular_config *)data->dev->config;
571
572 if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
573 gpio_pin_set_dt(&config->reset_gpio, 1);
574 }
575
576 modem_cellular_notify_user_pipes_disconnected(data);
577 modem_chat_release(&data->chat);
578 modem_ppp_release(data->ppp);
579 modem_cmux_release(&data->cmux);
580 modem_pipe_close_async(data->uart_pipe);
581 k_sem_give(&data->suspended_sem);
582 return 0;
583 }
584
modem_cellular_idle_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)585 static void modem_cellular_idle_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_RESUME:
593 if (config->autostarts) {
594 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON);
595 break;
596 }
597
598 if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
599 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_POWER_ON_PULSE);
600 break;
601 }
602
603 if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
604 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON);
605 break;
606 }
607
608 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT);
609 break;
610
611 case MODEM_CELLULAR_EVENT_SUSPEND:
612 k_sem_give(&data->suspended_sem);
613 break;
614
615 default:
616 break;
617 }
618 }
619
modem_cellular_on_idle_state_leave(struct modem_cellular_data * data)620 static int modem_cellular_on_idle_state_leave(struct modem_cellular_data *data)
621 {
622 const struct modem_cellular_config *config =
623 (const struct modem_cellular_config *)data->dev->config;
624
625 k_sem_take(&data->suspended_sem, K_NO_WAIT);
626
627 if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
628 gpio_pin_set_dt(&config->reset_gpio, 0);
629 }
630
631 return 0;
632 }
633
modem_cellular_on_reset_pulse_state_enter(struct modem_cellular_data * data)634 static int modem_cellular_on_reset_pulse_state_enter(struct modem_cellular_data *data)
635 {
636 const struct modem_cellular_config *config =
637 (const struct modem_cellular_config *)data->dev->config;
638
639 gpio_pin_set_dt(&config->reset_gpio, 1);
640 modem_cellular_start_timer(data, K_MSEC(config->reset_pulse_duration_ms));
641 return 0;
642 }
643
modem_cellular_reset_pulse_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)644 static void modem_cellular_reset_pulse_event_handler(struct modem_cellular_data *data,
645 enum modem_cellular_event evt)
646 {
647 switch (evt) {
648 case MODEM_CELLULAR_EVENT_TIMEOUT:
649 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON);
650 break;
651
652 case MODEM_CELLULAR_EVENT_SUSPEND:
653 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
654 break;
655
656 default:
657 break;
658 }
659 }
660
modem_cellular_on_reset_pulse_state_leave(struct modem_cellular_data * data)661 static int modem_cellular_on_reset_pulse_state_leave(struct modem_cellular_data *data)
662 {
663 const struct modem_cellular_config *config =
664 (const struct modem_cellular_config *)data->dev->config;
665
666 gpio_pin_set_dt(&config->reset_gpio, 0);
667 modem_cellular_stop_timer(data);
668 return 0;
669 }
670
modem_cellular_on_power_on_pulse_state_enter(struct modem_cellular_data * data)671 static int modem_cellular_on_power_on_pulse_state_enter(struct modem_cellular_data *data)
672 {
673 const struct modem_cellular_config *config =
674 (const struct modem_cellular_config *)data->dev->config;
675
676 gpio_pin_set_dt(&config->power_gpio, 1);
677 modem_cellular_start_timer(data, K_MSEC(config->power_pulse_duration_ms));
678 return 0;
679 }
680
modem_cellular_power_on_pulse_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)681 static void modem_cellular_power_on_pulse_event_handler(struct modem_cellular_data *data,
682 enum modem_cellular_event evt)
683 {
684 switch (evt) {
685 case MODEM_CELLULAR_EVENT_TIMEOUT:
686 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON);
687 break;
688
689 case MODEM_CELLULAR_EVENT_SUSPEND:
690 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
691 break;
692
693 default:
694 break;
695 }
696 }
697
modem_cellular_on_power_on_pulse_state_leave(struct modem_cellular_data * data)698 static int modem_cellular_on_power_on_pulse_state_leave(struct modem_cellular_data *data)
699 {
700 const struct modem_cellular_config *config =
701 (const struct modem_cellular_config *)data->dev->config;
702
703 gpio_pin_set_dt(&config->power_gpio, 0);
704 modem_cellular_stop_timer(data);
705 return 0;
706 }
707
modem_cellular_on_await_power_on_state_enter(struct modem_cellular_data * data)708 static int modem_cellular_on_await_power_on_state_enter(struct modem_cellular_data *data)
709 {
710 const struct modem_cellular_config *config =
711 (const struct modem_cellular_config *)data->dev->config;
712
713 modem_cellular_start_timer(data, K_MSEC(config->startup_time_ms));
714 return 0;
715 }
716
modem_cellular_await_power_on_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)717 static void modem_cellular_await_power_on_event_handler(struct modem_cellular_data *data,
718 enum modem_cellular_event evt)
719 {
720 switch (evt) {
721 case MODEM_CELLULAR_EVENT_TIMEOUT:
722 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT);
723 break;
724
725 case MODEM_CELLULAR_EVENT_SUSPEND:
726 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
727 break;
728
729 default:
730 break;
731 }
732 }
733
modem_cellular_on_run_init_script_state_enter(struct modem_cellular_data * data)734 static int modem_cellular_on_run_init_script_state_enter(struct modem_cellular_data *data)
735 {
736 modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
737 return modem_pipe_open_async(data->uart_pipe);
738 }
739
modem_cellular_run_init_script_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)740 static void modem_cellular_run_init_script_event_handler(struct modem_cellular_data *data,
741 enum modem_cellular_event evt)
742 {
743 const struct modem_cellular_config *config =
744 (const struct modem_cellular_config *)data->dev->config;
745
746 switch (evt) {
747 case MODEM_CELLULAR_EVENT_BUS_OPENED:
748 modem_chat_attach(&data->chat, data->uart_pipe);
749 modem_chat_run_script_async(&data->chat, config->init_chat_script);
750 break;
751
752 case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
753 net_if_set_link_addr(modem_ppp_get_iface(data->ppp), data->imei,
754 ARRAY_SIZE(data->imei), NET_LINK_UNKNOWN);
755
756 modem_chat_release(&data->chat);
757 modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
758 modem_pipe_close_async(data->uart_pipe);
759 break;
760
761 case MODEM_CELLULAR_EVENT_BUS_CLOSED:
762 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_CONNECT_CMUX);
763 break;
764
765 case MODEM_CELLULAR_EVENT_SUSPEND:
766 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
767 break;
768
769 case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
770 if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
771 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_POWER_ON_PULSE);
772 break;
773 }
774
775 if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
776 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RESET_PULSE);
777 break;
778 }
779
780 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
781 break;
782
783 default:
784 break;
785 }
786 }
787
modem_cellular_on_connect_cmux_state_enter(struct modem_cellular_data * data)788 static int modem_cellular_on_connect_cmux_state_enter(struct modem_cellular_data *data)
789 {
790 /*
791 * Allow modem to switch bus into CMUX mode. Some modems disable UART RX while
792 * switching, resulting in UART RX errors as bus is no longer pulled up by modem.
793 */
794 modem_cellular_start_timer(data, K_MSEC(100));
795 return 0;
796 }
797
modem_cellular_connect_cmux_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)798 static void modem_cellular_connect_cmux_event_handler(struct modem_cellular_data *data,
799 enum modem_cellular_event evt)
800 {
801 switch (evt) {
802 case MODEM_CELLULAR_EVENT_TIMEOUT:
803 modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
804 modem_pipe_open_async(data->uart_pipe);
805 break;
806
807 case MODEM_CELLULAR_EVENT_BUS_OPENED:
808 modem_cmux_attach(&data->cmux, data->uart_pipe);
809 modem_cmux_connect_async(&data->cmux);
810 break;
811
812 case MODEM_CELLULAR_EVENT_CMUX_CONNECTED:
813 modem_cellular_notify_user_pipes_connected(data);
814 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_OPEN_DLCI1);
815 break;
816
817 case MODEM_CELLULAR_EVENT_SUSPEND:
818 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
819 break;
820
821 default:
822 break;
823 }
824 }
825
modem_cellular_on_open_dlci1_state_enter(struct modem_cellular_data * data)826 static int modem_cellular_on_open_dlci1_state_enter(struct modem_cellular_data *data)
827 {
828 modem_pipe_attach(data->dlci1_pipe, modem_cellular_dlci1_pipe_handler, data);
829 return modem_pipe_open_async(data->dlci1_pipe);
830 }
831
modem_cellular_open_dlci1_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)832 static void modem_cellular_open_dlci1_event_handler(struct modem_cellular_data *data,
833 enum modem_cellular_event evt)
834 {
835 switch (evt) {
836 case MODEM_CELLULAR_EVENT_DLCI1_OPENED:
837 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_OPEN_DLCI2);
838 break;
839
840 case MODEM_CELLULAR_EVENT_SUSPEND:
841 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
842 break;
843
844 default:
845 break;
846 }
847 }
848
modem_cellular_on_open_dlci1_state_leave(struct modem_cellular_data * data)849 static int modem_cellular_on_open_dlci1_state_leave(struct modem_cellular_data *data)
850 {
851 modem_pipe_release(data->dlci1_pipe);
852 return 0;
853 }
854
modem_cellular_on_open_dlci2_state_enter(struct modem_cellular_data * data)855 static int modem_cellular_on_open_dlci2_state_enter(struct modem_cellular_data *data)
856 {
857 modem_pipe_attach(data->dlci2_pipe, modem_cellular_dlci2_pipe_handler, data);
858 return modem_pipe_open_async(data->dlci2_pipe);
859 }
860
modem_cellular_open_dlci2_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)861 static void modem_cellular_open_dlci2_event_handler(struct modem_cellular_data *data,
862 enum modem_cellular_event evt)
863 {
864 switch (evt) {
865 case MODEM_CELLULAR_EVENT_DLCI2_OPENED:
866 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT);
867 break;
868
869 case MODEM_CELLULAR_EVENT_SUSPEND:
870 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
871 break;
872
873 default:
874 break;
875 }
876 }
877
modem_cellular_on_open_dlci2_state_leave(struct modem_cellular_data * data)878 static int modem_cellular_on_open_dlci2_state_leave(struct modem_cellular_data *data)
879 {
880 modem_pipe_release(data->dlci2_pipe);
881 return 0;
882 }
883
modem_cellular_on_run_dial_script_state_enter(struct modem_cellular_data * data)884 static int modem_cellular_on_run_dial_script_state_enter(struct modem_cellular_data *data)
885 {
886 /* Allow modem time to enter command mode before running dial script */
887 modem_cellular_start_timer(data, K_MSEC(100));
888 return 0;
889 }
890
modem_cellular_run_dial_script_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)891 static void modem_cellular_run_dial_script_event_handler(struct modem_cellular_data *data,
892 enum modem_cellular_event evt)
893 {
894 const struct modem_cellular_config *config =
895 (const struct modem_cellular_config *)data->dev->config;
896
897 switch (evt) {
898 case MODEM_CELLULAR_EVENT_TIMEOUT:
899 modem_chat_attach(&data->chat, data->dlci1_pipe);
900 modem_chat_run_script_async(&data->chat, config->dial_chat_script);
901 break;
902
903 case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
904 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_REGISTERED);
905 break;
906
907 case MODEM_CELLULAR_EVENT_SUSPEND:
908 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
909 break;
910
911 default:
912 break;
913 }
914 }
915
modem_cellular_on_run_dial_script_state_leave(struct modem_cellular_data * data)916 static int modem_cellular_on_run_dial_script_state_leave(struct modem_cellular_data *data)
917 {
918 modem_chat_release(&data->chat);
919 return 0;
920 }
921
modem_cellular_on_await_registered_state_enter(struct modem_cellular_data * data)922 static int modem_cellular_on_await_registered_state_enter(struct modem_cellular_data *data)
923 {
924 if (modem_ppp_attach(data->ppp, data->dlci1_pipe) < 0) {
925 return -EAGAIN;
926 }
927
928 modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT);
929 return modem_chat_attach(&data->chat, data->dlci2_pipe);
930 }
931
modem_cellular_await_registered_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)932 static void modem_cellular_await_registered_event_handler(struct modem_cellular_data *data,
933 enum modem_cellular_event evt)
934 {
935 const struct modem_cellular_config *config =
936 (const struct modem_cellular_config *)data->dev->config;
937
938 switch (evt) {
939 case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
940 case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
941 modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT);
942 break;
943
944 case MODEM_CELLULAR_EVENT_TIMEOUT:
945 modem_chat_run_script_async(&data->chat, config->periodic_chat_script);
946 break;
947
948 case MODEM_CELLULAR_EVENT_REGISTERED:
949 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_CARRIER_ON);
950 break;
951
952 case MODEM_CELLULAR_EVENT_SUSPEND:
953 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
954 break;
955
956 default:
957 break;
958 }
959 }
960
modem_cellular_on_await_registered_state_leave(struct modem_cellular_data * data)961 static int modem_cellular_on_await_registered_state_leave(struct modem_cellular_data *data)
962 {
963 modem_cellular_stop_timer(data);
964 return 0;
965 }
966
modem_cellular_on_carrier_on_state_enter(struct modem_cellular_data * data)967 static int modem_cellular_on_carrier_on_state_enter(struct modem_cellular_data *data)
968 {
969 net_if_carrier_on(modem_ppp_get_iface(data->ppp));
970 modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT);
971 return 0;
972 }
973
modem_cellular_carrier_on_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)974 static void modem_cellular_carrier_on_event_handler(struct modem_cellular_data *data,
975 enum modem_cellular_event evt)
976 {
977 const struct modem_cellular_config *config =
978 (const struct modem_cellular_config *)data->dev->config;
979
980 switch (evt) {
981 case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
982 case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
983 modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT);
984 break;
985
986 case MODEM_CELLULAR_EVENT_TIMEOUT:
987 modem_chat_run_script_async(&data->chat, config->periodic_chat_script);
988 break;
989
990 case MODEM_CELLULAR_EVENT_DEREGISTERED:
991 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT);
992 break;
993
994 case MODEM_CELLULAR_EVENT_SUSPEND:
995 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_INIT_POWER_OFF);
996 break;
997
998 default:
999 break;
1000 }
1001 }
1002
modem_cellular_on_carrier_on_state_leave(struct modem_cellular_data * data)1003 static int modem_cellular_on_carrier_on_state_leave(struct modem_cellular_data *data)
1004 {
1005 modem_cellular_stop_timer(data);
1006 net_if_carrier_off(modem_ppp_get_iface(data->ppp));
1007 modem_chat_release(&data->chat);
1008 modem_ppp_release(data->ppp);
1009 return 0;
1010 }
1011
modem_cellular_on_init_power_off_state_enter(struct modem_cellular_data * data)1012 static int modem_cellular_on_init_power_off_state_enter(struct modem_cellular_data *data)
1013 {
1014 modem_pipe_close_async(data->uart_pipe);
1015 modem_cellular_start_timer(data, K_MSEC(2000));
1016 return 0;
1017 }
1018
modem_cellular_init_power_off_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1019 static void modem_cellular_init_power_off_event_handler(struct modem_cellular_data *data,
1020 enum modem_cellular_event evt)
1021 {
1022 const struct modem_cellular_config *config =
1023 (const struct modem_cellular_config *)data->dev->config;
1024
1025 switch (evt) {
1026 case MODEM_CELLULAR_EVENT_TIMEOUT:
1027 if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
1028 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_POWER_OFF_PULSE);
1029 break;
1030 }
1031
1032 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
1033 break;
1034
1035 default:
1036 break;
1037 }
1038 }
1039
modem_cellular_on_init_power_off_state_leave(struct modem_cellular_data * data)1040 static int modem_cellular_on_init_power_off_state_leave(struct modem_cellular_data *data)
1041 {
1042 modem_cellular_notify_user_pipes_disconnected(data);
1043 modem_chat_release(&data->chat);
1044 modem_ppp_release(data->ppp);
1045 return 0;
1046 }
1047
modem_cellular_on_power_off_pulse_state_enter(struct modem_cellular_data * data)1048 static int modem_cellular_on_power_off_pulse_state_enter(struct modem_cellular_data *data)
1049 {
1050 const struct modem_cellular_config *config =
1051 (const struct modem_cellular_config *)data->dev->config;
1052
1053 gpio_pin_set_dt(&config->power_gpio, 1);
1054 modem_cellular_start_timer(data, K_MSEC(config->power_pulse_duration_ms));
1055 return 0;
1056 }
1057
modem_cellular_power_off_pulse_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1058 static void modem_cellular_power_off_pulse_event_handler(struct modem_cellular_data *data,
1059 enum modem_cellular_event evt)
1060 {
1061 switch (evt) {
1062 case MODEM_CELLULAR_EVENT_TIMEOUT:
1063 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_OFF);
1064 break;
1065
1066 default:
1067 break;
1068 }
1069 }
1070
modem_cellular_on_power_off_pulse_state_leave(struct modem_cellular_data * data)1071 static int modem_cellular_on_power_off_pulse_state_leave(struct modem_cellular_data *data)
1072 {
1073 const struct modem_cellular_config *config =
1074 (const struct modem_cellular_config *)data->dev->config;
1075
1076 gpio_pin_set_dt(&config->power_gpio, 0);
1077 modem_cellular_stop_timer(data);
1078 return 0;
1079 }
1080
modem_cellular_on_await_power_off_state_enter(struct modem_cellular_data * data)1081 static int modem_cellular_on_await_power_off_state_enter(struct modem_cellular_data *data)
1082 {
1083 const struct modem_cellular_config *config =
1084 (const struct modem_cellular_config *)data->dev->config;
1085
1086 modem_cellular_start_timer(data, K_MSEC(config->shutdown_time_ms));
1087 return 0;
1088 }
1089
modem_cellular_await_power_off_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1090 static void modem_cellular_await_power_off_event_handler(struct modem_cellular_data *data,
1091 enum modem_cellular_event evt)
1092 {
1093 switch (evt) {
1094 case MODEM_CELLULAR_EVENT_TIMEOUT:
1095 modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE);
1096 break;
1097
1098 default:
1099 break;
1100 }
1101 }
1102
modem_cellular_on_state_enter(struct modem_cellular_data * data)1103 static int modem_cellular_on_state_enter(struct modem_cellular_data *data)
1104 {
1105 int ret;
1106
1107 switch (data->state) {
1108 case MODEM_CELLULAR_STATE_IDLE:
1109 ret = modem_cellular_on_idle_state_enter(data);
1110 break;
1111
1112 case MODEM_CELLULAR_STATE_RESET_PULSE:
1113 ret = modem_cellular_on_reset_pulse_state_enter(data);
1114 break;
1115
1116 case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
1117 ret = modem_cellular_on_power_on_pulse_state_enter(data);
1118 break;
1119
1120 case MODEM_CELLULAR_STATE_AWAIT_POWER_ON:
1121 ret = modem_cellular_on_await_power_on_state_enter(data);
1122 break;
1123
1124 case MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT:
1125 ret = modem_cellular_on_run_init_script_state_enter(data);
1126 break;
1127
1128 case MODEM_CELLULAR_STATE_CONNECT_CMUX:
1129 ret = modem_cellular_on_connect_cmux_state_enter(data);
1130 break;
1131
1132 case MODEM_CELLULAR_STATE_OPEN_DLCI1:
1133 ret = modem_cellular_on_open_dlci1_state_enter(data);
1134 break;
1135
1136 case MODEM_CELLULAR_STATE_OPEN_DLCI2:
1137 ret = modem_cellular_on_open_dlci2_state_enter(data);
1138 break;
1139
1140 case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
1141 ret = modem_cellular_on_run_dial_script_state_enter(data);
1142 break;
1143
1144 case MODEM_CELLULAR_STATE_AWAIT_REGISTERED:
1145 ret = modem_cellular_on_await_registered_state_enter(data);
1146 break;
1147
1148 case MODEM_CELLULAR_STATE_CARRIER_ON:
1149 ret = modem_cellular_on_carrier_on_state_enter(data);
1150 break;
1151
1152 case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
1153 ret = modem_cellular_on_init_power_off_state_enter(data);
1154 break;
1155
1156 case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
1157 ret = modem_cellular_on_power_off_pulse_state_enter(data);
1158 break;
1159
1160 case MODEM_CELLULAR_STATE_AWAIT_POWER_OFF:
1161 ret = modem_cellular_on_await_power_off_state_enter(data);
1162 break;
1163
1164 default:
1165 ret = 0;
1166 break;
1167 }
1168
1169 return ret;
1170 }
1171
modem_cellular_on_state_leave(struct modem_cellular_data * data)1172 static int modem_cellular_on_state_leave(struct modem_cellular_data *data)
1173 {
1174 int ret;
1175
1176 switch (data->state) {
1177 case MODEM_CELLULAR_STATE_IDLE:
1178 ret = modem_cellular_on_idle_state_leave(data);
1179 break;
1180
1181 case MODEM_CELLULAR_STATE_RESET_PULSE:
1182 ret = modem_cellular_on_reset_pulse_state_leave(data);
1183 break;
1184
1185 case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
1186 ret = modem_cellular_on_power_on_pulse_state_leave(data);
1187 break;
1188
1189 case MODEM_CELLULAR_STATE_OPEN_DLCI1:
1190 ret = modem_cellular_on_open_dlci1_state_leave(data);
1191 break;
1192
1193 case MODEM_CELLULAR_STATE_OPEN_DLCI2:
1194 ret = modem_cellular_on_open_dlci2_state_leave(data);
1195 break;
1196
1197 case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
1198 ret = modem_cellular_on_run_dial_script_state_leave(data);
1199 break;
1200
1201 case MODEM_CELLULAR_STATE_AWAIT_REGISTERED:
1202 ret = modem_cellular_on_await_registered_state_leave(data);
1203 break;
1204
1205 case MODEM_CELLULAR_STATE_CARRIER_ON:
1206 ret = modem_cellular_on_carrier_on_state_leave(data);
1207 break;
1208
1209 case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
1210 ret = modem_cellular_on_init_power_off_state_leave(data);
1211 break;
1212
1213 case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
1214 ret = modem_cellular_on_power_off_pulse_state_leave(data);
1215 break;
1216
1217 default:
1218 ret = 0;
1219 break;
1220 }
1221
1222 return ret;
1223 }
1224
modem_cellular_enter_state(struct modem_cellular_data * data,enum modem_cellular_state state)1225 static void modem_cellular_enter_state(struct modem_cellular_data *data,
1226 enum modem_cellular_state state)
1227 {
1228 int ret;
1229
1230 ret = modem_cellular_on_state_leave(data);
1231
1232 if (ret < 0) {
1233 LOG_WRN("failed to leave state, error: %i", ret);
1234
1235 return;
1236 }
1237
1238 data->state = state;
1239 ret = modem_cellular_on_state_enter(data);
1240
1241 if (ret < 0) {
1242 LOG_WRN("failed to enter state error: %i", ret);
1243 }
1244 }
1245
modem_cellular_event_handler(struct modem_cellular_data * data,enum modem_cellular_event evt)1246 static void modem_cellular_event_handler(struct modem_cellular_data *data,
1247 enum modem_cellular_event evt)
1248 {
1249 enum modem_cellular_state state;
1250
1251 state = data->state;
1252
1253 modem_cellular_log_event(evt);
1254
1255 switch (data->state) {
1256 case MODEM_CELLULAR_STATE_IDLE:
1257 modem_cellular_idle_event_handler(data, evt);
1258 break;
1259
1260 case MODEM_CELLULAR_STATE_RESET_PULSE:
1261 modem_cellular_reset_pulse_event_handler(data, evt);
1262 break;
1263
1264 case MODEM_CELLULAR_STATE_POWER_ON_PULSE:
1265 modem_cellular_power_on_pulse_event_handler(data, evt);
1266 break;
1267
1268 case MODEM_CELLULAR_STATE_AWAIT_POWER_ON:
1269 modem_cellular_await_power_on_event_handler(data, evt);
1270 break;
1271
1272 case MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT:
1273 modem_cellular_run_init_script_event_handler(data, evt);
1274 break;
1275
1276 case MODEM_CELLULAR_STATE_CONNECT_CMUX:
1277 modem_cellular_connect_cmux_event_handler(data, evt);
1278 break;
1279
1280 case MODEM_CELLULAR_STATE_OPEN_DLCI1:
1281 modem_cellular_open_dlci1_event_handler(data, evt);
1282 break;
1283
1284 case MODEM_CELLULAR_STATE_OPEN_DLCI2:
1285 modem_cellular_open_dlci2_event_handler(data, evt);
1286 break;
1287
1288 case MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT:
1289 modem_cellular_run_dial_script_event_handler(data, evt);
1290 break;
1291
1292 case MODEM_CELLULAR_STATE_AWAIT_REGISTERED:
1293 modem_cellular_await_registered_event_handler(data, evt);
1294 break;
1295
1296 case MODEM_CELLULAR_STATE_CARRIER_ON:
1297 modem_cellular_carrier_on_event_handler(data, evt);
1298 break;
1299
1300 case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
1301 modem_cellular_init_power_off_event_handler(data, evt);
1302 break;
1303
1304 case MODEM_CELLULAR_STATE_POWER_OFF_PULSE:
1305 modem_cellular_power_off_pulse_event_handler(data, evt);
1306 break;
1307
1308 case MODEM_CELLULAR_STATE_AWAIT_POWER_OFF:
1309 modem_cellular_await_power_off_event_handler(data, evt);
1310 break;
1311 }
1312
1313 if (state != data->state) {
1314 modem_cellular_log_state_changed(state, data->state);
1315 }
1316 }
1317
modem_cellular_cmux_handler(struct modem_cmux * cmux,enum modem_cmux_event event,void * user_data)1318 static void modem_cellular_cmux_handler(struct modem_cmux *cmux, enum modem_cmux_event event,
1319 void *user_data)
1320 {
1321 struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
1322
1323 switch (event) {
1324 case MODEM_CMUX_EVENT_CONNECTED:
1325 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_CMUX_CONNECTED);
1326 break;
1327
1328 default:
1329 break;
1330 }
1331 }
1332
1333 MODEM_CHAT_SCRIPT_CMDS_DEFINE(get_signal_csq_chat_script_cmds,
1334 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CSQ", csq_match),
1335 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match));
1336
1337 MODEM_CHAT_SCRIPT_DEFINE(get_signal_csq_chat_script, get_signal_csq_chat_script_cmds,
1338 abort_matches, modem_cellular_chat_callback_handler, 2);
1339
modem_cellular_csq_parse_rssi(uint8_t rssi,int16_t * value)1340 static inline int modem_cellular_csq_parse_rssi(uint8_t rssi, int16_t *value)
1341 {
1342 /* AT+CSQ returns a response +CSQ: <rssi>,<ber> where:
1343 * - rssi is a integer from 0 to 31 whose values describes a signal strength
1344 * between -113 dBm for 0 and -51dbM for 31 or unknown for 99
1345 * - ber is an integer from 0 to 7 that describes the error rate, it can also
1346 * be 99 for an unknown error rate
1347 */
1348 if (rssi == CSQ_RSSI_UNKNOWN) {
1349 return -EINVAL;
1350 }
1351
1352 *value = (int16_t)CSQ_RSSI_TO_DB(rssi);
1353 return 0;
1354 }
1355
1356 MODEM_CHAT_SCRIPT_CMDS_DEFINE(get_signal_cesq_chat_script_cmds,
1357 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CESQ", cesq_match),
1358 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match));
1359
1360 MODEM_CHAT_SCRIPT_DEFINE(get_signal_cesq_chat_script, get_signal_cesq_chat_script_cmds,
1361 abort_matches, modem_cellular_chat_callback_handler, 2);
1362
1363 /* AT+CESQ returns a response +CESQ: <rxlev>,<ber>,<rscp>,<ecn0>,<rsrq>,<rsrp> where:
1364 * - rsrq is a integer from 0 to 34 whose values describes the Reference Signal Receive
1365 * Quality between -20 dB for 0 and -3 dB for 34 (0.5 dB steps), or unknown for 255
1366 * - rsrp is an integer from 0 to 97 that describes the Reference Signal Receive Power
1367 * between -140 dBm for 0 and -44 dBm for 97 (1 dBm steps), or unknown for 255
1368 */
modem_cellular_cesq_parse_rsrp(uint8_t rsrp,int16_t * value)1369 static inline int modem_cellular_cesq_parse_rsrp(uint8_t rsrp, int16_t *value)
1370 {
1371 if (rsrp == CESQ_RSRP_UNKNOWN) {
1372 return -EINVAL;
1373 }
1374
1375 *value = (int16_t)CESQ_RSRP_TO_DB(rsrp);
1376 return 0;
1377 }
1378
modem_cellular_cesq_parse_rsrq(uint8_t rsrq,int16_t * value)1379 static inline int modem_cellular_cesq_parse_rsrq(uint8_t rsrq, int16_t *value)
1380 {
1381 if (rsrq == CESQ_RSRQ_UNKNOWN) {
1382 return -EINVAL;
1383 }
1384
1385 *value = (int16_t)CESQ_RSRQ_TO_DB(rsrq);
1386 return 0;
1387 }
1388
modem_cellular_get_signal(const struct device * dev,const enum cellular_signal_type type,int16_t * value)1389 static int modem_cellular_get_signal(const struct device *dev,
1390 const enum cellular_signal_type type,
1391 int16_t *value)
1392 {
1393 int ret = -ENOTSUP;
1394 struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1395
1396 if ((data->state != MODEM_CELLULAR_STATE_AWAIT_REGISTERED) &&
1397 (data->state != MODEM_CELLULAR_STATE_CARRIER_ON)) {
1398 return -ENODATA;
1399 }
1400
1401 /* Run chat script */
1402 switch (type) {
1403 case CELLULAR_SIGNAL_RSSI:
1404 ret = modem_chat_run_script(&data->chat, &get_signal_csq_chat_script);
1405 break;
1406
1407 case CELLULAR_SIGNAL_RSRP:
1408 case CELLULAR_SIGNAL_RSRQ:
1409 ret = modem_chat_run_script(&data->chat, &get_signal_cesq_chat_script);
1410 break;
1411
1412 default:
1413 ret = -ENOTSUP;
1414 break;
1415 }
1416
1417 /* Verify chat script ran successfully */
1418 if (ret < 0) {
1419 return ret;
1420 }
1421
1422 /* Parse received value */
1423 switch (type) {
1424 case CELLULAR_SIGNAL_RSSI:
1425 ret = modem_cellular_csq_parse_rssi(data->rssi, value);
1426 break;
1427
1428 case CELLULAR_SIGNAL_RSRP:
1429 ret = modem_cellular_cesq_parse_rsrp(data->rsrp, value);
1430 break;
1431
1432 case CELLULAR_SIGNAL_RSRQ:
1433 ret = modem_cellular_cesq_parse_rsrq(data->rsrq, value);
1434 break;
1435
1436 default:
1437 ret = -ENOTSUP;
1438 break;
1439 }
1440
1441 return ret;
1442 }
1443
modem_cellular_get_modem_info(const struct device * dev,enum cellular_modem_info_type type,char * info,size_t size)1444 static int modem_cellular_get_modem_info(const struct device *dev,
1445 enum cellular_modem_info_type type,
1446 char *info, size_t size)
1447 {
1448 int ret = 0;
1449 struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1450
1451 switch (type) {
1452 case CELLULAR_MODEM_INFO_IMEI:
1453 strncpy(info, &data->imei[0], MIN(size, sizeof(data->imei)));
1454 break;
1455 case CELLULAR_MODEM_INFO_SIM_IMSI:
1456 strncpy(info, &data->imsi[0], MIN(size, sizeof(data->imsi)));
1457 break;
1458 case CELLULAR_MODEM_INFO_MANUFACTURER:
1459 strncpy(info, &data->manufacturer[0], MIN(size, sizeof(data->manufacturer)));
1460 break;
1461 case CELLULAR_MODEM_INFO_FW_VERSION:
1462 strncpy(info, &data->fw_version[0], MIN(size, sizeof(data->fw_version)));
1463 break;
1464 case CELLULAR_MODEM_INFO_MODEL_ID:
1465 strncpy(info, &data->model_id[0], MIN(size, sizeof(data->model_id)));
1466 break;
1467 case CELLULAR_MODEM_INFO_SIM_ICCID:
1468 strncpy(info, &data->iccid[0], MIN(size, sizeof(data->iccid)));
1469 break;
1470 default:
1471 ret = -ENODATA;
1472 break;
1473 }
1474
1475 return ret;
1476 }
modem_cellular_get_registration_status(const struct device * dev,enum cellular_access_technology tech,enum cellular_registration_status * status)1477 static int modem_cellular_get_registration_status(const struct device *dev,
1478 enum cellular_access_technology tech,
1479 enum cellular_registration_status *status)
1480 {
1481 int ret = 0;
1482 struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1483
1484 switch (tech) {
1485 case CELLULAR_ACCESS_TECHNOLOGY_GSM:
1486 *status = data->registration_status_gsm;
1487 break;
1488 case CELLULAR_ACCESS_TECHNOLOGY_GPRS:
1489 case CELLULAR_ACCESS_TECHNOLOGY_UMTS:
1490 case CELLULAR_ACCESS_TECHNOLOGY_EDGE:
1491 *status = data->registration_status_gprs;
1492 break;
1493 case CELLULAR_ACCESS_TECHNOLOGY_LTE:
1494 case CELLULAR_ACCESS_TECHNOLOGY_LTE_CAT_M1:
1495 case CELLULAR_ACCESS_TECHNOLOGY_LTE_CAT_M2:
1496 case CELLULAR_ACCESS_TECHNOLOGY_NB_IOT:
1497 *status = data->registration_status_lte;
1498 break;
1499 default:
1500 ret = -ENODATA;
1501 break;
1502 }
1503
1504 return ret;
1505 }
1506
1507 const static struct cellular_driver_api modem_cellular_api = {
1508 .get_signal = modem_cellular_get_signal,
1509 .get_modem_info = modem_cellular_get_modem_info,
1510 .get_registration_status = modem_cellular_get_registration_status,
1511 };
1512
1513 #ifdef CONFIG_PM_DEVICE
modem_cellular_pm_action(const struct device * dev,enum pm_device_action action)1514 static int modem_cellular_pm_action(const struct device *dev, enum pm_device_action action)
1515 {
1516 struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1517 int ret;
1518
1519 switch (action) {
1520 case PM_DEVICE_ACTION_RESUME:
1521 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_RESUME);
1522 ret = 0;
1523 break;
1524
1525 case PM_DEVICE_ACTION_SUSPEND:
1526 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_SUSPEND);
1527 ret = k_sem_take(&data->suspended_sem, K_SECONDS(30));
1528 break;
1529
1530 default:
1531 ret = -ENOTSUP;
1532 break;
1533 }
1534
1535 return ret;
1536 }
1537 #endif /* CONFIG_PM_DEVICE */
1538
modem_cellular_init(const struct device * dev)1539 static int modem_cellular_init(const struct device *dev)
1540 {
1541 struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
1542 struct modem_cellular_config *config = (struct modem_cellular_config *)dev->config;
1543
1544 data->dev = dev;
1545
1546 k_work_init_delayable(&data->timeout_work, modem_cellular_timeout_handler);
1547
1548 k_work_init(&data->event_dispatch_work, modem_cellular_event_dispatch_handler);
1549 ring_buf_init(&data->event_rb, sizeof(data->event_buf), data->event_buf);
1550
1551 k_sem_init(&data->suspended_sem, 0, 1);
1552
1553 if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
1554 gpio_pin_configure_dt(&config->power_gpio, GPIO_OUTPUT_INACTIVE);
1555 }
1556
1557 if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
1558 gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE);
1559 }
1560
1561 {
1562 const struct modem_backend_uart_config uart_backend_config = {
1563 .uart = config->uart,
1564 .receive_buf = data->uart_backend_receive_buf,
1565 .receive_buf_size = ARRAY_SIZE(data->uart_backend_receive_buf),
1566 .transmit_buf = data->uart_backend_transmit_buf,
1567 .transmit_buf_size = ARRAY_SIZE(data->uart_backend_transmit_buf),
1568 };
1569
1570 data->uart_pipe = modem_backend_uart_init(&data->uart_backend,
1571 &uart_backend_config);
1572 }
1573
1574 {
1575 const struct modem_cmux_config cmux_config = {
1576 .callback = modem_cellular_cmux_handler,
1577 .user_data = data,
1578 .receive_buf = data->cmux_receive_buf,
1579 .receive_buf_size = ARRAY_SIZE(data->cmux_receive_buf),
1580 .transmit_buf = data->cmux_transmit_buf,
1581 .transmit_buf_size = ARRAY_SIZE(data->cmux_transmit_buf),
1582 };
1583
1584 modem_cmux_init(&data->cmux, &cmux_config);
1585 }
1586
1587 {
1588 const struct modem_cmux_dlci_config dlci1_config = {
1589 .dlci_address = 1,
1590 .receive_buf = data->dlci1_receive_buf,
1591 .receive_buf_size = ARRAY_SIZE(data->dlci1_receive_buf),
1592 };
1593
1594 data->dlci1_pipe = modem_cmux_dlci_init(&data->cmux, &data->dlci1,
1595 &dlci1_config);
1596 }
1597
1598 {
1599 const struct modem_cmux_dlci_config dlci2_config = {
1600 .dlci_address = 2,
1601 .receive_buf = data->dlci2_receive_buf,
1602 .receive_buf_size = ARRAY_SIZE(data->dlci2_receive_buf),
1603 };
1604
1605 data->dlci2_pipe = modem_cmux_dlci_init(&data->cmux, &data->dlci2,
1606 &dlci2_config);
1607 }
1608
1609 for (uint8_t i = 0; i < config->user_pipes_size; i++) {
1610 struct modem_cellular_user_pipe *user_pipe = &config->user_pipes[i];
1611 const struct modem_cmux_dlci_config user_dlci_config = {
1612 .dlci_address = user_pipe->dlci_address,
1613 .receive_buf = user_pipe->dlci_receive_buf,
1614 .receive_buf_size = user_pipe->dlci_receive_buf_size,
1615 };
1616
1617 user_pipe->pipe = modem_cmux_dlci_init(&data->cmux, &user_pipe->dlci,
1618 &user_dlci_config);
1619
1620 modem_pipelink_init(user_pipe->pipelink, user_pipe->pipe);
1621 }
1622
1623 {
1624 const struct modem_chat_config chat_config = {
1625 .user_data = data,
1626 .receive_buf = data->chat_receive_buf,
1627 .receive_buf_size = ARRAY_SIZE(data->chat_receive_buf),
1628 .delimiter = data->chat_delimiter,
1629 .delimiter_size = strlen(data->chat_delimiter),
1630 .filter = data->chat_filter,
1631 .filter_size = data->chat_filter ? strlen(data->chat_filter) : 0,
1632 .argv = data->chat_argv,
1633 .argv_size = ARRAY_SIZE(data->chat_argv),
1634 .unsol_matches = unsol_matches,
1635 .unsol_matches_size = ARRAY_SIZE(unsol_matches),
1636 };
1637
1638 modem_chat_init(&data->chat, &chat_config);
1639 }
1640
1641 #ifndef CONFIG_PM_DEVICE
1642 modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_RESUME);
1643 #else
1644 pm_device_init_suspended(dev);
1645 #endif /* CONFIG_PM_DEVICE */
1646
1647 return 0;
1648 }
1649
1650 /*
1651 * Every modem uses two custom scripts to initialize the modem and dial out.
1652 *
1653 * The first script is named <dt driver compatible>_init_chat_script, with its
1654 * script commands named <dt driver compatible>_init_chat_script_cmds. This
1655 * script is sent to the modem after it has started up, and must configure the
1656 * modem to use CMUX.
1657 *
1658 * The second script is named <dt driver compatible>_dial_chat_script, with its
1659 * script commands named <dt driver compatible>_dial_chat_script_cmds. This
1660 * script is sent on a DLCI channel in command mode, and must request the modem
1661 * dial out and put the DLCI channel into data mode.
1662 */
1663
1664 #if DT_HAS_COMPAT_STATUS_OKAY(quectel_bg95)
1665 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_init_chat_script_cmds,
1666 MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1667 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1668 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1669 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1670 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1671 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1672 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1673 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1674 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1675 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1676 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1677 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1678 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1679 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
1680 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1681 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
1682 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1683 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
1684 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1685 MODEM_CHAT_SCRIPT_CMD_RESP("AT+QCCID", qccid_match),
1686 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1687 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300));
1688
1689 MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_init_chat_script, quectel_bg95_init_chat_script_cmds,
1690 abort_matches, modem_cellular_chat_callback_handler, 10);
1691
1692 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_dial_chat_script_cmds,
1693 MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1694 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1695 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1696 ok_match),
1697 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1698 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1699
1700 MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_dial_chat_script, quectel_bg95_dial_chat_script_cmds,
1701 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1702
1703 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_periodic_chat_script_cmds,
1704 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1705 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1706 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
1707
1708 MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_periodic_chat_script,
1709 quectel_bg95_periodic_chat_script_cmds, abort_matches,
1710 modem_cellular_chat_callback_handler, 4);
1711 #endif
1712
1713 #if DT_HAS_COMPAT_STATUS_OKAY(quectel_eg25_g)
1714 MODEM_CHAT_SCRIPT_CMDS_DEFINE(
1715 quectel_eg25_g_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1716 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1717 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1718 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1719 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1720 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1721 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1722 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1723 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1724 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1725 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1726 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1727 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1728 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
1729 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1730 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
1731 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1732 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
1733 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1734 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2", 100));
1735
1736 MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_init_chat_script, quectel_eg25_g_init_chat_script_cmds,
1737 abort_matches, modem_cellular_chat_callback_handler, 10);
1738
1739 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_eg25_g_dial_chat_script_cmds,
1740 MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1741 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1742 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1743 ok_match),
1744 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1745 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1746
1747 MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_dial_chat_script, quectel_eg25_g_dial_chat_script_cmds,
1748 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1749
1750 MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_eg25_g_periodic_chat_script_cmds,
1751 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1752 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1753 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1754 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CSQ", csq_match));
1755
1756 MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_periodic_chat_script,
1757 quectel_eg25_g_periodic_chat_script_cmds, abort_matches,
1758 modem_cellular_chat_callback_handler, 4);
1759 #endif
1760
1761 #if DT_HAS_COMPAT_STATUS_OKAY(simcom_sim7080)
1762 MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_init_chat_script_cmds,
1763 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1764 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1765 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1766 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1767 MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1768 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1769 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1770 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1771 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1772 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1773 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1774 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1775 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1776 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1777 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1778 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1779 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1780 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300));
1781
1782 MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_init_chat_script, simcom_sim7080_init_chat_script_cmds,
1783 abort_matches, modem_cellular_chat_callback_handler, 10);
1784
1785 MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_dial_chat_script_cmds,
1786 MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1787 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1788 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1789 ok_match),
1790 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1791 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1792
1793 MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_dial_chat_script, simcom_sim7080_dial_chat_script_cmds,
1794 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1795
1796 MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_periodic_chat_script_cmds,
1797 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1798 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1799 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
1800
1801 MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_periodic_chat_script,
1802 simcom_sim7080_periodic_chat_script_cmds, abort_matches,
1803 modem_cellular_chat_callback_handler, 4);
1804 #endif
1805
1806 #if DT_HAS_COMPAT_STATUS_OKAY(u_blox_sara_r4)
1807 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_init_chat_script_cmds,
1808 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1809 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1810 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1811 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1812 MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1813 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1814 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1815 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1816 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1817 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1818 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1819 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1820 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1821 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1822 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1823 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1824 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1825 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMUX=0,0,5,127", ok_match));
1826
1827 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_init_chat_script, u_blox_sara_r4_init_chat_script_cmds,
1828 abort_matches, modem_cellular_chat_callback_handler, 10);
1829
1830 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_dial_chat_script_cmds,
1831 MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1832 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1833 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1834 ok_match),
1835 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1836 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1837
1838 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_dial_chat_script, u_blox_sara_r4_dial_chat_script_cmds,
1839 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1840
1841 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_periodic_chat_script_cmds,
1842 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1843 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1844 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
1845
1846 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_periodic_chat_script,
1847 u_blox_sara_r4_periodic_chat_script_cmds, abort_matches,
1848 modem_cellular_chat_callback_handler, 4);
1849 #endif
1850
1851 #if DT_HAS_COMPAT_STATUS_OKAY(u_blox_sara_r5)
1852 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r5_init_chat_script_cmds,
1853 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1854 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1855 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1856 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1857 MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1858 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1859 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1860 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1861 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1862 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1863 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1864 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1865 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1866 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1867 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1868 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1869 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1870 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
1871 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1872 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
1873 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1874 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
1875 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1876 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMUX=0,0,5,127", ok_match));
1877
1878 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r5_init_chat_script, u_blox_sara_r5_init_chat_script_cmds,
1879 abort_matches, modem_cellular_chat_callback_handler, 10);
1880
1881 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r5_dial_chat_script_cmds,
1882 MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
1883 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1884 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1885 ok_match),
1886 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1887 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
1888
1889 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r5_dial_chat_script, u_blox_sara_r5_dial_chat_script_cmds,
1890 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1891
1892 MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r5_periodic_chat_script_cmds,
1893 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1894 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1895 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
1896
1897 MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r5_periodic_chat_script,
1898 u_blox_sara_r5_periodic_chat_script_cmds, abort_matches,
1899 modem_cellular_chat_callback_handler, 4);
1900 #endif
1901
1902 #if DT_HAS_COMPAT_STATUS_OKAY(swir_hl7800)
1903 MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_init_chat_script_cmds,
1904 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1905 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1906 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1907 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1908 MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1909 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1910 MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0", allow_match),
1911 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1912 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1913 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1914 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1915 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1916 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1917 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1918 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1919 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1920 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1921 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
1922 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1923 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
1924 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1925 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
1926 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1927 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 0));
1928
1929 MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_init_chat_script, swir_hl7800_init_chat_script_cmds,
1930 abort_matches, modem_cellular_chat_callback_handler, 10);
1931
1932 MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_dial_chat_script_cmds,
1933 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1934 "\""CONFIG_MODEM_CELLULAR_APN"\"",
1935 ok_match),
1936 MODEM_CHAT_SCRIPT_CMD_RESP("AT+KCNXCFG=1,\"GPRS\",\""
1937 CONFIG_MODEM_CELLULAR_APN
1938 "\",,,\"IPV4\"",
1939 ok_match),
1940 MODEM_CHAT_SCRIPT_CMD_RESP("AT+WPPP=0", ok_match),
1941 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1942 MODEM_CHAT_SCRIPT_CMD_RESP("ATD*99***1#", connect_match));
1943
1944 MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_periodic_chat_script_cmds,
1945 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1946 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match));
1947
1948 MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_periodic_chat_script,
1949 swir_hl7800_periodic_chat_script_cmds, abort_matches,
1950 modem_cellular_chat_callback_handler, 4);
1951
1952 MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_dial_chat_script, swir_hl7800_dial_chat_script_cmds,
1953 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
1954 #endif
1955
1956 #if DT_HAS_COMPAT_STATUS_OKAY(telit_me910g1)
1957 MODEM_CHAT_SCRIPT_CMDS_DEFINE(telit_me910g1_init_chat_script_cmds,
1958 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1959 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1960 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1961 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
1962 MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
1963 MODEM_CHAT_SCRIPT_CMD_RESP("AT+ICCID", iccid_match),
1964 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1965 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
1966 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1967 /* The Telit me910g1 often has an error trying
1968 * to set the PDP context. The radio must be on to set
1969 * the context, and this step must be successful.
1970 * It is moved to the init script to allow retries.
1971 */
1972 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
1973 "\"" CONFIG_MODEM_CELLULAR_APN "\"",
1974 ok_match),
1975 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
1976 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
1977 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
1978 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
1979 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
1980 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
1981 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
1982 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
1983 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
1984 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1985 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
1986 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1987 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
1988 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1989 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
1990 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
1991 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
1992 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2",
1993 300));
1994
1995 MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_init_chat_script, telit_me910g1_init_chat_script_cmds,
1996 abort_matches, modem_cellular_chat_callback_handler, 10);
1997
1998 MODEM_CHAT_SCRIPT_CMDS_DEFINE(telit_me910g1_dial_chat_script_cmds,
1999 MODEM_CHAT_SCRIPT_CMD_RESP("AT", ok_match),
2000 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0));
2001
2002 MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_dial_chat_script, telit_me910g1_dial_chat_script_cmds,
2003 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
2004
2005 MODEM_CHAT_SCRIPT_CMDS_DEFINE(telit_me910g1_periodic_chat_script_cmds,
2006 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2007 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
2008 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match));
2009
2010 MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script,
2011 telit_me910g1_periodic_chat_script_cmds, abort_matches,
2012 modem_cellular_chat_callback_handler, 4);
2013 #endif
2014
2015 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf91_slm)
2016 MODEM_CHAT_SCRIPT_CMDS_DEFINE(nordic_nrf91_slm_init_chat_script_cmds,
2017 MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT", allow_match),
2018 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
2019 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
2020 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2021 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
2022 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2023 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
2024 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2025 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
2026 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2027 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
2028 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2029 MODEM_CHAT_SCRIPT_CMD_RESP("AT#XCMUX=1", ok_match));
2030
2031 MODEM_CHAT_SCRIPT_DEFINE(nordic_nrf91_slm_init_chat_script, nordic_nrf91_slm_init_chat_script_cmds,
2032 abort_matches, modem_cellular_chat_callback_handler, 10);
2033
2034 MODEM_CHAT_SCRIPT_CMDS_DEFINE(nordic_nrf91_slm_dial_chat_script_cmds,
2035 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
2036 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
2037 MODEM_CHAT_SCRIPT_CMD_RESP("AT#XCMUX=2", ok_match));
2038
2039 MODEM_CHAT_SCRIPT_DEFINE(nordic_nrf91_slm_dial_chat_script, nordic_nrf91_slm_dial_chat_script_cmds,
2040 dial_abort_matches, modem_cellular_chat_callback_handler, 10);
2041
2042 MODEM_CHAT_SCRIPT_CMDS_DEFINE(nordic_nrf91_slm_periodic_chat_script_cmds,
2043 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match));
2044
2045 MODEM_CHAT_SCRIPT_DEFINE(nordic_nrf91_slm_periodic_chat_script,
2046 nordic_nrf91_slm_periodic_chat_script_cmds, abort_matches,
2047 modem_cellular_chat_callback_handler, 4);
2048 #endif
2049
2050 #if DT_HAS_COMPAT_STATUS_OKAY(sqn_gm02s)
2051 MODEM_CHAT_SCRIPT_CMDS_DEFINE(sqn_gm02s_init_chat_script_cmds,
2052 MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
2053 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
2054 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
2055 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
2056 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2057 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
2058 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2059 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
2060 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2061 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match),
2062 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2063 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match),
2064 MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2065 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMUX=0,0,5,127", ok_match));
2066
2067 MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_init_chat_script, sqn_gm02s_init_chat_script_cmds,
2068 abort_matches, modem_cellular_chat_callback_handler, 10);
2069
2070 MODEM_CHAT_SCRIPT_CMDS_DEFINE(sqn_gm02s_dial_chat_script_cmds,
2071 MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
2072 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
2073 "\""CONFIG_MODEM_CELLULAR_APN"\"",
2074 ok_match),
2075 MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CFUN=1", 10000),
2076 MODEM_CHAT_SCRIPT_CMD_RESP("ATD*99***1#", connect_match));
2077
2078 MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_dial_chat_script, sqn_gm02s_dial_chat_script_cmds,
2079 dial_abort_matches, modem_cellular_chat_callback_handler, 15);
2080
2081 MODEM_CHAT_SCRIPT_CMDS_DEFINE(sqn_gm02s_periodic_chat_script_cmds,
2082 MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match));
2083
2084 MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script,
2085 sqn_gm02s_periodic_chat_script_cmds, abort_matches,
2086 modem_cellular_chat_callback_handler, 4);
2087 #endif
2088
2089 #define MODEM_CELLULAR_INST_NAME(name, inst) \
2090 _CONCAT_4(name, _, DT_DRV_COMPAT, inst)
2091
2092 #define MODEM_CELLULAR_DEFINE_USER_PIPE_DATA(inst, name, size) \
2093 MODEM_PIPELINK_DT_INST_DEFINE(inst, name); \
2094 static uint8_t MODEM_CELLULAR_INST_NAME(name, inst)[size] \
2095
2096 #define MODEM_CELLULAR_INIT_USER_PIPE(_inst, _name, _dlci_address) \
2097 { \
2098 .dlci_address = _dlci_address, \
2099 .dlci_receive_buf = MODEM_CELLULAR_INST_NAME(_name, _inst), \
2100 .dlci_receive_buf_size = sizeof(MODEM_CELLULAR_INST_NAME(_name, _inst)), \
2101 .pipelink = MODEM_PIPELINK_DT_INST_GET(_inst, _name), \
2102 }
2103
2104 #define MODEM_CELLULAR_DEFINE_USER_PIPES(inst, ...) \
2105 static struct modem_cellular_user_pipe MODEM_CELLULAR_INST_NAME(user_pipes, inst)[] = { \
2106 __VA_ARGS__ \
2107 }
2108
2109 #define MODEM_CELLULAR_GET_USER_PIPES(inst) \
2110 MODEM_CELLULAR_INST_NAME(user_pipes, inst)
2111
2112 #define MODEM_CELLULAR_DEVICE_QUECTEL_BG95(inst) \
2113 MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \
2114 \
2115 static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \
2116 .chat_delimiter = "\r", \
2117 .chat_filter = "\n", \
2118 .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \
2119 }; \
2120 \
2121 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2122 inst, \
2123 user_pipe_0, \
2124 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2125 ); \
2126 \
2127 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2128 inst, \
2129 user_pipe_1, \
2130 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2131 ); \
2132 \
2133 MODEM_CELLULAR_DEFINE_USER_PIPES( \
2134 inst, \
2135 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 3), \
2136 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 4), \
2137 ); \
2138 \
2139 static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \
2140 .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
2141 .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
2142 .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
2143 .power_pulse_duration_ms = 1500, \
2144 .reset_pulse_duration_ms = 100, \
2145 .startup_time_ms = 10000, \
2146 .shutdown_time_ms = 5000, \
2147 .init_chat_script = &quectel_bg95_init_chat_script, \
2148 .dial_chat_script = &quectel_bg95_dial_chat_script, \
2149 .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \
2150 .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \
2151 .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \
2152 }; \
2153 \
2154 PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
2155 \
2156 DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \
2157 &MODEM_CELLULAR_INST_NAME(data, inst), \
2158 &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \
2159 &modem_cellular_api);
2160
2161 #define MODEM_CELLULAR_DEVICE_QUECTEL_EG25_G(inst) \
2162 MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \
2163 \
2164 static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \
2165 .chat_delimiter = "\r", \
2166 .chat_filter = "\n", \
2167 .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \
2168 }; \
2169 \
2170 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2171 inst, \
2172 user_pipe_0, \
2173 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2174 ); \
2175 \
2176 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2177 inst, \
2178 user_pipe_1, \
2179 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2180 ); \
2181 \
2182 MODEM_CELLULAR_DEFINE_USER_PIPES( \
2183 inst, \
2184 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 3), \
2185 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 4), \
2186 ); \
2187 \
2188 static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \
2189 .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
2190 .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
2191 .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
2192 .power_pulse_duration_ms = 1500, \
2193 .reset_pulse_duration_ms = 500, \
2194 .startup_time_ms = 15000, \
2195 .shutdown_time_ms = 5000, \
2196 .init_chat_script = &quectel_eg25_g_init_chat_script, \
2197 .dial_chat_script = &quectel_eg25_g_dial_chat_script, \
2198 .periodic_chat_script = &_CONCAT(DT_DRV_COMPAT, _periodic_chat_script), \
2199 .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \
2200 .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \
2201 }; \
2202 \
2203 PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
2204 \
2205 DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \
2206 &MODEM_CELLULAR_INST_NAME(data, inst), \
2207 &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \
2208 &modem_cellular_api);
2209
2210 #define MODEM_CELLULAR_DEVICE_SIMCOM_SIM7080(inst) \
2211 MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \
2212 \
2213 static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \
2214 .chat_delimiter = "\r", \
2215 .chat_filter = "\n", \
2216 .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \
2217 }; \
2218 \
2219 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2220 inst, \
2221 user_pipe_0, \
2222 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2223 ); \
2224 \
2225 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2226 inst, \
2227 user_pipe_1, \
2228 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2229 ); \
2230 \
2231 MODEM_CELLULAR_DEFINE_USER_PIPES( \
2232 inst, \
2233 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 3), \
2234 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 4), \
2235 ); \
2236 \
2237 static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \
2238 .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
2239 .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
2240 .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
2241 .power_pulse_duration_ms = 1500, \
2242 .reset_pulse_duration_ms = 100, \
2243 .startup_time_ms = 10000, \
2244 .shutdown_time_ms = 5000, \
2245 .init_chat_script = &simcom_sim7080_init_chat_script, \
2246 .dial_chat_script = &simcom_sim7080_dial_chat_script, \
2247 .periodic_chat_script = &simcom_sim7080_periodic_chat_script, \
2248 .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \
2249 .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \
2250 }; \
2251 \
2252 PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
2253 \
2254 DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \
2255 &MODEM_CELLULAR_INST_NAME(data, inst), \
2256 &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \
2257 &modem_cellular_api);
2258
2259 #define MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R4(inst) \
2260 MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \
2261 \
2262 static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \
2263 .chat_delimiter = "\r", \
2264 .chat_filter = "\n", \
2265 .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \
2266 }; \
2267 \
2268 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2269 inst, \
2270 gnss_pipe, \
2271 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2272 ); \
2273 \
2274 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2275 inst, \
2276 user_pipe_0, \
2277 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2278 ); \
2279 \
2280 MODEM_CELLULAR_DEFINE_USER_PIPES( \
2281 inst, \
2282 MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 3), \
2283 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 4), \
2284 ); \
2285 \
2286 static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \
2287 .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
2288 .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
2289 .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
2290 .power_pulse_duration_ms = 1500, \
2291 .reset_pulse_duration_ms = 100, \
2292 .startup_time_ms = 10000, \
2293 .shutdown_time_ms = 5000, \
2294 .init_chat_script = &u_blox_sara_r4_init_chat_script, \
2295 .dial_chat_script = &u_blox_sara_r4_dial_chat_script, \
2296 .periodic_chat_script = &u_blox_sara_r4_periodic_chat_script, \
2297 .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \
2298 .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \
2299 }; \
2300 \
2301 PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
2302 \
2303 DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \
2304 &MODEM_CELLULAR_INST_NAME(data, inst), \
2305 &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \
2306 &modem_cellular_api);
2307
2308 #define MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R5(inst) \
2309 MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \
2310 \
2311 static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \
2312 .chat_delimiter = "\r", \
2313 .chat_filter = "\n", \
2314 .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \
2315 }; \
2316 \
2317 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2318 inst, \
2319 gnss_pipe, \
2320 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2321 ); \
2322 \
2323 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2324 inst, \
2325 user_pipe_0, \
2326 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2327 ); \
2328 \
2329 MODEM_CELLULAR_DEFINE_USER_PIPES( \
2330 inst, \
2331 MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 4), \
2332 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 3), \
2333 ); \
2334 \
2335 static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \
2336 .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
2337 .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
2338 .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
2339 .autostarts = true, \
2340 .power_pulse_duration_ms = 1500, \
2341 .reset_pulse_duration_ms = 100, \
2342 .startup_time_ms = 1500, \
2343 .shutdown_time_ms = 13000, \
2344 .init_chat_script = &u_blox_sara_r5_init_chat_script, \
2345 .dial_chat_script = &u_blox_sara_r5_dial_chat_script, \
2346 .periodic_chat_script = &u_blox_sara_r5_periodic_chat_script, \
2347 .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \
2348 .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \
2349 }; \
2350 \
2351 PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
2352 \
2353 DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \
2354 &MODEM_CELLULAR_INST_NAME(data, inst), \
2355 &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \
2356 &modem_cellular_api);
2357
2358 #define MODEM_CELLULAR_DEVICE_SWIR_HL7800(inst) \
2359 MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \
2360 \
2361 static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \
2362 .chat_delimiter = "\r", \
2363 .chat_filter = "\n", \
2364 .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \
2365 }; \
2366 \
2367 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2368 inst, \
2369 user_pipe_0, \
2370 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2371 ); \
2372 \
2373 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2374 inst, \
2375 user_pipe_1, \
2376 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2377 ); \
2378 \
2379 MODEM_CELLULAR_DEFINE_USER_PIPES( \
2380 inst, \
2381 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 3), \
2382 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 4), \
2383 ); \
2384 \
2385 static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \
2386 .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
2387 .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
2388 .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
2389 .power_pulse_duration_ms = 1500, \
2390 .reset_pulse_duration_ms = 100, \
2391 .startup_time_ms = 10000, \
2392 .shutdown_time_ms = 5000, \
2393 .init_chat_script = &swir_hl7800_init_chat_script, \
2394 .dial_chat_script = &swir_hl7800_dial_chat_script, \
2395 .periodic_chat_script = &swir_hl7800_periodic_chat_script, \
2396 .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \
2397 .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \
2398 }; \
2399 \
2400 PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
2401 \
2402 DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \
2403 &MODEM_CELLULAR_INST_NAME(data, inst), \
2404 &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \
2405 &modem_cellular_api);
2406
2407 #define MODEM_CELLULAR_DEVICE_TELIT_ME910G1(inst) \
2408 MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \
2409 \
2410 static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \
2411 .chat_delimiter = "\r", \
2412 .chat_filter = "\n", \
2413 .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \
2414 }; \
2415 \
2416 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2417 inst, \
2418 user_pipe_0, \
2419 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2420 ); \
2421 \
2422 MODEM_CELLULAR_DEFINE_USER_PIPES( \
2423 inst, \
2424 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 3), \
2425 ); \
2426 \
2427 static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \
2428 .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
2429 .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
2430 .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
2431 .power_pulse_duration_ms = 5050, \
2432 .reset_pulse_duration_ms = 250, \
2433 .startup_time_ms = 15000, \
2434 .shutdown_time_ms = 5000, \
2435 .init_chat_script = &telit_me910g1_init_chat_script, \
2436 .dial_chat_script = &telit_me910g1_dial_chat_script, \
2437 .periodic_chat_script = &telit_me910g1_periodic_chat_script, \
2438 .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \
2439 .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \
2440 }; \
2441 \
2442 PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
2443 \
2444 DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \
2445 &MODEM_CELLULAR_INST_NAME(data, inst), \
2446 &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \
2447 &modem_cellular_api);
2448
2449 #define MODEM_CELLULAR_DEVICE_NORDIC_NRF91_SLM(inst) \
2450 MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 1500); \
2451 \
2452 static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \
2453 .chat_delimiter = "\r\n", \
2454 .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \
2455 }; \
2456 \
2457 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2458 inst, \
2459 gnss_pipe, \
2460 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2461 ); \
2462 \
2463 MODEM_CELLULAR_DEFINE_USER_PIPES( \
2464 inst, \
2465 MODEM_CELLULAR_INIT_USER_PIPE(inst, gnss_pipe, 3), \
2466 ); \
2467 \
2468 static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \
2469 .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
2470 .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
2471 .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
2472 .power_pulse_duration_ms = 100, \
2473 .reset_pulse_duration_ms = 100, \
2474 .startup_time_ms = 2000, \
2475 .shutdown_time_ms = 10000, \
2476 .init_chat_script = &nordic_nrf91_slm_init_chat_script, \
2477 .dial_chat_script = &nordic_nrf91_slm_dial_chat_script, \
2478 .periodic_chat_script = &nordic_nrf91_slm_periodic_chat_script, \
2479 .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \
2480 .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \
2481 }; \
2482 \
2483 PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
2484 \
2485 DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \
2486 &MODEM_CELLULAR_INST_NAME(data, inst), \
2487 &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \
2488 &modem_cellular_api);
2489
2490 #define MODEM_CELLULAR_DEVICE_SQN_GM02S(inst) \
2491 MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \
2492 \
2493 static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \
2494 .chat_delimiter = "\r", \
2495 .chat_filter = "\n", \
2496 .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \
2497 }; \
2498 \
2499 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2500 inst, \
2501 user_pipe_0, \
2502 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2503 ); \
2504 \
2505 MODEM_CELLULAR_DEFINE_USER_PIPE_DATA( \
2506 inst, \
2507 user_pipe_1, \
2508 CONFIG_MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES \
2509 ); \
2510 \
2511 MODEM_CELLULAR_DEFINE_USER_PIPES( \
2512 inst, \
2513 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_0, 3), \
2514 MODEM_CELLULAR_INIT_USER_PIPE(inst, user_pipe_1, 4), \
2515 ); \
2516 \
2517 static const struct modem_cellular_config MODEM_CELLULAR_INST_NAME(config, inst) = { \
2518 .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
2519 .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
2520 .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
2521 .autostarts = true, \
2522 .power_pulse_duration_ms = 1500, \
2523 .reset_pulse_duration_ms = 100, \
2524 .startup_time_ms = 2000, \
2525 .shutdown_time_ms = 5000, \
2526 .init_chat_script = &sqn_gm02s_init_chat_script, \
2527 .dial_chat_script = &sqn_gm02s_dial_chat_script, \
2528 .periodic_chat_script = &sqn_gm02s_periodic_chat_script, \
2529 .user_pipes = MODEM_CELLULAR_GET_USER_PIPES(inst), \
2530 .user_pipes_size = ARRAY_SIZE(MODEM_CELLULAR_GET_USER_PIPES(inst)), \
2531 }; \
2532 \
2533 PM_DEVICE_DT_INST_DEFINE(inst, modem_cellular_pm_action); \
2534 \
2535 DEVICE_DT_INST_DEFINE(inst, modem_cellular_init, PM_DEVICE_DT_INST_GET(inst), \
2536 &MODEM_CELLULAR_INST_NAME(data, inst), \
2537 &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \
2538 &modem_cellular_api);
2539
2540 #define DT_DRV_COMPAT quectel_bg95
2541 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_QUECTEL_BG95)
2542 #undef DT_DRV_COMPAT
2543
2544 #define DT_DRV_COMPAT quectel_eg25_g
2545 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_QUECTEL_EG25_G)
2546 #undef DT_DRV_COMPAT
2547
2548 #define DT_DRV_COMPAT simcom_sim7080
2549 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SIMCOM_SIM7080)
2550 #undef DT_DRV_COMPAT
2551
2552 #define DT_DRV_COMPAT u_blox_sara_r4
2553 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R4)
2554 #undef DT_DRV_COMPAT
2555
2556 #define DT_DRV_COMPAT u_blox_sara_r5
2557 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R5)
2558 #undef DT_DRV_COMPAT
2559
2560 #define DT_DRV_COMPAT swir_hl7800
2561 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SWIR_HL7800)
2562 #undef DT_DRV_COMPAT
2563
2564 #define DT_DRV_COMPAT telit_me910g1
2565 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_TELIT_ME910G1)
2566 #undef DT_DRV_COMPAT
2567
2568 #define DT_DRV_COMPAT nordic_nrf91_slm
2569 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_NORDIC_NRF91_SLM)
2570 #undef DT_DRV_COMPAT
2571
2572 #define DT_DRV_COMPAT sqn_gm02s
2573 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SQN_GM02S)
2574 #undef DT_DRV_COMPAT
2575