modem: gsm: Initialize the modem UART separately

This is needed if muxing is enabled in which case we must
change the UART to muxing UART after the AT+CMUX command
has succeed.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2020-03-31 16:49:09 +03:00
commit 775dcb222e
3 changed files with 81 additions and 19 deletions

View file

@ -317,6 +317,30 @@ static void gsm_finalize_connection(struct gsm_modem *gsm)
}
set_ppp_carrier_on(gsm);
if (IS_ENABLED(CONFIG_GSM_MUX) && gsm->mux_enabled) {
/* Re-use the original iface for AT channel */
ret = modem_iface_uart_init_dev(&gsm->context.iface,
gsm->at_dev->config->name);
if (ret < 0) {
LOG_DBG("iface %suart error %d", "AT ", ret);
} else {
/* Do a test and try to send AT command to modem */
ret = modem_cmd_send(&gsm->context.iface,
&gsm->context.cmd_handler,
&response_cmds[0],
ARRAY_SIZE(response_cmds),
"AT", &gsm->sem_response,
GSM_CMD_AT_TIMEOUT);
if (ret < 0) {
LOG_DBG("modem setup returned %d, %s",
ret, "AT cmds failed");
} else {
LOG_INF("AT channel %d connected to %s",
DLCI_AT, gsm->at_dev->config->name);
}
}
}
}
static int mux_enable(struct gsm_modem *gsm)
@ -455,16 +479,23 @@ static void mux_setup(struct k_work *work)
break;
case STATE_DONE:
/* Re-use the original iface for AT channel */
ret = modem_iface_uart_init(&gsm->context.iface,
&gsm->gsm_data,
gsm->at_dev->config->name);
/* At least the SIMCOM modem expects that the Internet
* connection is created in PPP channel. We will need
* to attach the AT channel to context iface after the
* PPP connection is established in order to give AT commands
* to the modem.
*/
ret = modem_iface_uart_init_dev(&gsm->context.iface,
gsm->ppp_dev->config->name);
if (ret < 0) {
LOG_DBG("iface %suart error %d", "mux ", ret);
LOG_DBG("iface %suart error %d", "PPP ", ret);
gsm->mux_enabled = false;
goto fail;
}
LOG_INF("PPP channel %d connected to %s",
DLCI_PPP, gsm->ppp_dev->config->name);
gsm_finalize_connection(gsm);
break;
}

View file

@ -121,27 +121,15 @@ static int modem_iface_uart_write(struct modem_iface *iface,
return 0;
}
int modem_iface_uart_init(struct modem_iface *iface,
struct modem_iface_uart_data *data,
const char *dev_name)
int modem_iface_uart_init_dev(struct modem_iface *iface,
const char *dev_name)
{
if (!iface || !data) {
return -EINVAL;
}
/* get UART device */
iface->dev = device_get_binding(dev_name);
if (!iface->dev) {
return -ENODEV;
}
iface->iface_data = data;
iface->read = modem_iface_uart_read;
iface->write = modem_iface_uart_write;
ring_buf_init(&data->rx_rb, data->rx_rb_buf_len, data->rx_rb_buf);
k_sem_init(&data->rx_sem, 0, 1);
uart_irq_rx_disable(iface->dev);
uart_irq_tx_disable(iface->dev);
modem_iface_uart_flush(iface);
@ -150,3 +138,33 @@ int modem_iface_uart_init(struct modem_iface *iface,
return 0;
}
int modem_iface_uart_init(struct modem_iface *iface,
struct modem_iface_uart_data *data,
const char *dev_name)
{
int ret;
if (!iface || !data) {
return -EINVAL;
}
iface->iface_data = data;
iface->read = modem_iface_uart_read;
iface->write = modem_iface_uart_write;
ring_buf_init(&data->rx_rb, data->rx_rb_buf_len, data->rx_rb_buf);
k_sem_init(&data->rx_sem, 0, 1);
/* get UART device */
ret = modem_iface_uart_init_dev(iface, dev_name);
if (ret < 0) {
iface->iface_data = NULL;
iface->read = NULL;
iface->write = NULL;
return ret;
}
return 0;
}

View file

@ -35,6 +35,19 @@ struct modem_iface_uart_data {
struct k_sem rx_sem;
};
/**
* @brief Init modem interface device for UART
*
* @details This can be called after the init if the UART is changed.
*
* @param *iface: modem interface to initialize.
* @param *dev_name: name of the UART device to use
*
* @retval 0 if ok, < 0 if error.
*/
int modem_iface_uart_init_dev(struct modem_iface *iface,
const char *dev_name);
/**
* @brief Init modem interface for UART
*