diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index 23f1af0b9a0c..9c4d18aa33cb 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -30661,6 +30661,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) @@ -30873,6 +30917,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; } diff --git a/dsp/q6afe.c b/dsp/q6afe.c index 8fbbfd9b873e..74a7def97c94 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -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}, - { AFE_PORT_ID_PRIMARY_SPDIF_RX, - AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE}, - { AFE_PORT_ID_PRIMARY_SPDIF_TX, - AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE}, - { AFE_PORT_ID_SECONDARY_SPDIF_RX, - AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_CORE}, - { 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}, +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, + MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, + { AFE_PORT_ID_PRIMARY_SPDIF_TX, + 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, + MCLK_SRC_INT, Q6AFE_EXT_MCLK_FREQ_DEFAULT}, + { AFE_PORT_ID_SECONDARY_SPDIF_TX, + 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; @@ -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; @@ -8920,6 +8981,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 * @@ -8992,6 +9136,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) { @@ -9008,9 +9157,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); + } - ret = afe_set_lpass_clk_cfg(index, cfg); if (ret) pr_err("%s: afe_set_lpass_clk_cfg_v2 failed %d\n", __func__, ret); @@ -9019,6 +9208,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) { diff --git a/dsp/q6core.c b/dsp/q6core.c index 392b09dec8e7..0bb767896f8a 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -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 diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 090bceb4d5f9..314f4270ce56 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -12159,6 +12159,27 @@ struct afe_clk_set { uint32_t enable; }; +#define AVS_BUILD_MAJOR_VERSION_V2 2 +#define AVS_BUILD_MINOR_VERSION_V9 9 +#define AVS_BUILD_BRANCH_VERSION_V3 3 + +#define AFE_PARAM_ID_CLOCK_SET_V2 0x000102E6 + +#define AFE_API_VERSION_CLOCK_SET_V2 0x1 + +struct afe_param_id_clock_set_v2_t { + uint32_t clk_set_minor_version; + uint32_t clk_id; + uint32_t clk_freq_in_hz; + uint16_t clk_attri; + uint16_t clk_root; + uint32_t enable; + uint32_t divider_2x; + uint32_t m; + uint32_t n; + uint32_t d; +}; + struct afe_clk_cfg { /* Minor version used for tracking the version of the I2S * configuration interface. diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h index bd048f85791c..9cb3e6350edc 100644 --- a/include/dsp/q6afe-v2.h +++ b/include/dsp/q6afe-v2.h @@ -50,6 +50,9 @@ #define AFE_API_VERSION_V6 6 /* for Speaker Protection V4 */ #define AFE_API_VERSION_V9 9 +/* for external mclk dynamic switch */ +#define AFE_API_VERSION_V8 8 + typedef int (*routing_cb)(int port); @@ -319,6 +322,24 @@ struct vad_config { u32 pre_roll; }; +enum afe_mclk_src_id { + MCLK_SRC_INT = 0x00, + MCLK_SRC_EXT_0 = 0x01, + MCLK_SRC_MAX, +}; + +enum afe_mclk_freq { + MCLK_FREQ_MIN = 0, + MCLK_FREQ_11P2896_MHZ = MCLK_FREQ_MIN, + MCLK_FREQ_12P288_MHZ, + MCLK_FREQ_16P384_MHZ, + MCLK_FREQ_22P5792_MHZ, + MCLK_FREQ_24P576_MHZ, + MCLK_FREQ_MAX, +}; + +#define Q6AFE_EXT_MCLK_FREQ_DEFAULT 0 + struct afe_audio_buffer { dma_addr_t phys; void *data; @@ -512,6 +533,19 @@ enum { AFE_LPASS_CORE_HW_DCODEC_BLOCK, AFE_LPASS_CORE_HW_VOTE_MAX }; +int afe_set_mclk_src_cfg(u16 port_id, uint32_t mclk_src_id, uint32_t mclk_freq); + +typedef int (*afe_enable_mclk_and_get_info_cb_func) (void *private_data, + uint32_t enable, uint32_t mclk_freq, + struct afe_param_id_clock_set_v2_t *dyn_mclk_cfg); + +int afe_register_ext_mclk_cb(afe_enable_mclk_and_get_info_cb_func fn1, + void *private_data); +void afe_unregister_ext_mclk_cb(void); + +#define AFE_LPASS_CORE_HW_BLOCK_ID_NONE 0 +#define AFE_LPASS_CORE_HW_BLOCK_ID_AVTIMER 2 +#define AFE_LPASS_CORE_HW_MACRO_BLOCK 3 /* Handles audio-video timer (avtimer) and BTSC vote requests from clients. */ diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index 52722d658304..191636bd2a07 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -435,4 +435,7 @@ int q6core_destroy_lpass_npa_client(uint32_t client_handle); int q6core_request_island_transition(uint32_t client_handle, uint32_t island_allow_mode); +int q6core_get_avcs_avs_build_version_info( + uint32_t *build_major_version, uint32_t *build_minor_version, + uint32_t *build_branch_version); #endif /* __Q6CORE_H__ */