Skip to content

Commit 043773a

Browse files
committed
Backport changes from upstream zephyr
Updated `cellular_modem.c` to include recent changes from upstream Zephyr, including bug fixes, improvements, and the addition of support for the A76xx modem driver.
1 parent 5e2af66 commit 043773a

File tree

9 files changed

+251
-10
lines changed

9 files changed

+251
-10
lines changed

drivers/modem/Kconfig.cellular

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ config MODEM_CELLULAR
1313
select RING_BUFFER
1414
select NET_L2_PPP_OPTION_MRU
1515
select NET_L2_PPP_PAP
16-
depends on (DT_HAS_QUECTEL_BG95_ENABLED || \
16+
select NET_L2_PPP_MGMT
17+
depends on (DT_HAS_QUECTEL_BG95_ENABLED || DT_HAS_SIMCOM_A76XX_ENABLED || \
1718
DT_HAS_SIMCOM_SIM7080_ENABLED || DT_HAS_U_BLOX_SARA_R4_ENABLED || \
1819
DT_HAS_U_BLOX_SARA_R5_ENABLED || DT_HAS_SWIR_HL7800_ENABLED || \
1920
DT_HAS_TELIT_ME910G1_ENABLED || DT_HAS_TELIT_ME310G1_ENABLED || \

drivers/modem/modem_cellular.c

Lines changed: 187 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ enum modem_cellular_state {
6060
MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT,
6161
MODEM_CELLULAR_STATE_AWAIT_REGISTERED,
6262
MODEM_CELLULAR_STATE_CARRIER_ON,
63+
MODEM_CELLULAR_STATE_DORMANT,
6364
MODEM_CELLULAR_STATE_INIT_POWER_OFF,
6465
MODEM_CELLULAR_STATE_RUN_SHUTDOWN_SCRIPT,
6566
MODEM_CELLULAR_STATE_POWER_OFF_PULSE,
@@ -79,6 +80,7 @@ enum modem_cellular_event {
7980
MODEM_CELLULAR_EVENT_DEREGISTERED,
8081
MODEM_CELLULAR_EVENT_BUS_OPENED,
8182
MODEM_CELLULAR_EVENT_BUS_CLOSED,
83+
MODEM_CELLULAR_EVENT_PPP_DEAD,
8284
};
8385

8486
struct modem_cellular_data {
@@ -126,6 +128,7 @@ struct modem_cellular_data {
126128

127129
/* PPP */
128130
struct modem_ppp *ppp;
131+
struct net_mgmt_event_callback net_mgmt_event_callback;
129132

130133
enum modem_cellular_state state;
131134
const struct device *dev;
@@ -154,6 +157,7 @@ struct modem_cellular_config {
154157
const struct device *uart;
155158
struct gpio_dt_spec power_gpio;
156159
struct gpio_dt_spec reset_gpio;
160+
struct gpio_dt_spec wake_gpio;
157161
uint16_t power_pulse_duration_ms;
158162
uint16_t reset_pulse_duration_ms;
159163
uint16_t startup_time_ms;
@@ -195,6 +199,8 @@ static const char *modem_cellular_state_str(enum modem_cellular_state state)
195199
return "run dial script";
196200
case MODEM_CELLULAR_STATE_CARRIER_ON:
197201
return "carrier on";
202+
case MODEM_CELLULAR_STATE_DORMANT:
203+
return "dormant";
198204
case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
199205
return "init power off";
200206
case MODEM_CELLULAR_STATE_RUN_SHUTDOWN_SCRIPT:
@@ -235,6 +241,8 @@ static const char *modem_cellular_event_str(enum modem_cellular_event event)
235241
return "bus opened";
236242
case MODEM_CELLULAR_EVENT_BUS_CLOSED:
237243
return "bus closed";
244+
case MODEM_CELLULAR_EVENT_PPP_DEAD:
245+
return "ppp dead";
238246
}
239247

240248
return "";
@@ -517,7 +525,7 @@ MODEM_CHAT_MATCHES_DEFINE(dial_abort_matches,
517525
MODEM_CHAT_MATCH("NO CARRIER", "", NULL),
518526
MODEM_CHAT_MATCH("NO DIALTONE", "", NULL));
519527

520-
#if DT_HAS_COMPAT_STATUS_OKAY(swir_hl7800) || DT_HAS_COMPAT_STATUS_OKAY(sqn_gm02s)
528+
#if DT_HAS_COMPAT_STATUS_OKAY(swir_hl7800) || DT_HAS_COMPAT_STATUS_OKAY(sqn_gm02s) || DT_HAS_COMPAT_STATUS_OKAY(simcom_a76xx)
521529
MODEM_CHAT_MATCH_DEFINE(connect_match, "CONNECT", "", NULL);
522530
#endif
523531

@@ -599,11 +607,17 @@ static int modem_cellular_on_idle_state_enter(struct modem_cellular_data *data)
599607
const struct modem_cellular_config *config =
600608
(const struct modem_cellular_config *)data->dev->config;
601609

610+
if (modem_cellular_gpio_is_enabled(&config->wake_gpio)) {
611+
gpio_pin_set_dt(&config->wake_gpio, 0);
612+
}
613+
602614
if (modem_cellular_gpio_is_enabled(&config->reset_gpio)) {
603615
gpio_pin_set_dt(&config->reset_gpio, 1);
604616
}
605617

606618
modem_cellular_notify_user_pipes_disconnected(data);
619+
net_if_carrier_off(modem_ppp_get_iface(data->ppp));
620+
net_if_dormant_off(modem_ppp_get_iface(data->ppp));
607621
modem_chat_release(&data->chat);
608622
modem_ppp_release(data->ppp);
609623
modem_cmux_release(&data->cmux);
@@ -662,6 +676,10 @@ static int modem_cellular_on_idle_state_leave(struct modem_cellular_data *data)
662676
gpio_pin_set_dt(&config->reset_gpio, 0);
663677
}
664678

679+
if (modem_cellular_gpio_is_enabled(&config->wake_gpio)) {
680+
gpio_pin_set_dt(&config->wake_gpio, 1);
681+
}
682+
665683
return 0;
666684
}
667685

@@ -670,6 +688,10 @@ static int modem_cellular_on_reset_pulse_state_enter(struct modem_cellular_data
670688
const struct modem_cellular_config *config =
671689
(const struct modem_cellular_config *)data->dev->config;
672690

691+
if (modem_cellular_gpio_is_enabled(&config->wake_gpio)) {
692+
gpio_pin_set_dt(&config->wake_gpio, 0);
693+
}
694+
673695
gpio_pin_set_dt(&config->reset_gpio, 1);
674696
modem_cellular_start_timer(data, K_MSEC(config->reset_pulse_duration_ms));
675697
return 0;
@@ -698,6 +720,11 @@ static int modem_cellular_on_reset_pulse_state_leave(struct modem_cellular_data
698720
(const struct modem_cellular_config *)data->dev->config;
699721

700722
gpio_pin_set_dt(&config->reset_gpio, 0);
723+
724+
if (modem_cellular_gpio_is_enabled(&config->wake_gpio)) {
725+
gpio_pin_set_dt(&config->wake_gpio, 1);
726+
}
727+
701728
modem_cellular_stop_timer(data);
702729
return 0;
703730
}
@@ -1003,7 +1030,9 @@ static void modem_cellular_run_dial_script_event_handler(struct modem_cellular_d
10031030
modem_chat_attach(&data->chat, data->dlci1_pipe);
10041031
modem_chat_run_script_async(&data->chat, config->dial_chat_script);
10051032
break;
1006-
1033+
case MODEM_CELLULAR_EVENT_SCRIPT_FAILED:
1034+
modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT);
1035+
break;
10071036
case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
10081037
modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_REGISTERED);
10091038
break;
@@ -1092,7 +1121,7 @@ static void modem_cellular_carrier_on_event_handler(struct modem_cellular_data *
10921121
break;
10931122

10941123
case MODEM_CELLULAR_EVENT_DEREGISTERED:
1095-
modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT);
1124+
modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_DORMANT);
10961125
break;
10971126

10981127
case MODEM_CELLULAR_EVENT_SUSPEND:
@@ -1107,9 +1136,37 @@ static void modem_cellular_carrier_on_event_handler(struct modem_cellular_data *
11071136
static int modem_cellular_on_carrier_on_state_leave(struct modem_cellular_data *data)
11081137
{
11091138
modem_cellular_stop_timer(data);
1139+
1140+
return 0;
1141+
}
1142+
1143+
static int modem_cellular_on_dormant_state_enter(struct modem_cellular_data *data)
1144+
{
1145+
net_if_dormant_on(modem_ppp_get_iface(data->ppp));
1146+
1147+
return 0;
1148+
}
1149+
1150+
static void modem_cellular_dormant_event_handler(struct modem_cellular_data *data,
1151+
enum modem_cellular_event evt)
1152+
{
1153+
switch (evt) {
1154+
case MODEM_CELLULAR_EVENT_PPP_DEAD:
1155+
modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_RUN_DIAL_SCRIPT);
1156+
break;
1157+
1158+
default:
1159+
break;
1160+
}
1161+
}
1162+
1163+
static int modem_cellular_on_dormant_state_leave(struct modem_cellular_data *data)
1164+
{
11101165
net_if_carrier_off(modem_ppp_get_iface(data->ppp));
11111166
modem_chat_release(&data->chat);
11121167
modem_ppp_release(data->ppp);
1168+
net_if_dormant_off(modem_ppp_get_iface(data->ppp));
1169+
11131170
return 0;
11141171
}
11151172

@@ -1298,6 +1355,10 @@ static int modem_cellular_on_state_enter(struct modem_cellular_data *data)
12981355
ret = modem_cellular_on_carrier_on_state_enter(data);
12991356
break;
13001357

1358+
case MODEM_CELLULAR_STATE_DORMANT:
1359+
ret = modem_cellular_on_dormant_state_enter(data);
1360+
break;
1361+
13011362
case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
13021363
ret = modem_cellular_on_init_power_off_state_enter(data);
13031364
break;
@@ -1359,6 +1420,10 @@ static int modem_cellular_on_state_leave(struct modem_cellular_data *data)
13591420
ret = modem_cellular_on_carrier_on_state_leave(data);
13601421
break;
13611422

1423+
case MODEM_CELLULAR_STATE_DORMANT:
1424+
ret = modem_cellular_on_dormant_state_leave(data);
1425+
break;
1426+
13621427
case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
13631428
ret = modem_cellular_on_init_power_off_state_leave(data);
13641429
break;
@@ -1458,6 +1523,10 @@ static void modem_cellular_event_handler(struct modem_cellular_data *data,
14581523
modem_cellular_carrier_on_event_handler(data, evt);
14591524
break;
14601525

1526+
case MODEM_CELLULAR_STATE_DORMANT:
1527+
modem_cellular_dormant_event_handler(data, evt);
1528+
break;
1529+
14611530
case MODEM_CELLULAR_STATE_INIT_POWER_OFF:
14621531
modem_cellular_init_power_off_event_handler(data, evt);
14631532
break;
@@ -1701,6 +1770,22 @@ static int modem_cellular_pm_action(const struct device *dev, enum pm_device_act
17011770
}
17021771
#endif /* CONFIG_PM_DEVICE */
17031772

1773+
static void net_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
1774+
struct net_if *iface)
1775+
{
1776+
struct modem_cellular_data *data =
1777+
CONTAINER_OF(cb, struct modem_cellular_data, net_mgmt_event_callback);
1778+
1779+
switch (mgmt_event) {
1780+
case NET_EVENT_PPP_PHASE_DEAD:
1781+
modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_PPP_DEAD);
1782+
break;
1783+
1784+
default:
1785+
break;
1786+
}
1787+
}
1788+
17041789
static int modem_cellular_init(const struct device *dev)
17051790
{
17061791
struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data;
@@ -1715,6 +1800,10 @@ static int modem_cellular_init(const struct device *dev)
17151800

17161801
k_sem_init(&data->suspended_sem, 0, 1);
17171802

1803+
if (modem_cellular_gpio_is_enabled(&config->wake_gpio)) {
1804+
gpio_pin_configure_dt(&config->wake_gpio, GPIO_OUTPUT_INACTIVE);
1805+
}
1806+
17181807
if (modem_cellular_gpio_is_enabled(&config->power_gpio)) {
17191808
gpio_pin_configure_dt(&config->power_gpio, GPIO_OUTPUT_INACTIVE);
17201809
}
@@ -1805,6 +1894,13 @@ static int modem_cellular_init(const struct device *dev)
18051894
modem_chat_init(&data->chat, &chat_config);
18061895
}
18071896

1897+
{
1898+
net_mgmt_init_event_callback(&data->net_mgmt_event_callback, net_mgmt_event_handler,
1899+
NET_EVENT_PPP_PHASE_DEAD);
1900+
net_mgmt_add_event_callback(&data->net_mgmt_event_callback);
1901+
}
1902+
1903+
18081904
#ifndef CONFIG_PM_DEVICE
18091905
modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_RESUME);
18101906
#else
@@ -1970,6 +2066,59 @@ MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_periodic_chat_script,
19702066
modem_cellular_chat_callback_handler, 4);
19712067
#endif
19722068

2069+
#if DT_HAS_COMPAT_STATUS_OKAY(simcom_a76xx)
2070+
MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_a76xx_init_chat_script_cmds,
2071+
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2072+
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2073+
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2074+
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2075+
MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
2076+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match),
2077+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
2078+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG=1", ok_match),
2079+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG=1", ok_match),
2080+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
2081+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2082+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2083+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match),
2084+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match),
2085+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2086+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
2087+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
2088+
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127", 300));
2089+
2090+
MODEM_CHAT_SCRIPT_DEFINE(simcom_a76xx_init_chat_script, simcom_a76xx_init_chat_script_cmds,
2091+
abort_matches, modem_cellular_chat_callback_handler, 10);
2092+
2093+
MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_a76xx_dial_chat_script_cmds,
2094+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDCONT=1,\"IP\","
2095+
"\""CONFIG_MODEM_CELLULAR_APN"\"",
2096+
ok_match),
2097+
MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
2098+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
2099+
MODEM_CHAT_SCRIPT_CMD_RESP("ATD*99***1#", connect_match),);
2100+
2101+
MODEM_CHAT_SCRIPT_DEFINE(simcom_a76xx_dial_chat_script, simcom_a76xx_dial_chat_script_cmds,
2102+
dial_abort_matches, modem_cellular_chat_callback_handler, 10);
2103+
2104+
MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_a76xx_periodic_chat_script_cmds,
2105+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?", ok_match),
2106+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
2107+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGREG?", ok_match));
2108+
2109+
MODEM_CHAT_SCRIPT_DEFINE(simcom_a76xx_periodic_chat_script,
2110+
simcom_a76xx_periodic_chat_script_cmds, abort_matches,
2111+
modem_cellular_chat_callback_handler, 4);
2112+
2113+
MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_a76xx_shutdown_chat_script_cmds,
2114+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CPOF", ok_match));
2115+
2116+
MODEM_CHAT_SCRIPT_DEFINE(simcom_a76xx_shutdown_chat_script,
2117+
simcom_a76xx_shutdown_chat_script_cmds, abort_matches,
2118+
modem_cellular_chat_callback_handler, 15);
2119+
2120+
#endif
2121+
19732122
#if DT_HAS_COMPAT_STATUS_OKAY(u_blox_sara_r4)
19742123
MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_init_chat_script_cmds,
19752124
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
@@ -2127,10 +2276,16 @@ MODEM_CHAT_SCRIPT_DEFINE(u_blox_lara_r6_periodic_chat_script,
21272276

21282277
#if DT_HAS_COMPAT_STATUS_OKAY(swir_hl7800)
21292278
MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_init_chat_script_cmds,
2130-
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2131-
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2132-
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2133-
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100),
2279+
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 1000),
2280+
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 1000),
2281+
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 1000),
2282+
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 1000),
2283+
/* Turn off sleep mode */
2284+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+KSLEEP=2", ok_match),
2285+
/* Turn off PSM */
2286+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CPSMS=0", ok_match),
2287+
/* Turn off eDRX */
2288+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEDRXS=0", ok_match),
21342289
MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match),
21352290
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
21362291
MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0", allow_match),
@@ -2388,6 +2543,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script,
23882543
.uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
23892544
.power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \
23902545
.reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \
2546+
.wake_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_wake_gpios, {}), \
23912547
.power_pulse_duration_ms = (power_ms), \
23922548
.reset_pulse_duration_ms = (reset_ms), \
23932549
.startup_time_ms = (startup_ms), \
@@ -2466,6 +2622,26 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script,
24662622
&simcom_sim7080_dial_chat_script, \
24672623
&simcom_sim7080_periodic_chat_script, NULL)
24682624

2625+
#define MODEM_CELLULAR_DEVICE_SIMCOM_A76XX(inst) \
2626+
MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \
2627+
\
2628+
static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \
2629+
.chat_delimiter = "\r", \
2630+
.chat_filter = "\n", \
2631+
.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \
2632+
}; \
2633+
\
2634+
MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst, \
2635+
(user_pipe_0, 3), \
2636+
(user_pipe_1, 4)) \
2637+
\
2638+
MODEM_CELLULAR_DEFINE_INSTANCE(inst, 500, 100, 15000, 5000, false, \
2639+
NULL, \
2640+
&simcom_a76xx_init_chat_script, \
2641+
&simcom_a76xx_dial_chat_script, \
2642+
&simcom_a76xx_periodic_chat_script, \
2643+
&simcom_a76xx_shutdown_chat_script)
2644+
24692645
#define MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R4(inst) \
24702646
MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \
24712647
\
@@ -2629,6 +2805,10 @@ DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_QUECTEL_EG25_G)
26292805
DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SIMCOM_SIM7080)
26302806
#undef DT_DRV_COMPAT
26312807

2808+
#define DT_DRV_COMPAT simcom_a76xx
2809+
DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SIMCOM_A76XX)
2810+
#undef DT_DRV_COMPAT
2811+
26322812
#define DT_DRV_COMPAT u_blox_sara_r4
26332813
DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R4)
26342814
#undef DT_DRV_COMPAT

0 commit comments

Comments
 (0)