Loading asoc/codecs/ep92/ep92.c +126 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,61 @@ static const unsigned int ep92_dsd_freq_table[4] = { 64, 128, 256, 0 }; /* EP92 register default values */ static struct reg_default ep92_reg_defaults[] = { {EP92_BI_VENDOR_ID_0, 0x17}, {EP92_BI_VENDOR_ID_1, 0x7A}, {EP92_BI_DEVICE_ID_0, 0x94}, {EP92_BI_DEVICE_ID_1, 0xA3}, {EP92_BI_VERSION_NUM, 0x10}, {EP92_BI_VERSION_YEAR, 0x09}, {EP92_BI_VERSION_MONTH, 0x07}, {EP92_BI_VERSION_DATE, 0x06}, {EP92_BI_GENERAL_INFO_0, 0x00}, {EP92_BI_GENERAL_INFO_1, 0x00}, {EP92_BI_GENERAL_INFO_2, 0x00}, {EP92_BI_GENERAL_INFO_3, 0x00}, {EP92_BI_GENERAL_INFO_4, 0x00}, {EP92_BI_GENERAL_INFO_5, 0x00}, {EP92_BI_GENERAL_INFO_6, 0x00}, {EP92_ISP_MODE_ENTER_ISP, 0x00}, {EP92_GENERAL_CONTROL_0, 0x20}, {EP92_GENERAL_CONTROL_1, 0x00}, {EP92_GENERAL_CONTROL_2, 0x00}, {EP92_GENERAL_CONTROL_3, 0x10}, {EP92_GENERAL_CONTROL_4, 0x00}, {EP92_CEC_EVENT_CODE, 0x00}, {EP92_CEC_EVENT_PARAM_1, 0x00}, {EP92_CEC_EVENT_PARAM_2, 0x00}, {EP92_CEC_EVENT_PARAM_3, 0x00}, {EP92_CEC_EVENT_PARAM_4, 0x00}, {EP92_AUDIO_INFO_SYSTEM_STATUS_0, 0x00}, {EP92_AUDIO_INFO_SYSTEM_STATUS_1, 0x00}, {EP92_AUDIO_INFO_AUDIO_STATUS, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_0, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_1, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_2, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_3, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_4, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_0, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_1, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_2, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_3, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_4, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_5, 0x00}, {EP92_OTHER_PACKETS_HDMI_VS_0, 0x00}, {EP92_OTHER_PACKETS_HDMI_VS_1, 0x00}, {EP92_OTHER_PACKETS_ACP_PACKET, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_0, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_1, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_2, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_3, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_4, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_0, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_1, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_2, 0x00}, }; static bool ep92_volatile_register(struct device *dev, unsigned int reg) { /* do not cache register state in regmap */ Loading Loading @@ -115,6 +170,77 @@ struct ep92_pdata { #endif /* CONFIG_DEBUG_FS */ }; struct ep92_mclk_cfg_info { uint32_t in_sample_rate; uint32_t out_mclk_freq; uint8_t mul_val; }; #define EP92_MCLK_MUL_512 0x3 #define EP92_MCLK_MUL_384 0x2 #define EP92_MCLK_MUL_256 0x1 #define EP92_MCLK_MUL_128 0x0 #define EP92_MCLK_MUL_MASK 0x3 /** * ep92_set_ext_mclk - Configure the mclk based on sample freq * * @codec: handle pointer to ep92 codec * @mclk_freq: mclk frequency to be set * * Returns 0 for sucess or appropriate negative error code */ int ep92_set_ext_mclk(struct snd_soc_codec *codec, uint32_t mclk_freq) { unsigned int samp_freq = 0; struct ep92_pdata *ep92 = NULL; uint8_t value = 0; int ret = 0; if (!codec) return -EINVAL; ep92 = snd_soc_codec_get_drvdata(codec); samp_freq = ep92_samp_freq_table[(ep92->ai.audio_status) & EP92_AI_RATE_MASK]; if (!mclk_freq || (mclk_freq % samp_freq)) { pr_err("%s incompatbile mclk:%u and sample freq:%u\n", __func__, mclk_freq, samp_freq); return -EINVAL; } switch (mclk_freq / samp_freq) { case 512: value = EP92_MCLK_MUL_512; break; case 384: value = EP92_MCLK_MUL_384; break; case 256: value = EP92_MCLK_MUL_256; break; case 128: value = EP92_MCLK_MUL_128; break; default: dev_err(codec->dev, "unsupported mclk:%u for sample freq:%u\n", mclk_freq, samp_freq); return -EINVAL; } pr_debug("%s mclk:%u, in sample freq:%u, write reg:0x%02x val:0x%02x\n", __func__, mclk_freq, samp_freq, EP92_GENERAL_CONTROL_2, EP92_MCLK_MUL_MASK & value); ret = snd_soc_update_bits(codec, EP92_GENERAL_CONTROL_2, EP92_MCLK_MUL_MASK, value); return (((ret == 0) || (ret == 1)) ? 0 : ret); } EXPORT_SYMBOL(ep92_set_ext_mclk); #if IS_ENABLED(CONFIG_DEBUG_FS) static int debugfs_codec_open_op(struct inode *inode, struct file *file) { Loading asoc/codecs/ep92/ep92.h +2 −57 Original line number Diff line number Diff line Loading @@ -69,63 +69,6 @@ #define EP92_MAX_REGISTER_ADDR EP92_OTHER_PACKETS_GC_PACKET_2 /* EP92 register default values */ static struct reg_default ep92_reg_defaults[] = { {EP92_BI_VENDOR_ID_0, 0x17}, {EP92_BI_VENDOR_ID_1, 0x7A}, {EP92_BI_DEVICE_ID_0, 0x94}, {EP92_BI_DEVICE_ID_1, 0xA3}, {EP92_BI_VERSION_NUM, 0x10}, {EP92_BI_VERSION_YEAR, 0x09}, {EP92_BI_VERSION_MONTH, 0x07}, {EP92_BI_VERSION_DATE, 0x06}, {EP92_BI_GENERAL_INFO_0, 0x00}, {EP92_BI_GENERAL_INFO_1, 0x00}, {EP92_BI_GENERAL_INFO_2, 0x00}, {EP92_BI_GENERAL_INFO_3, 0x00}, {EP92_BI_GENERAL_INFO_4, 0x00}, {EP92_BI_GENERAL_INFO_5, 0x00}, {EP92_BI_GENERAL_INFO_6, 0x00}, {EP92_ISP_MODE_ENTER_ISP, 0x00}, {EP92_GENERAL_CONTROL_0, 0x20}, {EP92_GENERAL_CONTROL_1, 0x00}, {EP92_GENERAL_CONTROL_2, 0x00}, {EP92_GENERAL_CONTROL_3, 0x10}, {EP92_GENERAL_CONTROL_4, 0x00}, {EP92_CEC_EVENT_CODE, 0x00}, {EP92_CEC_EVENT_PARAM_1, 0x00}, {EP92_CEC_EVENT_PARAM_2, 0x00}, {EP92_CEC_EVENT_PARAM_3, 0x00}, {EP92_CEC_EVENT_PARAM_4, 0x00}, {EP92_AUDIO_INFO_SYSTEM_STATUS_0, 0x00}, {EP92_AUDIO_INFO_SYSTEM_STATUS_1, 0x00}, {EP92_AUDIO_INFO_AUDIO_STATUS, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_0, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_1, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_2, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_3, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_4, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_0, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_1, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_2, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_3, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_4, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_5, 0x00}, {EP92_OTHER_PACKETS_HDMI_VS_0, 0x00}, {EP92_OTHER_PACKETS_HDMI_VS_1, 0x00}, {EP92_OTHER_PACKETS_ACP_PACKET, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_0, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_1, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_2, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_3, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_4, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_0, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_1, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_2, 0x00}, }; /* shift/masks for register bits * GI = General Info * GC = General Control Loading Loading @@ -211,4 +154,6 @@ enum { EP92_KCTL_MAX }; int ep92_set_ext_mclk(struct snd_soc_codec *codec, uint32_t mclk_freq); #endif /* __EP92_H__ */ asoc/msm-pcm-routing-v2.c +46 −0 Original line number Diff line number Diff line Loading @@ -32126,6 +32126,50 @@ static const struct snd_kcontrol_new }, }; static int msm_routing_put_mclk_src_cfg(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u16 port_id = 0; int32_t mclk_src_id = 0; uint32_t mclk_freq = 0; int be_idx, ret = -EINVAL; be_idx = ucontrol->value.integer.value[0]; mclk_src_id = ucontrol->value.integer.value[1]; mclk_freq = ucontrol->value.integer.value[2]; if (be_idx < 0 && be_idx >= MSM_BACKEND_DAI_MAX) { pr_err("%s: Invalid be id %d\n", __func__, be_idx); return -EINVAL; } if (mclk_src_id < MCLK_SRC_INT && mclk_src_id >= MCLK_SRC_MAX) { pr_err("%s: Invalid MCLK src %d\n", __func__, mclk_src_id); return -EINVAL; } if (msm_bedais[be_idx].active) { pr_err("%s:BE is active %d, cannot set mclk clock src\n", __func__, be_idx); return -EINVAL; } port_id = msm_bedais[be_idx].port_id; pr_debug("%s: be idx %d mclk_src id %d mclk_freq %d port id 0x%x\n", __func__, be_idx, mclk_src_id, mclk_freq, port_id); ret = afe_set_mclk_src_cfg(port_id, mclk_src_id, mclk_freq); if (ret < 0) pr_err("%s: failed to set mclk src cfg\n", __func__); return ret; } static const struct snd_kcontrol_new mclk_src_controls[] = { SOC_SINGLE_MULTI_EXT("MCLK_SRC CFG", SND_SOC_NOPM, 0, 24576000, 0, 3, NULL, msm_routing_put_mclk_src_cfg), }; static int msm_routing_stereo_channel_reverse_control_get( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) Loading Loading @@ -32418,6 +32462,8 @@ static int msm_routing_probe(struct snd_soc_component *component) snd_soc_add_component_controls(component, pll_clk_drift_controls, ARRAY_SIZE(pll_clk_drift_controls)); snd_soc_add_component_controls(component, mclk_src_controls, ARRAY_SIZE(mclk_src_controls)); return 0; } dsp/q6afe.c +312 −28 Original line number Diff line number Diff line Loading @@ -252,40 +252,70 @@ struct afe_ctl { struct afe_clkinfo_per_port { u16 port_id; /* AFE port ID */ uint32_t clk_id; /* Clock ID */ uint32_t mclk_src_id; /* MCLK SRC ID */ uint32_t mclk_freq; /* MCLK_FREQ */ }; struct afe_clkinfo_per_port clkinfo_per_port[] = { { AFE_PORT_ID_PRIMARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT}, { AFE_PORT_ID_SECONDARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT}, { AFE_PORT_ID_TERTIARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT}, { AFE_PORT_ID_QUATERNARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT}, { AFE_PORT_ID_QUINARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT}, { AFE_PORT_ID_SENARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT}, { AFE_PORT_ID_PRIMARY_PCM_RX, Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT}, { AFE_PORT_ID_SECONDARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT}, { AFE_PORT_ID_TERTIARY_PCM_RX, Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT}, { AFE_PORT_ID_QUATERNARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT}, { AFE_PORT_ID_QUINARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT}, { AFE_PORT_ID_SENARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEN_PCM_IBIT}, { AFE_PORT_ID_PRIMARY_TDM_RX, Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT}, { AFE_PORT_ID_SECONDARY_TDM_RX, Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT}, { AFE_PORT_ID_TERTIARY_TDM_RX, Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT}, { AFE_PORT_ID_QUATERNARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT}, { AFE_PORT_ID_QUINARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT}, struct afe_ext_mclk_cb_info { afe_enable_mclk_and_get_info_cb_func ext_mclk_cb; void *private_data; }; static struct afe_clkinfo_per_port clkinfo_per_port[] = { { AFE_PORT_ID_PRIMARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_TERTIARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUATERNARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUINARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SENARY_MI2S_TX, Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_PRIMARY_PCM_RX, Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_TERTIARY_PCM_RX, Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUATERNARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUINARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SENARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEN_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_PRIMARY_TDM_RX, Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_TDM_RX, Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_TERTIARY_TDM_RX, Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUATERNARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUINARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_PRIMARY_SPDIF_RX, AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE}, AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_PRIMARY_SPDIF_TX, AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE}, AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_SPDIF_RX, AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_CORE}, AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_CORE, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_SPDIF_TX, AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE}, { AFE_PORT_ID_PRIMARY_META_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT}, { AFE_PORT_ID_SECONDARY_META_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT}, AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_PRIMARY_META_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_META_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, }; static struct afe_ext_mclk_cb_info afe_ext_mclk; static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; static unsigned long afe_configured_cmd; Loading Loading @@ -425,6 +455,37 @@ static int afe_get_cal_hw_delay(int32_t path, struct audio_cal_hw_delay_entry *entry); static int remap_cal_data(struct cal_block_data *cal_block, int cal_index); /** * afe_register_ext_mclk_cb - register callback for external mclk * * @fn - external mclk callback function * @private_data - external mclk callback specific data * * Returns 0 in case of success and -EINVAL for failure */ int afe_register_ext_mclk_cb(afe_enable_mclk_and_get_info_cb_func fn, void *private_data) { if (fn && private_data) { afe_ext_mclk.ext_mclk_cb = fn; afe_ext_mclk.private_data = private_data; return 0; } return -EINVAL; } EXPORT_SYMBOL(afe_register_ext_mclk_cb); /** * afe_unregister_ext_mclk_cb - unregister external mclk callback */ void afe_unregister_ext_mclk_cb(void) { afe_ext_mclk.ext_mclk_cb = NULL; afe_ext_mclk.private_data = NULL; } EXPORT_SYMBOL(afe_unregister_ext_mclk_cb); int afe_get_spk_initial_cal(void) { return this_afe.initial_cal; Loading Loading @@ -3036,6 +3097,63 @@ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id, return ret; } static int afe_port_topology_deregister(u16 port_id) { struct param_hdr_v3 param_info; int ret = 0; uint32_t build_major_version = 0; uint32_t build_minor_version = 0; uint32_t build_branch_version = 0; uint32_t afe_api_version = 0; ret = q6core_get_avcs_avs_build_version_info(&build_major_version, &build_minor_version, &build_branch_version); if (ret < 0) { pr_err("%s: get AVS build versions failed %d\n", __func__, ret); goto done; } afe_api_version = q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_AFE_V); if (afe_api_version < 0) { ret = -EINVAL; goto done; } pr_debug("%s: major: %u, minor: %u, branch: %u, afe_api: %u\n", __func__, build_major_version, build_minor_version, build_branch_version, afe_api_version); if (build_major_version != AVS_BUILD_MAJOR_VERSION_V2 || build_minor_version != AVS_BUILD_MINOR_VERSION_V9 || (build_branch_version != AVS_BUILD_BRANCH_VERSION_V0 && build_branch_version != AVS_BUILD_BRANCH_VERSION_V3) || afe_api_version < AFE_API_VERSION_V9) { ret = -EINVAL; pr_err("%s: AVS build versions mismatched %d\n", __func__, ret); goto done; } memset(¶m_info, 0, sizeof(param_info)); param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; param_info.instance_id = INSTANCE_ID_0; param_info.param_id = AFE_PARAM_ID_DEREGISTER_TOPOLOGY; param_info.param_size = 0; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_info, NULL); if (ret < 0) pr_err("%s: AFE deregister topology for port 0x%x failed %d\n", __func__, port_id, ret); done: pr_debug("%s: AFE port 0x%x deregister topology, ret %d\n", __func__, port_id, ret); return ret; } static int afe_send_port_topology_id(u16 port_id) { struct afe_param_id_set_topology_cfg topology; Loading Loading @@ -5517,6 +5635,14 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) { /* One time call: only for first time */ afe_send_custom_topology(); /* * Deregister existing afe topology before * sending a new one for VA use cases only */ if (port_id == AFE_PORT_ID_VA_CODEC_DMA_TX_0 || port_id == AFE_PORT_ID_VA_CODEC_DMA_TX_1 || port_id == AFE_PORT_ID_VA_CODEC_DMA_TX_2) afe_port_topology_deregister(port_id); afe_send_port_topology_id(port_id); afe_send_cal(port_id); afe_send_hw_delay(port_id, rate); Loading Loading @@ -8980,6 +9106,89 @@ int afe_set_pll_clk_drift(u16 port_id, int32_t set_clk_drift, } EXPORT_SYMBOL(afe_set_pll_clk_drift); static int afe_set_lpass_clk_cfg_ext_mclk(int index, struct afe_clk_set *cfg, uint32_t mclk_freq) { struct param_hdr_v3 param_hdr; struct afe_param_id_clock_set_v2_t dyn_mclk_cfg; int ret = 0; if (!cfg) { pr_err("%s: clock cfg is NULL\n", __func__); ret = -EINVAL; return ret; } if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: index[%d] invalid!\n", __func__, index); return -EINVAL; } memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_CLOCK_SET; param_hdr.instance_id = INSTANCE_ID_0; param_hdr.param_id = AFE_PARAM_ID_CLOCK_SET_V2; param_hdr.param_size = sizeof(struct afe_param_id_clock_set_v2_t); memset(&dyn_mclk_cfg, 0, sizeof(dyn_mclk_cfg)); dyn_mclk_cfg.clk_freq_in_hz = cfg->clk_freq_in_hz; if (afe_ext_mclk.ext_mclk_cb) { ret = afe_ext_mclk.ext_mclk_cb(afe_ext_mclk.private_data, cfg->enable, mclk_freq, &dyn_mclk_cfg); if (ret) { pr_err_ratelimited("%s: get mclk cfg failed %d\n", __func__, ret); return ret; } } else { pr_err_ratelimited("%s: mclk callback not registered\n", __func__); return -EINVAL; } dyn_mclk_cfg.clk_set_minor_version = 1; dyn_mclk_cfg.clk_id = cfg->clk_id; dyn_mclk_cfg.clk_attri = cfg->clk_attri; dyn_mclk_cfg.enable = cfg->enable; pr_debug("%s: Minor version =0x%x clk id = %d\n", __func__, dyn_mclk_cfg.clk_set_minor_version, dyn_mclk_cfg.clk_id); pr_debug("%s: clk freq (Hz) = %d, clk attri = 0x%x\n", __func__, dyn_mclk_cfg.clk_freq_in_hz, dyn_mclk_cfg.clk_attri); pr_debug("%s: clk root = 0x%x clk enable = 0x%x\n", __func__, dyn_mclk_cfg.clk_root, dyn_mclk_cfg.enable); pr_debug("%s: divider_2x =%d m = %d n = %d, d =%d\n", __func__, dyn_mclk_cfg.divider_2x, dyn_mclk_cfg.m, dyn_mclk_cfg.n, dyn_mclk_cfg.d); ret = afe_q6_interface_prepare(); if (ret != 0) { pr_err_ratelimited("%s: Q6 interface prepare failed %d\n", __func__, ret); goto stop_mclk; } mutex_lock(&this_afe.afe_cmd_lock); ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr, (u8 *) &dyn_mclk_cfg); if (ret < 0) pr_err_ratelimited("%s: ext MCLK clk cfg failed with ret %d\n", __func__, ret); mutex_unlock(&this_afe.afe_cmd_lock); if (ret >= 0) return ret; stop_mclk: if (afe_ext_mclk.ext_mclk_cb && cfg->enable) { afe_ext_mclk.ext_mclk_cb(afe_ext_mclk.private_data, cfg->enable, mclk_freq, &dyn_mclk_cfg); } return ret; } /** * afe_set_lpass_clk_cfg - Set AFE clk config * Loading Loading @@ -9052,6 +9261,11 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) { int index = 0; int ret = 0; u16 idx = 0; uint32_t build_major_version = 0; uint32_t build_minor_version = 0; uint32_t build_branch_version = 0; int afe_api_version = 0; index = q6audio_get_port_index(port_id); if (index < 0 || index >= AFE_MAX_PORTS) { Loading @@ -9068,9 +9282,49 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) ret = afe_set_clk_id(port_id, cfg->clk_id); if (ret < 0) pr_debug("%s: afe_set_clk_id fail %d\n", __func__, ret); pr_err("%s: afe_set_clk_id fail %d\n", __func__, ret); idx = afe_get_port_idx(port_id); if (idx < 0) { pr_err("%s: cannot get clock id for port id 0x%x\n", __func__, port_id); return -EINVAL; } if (clkinfo_per_port[idx].mclk_src_id != MCLK_SRC_INT) { pr_debug("%s: ext MCLK src %d\n", __func__, clkinfo_per_port[idx].mclk_src_id); ret = q6core_get_avcs_avs_build_version_info( &build_major_version, &build_minor_version, &build_branch_version); if (ret < 0) return ret; ret = q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_AFE_V); if (ret < 0) return ret; afe_api_version = ret; pr_debug("%s: mjor: %u, mnor: %u, brnch: %u, afe_api: %u\n", __func__, build_major_version, build_minor_version, build_branch_version, afe_api_version); if ((build_major_version != AVS_BUILD_MAJOR_VERSION_V2) || (build_minor_version != AVS_BUILD_MINOR_VERSION_V9) || (build_branch_version != AVS_BUILD_BRANCH_VERSION_V3) || (afe_api_version < AFE_API_VERSION_V8)) { pr_err("%s: ext mclk not supported by AVS\n", __func__); return -EINVAL; } ret = afe_set_lpass_clk_cfg_ext_mclk(index, cfg, clkinfo_per_port[idx].mclk_freq); } else { ret = afe_set_lpass_clk_cfg(index, cfg); } if (ret) pr_err("%s: afe_set_lpass_clk_cfg_v2 failed %d\n", __func__, ret); Loading @@ -9079,6 +9333,36 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) } EXPORT_SYMBOL(afe_set_lpass_clock_v2); /** * afe_set_mclk_src_cfg - Set audio interface MCLK source configuration * * @port_id: AFE port id * @mclk_src_id: mclk id to represent internal or one of external MCLK * @mclk_freq: frequency of the MCLK * * Returns 0 on success, appropriate error code otherwise */ int afe_set_mclk_src_cfg(u16 port_id, uint32_t mclk_src_id, uint32_t mclk_freq) { int idx = 0; idx = afe_get_port_idx(port_id); if (idx < 0) { pr_err("%s: cannot get clock id for port id 0x%x\n", __func__, port_id); return -EINVAL; } clkinfo_per_port[idx].mclk_src_id = mclk_src_id; clkinfo_per_port[idx].mclk_freq = mclk_freq; pr_debug("%s: mclk src id 0x%x mclk_freq %d port id 0x%x\n", __func__, mclk_src_id, mclk_freq, port_id); return 0; } EXPORT_SYMBOL(afe_set_mclk_src_cfg); int afe_set_lpass_internal_digital_codec_clock(u16 port_id, struct afe_digital_clk_cfg *cfg) { Loading dsp/q6core.c +38 −0 Original line number Diff line number Diff line Loading @@ -737,6 +737,44 @@ int q6core_get_avcs_api_version_per_service(uint32_t service_id) } EXPORT_SYMBOL(q6core_get_avcs_api_version_per_service); /** * q6core_get_avcs_avs_build_version_info - Get AVS build version information * * @build_major_version - pointer to build major version * @build_minor_version - pointer to build minor version * @build_branch_version - pointer to build branch version * * Returns 0 on success and error on failure */ int q6core_get_avcs_avs_build_version_info( uint32_t *build_major_version, uint32_t *build_minor_version, uint32_t *build_branch_version) { struct avcs_fwk_ver_info *cached_ver_info = NULL; int ret = 0; if (!build_major_version || !build_minor_version || !build_branch_version) return -EINVAL; ret = q6core_get_avcs_fwk_version(); if (ret < 0) return ret; cached_ver_info = q6core_lcl.q6core_avcs_ver_info.ver_info; *build_major_version = cached_ver_info->avcs_fwk_version.build_major_version; *build_minor_version = cached_ver_info->avcs_fwk_version.build_minor_version; *build_branch_version = cached_ver_info->avcs_fwk_version.build_branch_version; return ret; } EXPORT_SYMBOL(q6core_get_avcs_avs_build_version_info); /** * core_set_license - * command to set license for module Loading Loading
asoc/codecs/ep92/ep92.c +126 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,61 @@ static const unsigned int ep92_dsd_freq_table[4] = { 64, 128, 256, 0 }; /* EP92 register default values */ static struct reg_default ep92_reg_defaults[] = { {EP92_BI_VENDOR_ID_0, 0x17}, {EP92_BI_VENDOR_ID_1, 0x7A}, {EP92_BI_DEVICE_ID_0, 0x94}, {EP92_BI_DEVICE_ID_1, 0xA3}, {EP92_BI_VERSION_NUM, 0x10}, {EP92_BI_VERSION_YEAR, 0x09}, {EP92_BI_VERSION_MONTH, 0x07}, {EP92_BI_VERSION_DATE, 0x06}, {EP92_BI_GENERAL_INFO_0, 0x00}, {EP92_BI_GENERAL_INFO_1, 0x00}, {EP92_BI_GENERAL_INFO_2, 0x00}, {EP92_BI_GENERAL_INFO_3, 0x00}, {EP92_BI_GENERAL_INFO_4, 0x00}, {EP92_BI_GENERAL_INFO_5, 0x00}, {EP92_BI_GENERAL_INFO_6, 0x00}, {EP92_ISP_MODE_ENTER_ISP, 0x00}, {EP92_GENERAL_CONTROL_0, 0x20}, {EP92_GENERAL_CONTROL_1, 0x00}, {EP92_GENERAL_CONTROL_2, 0x00}, {EP92_GENERAL_CONTROL_3, 0x10}, {EP92_GENERAL_CONTROL_4, 0x00}, {EP92_CEC_EVENT_CODE, 0x00}, {EP92_CEC_EVENT_PARAM_1, 0x00}, {EP92_CEC_EVENT_PARAM_2, 0x00}, {EP92_CEC_EVENT_PARAM_3, 0x00}, {EP92_CEC_EVENT_PARAM_4, 0x00}, {EP92_AUDIO_INFO_SYSTEM_STATUS_0, 0x00}, {EP92_AUDIO_INFO_SYSTEM_STATUS_1, 0x00}, {EP92_AUDIO_INFO_AUDIO_STATUS, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_0, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_1, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_2, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_3, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_4, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_0, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_1, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_2, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_3, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_4, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_5, 0x00}, {EP92_OTHER_PACKETS_HDMI_VS_0, 0x00}, {EP92_OTHER_PACKETS_HDMI_VS_1, 0x00}, {EP92_OTHER_PACKETS_ACP_PACKET, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_0, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_1, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_2, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_3, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_4, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_0, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_1, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_2, 0x00}, }; static bool ep92_volatile_register(struct device *dev, unsigned int reg) { /* do not cache register state in regmap */ Loading Loading @@ -115,6 +170,77 @@ struct ep92_pdata { #endif /* CONFIG_DEBUG_FS */ }; struct ep92_mclk_cfg_info { uint32_t in_sample_rate; uint32_t out_mclk_freq; uint8_t mul_val; }; #define EP92_MCLK_MUL_512 0x3 #define EP92_MCLK_MUL_384 0x2 #define EP92_MCLK_MUL_256 0x1 #define EP92_MCLK_MUL_128 0x0 #define EP92_MCLK_MUL_MASK 0x3 /** * ep92_set_ext_mclk - Configure the mclk based on sample freq * * @codec: handle pointer to ep92 codec * @mclk_freq: mclk frequency to be set * * Returns 0 for sucess or appropriate negative error code */ int ep92_set_ext_mclk(struct snd_soc_codec *codec, uint32_t mclk_freq) { unsigned int samp_freq = 0; struct ep92_pdata *ep92 = NULL; uint8_t value = 0; int ret = 0; if (!codec) return -EINVAL; ep92 = snd_soc_codec_get_drvdata(codec); samp_freq = ep92_samp_freq_table[(ep92->ai.audio_status) & EP92_AI_RATE_MASK]; if (!mclk_freq || (mclk_freq % samp_freq)) { pr_err("%s incompatbile mclk:%u and sample freq:%u\n", __func__, mclk_freq, samp_freq); return -EINVAL; } switch (mclk_freq / samp_freq) { case 512: value = EP92_MCLK_MUL_512; break; case 384: value = EP92_MCLK_MUL_384; break; case 256: value = EP92_MCLK_MUL_256; break; case 128: value = EP92_MCLK_MUL_128; break; default: dev_err(codec->dev, "unsupported mclk:%u for sample freq:%u\n", mclk_freq, samp_freq); return -EINVAL; } pr_debug("%s mclk:%u, in sample freq:%u, write reg:0x%02x val:0x%02x\n", __func__, mclk_freq, samp_freq, EP92_GENERAL_CONTROL_2, EP92_MCLK_MUL_MASK & value); ret = snd_soc_update_bits(codec, EP92_GENERAL_CONTROL_2, EP92_MCLK_MUL_MASK, value); return (((ret == 0) || (ret == 1)) ? 0 : ret); } EXPORT_SYMBOL(ep92_set_ext_mclk); #if IS_ENABLED(CONFIG_DEBUG_FS) static int debugfs_codec_open_op(struct inode *inode, struct file *file) { Loading
asoc/codecs/ep92/ep92.h +2 −57 Original line number Diff line number Diff line Loading @@ -69,63 +69,6 @@ #define EP92_MAX_REGISTER_ADDR EP92_OTHER_PACKETS_GC_PACKET_2 /* EP92 register default values */ static struct reg_default ep92_reg_defaults[] = { {EP92_BI_VENDOR_ID_0, 0x17}, {EP92_BI_VENDOR_ID_1, 0x7A}, {EP92_BI_DEVICE_ID_0, 0x94}, {EP92_BI_DEVICE_ID_1, 0xA3}, {EP92_BI_VERSION_NUM, 0x10}, {EP92_BI_VERSION_YEAR, 0x09}, {EP92_BI_VERSION_MONTH, 0x07}, {EP92_BI_VERSION_DATE, 0x06}, {EP92_BI_GENERAL_INFO_0, 0x00}, {EP92_BI_GENERAL_INFO_1, 0x00}, {EP92_BI_GENERAL_INFO_2, 0x00}, {EP92_BI_GENERAL_INFO_3, 0x00}, {EP92_BI_GENERAL_INFO_4, 0x00}, {EP92_BI_GENERAL_INFO_5, 0x00}, {EP92_BI_GENERAL_INFO_6, 0x00}, {EP92_ISP_MODE_ENTER_ISP, 0x00}, {EP92_GENERAL_CONTROL_0, 0x20}, {EP92_GENERAL_CONTROL_1, 0x00}, {EP92_GENERAL_CONTROL_2, 0x00}, {EP92_GENERAL_CONTROL_3, 0x10}, {EP92_GENERAL_CONTROL_4, 0x00}, {EP92_CEC_EVENT_CODE, 0x00}, {EP92_CEC_EVENT_PARAM_1, 0x00}, {EP92_CEC_EVENT_PARAM_2, 0x00}, {EP92_CEC_EVENT_PARAM_3, 0x00}, {EP92_CEC_EVENT_PARAM_4, 0x00}, {EP92_AUDIO_INFO_SYSTEM_STATUS_0, 0x00}, {EP92_AUDIO_INFO_SYSTEM_STATUS_1, 0x00}, {EP92_AUDIO_INFO_AUDIO_STATUS, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_0, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_1, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_2, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_3, 0x00}, {EP92_AUDIO_INFO_CHANNEL_STATUS_4, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_0, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_1, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_2, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_3, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_4, 0x00}, {EP92_AUDIO_INFO_ADO_INFO_FRAME_5, 0x00}, {EP92_OTHER_PACKETS_HDMI_VS_0, 0x00}, {EP92_OTHER_PACKETS_HDMI_VS_1, 0x00}, {EP92_OTHER_PACKETS_ACP_PACKET, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_0, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_1, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_2, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_3, 0x00}, {EP92_OTHER_PACKETS_AVI_INFO_FRAME_4, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_0, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_1, 0x00}, {EP92_OTHER_PACKETS_GC_PACKET_2, 0x00}, }; /* shift/masks for register bits * GI = General Info * GC = General Control Loading Loading @@ -211,4 +154,6 @@ enum { EP92_KCTL_MAX }; int ep92_set_ext_mclk(struct snd_soc_codec *codec, uint32_t mclk_freq); #endif /* __EP92_H__ */
asoc/msm-pcm-routing-v2.c +46 −0 Original line number Diff line number Diff line Loading @@ -32126,6 +32126,50 @@ static const struct snd_kcontrol_new }, }; static int msm_routing_put_mclk_src_cfg(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u16 port_id = 0; int32_t mclk_src_id = 0; uint32_t mclk_freq = 0; int be_idx, ret = -EINVAL; be_idx = ucontrol->value.integer.value[0]; mclk_src_id = ucontrol->value.integer.value[1]; mclk_freq = ucontrol->value.integer.value[2]; if (be_idx < 0 && be_idx >= MSM_BACKEND_DAI_MAX) { pr_err("%s: Invalid be id %d\n", __func__, be_idx); return -EINVAL; } if (mclk_src_id < MCLK_SRC_INT && mclk_src_id >= MCLK_SRC_MAX) { pr_err("%s: Invalid MCLK src %d\n", __func__, mclk_src_id); return -EINVAL; } if (msm_bedais[be_idx].active) { pr_err("%s:BE is active %d, cannot set mclk clock src\n", __func__, be_idx); return -EINVAL; } port_id = msm_bedais[be_idx].port_id; pr_debug("%s: be idx %d mclk_src id %d mclk_freq %d port id 0x%x\n", __func__, be_idx, mclk_src_id, mclk_freq, port_id); ret = afe_set_mclk_src_cfg(port_id, mclk_src_id, mclk_freq); if (ret < 0) pr_err("%s: failed to set mclk src cfg\n", __func__); return ret; } static const struct snd_kcontrol_new mclk_src_controls[] = { SOC_SINGLE_MULTI_EXT("MCLK_SRC CFG", SND_SOC_NOPM, 0, 24576000, 0, 3, NULL, msm_routing_put_mclk_src_cfg), }; static int msm_routing_stereo_channel_reverse_control_get( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) Loading Loading @@ -32418,6 +32462,8 @@ static int msm_routing_probe(struct snd_soc_component *component) snd_soc_add_component_controls(component, pll_clk_drift_controls, ARRAY_SIZE(pll_clk_drift_controls)); snd_soc_add_component_controls(component, mclk_src_controls, ARRAY_SIZE(mclk_src_controls)); return 0; }
dsp/q6afe.c +312 −28 Original line number Diff line number Diff line Loading @@ -252,40 +252,70 @@ struct afe_ctl { struct afe_clkinfo_per_port { u16 port_id; /* AFE port ID */ uint32_t clk_id; /* Clock ID */ uint32_t mclk_src_id; /* MCLK SRC ID */ uint32_t mclk_freq; /* MCLK_FREQ */ }; struct afe_clkinfo_per_port clkinfo_per_port[] = { { AFE_PORT_ID_PRIMARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT}, { AFE_PORT_ID_SECONDARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT}, { AFE_PORT_ID_TERTIARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT}, { AFE_PORT_ID_QUATERNARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT}, { AFE_PORT_ID_QUINARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT}, { AFE_PORT_ID_SENARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT}, { AFE_PORT_ID_PRIMARY_PCM_RX, Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT}, { AFE_PORT_ID_SECONDARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT}, { AFE_PORT_ID_TERTIARY_PCM_RX, Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT}, { AFE_PORT_ID_QUATERNARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT}, { AFE_PORT_ID_QUINARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT}, { AFE_PORT_ID_SENARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEN_PCM_IBIT}, { AFE_PORT_ID_PRIMARY_TDM_RX, Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT}, { AFE_PORT_ID_SECONDARY_TDM_RX, Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT}, { AFE_PORT_ID_TERTIARY_TDM_RX, Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT}, { AFE_PORT_ID_QUATERNARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT}, { AFE_PORT_ID_QUINARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT}, struct afe_ext_mclk_cb_info { afe_enable_mclk_and_get_info_cb_func ext_mclk_cb; void *private_data; }; static struct afe_clkinfo_per_port clkinfo_per_port[] = { { AFE_PORT_ID_PRIMARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_TERTIARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUATERNARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUINARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SENARY_MI2S_TX, Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_PRIMARY_PCM_RX, Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_TERTIARY_PCM_RX, Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUATERNARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUINARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SENARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEN_PCM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_PRIMARY_TDM_RX, Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_TDM_RX, Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_TERTIARY_TDM_RX, Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUATERNARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_QUINARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_PRIMARY_SPDIF_RX, AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE}, AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_PRIMARY_SPDIF_TX, AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE}, AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_SPDIF_RX, AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_CORE}, AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_CORE, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_SPDIF_TX, AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE}, { AFE_PORT_ID_PRIMARY_META_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT}, { AFE_PORT_ID_SECONDARY_META_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT}, AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_PRIMARY_META_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, { AFE_PORT_ID_SECONDARY_META_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, }; static struct afe_ext_mclk_cb_info afe_ext_mclk; static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; static unsigned long afe_configured_cmd; Loading Loading @@ -425,6 +455,37 @@ static int afe_get_cal_hw_delay(int32_t path, struct audio_cal_hw_delay_entry *entry); static int remap_cal_data(struct cal_block_data *cal_block, int cal_index); /** * afe_register_ext_mclk_cb - register callback for external mclk * * @fn - external mclk callback function * @private_data - external mclk callback specific data * * Returns 0 in case of success and -EINVAL for failure */ int afe_register_ext_mclk_cb(afe_enable_mclk_and_get_info_cb_func fn, void *private_data) { if (fn && private_data) { afe_ext_mclk.ext_mclk_cb = fn; afe_ext_mclk.private_data = private_data; return 0; } return -EINVAL; } EXPORT_SYMBOL(afe_register_ext_mclk_cb); /** * afe_unregister_ext_mclk_cb - unregister external mclk callback */ void afe_unregister_ext_mclk_cb(void) { afe_ext_mclk.ext_mclk_cb = NULL; afe_ext_mclk.private_data = NULL; } EXPORT_SYMBOL(afe_unregister_ext_mclk_cb); int afe_get_spk_initial_cal(void) { return this_afe.initial_cal; Loading Loading @@ -3036,6 +3097,63 @@ static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id, return ret; } static int afe_port_topology_deregister(u16 port_id) { struct param_hdr_v3 param_info; int ret = 0; uint32_t build_major_version = 0; uint32_t build_minor_version = 0; uint32_t build_branch_version = 0; uint32_t afe_api_version = 0; ret = q6core_get_avcs_avs_build_version_info(&build_major_version, &build_minor_version, &build_branch_version); if (ret < 0) { pr_err("%s: get AVS build versions failed %d\n", __func__, ret); goto done; } afe_api_version = q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_AFE_V); if (afe_api_version < 0) { ret = -EINVAL; goto done; } pr_debug("%s: major: %u, minor: %u, branch: %u, afe_api: %u\n", __func__, build_major_version, build_minor_version, build_branch_version, afe_api_version); if (build_major_version != AVS_BUILD_MAJOR_VERSION_V2 || build_minor_version != AVS_BUILD_MINOR_VERSION_V9 || (build_branch_version != AVS_BUILD_BRANCH_VERSION_V0 && build_branch_version != AVS_BUILD_BRANCH_VERSION_V3) || afe_api_version < AFE_API_VERSION_V9) { ret = -EINVAL; pr_err("%s: AVS build versions mismatched %d\n", __func__, ret); goto done; } memset(¶m_info, 0, sizeof(param_info)); param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; param_info.instance_id = INSTANCE_ID_0; param_info.param_id = AFE_PARAM_ID_DEREGISTER_TOPOLOGY; param_info.param_size = 0; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_info, NULL); if (ret < 0) pr_err("%s: AFE deregister topology for port 0x%x failed %d\n", __func__, port_id, ret); done: pr_debug("%s: AFE port 0x%x deregister topology, ret %d\n", __func__, port_id, ret); return ret; } static int afe_send_port_topology_id(u16 port_id) { struct afe_param_id_set_topology_cfg topology; Loading Loading @@ -5517,6 +5635,14 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) { /* One time call: only for first time */ afe_send_custom_topology(); /* * Deregister existing afe topology before * sending a new one for VA use cases only */ if (port_id == AFE_PORT_ID_VA_CODEC_DMA_TX_0 || port_id == AFE_PORT_ID_VA_CODEC_DMA_TX_1 || port_id == AFE_PORT_ID_VA_CODEC_DMA_TX_2) afe_port_topology_deregister(port_id); afe_send_port_topology_id(port_id); afe_send_cal(port_id); afe_send_hw_delay(port_id, rate); Loading Loading @@ -8980,6 +9106,89 @@ int afe_set_pll_clk_drift(u16 port_id, int32_t set_clk_drift, } EXPORT_SYMBOL(afe_set_pll_clk_drift); static int afe_set_lpass_clk_cfg_ext_mclk(int index, struct afe_clk_set *cfg, uint32_t mclk_freq) { struct param_hdr_v3 param_hdr; struct afe_param_id_clock_set_v2_t dyn_mclk_cfg; int ret = 0; if (!cfg) { pr_err("%s: clock cfg is NULL\n", __func__); ret = -EINVAL; return ret; } if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: index[%d] invalid!\n", __func__, index); return -EINVAL; } memset(¶m_hdr, 0, sizeof(param_hdr)); param_hdr.module_id = AFE_MODULE_CLOCK_SET; param_hdr.instance_id = INSTANCE_ID_0; param_hdr.param_id = AFE_PARAM_ID_CLOCK_SET_V2; param_hdr.param_size = sizeof(struct afe_param_id_clock_set_v2_t); memset(&dyn_mclk_cfg, 0, sizeof(dyn_mclk_cfg)); dyn_mclk_cfg.clk_freq_in_hz = cfg->clk_freq_in_hz; if (afe_ext_mclk.ext_mclk_cb) { ret = afe_ext_mclk.ext_mclk_cb(afe_ext_mclk.private_data, cfg->enable, mclk_freq, &dyn_mclk_cfg); if (ret) { pr_err_ratelimited("%s: get mclk cfg failed %d\n", __func__, ret); return ret; } } else { pr_err_ratelimited("%s: mclk callback not registered\n", __func__); return -EINVAL; } dyn_mclk_cfg.clk_set_minor_version = 1; dyn_mclk_cfg.clk_id = cfg->clk_id; dyn_mclk_cfg.clk_attri = cfg->clk_attri; dyn_mclk_cfg.enable = cfg->enable; pr_debug("%s: Minor version =0x%x clk id = %d\n", __func__, dyn_mclk_cfg.clk_set_minor_version, dyn_mclk_cfg.clk_id); pr_debug("%s: clk freq (Hz) = %d, clk attri = 0x%x\n", __func__, dyn_mclk_cfg.clk_freq_in_hz, dyn_mclk_cfg.clk_attri); pr_debug("%s: clk root = 0x%x clk enable = 0x%x\n", __func__, dyn_mclk_cfg.clk_root, dyn_mclk_cfg.enable); pr_debug("%s: divider_2x =%d m = %d n = %d, d =%d\n", __func__, dyn_mclk_cfg.divider_2x, dyn_mclk_cfg.m, dyn_mclk_cfg.n, dyn_mclk_cfg.d); ret = afe_q6_interface_prepare(); if (ret != 0) { pr_err_ratelimited("%s: Q6 interface prepare failed %d\n", __func__, ret); goto stop_mclk; } mutex_lock(&this_afe.afe_cmd_lock); ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr, (u8 *) &dyn_mclk_cfg); if (ret < 0) pr_err_ratelimited("%s: ext MCLK clk cfg failed with ret %d\n", __func__, ret); mutex_unlock(&this_afe.afe_cmd_lock); if (ret >= 0) return ret; stop_mclk: if (afe_ext_mclk.ext_mclk_cb && cfg->enable) { afe_ext_mclk.ext_mclk_cb(afe_ext_mclk.private_data, cfg->enable, mclk_freq, &dyn_mclk_cfg); } return ret; } /** * afe_set_lpass_clk_cfg - Set AFE clk config * Loading Loading @@ -9052,6 +9261,11 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) { int index = 0; int ret = 0; u16 idx = 0; uint32_t build_major_version = 0; uint32_t build_minor_version = 0; uint32_t build_branch_version = 0; int afe_api_version = 0; index = q6audio_get_port_index(port_id); if (index < 0 || index >= AFE_MAX_PORTS) { Loading @@ -9068,9 +9282,49 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) ret = afe_set_clk_id(port_id, cfg->clk_id); if (ret < 0) pr_debug("%s: afe_set_clk_id fail %d\n", __func__, ret); pr_err("%s: afe_set_clk_id fail %d\n", __func__, ret); idx = afe_get_port_idx(port_id); if (idx < 0) { pr_err("%s: cannot get clock id for port id 0x%x\n", __func__, port_id); return -EINVAL; } if (clkinfo_per_port[idx].mclk_src_id != MCLK_SRC_INT) { pr_debug("%s: ext MCLK src %d\n", __func__, clkinfo_per_port[idx].mclk_src_id); ret = q6core_get_avcs_avs_build_version_info( &build_major_version, &build_minor_version, &build_branch_version); if (ret < 0) return ret; ret = q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_AFE_V); if (ret < 0) return ret; afe_api_version = ret; pr_debug("%s: mjor: %u, mnor: %u, brnch: %u, afe_api: %u\n", __func__, build_major_version, build_minor_version, build_branch_version, afe_api_version); if ((build_major_version != AVS_BUILD_MAJOR_VERSION_V2) || (build_minor_version != AVS_BUILD_MINOR_VERSION_V9) || (build_branch_version != AVS_BUILD_BRANCH_VERSION_V3) || (afe_api_version < AFE_API_VERSION_V8)) { pr_err("%s: ext mclk not supported by AVS\n", __func__); return -EINVAL; } ret = afe_set_lpass_clk_cfg_ext_mclk(index, cfg, clkinfo_per_port[idx].mclk_freq); } else { ret = afe_set_lpass_clk_cfg(index, cfg); } if (ret) pr_err("%s: afe_set_lpass_clk_cfg_v2 failed %d\n", __func__, ret); Loading @@ -9079,6 +9333,36 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) } EXPORT_SYMBOL(afe_set_lpass_clock_v2); /** * afe_set_mclk_src_cfg - Set audio interface MCLK source configuration * * @port_id: AFE port id * @mclk_src_id: mclk id to represent internal or one of external MCLK * @mclk_freq: frequency of the MCLK * * Returns 0 on success, appropriate error code otherwise */ int afe_set_mclk_src_cfg(u16 port_id, uint32_t mclk_src_id, uint32_t mclk_freq) { int idx = 0; idx = afe_get_port_idx(port_id); if (idx < 0) { pr_err("%s: cannot get clock id for port id 0x%x\n", __func__, port_id); return -EINVAL; } clkinfo_per_port[idx].mclk_src_id = mclk_src_id; clkinfo_per_port[idx].mclk_freq = mclk_freq; pr_debug("%s: mclk src id 0x%x mclk_freq %d port id 0x%x\n", __func__, mclk_src_id, mclk_freq, port_id); return 0; } EXPORT_SYMBOL(afe_set_mclk_src_cfg); int afe_set_lpass_internal_digital_codec_clock(u16 port_id, struct afe_digital_clk_cfg *cfg) { Loading
dsp/q6core.c +38 −0 Original line number Diff line number Diff line Loading @@ -737,6 +737,44 @@ int q6core_get_avcs_api_version_per_service(uint32_t service_id) } EXPORT_SYMBOL(q6core_get_avcs_api_version_per_service); /** * q6core_get_avcs_avs_build_version_info - Get AVS build version information * * @build_major_version - pointer to build major version * @build_minor_version - pointer to build minor version * @build_branch_version - pointer to build branch version * * Returns 0 on success and error on failure */ int q6core_get_avcs_avs_build_version_info( uint32_t *build_major_version, uint32_t *build_minor_version, uint32_t *build_branch_version) { struct avcs_fwk_ver_info *cached_ver_info = NULL; int ret = 0; if (!build_major_version || !build_minor_version || !build_branch_version) return -EINVAL; ret = q6core_get_avcs_fwk_version(); if (ret < 0) return ret; cached_ver_info = q6core_lcl.q6core_avcs_ver_info.ver_info; *build_major_version = cached_ver_info->avcs_fwk_version.build_major_version; *build_minor_version = cached_ver_info->avcs_fwk_version.build_minor_version; *build_branch_version = cached_ver_info->avcs_fwk_version.build_branch_version; return ret; } EXPORT_SYMBOL(q6core_get_avcs_avs_build_version_info); /** * core_set_license - * command to set license for module Loading