Loading asoc/msm-compress-q6-v2.c +30 −3 Original line number Diff line number Diff line Loading @@ -225,7 +225,7 @@ static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, int stream_id); static int msm_compr_set_render_mode(struct msm_compr_audio *prtd, uint32_t render_mode) { uint32_t render_mode, int dir) { int ret = -EINVAL; struct audio_client *ac = prtd->audio_client; Loading @@ -250,7 +250,7 @@ static int msm_compr_set_render_mode(struct msm_compr_audio *prtd, goto exit; } ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode); ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir); if (ret) { pr_err("%s, Render mode can't be set error %d\n", __func__, ret); Loading Loading @@ -324,6 +324,29 @@ static int msm_compr_set_render_window(struct audio_client *ac, return ret; } static int msm_compr_set_ttp_offset(struct audio_client *ac, uint32_t offset_lsw, uint32_t offset_msw, int dir) { int ret = -EINVAL; struct asm_session_mtmx_strtr_param_ttp_offset_t ttp_offset; uint32_t param_id; pr_debug("%s, ttp offset lsw 0x%x ttp offset msw 0x%x\n", __func__, offset_lsw, offset_msw); memset(&ttp_offset, 0, sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t)); ttp_offset.ttp_offset_lsw = offset_lsw; ttp_offset.ttp_offset_msw = offset_msw; param_id = ASM_SESSION_MTMX_STRTR_PARAM_TTP_OFFSET; ret = q6asm_send_mtmx_strtr_ttp_offset(ac, &ttp_offset, param_id, dir); if (ret) pr_err("%s, ttp offset can't be set error %d\n", __func__, ret); return ret; } static int msm_compr_enable_adjust_session_clock(struct audio_client *ac, bool enable) { Loading Loading @@ -3221,7 +3244,8 @@ static int msm_compr_set_metadata(struct snd_compr_stream *cstream, __func__, metadata->value[0]); prtd->gapless_state.initial_samples_drop = metadata->value[0]; } else if (metadata->key == SNDRV_COMPRESS_RENDER_MODE) { return msm_compr_set_render_mode(prtd, metadata->value[0]); return msm_compr_set_render_mode(prtd, metadata->value[0], cstream->direction); } else if (metadata->key == SNDRV_COMPRESS_CLK_REC_MODE) { return msm_compr_set_clk_rec_mode(ac, metadata->value[0]); } else if (metadata->key == SNDRV_COMPRESS_RENDER_WINDOW) { Loading @@ -3242,6 +3266,9 @@ static int msm_compr_set_metadata(struct snd_compr_stream *cstream, return msm_compr_adjust_session_clock(ac, metadata->value[0], metadata->value[1]); } else if (metadata->key == SNDRV_COMPRESS_IN_TTP_OFFSET) { return msm_compr_set_ttp_offset(ac, metadata->value[0], metadata->value[1], cstream->direction); } return 0; Loading asoc/msm-dai-q6-v2.c +135 −7 Original line number Diff line number Diff line Loading @@ -232,6 +232,7 @@ struct msm_dai_q6_dai_data { u16 afe_tx_out_bitformat; struct afe_enc_config enc_config; struct afe_dec_config dec_config; struct afe_ttp_config ttp_config; union afe_port_config port_config; u16 vi_feed_mono; u32 xt_logging_disable; Loading Loading @@ -2230,6 +2231,7 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, { struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); int rc = 0; uint16_t ttp_gen_enable = dai_data->ttp_config.ttp_gen_enable.enable; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { if (dai_data->enc_config.format != ENC_FMT_NONE) { Loading Loading @@ -2279,13 +2281,27 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, bitwidth = 0; break; } if (ttp_gen_enable == true) { pr_debug("%s: calling AFE_PORT_START_V3 with dec format: %d\n", __func__, dai_data->dec_config.format); rc = afe_port_start_v3(dai->id, &dai_data->port_config, dai_data->rate, dai_data->afe_tx_out_channels, bitwidth, NULL, &dai_data->dec_config, &dai_data->ttp_config); } else { pr_debug("%s: calling AFE_PORT_START_V2 with dec format: %d\n", __func__, dai_data->dec_config.format); rc = afe_port_start_v2(dai->id, &dai_data->port_config, rc = afe_port_start_v2(dai->id, &dai_data->port_config, dai_data->rate, dai_data->afe_tx_out_channels, bitwidth, NULL, &dai_data->dec_config); } if (rc < 0) { pr_err("%s: fail to open AFE port 0x%x\n", __func__, dai->id); Loading Loading @@ -3669,6 +3685,91 @@ static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, return ret; } static int msm_dai_q6_afe_enable_ttp_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = sizeof(struct afe_ttp_gen_enable_t); return 0; } static int msm_dai_q6_afe_enable_ttp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; pr_debug("%s:\n", __func__); if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); return -EINVAL; } memcpy(ucontrol->value.bytes.data, &dai_data->ttp_config.ttp_gen_enable, sizeof(struct afe_ttp_gen_enable_t)); return 0; } static int msm_dai_q6_afe_enable_ttp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; pr_debug("%s:\n", __func__); if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); return -EINVAL; } memcpy(&dai_data->ttp_config.ttp_gen_enable, ucontrol->value.bytes.data, sizeof(struct afe_ttp_gen_enable_t)); return 0; } static int msm_dai_q6_afe_ttp_cfg_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = sizeof(struct afe_ttp_gen_cfg_t); return 0; } static int msm_dai_q6_afe_ttp_cfg_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; pr_debug("%s:\n", __func__); if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); return -EINVAL; } memcpy(ucontrol->value.bytes.data, &dai_data->ttp_config.ttp_gen_cfg, sizeof(struct afe_ttp_gen_cfg_t)); return 0; } static int msm_dai_q6_afe_ttp_cfg_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; pr_debug("%s: Received ttp config\n", __func__); if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); return -EINVAL; } memcpy(&dai_data->ttp_config.ttp_gen_cfg, ucontrol->value.bytes.data, sizeof(struct afe_ttp_gen_cfg_t)); return 0; } static const struct snd_kcontrol_new afe_dec_config_controls[] = { { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | Loading Loading @@ -3696,6 +3797,27 @@ static const struct snd_kcontrol_new afe_dec_config_controls[] = { msm_dai_q6_afe_output_bit_format_put), }; static const struct snd_kcontrol_new afe_ttp_config_controls[] = { { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE), .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "TTP Enable", .info = msm_dai_q6_afe_enable_ttp_info, .get = msm_dai_q6_afe_enable_ttp_get, .put = msm_dai_q6_afe_enable_ttp_put, }, { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE), .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "AFE TTP config", .info = msm_dai_q6_afe_ttp_cfg_info, .get = msm_dai_q6_afe_ttp_cfg_get, .put = msm_dai_q6_afe_ttp_cfg_put, }, }; static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { Loading Loading @@ -3919,6 +4041,12 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_dec_config_controls[3], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_ttp_config_controls[0], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_ttp_config_controls[1], dai_data)); break; case RT_PROXY_DAI_001_RX: rc = snd_ctl_add(dai->component->card->snd_card, Loading asoc/msm-transcode-loopback-q6-v2.c +4 −3 Original line number Diff line number Diff line Loading @@ -613,7 +613,7 @@ static int msm_transcode_loopback_get_caps(struct snd_compr_stream *cstream, } static int msm_transcode_set_render_mode(struct msm_transcode_loopback *prtd, uint32_t render_mode) uint32_t render_mode, int dir) { int ret = -EINVAL; struct audio_client *ac = prtd->audio_client; Loading @@ -639,7 +639,7 @@ static int msm_transcode_set_render_mode(struct msm_transcode_loopback *prtd, goto exit; } ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode); ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir); if (ret) { pr_err("%s: Render mode can't be set error %d\n", __func__, ret); Loading Loading @@ -705,7 +705,8 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, } case SNDRV_COMPRESS_RENDER_MODE: { rc = msm_transcode_set_render_mode(prtd, metadata->value[0]); rc = msm_transcode_set_render_mode(prtd, metadata->value[0], cstream->direction); if (rc) pr_err("%s: error setting render mode %d\n", __func__, rc); Loading dsp/q6afe.c +94 −5 Original line number Diff line number Diff line Loading @@ -3925,6 +3925,51 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) return ret; } static int q6afe_send_ttp_config(u16 port_id, union afe_port_config afe_config, struct afe_ttp_config *ttp_cfg) { struct afe_ttp_gen_enable_t ttp_gen_enable; struct afe_ttp_gen_cfg_t ttp_gen_cfg; struct param_hdr_v3 param_hdr; int ret; memset(&ttp_gen_enable, 0, sizeof(ttp_gen_enable)); memset(&ttp_gen_cfg, 0, sizeof(ttp_gen_cfg)); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_ID_DECODER; param_hdr.instance_id = INSTANCE_ID_0; pr_debug("%s: Enable TTP generator\n", __func__); ttp_gen_enable = ttp_cfg->ttp_gen_enable; param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE; param_hdr.param_size = sizeof(struct afe_ttp_gen_enable_t); ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &ttp_gen_enable); if (ret) { pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } pr_debug("%s: sending TTP generator config\n", __func__); ttp_gen_cfg = ttp_cfg->ttp_gen_cfg; param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG; param_hdr.param_size = sizeof(struct afe_ttp_gen_cfg_t); ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &ttp_gen_cfg); if (ret) pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG for port 0x%x failed %d\n", __func__, port_id, ret); exit: return ret; } static int q6afe_send_dec_config(u16 port_id, union afe_port_config afe_config, struct afe_dec_config *cfg, Loading Loading @@ -4595,7 +4640,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, union afe_enc_config_data *enc_cfg, u32 codec_format, u32 scrambler_mode, u32 mono_mode, struct afe_dec_config *dec_cfg) struct afe_dec_config *dec_cfg, struct afe_ttp_config *ttp_cfg) { union afe_port_config port_cfg; struct param_hdr_v3 param_hdr; Loading Loading @@ -4913,6 +4959,15 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, goto fail_cmd; } } if (ttp_cfg != NULL) { ret = q6afe_send_ttp_config(port_id, *afe_config, ttp_cfg); if (ret) { pr_err("%s: AFE TTP config for port 0x%x failed %d\n", __func__, port_id, ret); goto fail_cmd; } } } port_index = afe_get_port_index(port_id); Loading Loading @@ -4959,8 +5014,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate) { return __afe_port_start(port_id, afe_config, rate, 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, 0, NULL); return __afe_port_start(port_id, afe_config, rate, 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, 0, NULL, NULL); } EXPORT_SYMBOL(afe_port_start); Loading Loading @@ -4990,16 +5045,50 @@ int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, afe_in_channels, afe_in_bit_width, &enc_cfg->data, enc_cfg->format, enc_cfg->scrambler_mode, enc_cfg->mono_mode, dec_cfg); enc_cfg->mono_mode, dec_cfg, NULL); else if (dec_cfg != NULL) ret = __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, NULL, dec_cfg->format, 0, 0, dec_cfg); NULL, dec_cfg->format, 0, 0, dec_cfg, NULL); return ret; } EXPORT_SYMBOL(afe_port_start_v2); /** * afe_port_start_v3 - to configure AFE session with * specified port configuration and encoder /decoder params * * @port_id: AFE port id number * @afe_config: port configuration * @rate: sampling rate of port * @enc_cfg: AFE enc configuration information to setup encoder * @afe_in_channels: AFE input channel configuration, this needs * update only if input channel is differ from AFE output * @dec_cfg: AFE dec configuration information to set up decoder * @ttp_cfg: TTP generator configuration to enable TTP in AFE * * Returns 0 on success or error value on port start failure. */ int afe_port_start_v3(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, struct afe_enc_config *enc_cfg, struct afe_dec_config *dec_cfg, struct afe_ttp_config *ttp_cfg) { int ret = 0; if (dec_cfg != NULL && ttp_cfg != NULL) ret = __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, NULL, dec_cfg->format, 0, 0, dec_cfg, ttp_cfg); return ret; } EXPORT_SYMBOL(afe_port_start_v3); int afe_get_port_index(u16 port_id) { switch (port_id) { Loading dsp/q6asm.c +91 −2 Original line number Diff line number Diff line Loading @@ -10047,17 +10047,106 @@ int q6asm_send_mtmx_strtr_window(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_send_mtmx_strtr_window); /** * q6asm_send_mtmx_strtr_ttp_offset - * command to send matrix for ttp offset * * @ac: Audio client handle * @ttp_offset: ttp offset params * @param_id: param id for ttp offset * @dir: RX or TX direction * * Returns 0 on success or error on failure */ int q6asm_send_mtmx_strtr_ttp_offset(struct audio_client *ac, struct asm_session_mtmx_strtr_param_ttp_offset_t *ttp_offset, uint32_t param_id, int dir) { struct asm_mtmx_strtr_params matrix; int sz = 0; int rc = 0; pr_debug("%s: ttp offset lsw is %d, ttp offset msw is %d\n", __func__, ttp_offset->ttp_offset_lsw, ttp_offset->ttp_offset_msw); if (!ac) { pr_err("%s: audio client handle is NULL\n", __func__); rc = -EINVAL; goto fail_cmd; } if (ac->apr == NULL) { pr_err("%s: ac->apr is NULL", __func__); rc = -EINVAL; goto fail_cmd; } memset(&matrix, 0, sizeof(struct asm_mtmx_strtr_params)); sz = sizeof(struct asm_mtmx_strtr_params); q6asm_add_hdr(ac, &matrix.hdr, sz, TRUE); atomic_set(&ac->cmd_state, -1); matrix.hdr.opcode = ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2; matrix.param.data_payload_addr_lsw = 0; matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t); matrix.param.direction = dir; matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; matrix.data.param_id = param_id; matrix.data.param_size = sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t); matrix.data.reserved = 0; memcpy(&(matrix.config.ttp_offset), ttp_offset, sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t)); rc = apr_send_pkt(ac->apr, (uint32_t *) &matrix); if (rc < 0) { pr_err("%s: ttp offset send failed paramid [0x%x]\n", __func__, matrix.data.param_id); rc = -EINVAL; goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, (atomic_read(&ac->cmd_state) >= 0), msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout, ttp offset paramid[0x%x]\n", __func__, matrix.data.param_id); rc = -ETIMEDOUT; goto fail_cmd; } if (atomic_read(&ac->cmd_state) > 0) { pr_err("%s: DSP returned error[%s]\n", __func__, adsp_err_get_err_str( atomic_read(&ac->cmd_state))); rc = adsp_err_get_lnx_err_code( atomic_read(&ac->cmd_state)); goto fail_cmd; } rc = 0; fail_cmd: return rc; } EXPORT_SYMBOL(q6asm_send_mtmx_strtr_ttp_offset); /** * q6asm_send_mtmx_strtr_render_mode - * command to send matrix for render mode * * @ac: Audio client handle * @render_mode: rendering mode * @dir: RX or TX direction * * Returns 0 on success or error on failure */ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, uint32_t render_mode) uint32_t render_mode, int dir) { struct asm_mtmx_strtr_params matrix; struct asm_session_mtmx_strtr_param_render_mode_t render_param; Loading Loading @@ -10101,7 +10190,7 @@ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, matrix.param.data_payload_size = sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_render_mode_t); matrix.param.direction = 0; /* RX */ matrix.param.direction = dir; matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; matrix.data.param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_MODE_CMD; matrix.data.param_size = Loading Loading
asoc/msm-compress-q6-v2.c +30 −3 Original line number Diff line number Diff line Loading @@ -225,7 +225,7 @@ static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, int stream_id); static int msm_compr_set_render_mode(struct msm_compr_audio *prtd, uint32_t render_mode) { uint32_t render_mode, int dir) { int ret = -EINVAL; struct audio_client *ac = prtd->audio_client; Loading @@ -250,7 +250,7 @@ static int msm_compr_set_render_mode(struct msm_compr_audio *prtd, goto exit; } ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode); ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir); if (ret) { pr_err("%s, Render mode can't be set error %d\n", __func__, ret); Loading Loading @@ -324,6 +324,29 @@ static int msm_compr_set_render_window(struct audio_client *ac, return ret; } static int msm_compr_set_ttp_offset(struct audio_client *ac, uint32_t offset_lsw, uint32_t offset_msw, int dir) { int ret = -EINVAL; struct asm_session_mtmx_strtr_param_ttp_offset_t ttp_offset; uint32_t param_id; pr_debug("%s, ttp offset lsw 0x%x ttp offset msw 0x%x\n", __func__, offset_lsw, offset_msw); memset(&ttp_offset, 0, sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t)); ttp_offset.ttp_offset_lsw = offset_lsw; ttp_offset.ttp_offset_msw = offset_msw; param_id = ASM_SESSION_MTMX_STRTR_PARAM_TTP_OFFSET; ret = q6asm_send_mtmx_strtr_ttp_offset(ac, &ttp_offset, param_id, dir); if (ret) pr_err("%s, ttp offset can't be set error %d\n", __func__, ret); return ret; } static int msm_compr_enable_adjust_session_clock(struct audio_client *ac, bool enable) { Loading Loading @@ -3221,7 +3244,8 @@ static int msm_compr_set_metadata(struct snd_compr_stream *cstream, __func__, metadata->value[0]); prtd->gapless_state.initial_samples_drop = metadata->value[0]; } else if (metadata->key == SNDRV_COMPRESS_RENDER_MODE) { return msm_compr_set_render_mode(prtd, metadata->value[0]); return msm_compr_set_render_mode(prtd, metadata->value[0], cstream->direction); } else if (metadata->key == SNDRV_COMPRESS_CLK_REC_MODE) { return msm_compr_set_clk_rec_mode(ac, metadata->value[0]); } else if (metadata->key == SNDRV_COMPRESS_RENDER_WINDOW) { Loading @@ -3242,6 +3266,9 @@ static int msm_compr_set_metadata(struct snd_compr_stream *cstream, return msm_compr_adjust_session_clock(ac, metadata->value[0], metadata->value[1]); } else if (metadata->key == SNDRV_COMPRESS_IN_TTP_OFFSET) { return msm_compr_set_ttp_offset(ac, metadata->value[0], metadata->value[1], cstream->direction); } return 0; Loading
asoc/msm-dai-q6-v2.c +135 −7 Original line number Diff line number Diff line Loading @@ -232,6 +232,7 @@ struct msm_dai_q6_dai_data { u16 afe_tx_out_bitformat; struct afe_enc_config enc_config; struct afe_dec_config dec_config; struct afe_ttp_config ttp_config; union afe_port_config port_config; u16 vi_feed_mono; u32 xt_logging_disable; Loading Loading @@ -2230,6 +2231,7 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, { struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); int rc = 0; uint16_t ttp_gen_enable = dai_data->ttp_config.ttp_gen_enable.enable; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { if (dai_data->enc_config.format != ENC_FMT_NONE) { Loading Loading @@ -2279,13 +2281,27 @@ static int msm_dai_q6_prepare(struct snd_pcm_substream *substream, bitwidth = 0; break; } if (ttp_gen_enable == true) { pr_debug("%s: calling AFE_PORT_START_V3 with dec format: %d\n", __func__, dai_data->dec_config.format); rc = afe_port_start_v3(dai->id, &dai_data->port_config, dai_data->rate, dai_data->afe_tx_out_channels, bitwidth, NULL, &dai_data->dec_config, &dai_data->ttp_config); } else { pr_debug("%s: calling AFE_PORT_START_V2 with dec format: %d\n", __func__, dai_data->dec_config.format); rc = afe_port_start_v2(dai->id, &dai_data->port_config, rc = afe_port_start_v2(dai->id, &dai_data->port_config, dai_data->rate, dai_data->afe_tx_out_channels, bitwidth, NULL, &dai_data->dec_config); } if (rc < 0) { pr_err("%s: fail to open AFE port 0x%x\n", __func__, dai->id); Loading Loading @@ -3669,6 +3685,91 @@ static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol, return ret; } static int msm_dai_q6_afe_enable_ttp_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = sizeof(struct afe_ttp_gen_enable_t); return 0; } static int msm_dai_q6_afe_enable_ttp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; pr_debug("%s:\n", __func__); if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); return -EINVAL; } memcpy(ucontrol->value.bytes.data, &dai_data->ttp_config.ttp_gen_enable, sizeof(struct afe_ttp_gen_enable_t)); return 0; } static int msm_dai_q6_afe_enable_ttp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; pr_debug("%s:\n", __func__); if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); return -EINVAL; } memcpy(&dai_data->ttp_config.ttp_gen_enable, ucontrol->value.bytes.data, sizeof(struct afe_ttp_gen_enable_t)); return 0; } static int msm_dai_q6_afe_ttp_cfg_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = sizeof(struct afe_ttp_gen_cfg_t); return 0; } static int msm_dai_q6_afe_ttp_cfg_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; pr_debug("%s:\n", __func__); if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); return -EINVAL; } memcpy(ucontrol->value.bytes.data, &dai_data->ttp_config.ttp_gen_cfg, sizeof(struct afe_ttp_gen_cfg_t)); return 0; } static int msm_dai_q6_afe_ttp_cfg_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; pr_debug("%s: Received ttp config\n", __func__); if (!dai_data) { pr_err("%s: Invalid dai data\n", __func__); return -EINVAL; } memcpy(&dai_data->ttp_config.ttp_gen_cfg, ucontrol->value.bytes.data, sizeof(struct afe_ttp_gen_cfg_t)); return 0; } static const struct snd_kcontrol_new afe_dec_config_controls[] = { { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | Loading Loading @@ -3696,6 +3797,27 @@ static const struct snd_kcontrol_new afe_dec_config_controls[] = { msm_dai_q6_afe_output_bit_format_put), }; static const struct snd_kcontrol_new afe_ttp_config_controls[] = { { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE), .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "TTP Enable", .info = msm_dai_q6_afe_enable_ttp_info, .get = msm_dai_q6_afe_enable_ttp_get, .put = msm_dai_q6_afe_enable_ttp_put, }, { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE), .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "AFE TTP config", .info = msm_dai_q6_afe_ttp_cfg_info, .get = msm_dai_q6_afe_ttp_cfg_get, .put = msm_dai_q6_afe_ttp_cfg_put, }, }; static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { Loading Loading @@ -3919,6 +4041,12 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_dec_config_controls[3], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_ttp_config_controls[0], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&afe_ttp_config_controls[1], dai_data)); break; case RT_PROXY_DAI_001_RX: rc = snd_ctl_add(dai->component->card->snd_card, Loading
asoc/msm-transcode-loopback-q6-v2.c +4 −3 Original line number Diff line number Diff line Loading @@ -613,7 +613,7 @@ static int msm_transcode_loopback_get_caps(struct snd_compr_stream *cstream, } static int msm_transcode_set_render_mode(struct msm_transcode_loopback *prtd, uint32_t render_mode) uint32_t render_mode, int dir) { int ret = -EINVAL; struct audio_client *ac = prtd->audio_client; Loading @@ -639,7 +639,7 @@ static int msm_transcode_set_render_mode(struct msm_transcode_loopback *prtd, goto exit; } ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode); ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir); if (ret) { pr_err("%s: Render mode can't be set error %d\n", __func__, ret); Loading Loading @@ -705,7 +705,8 @@ static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, } case SNDRV_COMPRESS_RENDER_MODE: { rc = msm_transcode_set_render_mode(prtd, metadata->value[0]); rc = msm_transcode_set_render_mode(prtd, metadata->value[0], cstream->direction); if (rc) pr_err("%s: error setting render mode %d\n", __func__, rc); Loading
dsp/q6afe.c +94 −5 Original line number Diff line number Diff line Loading @@ -3925,6 +3925,51 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) return ret; } static int q6afe_send_ttp_config(u16 port_id, union afe_port_config afe_config, struct afe_ttp_config *ttp_cfg) { struct afe_ttp_gen_enable_t ttp_gen_enable; struct afe_ttp_gen_cfg_t ttp_gen_cfg; struct param_hdr_v3 param_hdr; int ret; memset(&ttp_gen_enable, 0, sizeof(ttp_gen_enable)); memset(&ttp_gen_cfg, 0, sizeof(ttp_gen_cfg)); memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_ID_DECODER; param_hdr.instance_id = INSTANCE_ID_0; pr_debug("%s: Enable TTP generator\n", __func__); ttp_gen_enable = ttp_cfg->ttp_gen_enable; param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE; param_hdr.param_size = sizeof(struct afe_ttp_gen_enable_t); ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &ttp_gen_enable); if (ret) { pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } pr_debug("%s: sending TTP generator config\n", __func__); ttp_gen_cfg = ttp_cfg->ttp_gen_cfg; param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG; param_hdr.param_size = sizeof(struct afe_ttp_gen_cfg_t); ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &ttp_gen_cfg); if (ret) pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG for port 0x%x failed %d\n", __func__, port_id, ret); exit: return ret; } static int q6afe_send_dec_config(u16 port_id, union afe_port_config afe_config, struct afe_dec_config *cfg, Loading Loading @@ -4595,7 +4640,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, union afe_enc_config_data *enc_cfg, u32 codec_format, u32 scrambler_mode, u32 mono_mode, struct afe_dec_config *dec_cfg) struct afe_dec_config *dec_cfg, struct afe_ttp_config *ttp_cfg) { union afe_port_config port_cfg; struct param_hdr_v3 param_hdr; Loading Loading @@ -4913,6 +4959,15 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, goto fail_cmd; } } if (ttp_cfg != NULL) { ret = q6afe_send_ttp_config(port_id, *afe_config, ttp_cfg); if (ret) { pr_err("%s: AFE TTP config for port 0x%x failed %d\n", __func__, port_id, ret); goto fail_cmd; } } } port_index = afe_get_port_index(port_id); Loading Loading @@ -4959,8 +5014,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate) { return __afe_port_start(port_id, afe_config, rate, 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, 0, NULL); return __afe_port_start(port_id, afe_config, rate, 0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, 0, NULL, NULL); } EXPORT_SYMBOL(afe_port_start); Loading Loading @@ -4990,16 +5045,50 @@ int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config, afe_in_channels, afe_in_bit_width, &enc_cfg->data, enc_cfg->format, enc_cfg->scrambler_mode, enc_cfg->mono_mode, dec_cfg); enc_cfg->mono_mode, dec_cfg, NULL); else if (dec_cfg != NULL) ret = __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, NULL, dec_cfg->format, 0, 0, dec_cfg); NULL, dec_cfg->format, 0, 0, dec_cfg, NULL); return ret; } EXPORT_SYMBOL(afe_port_start_v2); /** * afe_port_start_v3 - to configure AFE session with * specified port configuration and encoder /decoder params * * @port_id: AFE port id number * @afe_config: port configuration * @rate: sampling rate of port * @enc_cfg: AFE enc configuration information to setup encoder * @afe_in_channels: AFE input channel configuration, this needs * update only if input channel is differ from AFE output * @dec_cfg: AFE dec configuration information to set up decoder * @ttp_cfg: TTP generator configuration to enable TTP in AFE * * Returns 0 on success or error value on port start failure. */ int afe_port_start_v3(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, struct afe_enc_config *enc_cfg, struct afe_dec_config *dec_cfg, struct afe_ttp_config *ttp_cfg) { int ret = 0; if (dec_cfg != NULL && ttp_cfg != NULL) ret = __afe_port_start(port_id, afe_config, rate, afe_in_channels, afe_in_bit_width, NULL, dec_cfg->format, 0, 0, dec_cfg, ttp_cfg); return ret; } EXPORT_SYMBOL(afe_port_start_v3); int afe_get_port_index(u16 port_id) { switch (port_id) { Loading
dsp/q6asm.c +91 −2 Original line number Diff line number Diff line Loading @@ -10047,17 +10047,106 @@ int q6asm_send_mtmx_strtr_window(struct audio_client *ac, } EXPORT_SYMBOL(q6asm_send_mtmx_strtr_window); /** * q6asm_send_mtmx_strtr_ttp_offset - * command to send matrix for ttp offset * * @ac: Audio client handle * @ttp_offset: ttp offset params * @param_id: param id for ttp offset * @dir: RX or TX direction * * Returns 0 on success or error on failure */ int q6asm_send_mtmx_strtr_ttp_offset(struct audio_client *ac, struct asm_session_mtmx_strtr_param_ttp_offset_t *ttp_offset, uint32_t param_id, int dir) { struct asm_mtmx_strtr_params matrix; int sz = 0; int rc = 0; pr_debug("%s: ttp offset lsw is %d, ttp offset msw is %d\n", __func__, ttp_offset->ttp_offset_lsw, ttp_offset->ttp_offset_msw); if (!ac) { pr_err("%s: audio client handle is NULL\n", __func__); rc = -EINVAL; goto fail_cmd; } if (ac->apr == NULL) { pr_err("%s: ac->apr is NULL", __func__); rc = -EINVAL; goto fail_cmd; } memset(&matrix, 0, sizeof(struct asm_mtmx_strtr_params)); sz = sizeof(struct asm_mtmx_strtr_params); q6asm_add_hdr(ac, &matrix.hdr, sz, TRUE); atomic_set(&ac->cmd_state, -1); matrix.hdr.opcode = ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2; matrix.param.data_payload_addr_lsw = 0; matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t); matrix.param.direction = dir; matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; matrix.data.param_id = param_id; matrix.data.param_size = sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t); matrix.data.reserved = 0; memcpy(&(matrix.config.ttp_offset), ttp_offset, sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t)); rc = apr_send_pkt(ac->apr, (uint32_t *) &matrix); if (rc < 0) { pr_err("%s: ttp offset send failed paramid [0x%x]\n", __func__, matrix.data.param_id); rc = -EINVAL; goto fail_cmd; } rc = wait_event_timeout(ac->cmd_wait, (atomic_read(&ac->cmd_state) >= 0), msecs_to_jiffies(TIMEOUT_MS)); if (!rc) { pr_err("%s: timeout, ttp offset paramid[0x%x]\n", __func__, matrix.data.param_id); rc = -ETIMEDOUT; goto fail_cmd; } if (atomic_read(&ac->cmd_state) > 0) { pr_err("%s: DSP returned error[%s]\n", __func__, adsp_err_get_err_str( atomic_read(&ac->cmd_state))); rc = adsp_err_get_lnx_err_code( atomic_read(&ac->cmd_state)); goto fail_cmd; } rc = 0; fail_cmd: return rc; } EXPORT_SYMBOL(q6asm_send_mtmx_strtr_ttp_offset); /** * q6asm_send_mtmx_strtr_render_mode - * command to send matrix for render mode * * @ac: Audio client handle * @render_mode: rendering mode * @dir: RX or TX direction * * Returns 0 on success or error on failure */ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, uint32_t render_mode) uint32_t render_mode, int dir) { struct asm_mtmx_strtr_params matrix; struct asm_session_mtmx_strtr_param_render_mode_t render_param; Loading Loading @@ -10101,7 +10190,7 @@ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, matrix.param.data_payload_size = sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_render_mode_t); matrix.param.direction = 0; /* RX */ matrix.param.direction = dir; matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; matrix.data.param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_MODE_CMD; matrix.data.param_size = Loading