diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index c09c9a12795ad..ec2a8ba1018cd 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -187,6 +187,7 @@ struct modem_cellular_config { struct gpio_dt_spec power_gpio; struct gpio_dt_spec reset_gpio; struct gpio_dt_spec wake_gpio; + struct gpio_dt_spec dtr_gpio; uint16_t power_pulse_duration_ms; uint16_t reset_pulse_duration_ms; uint16_t startup_time_ms; @@ -2198,6 +2199,7 @@ static int modem_cellular_init(const struct device *dev) { struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data; struct modem_cellular_config *config = (struct modem_cellular_config *)dev->config; + const struct gpio_dt_spec *dtr_gpio = NULL; data->dev = dev; @@ -2221,9 +2223,15 @@ static int modem_cellular_init(const struct device *dev) gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE); } + if (modem_cellular_gpio_is_enabled(&config->dtr_gpio)) { + gpio_pin_configure_dt(&config->dtr_gpio, GPIO_OUTPUT_INACTIVE); + dtr_gpio = &config->dtr_gpio; + } + { const struct modem_backend_uart_config uart_backend_config = { .uart = config->uart, + .dtr_gpio = dtr_gpio, .receive_buf = data->uart_backend_receive_buf, .receive_buf_size = ARRAY_SIZE(data->uart_backend_receive_buf), .transmit_buf = data->uart_backend_transmit_buf, @@ -2991,6 +2999,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .power_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_power_gpios, {}), \ .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_reset_gpios, {}), \ .wake_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_wake_gpios, {}), \ + .dtr_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mdm_dtr_gpios, {}), \ .power_pulse_duration_ms = (power_ms), \ .reset_pulse_duration_ms = (reset_ms), \ .startup_time_ms = (startup_ms), \ diff --git a/dts/bindings/modem/zephyr,cellular-modem-device.yaml b/dts/bindings/modem/zephyr,cellular-modem-device.yaml index bff39d7f9f613..66c7fd91d092f 100644 --- a/dts/bindings/modem/zephyr,cellular-modem-device.yaml +++ b/dts/bindings/modem/zephyr,cellular-modem-device.yaml @@ -17,3 +17,11 @@ properties: mdm-wake-gpios: type: phandle-array description: GPIO for modem wake + + mdm-dtr-gpios: + type: phandle-array + description: | + GPIO for modem data terminal ready. + + Asserted (logical high) when UART is active and + deasserted (logical low) when UART is inactive, powered down or in low power mode. diff --git a/include/zephyr/modem/backend/uart.h b/include/zephyr/modem/backend/uart.h index 73054b792d8e4..6407af8cf6afa 100644 --- a/include/zephyr/modem/backend/uart.h +++ b/include/zephyr/modem/backend/uart.h @@ -68,6 +68,7 @@ struct modem_backend_uart_async { struct modem_backend_uart { const struct device *uart; + const struct gpio_dt_spec *dtr_gpio; struct modem_pipe pipe; struct k_work_delayable receive_ready_work; struct k_work transmit_idle_work; @@ -85,6 +86,7 @@ struct modem_backend_uart { struct modem_backend_uart_config { const struct device *uart; + const struct gpio_dt_spec *dtr_gpio; /* Address must be word-aligned when CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC is enabled. */ uint8_t *receive_buf; uint32_t receive_buf_size; diff --git a/subsys/modem/backends/modem_backend_uart.c b/subsys/modem/backends/modem_backend_uart.c index 82242a76c0196..13a35406f182f 100644 --- a/subsys/modem/backends/modem_backend_uart.c +++ b/subsys/modem/backends/modem_backend_uart.c @@ -39,6 +39,7 @@ struct modem_pipe *modem_backend_uart_init(struct modem_backend_uart *backend, memset(backend, 0x00, sizeof(*backend)); backend->uart = config->uart; + backend->dtr_gpio = config->dtr_gpio; k_work_init_delayable(&backend->receive_ready_work, modem_backend_uart_receive_ready_handler); k_work_init(&backend->transmit_idle_work, modem_backend_uart_transmit_idle_handler); diff --git a/subsys/modem/backends/modem_backend_uart_async.c b/subsys/modem/backends/modem_backend_uart_async.c index 9b5edc8965c52..1615120a4d5e0 100644 --- a/subsys/modem/backends/modem_backend_uart_async.c +++ b/subsys/modem/backends/modem_backend_uart_async.c @@ -11,6 +11,7 @@ LOG_MODULE_REGISTER(modem_backend_uart_async, CONFIG_MODEM_MODULES_LOG_LEVEL); #include +#include #include enum { @@ -157,6 +158,10 @@ static int modem_backend_uart_async_open(void *data) atomic_clear(&backend->async.common.state); ring_buf_reset(&backend->async.receive_rb); + if (backend->dtr_gpio) { + gpio_pin_set_dt(backend->dtr_gpio, 1); + } + atomic_set_bit(&backend->async.common.state, MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF0_USED_BIT); atomic_set_bit(&backend->async.common.state, MODEM_BACKEND_UART_ASYNC_STATE_RECEIVING_BIT); @@ -268,6 +273,9 @@ static int modem_backend_uart_async_close(void *data) atomic_clear_bit(&backend->async.common.state, MODEM_BACKEND_UART_ASYNC_STATE_OPEN_BIT); uart_tx_abort(backend->uart); uart_rx_disable(backend->uart); + if (backend->dtr_gpio) { + gpio_pin_set_dt(backend->dtr_gpio, 0); + } return 0; } diff --git a/subsys/modem/backends/modem_backend_uart_async_hwfc.c b/subsys/modem/backends/modem_backend_uart_async_hwfc.c index 61d307604e5c5..3aaaad2e196c7 100644 --- a/subsys/modem/backends/modem_backend_uart_async_hwfc.c +++ b/subsys/modem/backends/modem_backend_uart_async_hwfc.c @@ -11,6 +11,7 @@ LOG_MODULE_REGISTER(modem_backend_uart_async_hwfc, CONFIG_MODEM_MODULES_LOG_LEVEL); #include +#include #include struct rx_buf_t { @@ -221,6 +222,10 @@ static int modem_backend_uart_async_hwfc_open(void *data) return -ENOMEM; } + if (backend->dtr_gpio) { + gpio_pin_set_dt(backend->dtr_gpio, 1); + } + atomic_clear(&backend->async.common.state); atomic_set_bit(&backend->async.common.state, MODEM_BACKEND_UART_ASYNC_STATE_OPEN_BIT); @@ -357,6 +362,9 @@ static int modem_backend_uart_async_hwfc_close(void *data) uart_rx_disable(backend->uart); } + if (backend->dtr_gpio) { + gpio_pin_set_dt(backend->dtr_gpio, 0); + } return 0; }