Loading include/sound/cpe_cmi.h +14 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/types.h> #define CPE_AFE_PORT_1_TX 1 #define CPE_AFE_PORT_ID_2_OUT 0x02 #define CMI_INBAND_MESSAGE_SIZE 127 /* Loading Loading @@ -81,6 +82,7 @@ #define CPE_AFE_PORT_CMD_SHARED_MEM_ALLOC (0x1005) #define CPE_AFE_PORT_CMDRSP_SHARED_MEM_ALLOC (0x1006) #define CPE_AFE_PORT_CMD_SHARED_MEM_DEALLOC (0x1007) #define CPE_AFE_PORT_CMD_GENERIC_CONFIG (0x1008) /* AFE Service module and param IDs */ #define CPE_AFE_CMD_SET_PARAM (0x1000) Loading Loading @@ -304,6 +306,14 @@ struct cpe_afe_port_cfg { u32 sample_rate; } __packed; struct cpe_afe_cmd_port_cfg { struct cmi_hdr hdr; u8 bit_width; u8 num_channels; u16 buffer_size; u32 sample_rate; } __packed; struct cpe_afe_params { struct cmi_hdr hdr; struct cpe_afe_hw_mad_ctrl hw_mad_ctrl; Loading Loading @@ -405,4 +415,8 @@ struct cpe_lsm_lab_latency_config { #define OUT_FMT_CFG_CMD_PAYLOAD_SIZE ( \ sizeof(struct cpe_lsm_output_format_cfg) - \ sizeof(struct cmi_hdr)) #define CPE_AFE_CMD_PORT_CFG_PAYLOAD_SIZE \ (sizeof(struct cpe_afe_cmd_port_cfg) - \ sizeof(struct cmi_hdr)) #endif /* __CPE_CMI_H__ */ include/sound/cpe_core.h +4 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ struct cpe_lsm_session { struct completion cmd_comp; struct wcd_cpe_afe_port_cfg afe_port_cfg; struct wcd_cpe_afe_port_cfg afe_out_port_cfg; struct mutex lsm_lock; u32 snd_model_size; Loading Loading @@ -90,6 +91,9 @@ struct wcd_cpe_afe_ops { int (*afe_port_resume) (void *core_handle, struct wcd_cpe_afe_port_cfg *cfg); int (*afe_port_cmd_cfg)(void *core_handle, struct wcd_cpe_afe_port_cfg *cfg); }; struct wcd_cpe_lsm_ops { Loading sound/soc/codecs/wcd_cpe_core.c +54 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ #define CMI_CMD_TIMEOUT (10 * HZ) #define WCD_CPE_LSM_MAX_SESSIONS 1 #define WCD_CPE_AFE_MAX_PORTS 1 #define WCD_CPE_AFE_MAX_PORTS 2 #define WCD_CPE_DRAM_SIZE 0x30000 #define WCD_CPE_DRAM_OFFSET 0x50000 Loading Loading @@ -67,6 +67,15 @@ #define CPE_ERR_IRQ_CB(core) \ (core->cpe_cdc_cb->cpe_err_irq_control) #define AFE_OUT_BUF_SAMPLES 8 /* * AFE output buffer size is always * AFE_OUT_BUF_SAMPLES * number of bytes per sample */ #define AFE_OUT_BUF_SIZE(bit_width) \ (AFE_OUT_BUF_SAMPLES * (bit_width / BITS_PER_BYTE)) enum afe_port_state { AFE_PORT_STATE_DEINIT = 0, AFE_PORT_STATE_INIT, Loading Loading @@ -3300,6 +3309,49 @@ static int wcd_cpe_is_valid_port(struct wcd_cpe_core *core, return 0; } static int wcd_cpe_afe_cmd_port_cfg(void *core_handle, struct wcd_cpe_afe_port_cfg *afe_cfg) { struct cpe_afe_cmd_port_cfg port_cfg_cmd; struct wcd_cpe_core *core = core_handle; struct wcd_cmi_afe_port_data *afe_port_d; int ret; ret = wcd_cpe_is_valid_port(core, afe_cfg, __func__); if (ret) goto done; afe_port_d = &afe_ports[afe_cfg->port_id]; afe_port_d->port_id = afe_cfg->port_id; WCD_CPE_GRAB_LOCK(&afe_port_d->afe_lock, "afe"); memset(&port_cfg_cmd, 0, sizeof(port_cfg_cmd)); if (fill_afe_cmd_header(&port_cfg_cmd.hdr, afe_cfg->port_id, CPE_AFE_PORT_CMD_GENERIC_CONFIG, CPE_AFE_CMD_PORT_CFG_PAYLOAD_SIZE, false)) { ret = -EINVAL; goto err_ret; } port_cfg_cmd.bit_width = afe_cfg->bit_width; port_cfg_cmd.num_channels = afe_cfg->num_channels; port_cfg_cmd.sample_rate = afe_cfg->sample_rate; port_cfg_cmd.buffer_size = AFE_OUT_BUF_SIZE(afe_cfg->bit_width); ret = wcd_cpe_cmi_send_afe_msg(core, afe_port_d, &port_cfg_cmd); if (ret) dev_err(core->dev, "%s: afe_port_config failed, err = %d\n", __func__, ret); err_ret: WCD_CPE_REL_LOCK(&afe_port_d->afe_lock, "afe"); done: return ret; } /* * wcd_cpe_afe_set_params: set the parameters for afe port * @afe_cfg: configuration data for the port for which the Loading Loading @@ -3529,6 +3581,7 @@ int wcd_cpe_get_afe_ops(struct wcd_cpe_afe_ops *afe_ops) afe_ops->afe_port_stop = wcd_cpe_afe_port_stop; afe_ops->afe_port_suspend = wcd_cpe_afe_port_suspend; afe_ops->afe_port_resume = wcd_cpe_afe_port_resume; afe_ops->afe_port_cmd_cfg = wcd_cpe_afe_cmd_port_cfg; return 0; } Loading sound/soc/msm/msm-cpe-lsm.c +54 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <sound/msm-slim-dma.h> #define LSM_VOICE_WAKEUP_APP_V2 2 #define AFE_OUT_PORT_2 2 #define LISTEN_MIN_NUM_PERIODS 2 #define LISTEN_MAX_NUM_PERIODS 8 #define LISTEN_MAX_PERIOD_SIZE 4096 Loading Loading @@ -104,6 +105,7 @@ struct cpe_hw_params { u16 sample_size; u32 buf_sz; u32 period_count; u16 channels; }; struct cpe_data_pcm_buf { Loading Loading @@ -239,10 +241,14 @@ static int msm_cpe_afe_port_cntl( int rc = 0; if (!afe_cfg->port_id) { dev_err(rtd->dev, /* * It is possible driver can get closed without prepare, * in which case afe ports will not be initialized. */ dev_dbg(rtd->dev, "%s: Invalid afe port id\n", __func__); return -EINVAL; return 0; } switch (cmd) { Loading Loading @@ -285,6 +291,7 @@ static int msm_cpe_lsm_lab_stop(struct snd_pcm_substream *substream) struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); struct cpe_priv *cpe = cpe_get_private_data(substream); struct wcd_cpe_lsm_ops *lsm_ops; struct wcd_cpe_afe_ops *afe_ops; struct cpe_lsm_session *session; struct cpe_lsm_lab *lab_d = &lsm_d->lab; struct msm_slim_dma_data *dma_data = NULL; Loading Loading @@ -317,6 +324,7 @@ static int msm_cpe_lsm_lab_stop(struct snd_pcm_substream *substream) } lsm_ops = &cpe->lsm_ops; afe_ops = &cpe->afe_ops; session = lsm_d->lsm_session; if (rtd->cpu_dai) dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, Loading Loading @@ -371,6 +379,18 @@ static int msm_cpe_lsm_lab_stop(struct snd_pcm_substream *substream) dev_err(rtd->dev, "%s: POST ch teardown failed, err = %d\n", __func__, rc); lab_d->thread_status = MSM_LSM_LAB_THREAD_STOP; /* * Even though LAB stop failed, * output AFE port needs to be stopped */ rc = afe_ops->afe_port_stop(cpe->core_handle, &session->afe_out_port_cfg); if (rc) dev_err(rtd->dev, "%s: AFE out port stop failed, err = %d\n", __func__, rc); return 0; } Loading Loading @@ -1444,7 +1464,11 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream, struct cpe_priv *cpe = NULL; struct cpe_lsm_session *session = NULL; struct cpe_lsm_lab *lab_d = NULL; struct cpe_hw_params *hw_params; struct wcd_cpe_lsm_ops *lsm_ops; struct wcd_cpe_afe_ops *afe_ops; struct wcd_cpe_afe_port_cfg *out_port; int rc; if (!substream || !substream->private_data) { pr_err("%s: invalid substream (%p)\n", Loading Loading @@ -1473,6 +1497,8 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream, session = lsm_d->lsm_session; lsm_ops = &cpe->lsm_ops; lab_d = &lsm_d->lab; afe_ops = &cpe->afe_ops; hw_params = &lsm_d->hw_params; if (!session->started) { dev_dbg(rtd->dev, Loading @@ -1487,6 +1513,30 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream, event_status->status == LSM_VOICE_WAKEUP_STATUS_DETECTED) { out_port = &session->afe_out_port_cfg; out_port->port_id = AFE_OUT_PORT_2; out_port->bit_width = hw_params->sample_size; out_port->num_channels = hw_params->channels; out_port->sample_rate = hw_params->sample_rate; rc = afe_ops->afe_port_cmd_cfg(cpe->core_handle, out_port); if (rc) { dev_err(rtd->dev, "%s: Failed afe generic config v2, err = %d\n", __func__, rc); return rc; } rc = afe_ops->afe_port_start(cpe->core_handle, out_port); if (rc) { dev_err(rtd->dev, "%s: AFE out port start failed, err = %d\n", __func__, rc); return rc; } atomic_set(&lab_d->abort_read, 0); dev_dbg(rtd->dev, "%s: KW detected, scheduling LAB thread\n", Loading Loading @@ -2052,7 +2102,9 @@ static int msm_cpe_lsm_hwparams(struct snd_pcm_substream *substream, hw_params->buf_sz = (params_buffer_bytes(params) / params_periods(params)); hw_params->period_count = params_periods(params); hw_params->channels = params_channels(params); hw_params->sample_rate = params_rate(params); if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) hw_params->sample_size = 16; else if (params_format(params) == Loading Loading
include/sound/cpe_cmi.h +14 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/types.h> #define CPE_AFE_PORT_1_TX 1 #define CPE_AFE_PORT_ID_2_OUT 0x02 #define CMI_INBAND_MESSAGE_SIZE 127 /* Loading Loading @@ -81,6 +82,7 @@ #define CPE_AFE_PORT_CMD_SHARED_MEM_ALLOC (0x1005) #define CPE_AFE_PORT_CMDRSP_SHARED_MEM_ALLOC (0x1006) #define CPE_AFE_PORT_CMD_SHARED_MEM_DEALLOC (0x1007) #define CPE_AFE_PORT_CMD_GENERIC_CONFIG (0x1008) /* AFE Service module and param IDs */ #define CPE_AFE_CMD_SET_PARAM (0x1000) Loading Loading @@ -304,6 +306,14 @@ struct cpe_afe_port_cfg { u32 sample_rate; } __packed; struct cpe_afe_cmd_port_cfg { struct cmi_hdr hdr; u8 bit_width; u8 num_channels; u16 buffer_size; u32 sample_rate; } __packed; struct cpe_afe_params { struct cmi_hdr hdr; struct cpe_afe_hw_mad_ctrl hw_mad_ctrl; Loading Loading @@ -405,4 +415,8 @@ struct cpe_lsm_lab_latency_config { #define OUT_FMT_CFG_CMD_PAYLOAD_SIZE ( \ sizeof(struct cpe_lsm_output_format_cfg) - \ sizeof(struct cmi_hdr)) #define CPE_AFE_CMD_PORT_CFG_PAYLOAD_SIZE \ (sizeof(struct cpe_afe_cmd_port_cfg) - \ sizeof(struct cmi_hdr)) #endif /* __CPE_CMI_H__ */
include/sound/cpe_core.h +4 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ struct cpe_lsm_session { struct completion cmd_comp; struct wcd_cpe_afe_port_cfg afe_port_cfg; struct wcd_cpe_afe_port_cfg afe_out_port_cfg; struct mutex lsm_lock; u32 snd_model_size; Loading Loading @@ -90,6 +91,9 @@ struct wcd_cpe_afe_ops { int (*afe_port_resume) (void *core_handle, struct wcd_cpe_afe_port_cfg *cfg); int (*afe_port_cmd_cfg)(void *core_handle, struct wcd_cpe_afe_port_cfg *cfg); }; struct wcd_cpe_lsm_ops { Loading
sound/soc/codecs/wcd_cpe_core.c +54 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ #define CMI_CMD_TIMEOUT (10 * HZ) #define WCD_CPE_LSM_MAX_SESSIONS 1 #define WCD_CPE_AFE_MAX_PORTS 1 #define WCD_CPE_AFE_MAX_PORTS 2 #define WCD_CPE_DRAM_SIZE 0x30000 #define WCD_CPE_DRAM_OFFSET 0x50000 Loading Loading @@ -67,6 +67,15 @@ #define CPE_ERR_IRQ_CB(core) \ (core->cpe_cdc_cb->cpe_err_irq_control) #define AFE_OUT_BUF_SAMPLES 8 /* * AFE output buffer size is always * AFE_OUT_BUF_SAMPLES * number of bytes per sample */ #define AFE_OUT_BUF_SIZE(bit_width) \ (AFE_OUT_BUF_SAMPLES * (bit_width / BITS_PER_BYTE)) enum afe_port_state { AFE_PORT_STATE_DEINIT = 0, AFE_PORT_STATE_INIT, Loading Loading @@ -3300,6 +3309,49 @@ static int wcd_cpe_is_valid_port(struct wcd_cpe_core *core, return 0; } static int wcd_cpe_afe_cmd_port_cfg(void *core_handle, struct wcd_cpe_afe_port_cfg *afe_cfg) { struct cpe_afe_cmd_port_cfg port_cfg_cmd; struct wcd_cpe_core *core = core_handle; struct wcd_cmi_afe_port_data *afe_port_d; int ret; ret = wcd_cpe_is_valid_port(core, afe_cfg, __func__); if (ret) goto done; afe_port_d = &afe_ports[afe_cfg->port_id]; afe_port_d->port_id = afe_cfg->port_id; WCD_CPE_GRAB_LOCK(&afe_port_d->afe_lock, "afe"); memset(&port_cfg_cmd, 0, sizeof(port_cfg_cmd)); if (fill_afe_cmd_header(&port_cfg_cmd.hdr, afe_cfg->port_id, CPE_AFE_PORT_CMD_GENERIC_CONFIG, CPE_AFE_CMD_PORT_CFG_PAYLOAD_SIZE, false)) { ret = -EINVAL; goto err_ret; } port_cfg_cmd.bit_width = afe_cfg->bit_width; port_cfg_cmd.num_channels = afe_cfg->num_channels; port_cfg_cmd.sample_rate = afe_cfg->sample_rate; port_cfg_cmd.buffer_size = AFE_OUT_BUF_SIZE(afe_cfg->bit_width); ret = wcd_cpe_cmi_send_afe_msg(core, afe_port_d, &port_cfg_cmd); if (ret) dev_err(core->dev, "%s: afe_port_config failed, err = %d\n", __func__, ret); err_ret: WCD_CPE_REL_LOCK(&afe_port_d->afe_lock, "afe"); done: return ret; } /* * wcd_cpe_afe_set_params: set the parameters for afe port * @afe_cfg: configuration data for the port for which the Loading Loading @@ -3529,6 +3581,7 @@ int wcd_cpe_get_afe_ops(struct wcd_cpe_afe_ops *afe_ops) afe_ops->afe_port_stop = wcd_cpe_afe_port_stop; afe_ops->afe_port_suspend = wcd_cpe_afe_port_suspend; afe_ops->afe_port_resume = wcd_cpe_afe_port_resume; afe_ops->afe_port_cmd_cfg = wcd_cpe_afe_cmd_port_cfg; return 0; } Loading
sound/soc/msm/msm-cpe-lsm.c +54 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <sound/msm-slim-dma.h> #define LSM_VOICE_WAKEUP_APP_V2 2 #define AFE_OUT_PORT_2 2 #define LISTEN_MIN_NUM_PERIODS 2 #define LISTEN_MAX_NUM_PERIODS 8 #define LISTEN_MAX_PERIOD_SIZE 4096 Loading Loading @@ -104,6 +105,7 @@ struct cpe_hw_params { u16 sample_size; u32 buf_sz; u32 period_count; u16 channels; }; struct cpe_data_pcm_buf { Loading Loading @@ -239,10 +241,14 @@ static int msm_cpe_afe_port_cntl( int rc = 0; if (!afe_cfg->port_id) { dev_err(rtd->dev, /* * It is possible driver can get closed without prepare, * in which case afe ports will not be initialized. */ dev_dbg(rtd->dev, "%s: Invalid afe port id\n", __func__); return -EINVAL; return 0; } switch (cmd) { Loading Loading @@ -285,6 +291,7 @@ static int msm_cpe_lsm_lab_stop(struct snd_pcm_substream *substream) struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream); struct cpe_priv *cpe = cpe_get_private_data(substream); struct wcd_cpe_lsm_ops *lsm_ops; struct wcd_cpe_afe_ops *afe_ops; struct cpe_lsm_session *session; struct cpe_lsm_lab *lab_d = &lsm_d->lab; struct msm_slim_dma_data *dma_data = NULL; Loading Loading @@ -317,6 +324,7 @@ static int msm_cpe_lsm_lab_stop(struct snd_pcm_substream *substream) } lsm_ops = &cpe->lsm_ops; afe_ops = &cpe->afe_ops; session = lsm_d->lsm_session; if (rtd->cpu_dai) dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, Loading Loading @@ -371,6 +379,18 @@ static int msm_cpe_lsm_lab_stop(struct snd_pcm_substream *substream) dev_err(rtd->dev, "%s: POST ch teardown failed, err = %d\n", __func__, rc); lab_d->thread_status = MSM_LSM_LAB_THREAD_STOP; /* * Even though LAB stop failed, * output AFE port needs to be stopped */ rc = afe_ops->afe_port_stop(cpe->core_handle, &session->afe_out_port_cfg); if (rc) dev_err(rtd->dev, "%s: AFE out port stop failed, err = %d\n", __func__, rc); return 0; } Loading Loading @@ -1444,7 +1464,11 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream, struct cpe_priv *cpe = NULL; struct cpe_lsm_session *session = NULL; struct cpe_lsm_lab *lab_d = NULL; struct cpe_hw_params *hw_params; struct wcd_cpe_lsm_ops *lsm_ops; struct wcd_cpe_afe_ops *afe_ops; struct wcd_cpe_afe_port_cfg *out_port; int rc; if (!substream || !substream->private_data) { pr_err("%s: invalid substream (%p)\n", Loading Loading @@ -1473,6 +1497,8 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream, session = lsm_d->lsm_session; lsm_ops = &cpe->lsm_ops; lab_d = &lsm_d->lab; afe_ops = &cpe->afe_ops; hw_params = &lsm_d->hw_params; if (!session->started) { dev_dbg(rtd->dev, Loading @@ -1487,6 +1513,30 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream, event_status->status == LSM_VOICE_WAKEUP_STATUS_DETECTED) { out_port = &session->afe_out_port_cfg; out_port->port_id = AFE_OUT_PORT_2; out_port->bit_width = hw_params->sample_size; out_port->num_channels = hw_params->channels; out_port->sample_rate = hw_params->sample_rate; rc = afe_ops->afe_port_cmd_cfg(cpe->core_handle, out_port); if (rc) { dev_err(rtd->dev, "%s: Failed afe generic config v2, err = %d\n", __func__, rc); return rc; } rc = afe_ops->afe_port_start(cpe->core_handle, out_port); if (rc) { dev_err(rtd->dev, "%s: AFE out port start failed, err = %d\n", __func__, rc); return rc; } atomic_set(&lab_d->abort_read, 0); dev_dbg(rtd->dev, "%s: KW detected, scheduling LAB thread\n", Loading Loading @@ -2052,7 +2102,9 @@ static int msm_cpe_lsm_hwparams(struct snd_pcm_substream *substream, hw_params->buf_sz = (params_buffer_bytes(params) / params_periods(params)); hw_params->period_count = params_periods(params); hw_params->channels = params_channels(params); hw_params->sample_rate = params_rate(params); if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) hw_params->sample_size = 16; else if (params_format(params) == Loading