From 38070be30b1d7bbcc7e9e862f81fabface2a0707 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Thu, 17 Aug 2017 18:21:59 +0530 Subject: [PATCH] audio-lnx: Add latest snapshot for audio drivers. Propagate the changes based on latest snapshot for audio kernel source tree at below cutoff of kernel msm-4.9 - (aed56b2df75 - "drm/msm/sde: update te vsync enable sequence change") Change-Id: I7ed5102146986b81e5cb9ca55432360b3549b60c Signed-off-by: Laxminath Kasam --- asoc/codecs/msm_sdw/msm_sdw_cdc.c | 12 +- asoc/codecs/pdata.h | 2 + asoc/codecs/wcd-dsp-mgr.c | 22 +- asoc/codecs/wcd934x/wcd934x-dsp-cntl.c | 8 +- asoc/codecs/wcd9xxx-core.c | 4 + asoc/codecs/wcd9xxx-utils.c | 13 + asoc/codecs/wsa881x.h | 28 +- asoc/msm-audio-effects-q6-v2.c | 60 ++--- asoc/msm-dai-fe.c | 14 +- asoc/msm-lsm-client.c | 14 +- asoc/msm-pcm-routing-v2.c | 98 ++++++- asoc/msm8998.c | 7 +- asoc/sdm660-common.c | 15 ++ asoc/sdm660-common.h | 1 + asoc/sdm660-ext-dai-links.c | 18 +- asoc/sdm660-external.c | 126 ++++++--- asoc/sdm660-external.h | 2 + asoc/sdm660-internal.c | 8 +- asoc/sdm845.c | 15 +- dsp/codecs/audio_utils_aio.c | 57 ++-- dsp/q6core.c | 256 +++++++++++++++++- dsp/q6voice.c | 353 ++++++++++++++++++++++++- include/dsp/apr_audio-v2.h | 70 +++++ include/dsp/q6core.h | 6 + include/dsp/q6voice.h | 118 ++++++++- soc/pinctrl-lpi.c | 42 +-- 26 files changed, 1192 insertions(+), 177 deletions(-) diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c index 3ff184c7fab3..05d1d801ce74 100644 --- a/asoc/codecs/msm_sdw/msm_sdw_cdc.c +++ b/asoc/codecs/msm_sdw/msm_sdw_cdc.c @@ -938,7 +938,7 @@ static int msm_sdw_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct msm_sdw_priv *msm_sdw_p = snd_soc_codec_get_drvdata(codec); @@ -951,7 +951,7 @@ static int msm_sdw_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = - snd_soc_dapm_kcontrol_widget(kcontrol); + snd_soc_dapm_kcontrol_widget(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm); struct msm_sdw_priv *msm_sdw_p = snd_soc_codec_get_drvdata(codec); struct soc_multi_mixer_control *mixer = @@ -1376,15 +1376,19 @@ int msm_sdw_codec_info_create_codec_entry(struct snd_info_entry *codec_root, struct snd_info_entry *version_entry; struct msm_sdw_priv *msm_sdw; struct snd_soc_card *card; + char name[80]; if (!codec_root || !codec) return -EINVAL; msm_sdw = snd_soc_codec_get_drvdata(codec); card = codec->component.card; + + snprintf(name, sizeof(name), "%x.%s", (u32)msm_sdw->sdw_base_addr, + "msm-sdw-codec"); msm_sdw->entry = snd_info_create_subdir(codec_root->module, - "152c1000.msm-sdw-codec", - codec_root); + (const char *)name, + codec_root); if (!msm_sdw->entry) { dev_err(codec->dev, "%s: failed to create msm_sdw entry\n", __func__); diff --git a/asoc/codecs/pdata.h b/asoc/codecs/pdata.h index fa16b3d1c8f5..6df80eb064d6 100644 --- a/asoc/codecs/pdata.h +++ b/asoc/codecs/pdata.h @@ -179,6 +179,8 @@ struct wcd9xxx_pdata { int irq_base; int num_irqs; int reset_gpio; + bool has_buck_vsel_gpio; + struct device_node *buck_vsel_ctl_np; struct device_node *wcd_rst_np; struct wcd9xxx_amic amic_settings; struct slim_device slimbus_slave_device; diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c index a6d46aef9724..6cc9f8c79d21 100644 --- a/asoc/codecs/wcd-dsp-mgr.c +++ b/asoc/codecs/wcd-dsp-mgr.c @@ -417,22 +417,23 @@ static int wdsp_download_segments(struct wdsp_mgr_priv *wdsp, /* Go through the list of segments and download one by one */ list_for_each_entry(seg, wdsp->seg_list, list) { ret = wdsp_load_each_segment(wdsp, seg); - if (ret < 0) { - wdsp_broadcast_event_downseq(wdsp, - WDSP_EVENT_DLOAD_FAILED, - NULL); + if (ret) goto dload_error; - } } + /* Flush the list before setting status and notifying components */ + wdsp_flush_segment_list(wdsp->seg_list); + WDSP_SET_STATUS(wdsp, status); /* Notify all components that image is downloaded */ wdsp_broadcast_event_downseq(wdsp, post, NULL); +done: + return ret; dload_error: wdsp_flush_segment_list(wdsp->seg_list); -done: + wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_DLOAD_FAILED, NULL); return ret; } @@ -486,10 +487,14 @@ static int wdsp_enable_dsp(struct wdsp_mgr_priv *wdsp) /* Make sure wdsp is in good state */ if (!WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_CODE_DLOADED)) { WDSP_ERR(wdsp, "WDSP in invalid state 0x%x", wdsp->status); - ret = -EINVAL; - goto done; + return -EINVAL; } + /* + * Acquire SSR mutex lock to make sure enablement of DSP + * does not race with SSR handling. + */ + WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); /* Download the read-write sections of image */ ret = wdsp_download_segments(wdsp, WDSP_ELF_FLAG_WRITE); if (ret < 0) { @@ -510,6 +515,7 @@ static int wdsp_enable_dsp(struct wdsp_mgr_priv *wdsp) wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_BOOTUP, NULL); WDSP_SET_STATUS(wdsp, WDSP_STATUS_BOOTED); done: + WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); return ret; } diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c index d82748b2689e..031940ecbaf9 100644 --- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c +++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c @@ -763,10 +763,6 @@ static int wcd_control_handler(struct device *dev, void *priv_data, case WDSP_EVENT_DLOAD_FAILED: case WDSP_EVENT_POST_SHUTDOWN: - if (event == WDSP_EVENT_POST_DLOAD_CODE) - /* Mark DSP online since code download is complete */ - wcd_cntl_change_online_state(cntl, 1); - /* Disable CPAR */ wcd_cntl_cpar_ctrl(cntl, false); /* Disable all the clocks */ @@ -775,6 +771,10 @@ static int wcd_control_handler(struct device *dev, void *priv_data, dev_err(codec->dev, "%s: Failed to disable clocks, err = %d\n", __func__, ret); + + if (event == WDSP_EVENT_POST_DLOAD_CODE) + /* Mark DSP online since code download is complete */ + wcd_cntl_change_online_state(cntl, 1); break; case WDSP_EVENT_PRE_DLOAD_DATA: diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c index 2ab5e894864e..81408e8928ef 100644 --- a/asoc/codecs/wcd9xxx-core.c +++ b/asoc/codecs/wcd9xxx-core.c @@ -1280,6 +1280,10 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) ret = -EINVAL; goto err_codec; } + + if (pdata->has_buck_vsel_gpio) + msm_cdc_pinctrl_select_active_state(pdata->buck_vsel_ctl_np); + device_id = slim_get_device_id(slim); if (!device_id) { dev_err(&slim->dev, "%s: Error, no device id\n", __func__); diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c index a1ea93843f28..eee90a28952d 100644 --- a/asoc/codecs/wcd9xxx-utils.c +++ b/asoc/codecs/wcd9xxx-utils.c @@ -342,6 +342,19 @@ struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev) goto err_parse_dt_prop; } + pdata->has_buck_vsel_gpio = of_property_read_bool(dev->of_node, + "qcom,has-buck-vsel-gpio"); + if (pdata->has_buck_vsel_gpio) { + pdata->buck_vsel_ctl_np = of_parse_phandle(dev->of_node, + "qcom,buck-vsel-gpio-node", 0); + if (!pdata->buck_vsel_ctl_np) { + dev_err(dev, "%s No entry for %s property in node %s\n", + __func__, "qcom,buck-vsel-gpio-node", + dev->of_node->full_name); + goto err_parse_dt_prop; + } + } + if (!(wcd9xxx_read_of_property_u32(dev, "qcom,cdc-mclk-clk-rate", &prop_val))) pdata->mclk_rate = prop_val; diff --git a/asoc/codecs/wsa881x.h b/asoc/codecs/wsa881x.h index be234ac0cd07..fbc60d86a12b 100644 --- a/asoc/codecs/wsa881x.h +++ b/asoc/codecs/wsa881x.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -20,9 +20,10 @@ #define WSA881X_MAX_SWR_PORTS 4 +#if IS_ENABLED(CONFIG_SND_SOC_WSA881X) extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, - u8 num_port, unsigned int *ch_mask, - unsigned int *ch_rate); + u8 num_port, unsigned int *ch_mask, + unsigned int *ch_rate); extern const u8 wsa881x_reg_readable[WSA881X_CACHE_SIZE]; extern struct regmap_config wsa881x_regmap_config; @@ -31,4 +32,25 @@ extern int wsa881x_codec_info_create_codec_entry( struct snd_soc_codec *codec); void wsa881x_regmap_defaults(struct regmap *regmap, u8 version); +#else +extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port, + u8 num_port, unsigned int *ch_mask, + unsigned int *ch_rate) +{ + return 0; +} + +extern int wsa881x_codec_info_create_codec_entry( + struct snd_info_entry *codec_root, + struct snd_soc_codec *codec) +{ + return 0; +} + +void wsa881x_regmap_defaults(struct regmap *regmap, u8 version) +{ +} + +#endif + #endif /* _WSA881X_H */ diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c index 962d64e94ba3..2385bac36f36 100644 --- a/asoc/msm-audio-effects-q6-v2.c +++ b/asoc/msm-audio-effects-q6-v2.c @@ -154,7 +154,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -182,7 +182,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT STRENGTH", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -210,7 +210,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT OUT_TYPE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -238,7 +238,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT GAIN_ADJUST", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -316,7 +316,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -344,7 +344,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_MODE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -372,7 +372,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_PRESET", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -400,7 +400,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_WET_MIX", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -428,7 +428,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_GAIN_ADJUST", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -456,7 +456,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_ROOM_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -484,7 +484,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_ROOM_HF_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -512,7 +512,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DECAY_TIME", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -540,7 +540,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DECAY_HF_RATIO", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -568,7 +568,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_REFLECTIONS_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -596,7 +596,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_REFLECTIONS_DELAY", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -624,7 +624,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -652,7 +652,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DELAY", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -680,7 +680,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DIFFUSION", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -708,7 +708,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DENSITY", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -787,7 +787,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "BASS_BOOST_ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST; *updt_params++ = @@ -815,7 +815,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "BASS_BOOST_MODE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST; *updt_params++ = @@ -843,7 +843,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "BASS_BOOST_STRENGTH", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST; *updt_params++ = @@ -920,7 +920,7 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "PBE_ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_PBE; *updt_params++ = @@ -946,7 +946,7 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "PBE_PARAM", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_PBE; *updt_params++ = @@ -1031,7 +1031,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1099,7 +1099,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_CONFIG", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1150,7 +1150,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_BAND_INDEX", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1182,7 +1182,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_SINGLE_BAND_FREQ", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1271,7 +1271,7 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, "VOLUME/VOLUME2_GAIN_2CH", rc); if (rc != 0) - break; + goto invalid_config; if (instance == SOFT_VOLUME_INSTANCE_2) *updt_params++ = ASM_MODULE_ID_VOL_CTRL2; @@ -1320,7 +1320,7 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, "VOLUME/VOLUME2_GAIN_MASTER", rc); if (rc != 0) - break; + goto invalid_config; if (instance == SOFT_VOLUME_INSTANCE_2) *updt_params++ = ASM_MODULE_ID_VOL_CTRL2; diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c index 30a4d59f2ba4..89a9cc24a2e0 100644 --- a/asoc/msm-dai-fe.c +++ b/asoc/msm-dai-fe.c @@ -2376,8 +2376,20 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .rate_min = 8000, .rate_max = 384000, }, + .capture = { + .stream_name = "MultiMedia10 Capture", + .aif_name = "MM_UL10", + .rates = (SNDRV_PCM_RATE_8000_48000 | + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, .ops = &msm_fe_Multimedia_dai_ops, - .compress_new = snd_soc_new_compress, .name = "MultiMedia10", .probe = fe_dai_probe, }, diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c index e96d111a61e4..339125e2d775 100644 --- a/asoc/msm-lsm-client.c +++ b/asoc/msm-lsm-client.c @@ -1682,7 +1682,7 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s REG_SND_MODEL failed err %d\n", __func__, err); - return err; + goto done; } break; case SNDRV_LSM_SET_PARAMS: { @@ -1852,13 +1852,15 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: Invalid params event_status_v3\n", __func__); - return -EINVAL; + err = -EINVAL; + goto done; } if (copy_from_user(&userarg, arg, sizeof(userarg))) { dev_err(rtd->dev, "%s: err copyuser event_status_v3\n", __func__); - return -EFAULT; + err = -EFAULT; + goto done; } if (userarg.payload_size > @@ -1866,7 +1868,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, pr_err("%s: payload_size %d is invalid, max allowed = %d\n", __func__, userarg.payload_size, LISTEN_MAX_STATUS_PAYLOAD_SIZE); - return -EINVAL; + err = -EINVAL; + goto done; } size = sizeof(struct snd_lsm_event_status_v3) + @@ -1876,7 +1879,8 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream, dev_err(rtd->dev, "%s: Allocation failed event status size %d\n", __func__, size); - return -EFAULT; + err = -EFAULT; + goto done; } user->payload_size = userarg.payload_size; err = msm_lsm_ioctl_shared(substream, cmd, user); diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index aa9b3abf6a48..8e3fe895d98d 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -1093,7 +1093,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode, port_type = MSM_AFE_PORT_TYPE_RX; } else if (stream_type == SNDRV_PCM_STREAM_CAPTURE) { session_type = SESSION_TYPE_TX; - if (passthr_mode != LEGACY_PCM) + if ((passthr_mode != LEGACY_PCM) && (passthr_mode != LISTEN)) path_type = ADM_PATH_COMPRESSED_TX; else path_type = ADM_PATH_LIVE_REC; @@ -3645,6 +3645,11 @@ static const struct snd_kcontrol_new ext_ec_ref_mux_ul16 = msm_route_ec_ref_rx_enum[0], msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); +static const struct snd_kcontrol_new ext_ec_ref_mux_ul10 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL10 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + static const struct snd_kcontrol_new ext_ec_ref_mux_ul17 = SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL17 MUX Mux", msm_route_ec_ref_rx_enum[0], @@ -7251,6 +7256,59 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new mmul10_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; static const struct snd_kcontrol_new mmul17_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, @@ -11489,6 +11547,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL10", "MultiMedia10 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL16", "MultiMedia16 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL17", "MultiMedia17 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), @@ -12225,6 +12284,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia9 Mixer", SND_SOC_NOPM, 0, 0, mmul9_mixer_controls, ARRAY_SIZE(mmul9_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia10 Mixer", SND_SOC_NOPM, 0, 0, + mmul10_mixer_controls, ARRAY_SIZE(mmul10_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia16 Mixer", SND_SOC_NOPM, 0, 0, mmul16_mixer_controls, ARRAY_SIZE(mmul16_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0, @@ -12557,6 +12618,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &ext_ec_ref_mux_ul8), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL9 MUX", SND_SOC_NOPM, 0, 0, &ext_ec_ref_mux_ul9), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL10 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul10), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL16 MUX", SND_SOC_NOPM, 0, 0, &ext_ec_ref_mux_ul16), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL17 MUX", SND_SOC_NOPM, 0, 0, @@ -12810,9 +12873,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia10 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia16 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, + {"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, {"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -13379,6 +13444,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia3 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia5 Mixer", "MI2S_TX", "MI2S_TX"}, + {"MultiMedia10 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia16 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"MultiMedia2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, @@ -13395,17 +13461,21 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"MultiMedia3 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, {"MultiMedia5 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, {"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia16 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"}, {"MultiMedia16 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia1 Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, {"MultiMedia1 Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia10 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia16 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia2 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, @@ -13418,13 +13488,16 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"MultiMedia10 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia6 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, {"MultiMedia3 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, {"MultiMedia5 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, + {"MultiMedia10 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, {"MultiMedia16 Mixer", "INT2_MI2S_TX", "INT2_MI2S_TX"}, {"MultiMedia6 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia3 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, + {"MultiMedia10 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia16 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"}, {"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, @@ -13559,6 +13632,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, + {"MultiMedia10 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, + {"MultiMedia10 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, {"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -13586,6 +13667,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia6 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia10 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, {"MultiMedia16 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia16 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -13682,6 +13764,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia3 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia4 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia10 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia17 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia18 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, @@ -13701,6 +13784,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia3 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia4 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia10 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia17 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia18 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"}, @@ -13716,6 +13800,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL6", NULL, "MultiMedia6 Mixer"}, {"MM_UL8", NULL, "MultiMedia8 Mixer"}, {"MM_UL9", NULL, "MultiMedia9 Mixer"}, + {"MM_UL10", NULL, "MultiMedia10 Mixer"}, {"MM_UL16", NULL, "MultiMedia16 Mixer"}, {"MM_UL17", NULL, "MultiMedia17 Mixer"}, {"MM_UL18", NULL, "MultiMedia18 Mixer"}, @@ -14104,6 +14189,16 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL9 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"AUDIO_REF_EC_UL9 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_0"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"}, + {"AUDIO_REF_EC_UL10 MUX", "QUAT_TDM_RX_2", "QUAT_TDM_RX_2"}, + {"AUDIO_REF_EC_UL10 MUX", "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, {"AUDIO_REF_EC_UL17 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"AUDIO_REF_EC_UL17 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"AUDIO_REF_EC_UL17 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -14127,6 +14222,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL6", NULL, "AUDIO_REF_EC_UL6 MUX"}, {"MM_UL8", NULL, "AUDIO_REF_EC_UL8 MUX"}, {"MM_UL9", NULL, "AUDIO_REF_EC_UL9 MUX"}, + {"MM_UL10", NULL, "AUDIO_REF_EC_UL10 MUX"}, {"MM_UL16", NULL, "AUDIO_REF_EC_UL16 MUX"}, {"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"}, {"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"}, diff --git a/asoc/msm8998.c b/asoc/msm8998.c index b2fc005ebbb4..5f0128d05b0c 100644 --- a/asoc/msm8998.c +++ b/asoc/msm8998.c @@ -5036,12 +5036,13 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA7, }, { - .name = MSM_DAILINK_NAME(Compress3), - .stream_name = "Compress3", + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp.1", .dynamic = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c index 16ecfaf9e8c7..f73e1cdd8f60 100644 --- a/asoc/sdm660-common.c +++ b/asoc/sdm660-common.c @@ -44,6 +44,8 @@ enum { EXT_DISP_RX_IDX_MAX, }; +bool codec_reg_done; + /* TDM default config */ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { { /* PRI TDM */ @@ -2016,6 +2018,12 @@ int msm_common_snd_controls_size(void) } EXPORT_SYMBOL(msm_common_snd_controls_size); +void msm_set_codec_reg_done(bool done) +{ + codec_reg_done = done; +} +EXPORT_SYMBOL(msm_set_codec_reg_done); + static inline int param_is_mask(int p) { return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && @@ -3027,6 +3035,12 @@ static const struct of_device_id sdm660_asoc_machine_of_match[] = { .data = "tasha_codec"}, { .compatible = "qcom,sdm660-asoc-snd-tavil", .data = "tavil_codec"}, + { .compatible = "qcom,sdm670-asoc-snd", + .data = "internal_codec"}, + { .compatible = "qcom,sdm670-asoc-snd-tasha", + .data = "tasha_codec"}, + { .compatible = "qcom,sdm670-asoc-snd-tavil", + .data = "tavil_codec"}, {}, }; @@ -3044,6 +3058,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) if (!pdata) return -ENOMEM; + msm_set_codec_reg_done(false); match = of_match_node(sdm660_asoc_machine_of_match, pdev->dev.of_node); if (!match) diff --git a/asoc/sdm660-common.h b/asoc/sdm660-common.h index 682dcd5d055e..0544b968d159 100644 --- a/asoc/sdm660-common.h +++ b/asoc/sdm660-common.h @@ -122,4 +122,5 @@ void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream); int msm_mi2s_snd_startup(struct snd_pcm_substream *substream); void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream); int msm_common_snd_controls_size(void); +void msm_set_codec_reg_done(bool done); #endif diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c index 71ba1fa9060f..a76c16d76d00 100644 --- a/asoc/sdm660-ext-dai-links.c +++ b/asoc/sdm660-ext-dai-links.c @@ -29,8 +29,15 @@ #define WCN_CDC_SLIM_RX_CH_MAX 2 #define WCN_CDC_SLIM_TX_CH_MAX 3 -static struct snd_soc_card snd_soc_card_msm_card_tavil; -static struct snd_soc_card snd_soc_card_msm_card_tasha; +static struct snd_soc_card snd_soc_card_msm_card_tavil = { + .name = "sdm670-tavil-snd-card", + .late_probe = msm_snd_card_tavil_late_probe, +}; + +static struct snd_soc_card snd_soc_card_msm_card_tasha = { + .name = "sdm670-tasha-snd-card", + .late_probe = msm_snd_card_tasha_late_probe, +}; static struct snd_soc_ops msm_ext_slimbus_be_ops = { .hw_params = msm_snd_hw_params, @@ -990,13 +997,14 @@ static struct snd_soc_dai_link msm_ext_common_fe_dai[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA7, }, {/* hw:x,16 */ - .name = MSM_DAILINK_NAME(Compress3), - .stream_name = "Compress3", + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp.1", .dynamic = 1, .dpcm_capture = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", diff --git a/asoc/sdm660-external.c b/asoc/sdm660-external.c index 9085282964c0..dd8983c973e4 100644 --- a/asoc/sdm660-external.c +++ b/asoc/sdm660-external.c @@ -56,7 +56,6 @@ static int msm_ext_spk_control = 1; static struct wcd_mbhc_config *wcd_mbhc_cfg_ptr; -bool codec_reg_done; struct msm_asoc_wcd93xx_codec { void* (*get_afe_config_fn)(struct snd_soc_codec *codec, @@ -604,23 +603,23 @@ static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol, static void *def_ext_mbhc_cal(void) { - void *tavil_wcd_cal; + void *wcd_mbhc_cal; struct wcd_mbhc_btn_detect_cfg *btn_cfg; u16 *btn_high; - tavil_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, + wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); - if (!tavil_wcd_cal) + if (!wcd_mbhc_cal) return NULL; -#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(tavil_wcd_cal)->X) = (Y)) +#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->X) = (Y)) S(v_hs_max, 1600); #undef S -#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal)->X) = (Y)) +#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->X) = (Y)) S(num_btn, WCD_MBHC_DEF_BUTTONS); #undef S - btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(tavil_wcd_cal); + btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal); btn_high = ((void *)&btn_cfg->_v_btn_low) + (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn); @@ -633,7 +632,7 @@ static void *def_ext_mbhc_cal(void) btn_high[6] = 500; btn_high[7] = 500; - return tavil_wcd_cal; + return wcd_mbhc_cal; } static inline int param_is_mask(int p) @@ -1479,6 +1478,79 @@ static struct snd_soc_dapm_route wcd_audio_paths[] = { {"MIC BIAS4", NULL, "MCLK"}, }; +int msm_snd_card_tasha_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + void *mbhc_calibration; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err_pcm_runtime; + } + + mbhc_calibration = def_ext_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err_mbhc_cal; + } + wcd_mbhc_cfg_ptr->calibration = mbhc_calibration; + ret = tasha_mbhc_hs_detect(rtd->codec, wcd_mbhc_cfg_ptr); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_hs_detect; + } + return 0; + +err_hs_detect: + kfree(mbhc_calibration); +err_mbhc_cal: +err_pcm_runtime: + return ret; +} + +int msm_snd_card_tavil_late_probe(struct snd_soc_card *card) +{ + const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX; + struct snd_soc_pcm_runtime *rtd; + int ret = 0; + void *mbhc_calibration; + + rtd = snd_soc_get_pcm_runtime(card, be_dl_name); + if (!rtd) { + dev_err(card->dev, + "%s: snd_soc_get_pcm_runtime for %s failed!\n", + __func__, be_dl_name); + ret = -EINVAL; + goto err; + } + + mbhc_calibration = def_ext_mbhc_cal(); + if (!mbhc_calibration) { + ret = -ENOMEM; + goto err; + } + wcd_mbhc_cfg_ptr->calibration = mbhc_calibration; + ret = tavil_mbhc_hs_detect(rtd->codec, wcd_mbhc_cfg_ptr); + if (ret) { + dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n", + __func__, ret); + goto err_free_mbhc_cal; + } + return 0; + +err_free_mbhc_cal: + kfree(mbhc_calibration); +err: + return ret; +} + /** * msm_audrx_init - Audio init function of sound card instantiate. * @@ -1699,7 +1771,6 @@ int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) if (!entry) { pr_debug("%s: Cannot create codecs module entry\n", __func__); - pdata->codec_root = NULL; goto done; } pdata->codec_root = entry; @@ -1722,50 +1793,17 @@ int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) if (!entry) { pr_debug("%s: Cannot create codecs module entry\n", __func__); - ret = 0; - goto err_snd_module; + goto done; } pdata->codec_root = entry; tasha_codec_info_create_codec_entry(pdata->codec_root, codec); tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, rtd->codec); } - - wcd_mbhc_cfg_ptr->calibration = def_ext_mbhc_cal(); - if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) { - if (wcd_mbhc_cfg_ptr->calibration) { - pdata->codec = codec; - ret = tavil_mbhc_hs_detect(codec, wcd_mbhc_cfg_ptr); - if (ret < 0) - pr_err("%s: Failed to intialise mbhc %d\n", - __func__, ret); - } else { - pr_err("%s: wcd_mbhc_cfg calibration is NULL\n", - __func__); - ret = -ENOMEM; - goto err_mbhc_cal; - } - } else { - if (wcd_mbhc_cfg_ptr->calibration) { - pdata->codec = codec; - ret = tasha_mbhc_hs_detect(codec, wcd_mbhc_cfg_ptr); - if (ret < 0) - pr_err("%s: Failed to intialise mbhc %d\n", - __func__, ret); - } else { - pr_err("%s: wcd_mbhc_cfg calibration is NULL\n", - __func__); - ret = -ENOMEM; - goto err_mbhc_cal; - } - - } - codec_reg_done = true; done: + msm_set_codec_reg_done(true); return 0; -err_snd_module: err_afe_cfg: -err_mbhc_cal: return ret; } EXPORT_SYMBOL(msm_audrx_init); diff --git a/asoc/sdm660-external.h b/asoc/sdm660-external.h index acf5735c2502..d53e7c7d9518 100644 --- a/asoc/sdm660-external.h +++ b/asoc/sdm660-external.h @@ -30,6 +30,8 @@ struct snd_soc_card *populate_snd_card_dailinks(struct device *dev, int snd_card_val); int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params); +int msm_snd_card_tavil_late_probe(struct snd_soc_card *card); +int msm_snd_card_tasha_late_probe(struct snd_soc_card *card); #ifdef CONFIG_SND_SOC_EXT_CODEC int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *, struct snd_soc_card **, struct wcd_mbhc_config *); diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c index fc2378d4e8d2..b5b05b10c9a5 100644 --- a/asoc/sdm660-internal.c +++ b/asoc/sdm660-internal.c @@ -1314,6 +1314,7 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) msm_dig_codec_info_create_codec_entry(codec_root, dig_cdc); msm_anlg_codec_info_create_codec_entry(codec_root, ana_cdc); done: + msm_set_codec_reg_done(true); return 0; } @@ -1914,13 +1915,14 @@ static struct snd_soc_dai_link msm_int_dai[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA7, }, {/* hw:x,16 */ - .name = MSM_DAILINK_NAME(Compress3), - .stream_name = "Compress3", + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp.1", .dynamic = 1, .dpcm_capture = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", diff --git a/asoc/sdm845.c b/asoc/sdm845.c index e38def3c9e95..7f29450062a9 100644 --- a/asoc/sdm845.c +++ b/asoc/sdm845.c @@ -5126,12 +5126,13 @@ static struct snd_soc_dai_link msm_common_dai_links[] = { .id = MSM_FRONTEND_DAI_MULTIMEDIA7, }, { - .name = MSM_DAILINK_NAME(Compress3), - .stream_name = "Compress3", + .name = MSM_DAILINK_NAME(MultiMedia10), + .stream_name = "MultiMedia10", .cpu_dai_name = "MultiMedia10", - .platform_name = "msm-compress-dsp", + .platform_name = "msm-pcm-dsp.1", .dynamic = 1, .dpcm_playback = 1, + .dpcm_capture = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .codec_dai_name = "snd-soc-dummy-dai", @@ -6696,16 +6697,18 @@ static int msm_init_wsa_dev(struct platform_device *pdev, ret = of_property_read_u32(pdev->dev.of_node, "qcom,wsa-max-devs", &wsa_max_devs); if (ret) { - dev_dbg(&pdev->dev, + dev_info(&pdev->dev, "%s: wsa-max-devs property missing in DT %s, ret = %d\n", __func__, pdev->dev.of_node->full_name, ret); - goto err; + card->num_aux_devs = 0; + return 0; } if (wsa_max_devs == 0) { dev_warn(&pdev->dev, "%s: Max WSA devices is 0 for this target?\n", __func__); - goto err; + card->num_aux_devs = 0; + return 0; } /* Get count of WSA device phandles for this platform */ diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c index 52dced4f3558..c67a24d7aa15 100644 --- a/dsp/codecs/audio_utils_aio.c +++ b/dsp/codecs/audio_utils_aio.c @@ -30,7 +30,9 @@ #ifdef CONFIG_USE_DEV_CTRL_VOLUME #include #endif /*CONFIG_USE_DEV_CTRL_VOLUME*/ +static DEFINE_MUTEX(lock); #ifdef CONFIG_DEBUG_FS + int audio_aio_debug_open(struct inode *inode, struct file *file) { file->private_data = inode->i_private; @@ -43,29 +45,37 @@ ssize_t audio_aio_debug_read(struct file *file, char __user *buf, const int debug_bufmax = 4096; static char buffer[4096]; int n = 0; - struct q6audio_aio *audio = file->private_data; + struct q6audio_aio *audio; - mutex_lock(&audio->lock); - n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened); - n += scnprintf(buffer + n, debug_bufmax - n, - "enabled %d\n", audio->enabled); - n += scnprintf(buffer + n, debug_bufmax - n, - "stopped %d\n", audio->stopped); - n += scnprintf(buffer + n, debug_bufmax - n, - "feedback %d\n", audio->feedback); - mutex_unlock(&audio->lock); - /* Following variables are only useful for debugging when - * when playback halts unexpectedly. Thus, no mutual exclusion - * enforced - */ - n += scnprintf(buffer + n, debug_bufmax - n, - "wflush %d\n", audio->wflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "rflush %d\n", audio->rflush); - n += scnprintf(buffer + n, debug_bufmax - n, - "inqueue empty %d\n", list_empty(&audio->in_queue)); - n += scnprintf(buffer + n, debug_bufmax - n, - "outqueue empty %d\n", list_empty(&audio->out_queue)); + mutex_lock(&lock); + if (file->private_data != NULL) { + audio = file->private_data; + mutex_lock(&audio->lock); + n = scnprintf(buffer, debug_bufmax, "opened %d\n", + audio->opened); + n += scnprintf(buffer + n, debug_bufmax - n, + "enabled %d\n", audio->enabled); + n += scnprintf(buffer + n, debug_bufmax - n, + "stopped %d\n", audio->stopped); + n += scnprintf(buffer + n, debug_bufmax - n, + "feedback %d\n", audio->feedback); + mutex_unlock(&audio->lock); + /* Following variables are only useful for debugging when + * when playback halts unexpectedly. Thus, no mutual exclusion + * enforced + */ + n += scnprintf(buffer + n, debug_bufmax - n, + "wflush %d\n", audio->wflush); + n += scnprintf(buffer + n, debug_bufmax - n, + "rflush %d\n", audio->rflush); + n += scnprintf(buffer + n, debug_bufmax - n, + "inqueue empty %d\n", + list_empty(&audio->in_queue)); + n += scnprintf(buffer + n, debug_bufmax - n, + "outqueue empty %d\n", + list_empty(&audio->out_queue)); + } + mutex_unlock(&lock); buffer[n] = 0; return simple_read_from_buffer(buf, count, ppos, buffer, n); } @@ -580,6 +590,7 @@ int audio_aio_release(struct inode *inode, struct file *file) struct q6audio_aio *audio = file->private_data; pr_debug("%s[%pK]\n", __func__, audio); + mutex_lock(&lock); mutex_lock(&audio->lock); mutex_lock(&audio->read_lock); mutex_lock(&audio->write_lock); @@ -622,6 +633,8 @@ int audio_aio_release(struct inode *inode, struct file *file) #endif kfree(audio->codec_cfg); kfree(audio); + file->private_data = NULL; + mutex_unlock(&lock); return 0; } diff --git a/dsp/q6core.c b/dsp/q6core.c index dd97a495221b..181a800cbf1f 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -20,7 +20,9 @@ #include #include #include +#include #include +#include "adsp_err.h" #define TIMEOUT_MS 1000 /* @@ -36,16 +38,30 @@ enum { CORE_MAX_CAL }; +enum ver_query_status { + VER_QUERY_UNATTEMPTED, + VER_QUERY_UNSUPPORTED, + VER_QUERY_SUPPORTED +}; + +struct q6core_avcs_ver_info { + enum ver_query_status status; + struct avcs_fwk_ver_info ver_info; +}; + struct q6core_str { struct apr_svc *core_handle_q; wait_queue_head_t bus_bw_req_wait; wait_queue_head_t cmd_req_wait; + wait_queue_head_t avcs_fwk_ver_req_wait; u32 bus_bw_resp_received; enum cmd_flags { FLAG_NONE, FLAG_CMDRSP_LICENSE_RESULT } cmd_resp_received_flag; + u32 avcs_fwk_ver_resp_received; struct mutex cmd_lock; + struct mutex ver_lock; union { struct avcs_cmdrsp_get_license_validation_result cmdrsp_license_result; @@ -54,6 +70,7 @@ struct q6core_str { struct cal_type_data *cal_data[CORE_MAX_CAL]; uint32_t mem_map_cal_handle; int32_t adsp_status; + struct q6core_avcs_ver_info q6core_avcs_ver_info; }; static struct q6core_str q6core_lcl; @@ -65,9 +82,61 @@ struct generic_get_data_ { }; static struct generic_get_data_ *generic_get_data; +static int parse_fwk_version_info(uint32_t *payload) +{ + size_t fwk_ver_size; + size_t svc_size; + int num_services; + int ret = 0; + + pr_debug("%s: Payload info num services %d\n", + __func__, payload[4]); + /* + * payload1[4] is the number of services running on DSP + * Based on this info, we copy the payload into core + * avcs version info structure. + */ + num_services = payload[4]; + q6core_lcl.q6core_avcs_ver_info.ver_info.avcs_fwk_version. + num_services = num_services; + if (num_services > VSS_MAX_AVCS_NUM_SERVICES) { + pr_err("%s: num_services: %d greater than max services: %d\n", + __func__, num_services, VSS_MAX_AVCS_NUM_SERVICES); + ret = -EINVAL; + goto done; + } + fwk_ver_size = sizeof(struct avcs_get_fwk_version); + svc_size = num_services * sizeof(struct avs_svc_api_info); + /* + * Dynamically allocate memory for all + * the services based on num_services + */ + q6core_lcl.q6core_avcs_ver_info.ver_info.services = NULL; + q6core_lcl.q6core_avcs_ver_info.ver_info.services = + kzalloc(svc_size, GFP_ATOMIC); + if (q6core_lcl.q6core_avcs_ver_info.ver_info.services == NULL) { + ret = -ENOMEM; + goto done; + } + /* + * memcpy is done twice because the memory allocated for + * q6core_lcl.q6core_avcs_ver_info.ver_info is not + * contiguous. + */ + memcpy(&q6core_lcl.q6core_avcs_ver_info.ver_info, + (uint8_t *)payload, fwk_ver_size); + memcpy(q6core_lcl.q6core_avcs_ver_info.ver_info.services, + (uint8_t *)&payload[sizeof(struct avcs_get_fwk_version)/ + sizeof(uint32_t)], svc_size); + ret = 0; +done: + return ret; +} + static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) { uint32_t *payload1; + int ret = 0; if (data == NULL) { pr_err("%s: data argument is null\n", __func__); @@ -118,6 +187,17 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.bus_bw_resp_received = 1; wake_up(&q6core_lcl.bus_bw_req_wait); break; + case AVCS_CMD_GET_FWK_VERSION: + pr_debug("%s: Cmd = AVCS_CMD_GET_FWK_VERSION status[%s]\n", + __func__, adsp_err_get_err_str(payload1[1])); + /* ADSP status to match Linux error standard */ + q6core_lcl.adsp_status = -payload1[1]; + if (payload1[1] == ADSP_EUNSUPPORTED) + q6core_lcl.q6core_avcs_ver_info.status = + VER_QUERY_UNSUPPORTED; + q6core_lcl.avcs_fwk_ver_resp_received = 1; + wake_up(&q6core_lcl.avcs_fwk_ver_req_wait); + break; default: pr_err("%s: Invalid cmd rsp[0x%x][0x%x] opcode %d\n", __func__, @@ -130,7 +210,7 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) case RESET_EVENTS:{ pr_debug("%s: Reset event received in Core service\n", __func__); - apr_reset(q6core_lcl.core_handle_q); + /* no reset done as the data will not change after SSR*/ q6core_lcl.core_handle_q = NULL; break; } @@ -161,6 +241,18 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv) q6core_lcl.cmd_resp_received_flag = FLAG_CMDRSP_LICENSE_RESULT; wake_up(&q6core_lcl.cmd_req_wait); break; + case AVCS_CMDRSP_GET_FWK_VERSION: + pr_debug("%s: Received AVCS_CMDRSP_GET_FWK_VERSION\n", + __func__); + payload1 = data->payload; + q6core_lcl.q6core_avcs_ver_info.status = VER_QUERY_SUPPORTED; + q6core_lcl.avcs_fwk_ver_resp_received = 1; + ret = parse_fwk_version_info(payload1); + if (ret < 0) + pr_err("%s: Failed to parse payload:%d\n", + __func__, ret); + wake_up(&q6core_lcl.avcs_fwk_ver_req_wait); + break; default: pr_err("%s: Message id from adsp core svc: 0x%x\n", __func__, data->opcode); @@ -217,6 +309,157 @@ struct cal_block_data *cal_utils_get_cal_block_by_key( return NULL; } +static int q6core_send_get_avcs_fwk_ver_cmd(void) +{ + struct apr_hdr avcs_ver_cmd; + int ret; + + avcs_ver_cmd.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + avcs_ver_cmd.pkt_size = sizeof(struct apr_hdr); + avcs_ver_cmd.src_port = 0; + avcs_ver_cmd.dest_port = 0; + avcs_ver_cmd.token = 0; + avcs_ver_cmd.opcode = AVCS_CMD_GET_FWK_VERSION; + + q6core_lcl.adsp_status = 0; + q6core_lcl.avcs_fwk_ver_resp_received = 0; + + ret = apr_send_pkt(q6core_lcl.core_handle_q, + (uint32_t *) &avcs_ver_cmd); + if (ret < 0) { + pr_err("%s: failed to send apr packet, ret=%d\n", __func__, + ret); + goto done; + } + + ret = wait_event_timeout(q6core_lcl.avcs_fwk_ver_req_wait, + (q6core_lcl.avcs_fwk_ver_resp_received == 1), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout for AVCS fwk version info\n", + __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (q6core_lcl.adsp_status < 0) { + /* + * adsp_err_get_err_str expects a positive value but we store + * the DSP error as negative to match the Linux error standard. + * Pass in the negated value so adsp_err_get_err_str returns + * the correct string. + */ + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(-q6core_lcl.adsp_status)); + ret = adsp_err_get_lnx_err_code(q6core_lcl.adsp_status); + goto done; + } + + ret = 0; + +done: + return ret; +} + +int q6core_get_service_version(uint32_t service_id, + struct avcs_fwk_ver_info *ver_info, + size_t size) +{ + int i; + uint32_t num_services; + size_t svc_size; + + svc_size = q6core_get_avcs_service_size(service_id); + if (svc_size != size) { + pr_err("%s: Expected size: %ld, Provided size: %ld", + __func__, svc_size, size); + return -EINVAL; + } + + num_services = + q6core_lcl.q6core_avcs_ver_info.ver_info. + avcs_fwk_version.num_services; + + if (ver_info == NULL) { + pr_err("%s: NULL parameter ver_info\n", __func__); + return -EINVAL; + } + + memcpy(ver_info, &q6core_lcl.q6core_avcs_ver_info. + ver_info.avcs_fwk_version, sizeof(struct avcs_get_fwk_version)); + + if (service_id == AVCS_SERVICE_ID_ALL) { + memcpy(&ver_info->services[0], &q6core_lcl. + q6core_avcs_ver_info.ver_info.services[0], + (num_services * sizeof(struct avs_svc_api_info))); + } else { + for (i = 0; i < num_services; i++) { + if (q6core_lcl.q6core_avcs_ver_info. + ver_info.services[i].service_id == service_id) { + memcpy(&ver_info->services[0], + &q6core_lcl.q6core_avcs_ver_info. + ver_info.services[i], size); + break; + } + } + } + + return 0; +} +EXPORT_SYMBOL(q6core_get_service_version); + +size_t q6core_get_avcs_service_size(uint32_t service_id) +{ + int ret = 0; + uint32_t num_services; + + num_services = + q6core_lcl.q6core_avcs_ver_info.ver_info. + avcs_fwk_version.num_services; + + mutex_lock(&(q6core_lcl.ver_lock)); + pr_debug("%s: q6core_avcs_ver_info.status(%d)\n", __func__, + q6core_lcl.q6core_avcs_ver_info.status); + + switch (q6core_lcl.q6core_avcs_ver_info.status) { + case VER_QUERY_SUPPORTED: + pr_debug("%s: AVCS FWK version query already attempted\n", + __func__); + ret = num_services * sizeof(struct avs_svc_api_info); + break; + case VER_QUERY_UNSUPPORTED: + ret = -EOPNOTSUPP; + break; + case VER_QUERY_UNATTEMPTED: + pr_debug("%s: Attempting AVCS FWK version query\n", __func__); + if (q6core_is_adsp_ready()) { + ret = q6core_send_get_avcs_fwk_ver_cmd(); + if (ret == 0) + ret = num_services * + sizeof(struct avs_svc_api_info); + } else { + pr_err("%s: ADSP is not ready to query version\n", + __func__); + ret = -ENODEV; + } + break; + default: + pr_err("%s: Invalid version query status %d\n", __func__, + q6core_lcl.q6core_avcs_ver_info.status); + ret = -EINVAL; + break; + } + mutex_unlock(&(q6core_lcl.ver_lock)); + + if (service_id != AVCS_SERVICE_ID_ALL) + return sizeof(struct avs_svc_api_info); + + return ret; +} +EXPORT_SYMBOL(q6core_get_avcs_service_size); + int32_t core_set_license(uint32_t key, uint32_t module_id) { struct avcs_cmd_set_license *cmd_setl = NULL; @@ -827,18 +1070,16 @@ err: static int __init core_init(void) { + memset(&q6core_lcl, 0, sizeof(struct q6core_str)); init_waitqueue_head(&q6core_lcl.bus_bw_req_wait); - q6core_lcl.bus_bw_resp_received = 0; - - q6core_lcl.core_handle_q = NULL; - init_waitqueue_head(&q6core_lcl.cmd_req_wait); + init_waitqueue_head(&q6core_lcl.avcs_fwk_ver_req_wait); q6core_lcl.cmd_resp_received_flag = FLAG_NONE; mutex_init(&q6core_lcl.cmd_lock); - q6core_lcl.mem_map_cal_handle = 0; - q6core_lcl.adsp_status = 0; + mutex_init(&q6core_lcl.ver_lock); q6core_init_cal_data(); + return 0; } module_init(core_init); @@ -846,6 +1087,7 @@ module_init(core_init); static void __exit core_exit(void) { mutex_destroy(&q6core_lcl.cmd_lock); + mutex_destroy(&q6core_lcl.ver_lock); q6core_delete_cal_data(); } module_exit(core_exit); diff --git a/dsp/q6voice.c b/dsp/q6voice.c index cfcc822d5484..28e50d9f55eb 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -24,8 +24,9 @@ #include #include #include -#include +#include #include +#include #include "adsp_err.h" #define TIMEOUT_MS 300 @@ -33,6 +34,9 @@ #define CMD_STATUS_SUCCESS 0 #define CMD_STATUS_FAIL 1 +#define NUM_CHANNELS_MONO 1 +#define NUM_CHANNELS_STEREO 2 +#define CVP_VERSION_2 2 enum { VOC_TOKEN_NONE, @@ -83,6 +87,11 @@ static int voice_send_cvp_device_channels_cmd(struct voice_data *v); static int voice_send_cvp_media_format_cmd(struct voice_data *v, uint32_t param_type); static int voice_send_cvp_topology_commit_cmd(struct voice_data *v); +static int voice_send_cvp_channel_info_cmd(struct voice_data *v); +static int voice_send_cvp_channel_info_v2(struct voice_data *v, + uint32_t param_type); +static int voice_get_avcs_version_per_service(uint32_t service_id); + static int voice_cvs_stop_playback(struct voice_data *v); static int voice_cvs_start_playback(struct voice_data *v); @@ -3793,6 +3802,295 @@ done: return result; } +static int voice_send_cvp_channel_info_v2(struct voice_data *v, + uint32_t param_type) +{ + int ret; + struct cvp_set_channel_info_cmd_v2 cvp_set_channel_info_cmd; + void *apr_cvp; + u16 cvp_handle; + struct vss_icommon_param_data_channel_info_v2_t + *channel_info_param_data = + &cvp_set_channel_info_cmd. + cvp_set_ch_info_param_v2.param_data; + struct vss_param_vocproc_dev_channel_info_t *channel_info = + &channel_info_param_data->channel_info; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + memset(&cvp_set_channel_info_cmd, 0, sizeof(cvp_set_channel_info_cmd)); + + cvp_set_channel_info_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_set_channel_info_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_set_channel_info_cmd) - APR_HDR_SIZE); + cvp_set_channel_info_cmd.hdr.src_svc = 0; + cvp_set_channel_info_cmd.hdr.src_domain = APR_DOMAIN_APPS; + cvp_set_channel_info_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_set_channel_info_cmd.hdr.dest_svc = 0; + cvp_set_channel_info_cmd.hdr.dest_domain = APR_DOMAIN_ADSP; + cvp_set_channel_info_cmd.hdr.dest_port = cvp_handle; + cvp_set_channel_info_cmd.hdr.token = 0; + cvp_set_channel_info_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; + + cvp_set_channel_info_cmd.cvp_set_ch_info_param_v2.mem_size = + sizeof(struct vss_icommon_param_data_channel_info_v2_t); + + channel_info_param_data->module_id = VSS_MODULE_CVD_GENERIC; + channel_info_param_data->param_size = + sizeof(struct vss_param_vocproc_dev_channel_info_t); + + /* Device specific data */ + switch (param_type) { + case RX_PATH: + channel_info_param_data->param_id = + VSS_PARAM_VOCPROC_RX_CHANNEL_INFO; + channel_info->num_channels = v->dev_rx.no_of_channels; + channel_info->bits_per_sample = v->dev_rx.bits_per_sample; + break; + + case TX_PATH: + channel_info_param_data->param_id = + VSS_PARAM_VOCPROC_TX_CHANNEL_INFO; + channel_info->num_channels = v->dev_tx.no_of_channels; + channel_info->bits_per_sample = v->dev_tx.bits_per_sample; + break; + + case EC_REF_PATH: + channel_info_param_data->param_id = + VSS_PARAM_VOCPROC_EC_REF_CHANNEL_INFO; + channel_info->num_channels = v->dev_rx.no_of_channels; + channel_info->bits_per_sample = v->dev_rx.bits_per_sample; + break; + default: + pr_err("%s: Invalid param type\n", + __func__); + ret = -EINVAL; + goto done; + } + + if (channel_info->num_channels == NUM_CHANNELS_MONO) { + channel_info->channel_mapping[0] = PCM_CHANNEL_FC; + } else if (channel_info->num_channels == NUM_CHANNELS_STEREO) { + channel_info->channel_mapping[0] = PCM_CHANNEL_FL; + channel_info->channel_mapping[1] = PCM_CHANNEL_FR; + } else { + pr_err("%s: Unsupported num channels: %d\n", + __func__, channel_info->num_channels); + ret = -EINVAL; + goto done; + } + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_channel_info_cmd); + if (ret < 0) { + pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2\n", + __func__); + goto done; + } + + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s] handle = %d\n", __func__, + adsp_err_get_err_str(v->async_err), cvp_handle); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; +done: + return ret; +} + +static int voice_send_cvp_channel_info_cmd(struct voice_data *v) +{ + int ret = 0; + + ret = voice_send_cvp_channel_info_v2(v, RX_PATH); + if (ret < 0) { + pr_err("%s: Error in sending cvp_channel_info RX: %d\n", + __func__, ret); + goto done; + } + + ret = voice_send_cvp_channel_info_v2(v, TX_PATH); + if (ret < 0) { + pr_err("%s: Error in sending cvp_channel_info TX: %d\n", + __func__, ret); + goto done; + } + + ret = voice_send_cvp_channel_info_v2(v, EC_REF_PATH); + if (ret < 0) { + pr_err("%s: Error in sending cvp_channel_info EC Ref: %d\n", + __func__, ret); + goto done; + } +done: + return ret; +} + +static int voice_send_cvp_mfc_config_v2(struct voice_data *v) +{ + int ret; + struct cvp_set_mfc_config_cmd_v2 cvp_set_mfc_config_cmd; + void *apr_cvp; + u16 cvp_handle; + struct vss_icommon_param_data_mfc_config_v2_t *cvp_config_param_data = + &cvp_set_mfc_config_cmd.cvp_set_mfc_param_v2.param_data; + struct vss_param_mfc_config_info_t *mfc_config_info = + &cvp_config_param_data->mfc_config_info; + + if (v == NULL) { + pr_err("%s: v is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + ret = -EINVAL; + goto done; + } + + cvp_handle = voice_get_cvp_handle(v); + memset(&cvp_set_mfc_config_cmd, 0, sizeof(cvp_set_mfc_config_cmd)); + + cvp_set_mfc_config_cmd.hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + cvp_set_mfc_config_cmd.hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, + sizeof(cvp_set_mfc_config_cmd) - APR_HDR_SIZE); + cvp_set_mfc_config_cmd.hdr.src_svc = 0; + cvp_set_mfc_config_cmd.hdr.src_domain = APR_DOMAIN_APPS; + cvp_set_mfc_config_cmd.hdr.src_port = + voice_get_idx_for_session(v->session_id); + cvp_set_mfc_config_cmd.hdr.dest_svc = 0; + cvp_set_mfc_config_cmd.hdr.dest_domain = APR_DOMAIN_ADSP; + cvp_set_mfc_config_cmd.hdr.dest_port = cvp_handle; + cvp_set_mfc_config_cmd.hdr.token = 0; + cvp_set_mfc_config_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; + cvp_set_mfc_config_cmd.cvp_set_mfc_param_v2.mem_size = + sizeof(struct vss_icommon_param_data_mfc_config_v2_t); + + cvp_config_param_data->module_id = AUDPROC_MODULE_ID_MFC; + cvp_config_param_data->param_id = + AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; + cvp_config_param_data->param_size = + sizeof(struct vss_param_mfc_config_info_t); + + mfc_config_info->num_channels = v->dev_rx.no_of_channels; + mfc_config_info->bits_per_sample = 16; + mfc_config_info->sample_rate = v->dev_rx.sample_rate; + + if (mfc_config_info->num_channels == NUM_CHANNELS_MONO) { + mfc_config_info->channel_type[0] = PCM_CHANNEL_FC; + } else if (mfc_config_info->num_channels == NUM_CHANNELS_STEREO) { + mfc_config_info->channel_type[0] = PCM_CHANNEL_FL; + mfc_config_info->channel_type[1] = PCM_CHANNEL_FR; + } else { + pr_err("%s: Unsupported num channels: %d\n", + __func__, mfc_config_info->num_channels); + ret = -EINVAL; + goto done; + } + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_mfc_config_cmd); + if (ret < 0) { + pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2 %d\n", + __func__, ret); + goto done; + } + ret = wait_event_timeout(v->cvp_wait, + (v->cvp_state == CMD_STATUS_SUCCESS), + msecs_to_jiffies(TIMEOUT_MS)); + + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s] handle = %d\n", __func__, + adsp_err_get_err_str(v->async_err), cvp_handle); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; +done: + return ret; +} + +static int voice_send_cvp_mfc_config_cmd(struct voice_data *v) +{ + int ret = 0; + + if (common.cvp_version >= CVP_VERSION_2) { + ret = voice_send_cvp_mfc_config_v2(v); + } else { + pr_warn("%s: CVP Version not supported\n", __func__); + ret = -EINVAL; + } + + return ret; +} + +static int voice_get_avcs_version_per_service(uint32_t service_id) +{ + int ret = 0; + size_t svc_size; + struct avcs_fwk_ver_info ver_info = {{0}, NULL}; + + if (service_id == AVCS_SERVICE_ID_ALL) { + pr_err("%s: Invalid service id: %d", __func__, + AVCS_SERVICE_ID_ALL); + return -EINVAL; + } + + svc_size = sizeof(struct avs_svc_api_info); + ver_info.services = kzalloc(svc_size, GFP_KERNEL); + if (ver_info.services == NULL) + return -ENOMEM; + + ret = q6core_get_service_version(service_id, &ver_info, svc_size); + if (ret < 0) + goto done; + + ret = ver_info.services[0].api_version; + common.is_avcs_version_queried = true; +done: + kfree(ver_info.services); + return ret; +} + static int voice_setup_vocproc(struct voice_data *v) { int ret = 0; @@ -3803,6 +4101,18 @@ static int voice_setup_vocproc(struct voice_data *v) goto fail; } + if (common.is_avcs_version_queried == false) + common.cvp_version = voice_get_avcs_version_per_service( + APRV2_IDS_SERVICE_ID_ADSP_CVP_V); + + if (common.cvp_version < 0) { + pr_err("%s: Invalid CVP version %d\n", + __func__, common.cvp_version); + ret = -EINVAL; + goto fail; + } + pr_debug("%s: CVP Version %d\n", __func__, common.cvp_version); + ret = voice_send_cvp_media_fmt_info_cmd(v); if (ret < 0) { pr_err("%s: Set media format info failed err:%d\n", __func__, @@ -3817,6 +4127,15 @@ static int voice_setup_vocproc(struct voice_data *v) goto fail; } + /* Send MFC config only when the no of channels are more than 1 */ + if (v->dev_rx.no_of_channels > NUM_CHANNELS_MONO) { + ret = voice_send_cvp_mfc_config_cmd(v); + if (ret < 0) { + pr_warn("%s: Set mfc config failed err:%d\n", + __func__, ret); + } + } + voice_send_cvs_register_cal_cmd(v); voice_send_cvp_register_dev_cfg_cmd(v); voice_send_cvp_register_cal_cmd(v); @@ -3962,11 +4281,18 @@ done: static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v) { - int ret; + int ret = 0; - ret = voice_send_cvp_device_channels_cmd(v); - if (ret < 0) + if (common.cvp_version < CVP_VERSION_2) + ret = voice_send_cvp_device_channels_cmd(v); + else + ret = voice_send_cvp_channel_info_cmd(v); + + if (ret < 0) { + pr_err("%s: Set channel info failed err: %d\n", __func__, + ret); goto done; + } if (voice_get_cvd_int_version(common.cvd_version) >= CVD_INT_VERSION_2_3) { @@ -3994,7 +4320,7 @@ static int voice_send_cvp_media_format_cmd(struct voice_data *v, void *apr_cvp; u16 cvp_handle; struct vss_icommon_param_data_t *media_fmt_param_data = - &cvp_set_media_format_cmd.cvp_set_param_v2.param_data; + &cvp_set_media_format_cmd.cvp_set_media_param_v2.param_data; struct vss_param_endpoint_media_format_info_t *media_fmt_info = &media_fmt_param_data->media_format_info; @@ -4032,7 +4358,7 @@ static int voice_send_cvp_media_format_cmd(struct voice_data *v, cvp_set_media_format_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; /* Fill param data */ - cvp_set_media_format_cmd.cvp_set_param_v2.mem_size = + cvp_set_media_format_cmd.cvp_set_media_param_v2.mem_size = sizeof(struct vss_icommon_param_data_t); media_fmt_param_data->module_id = VSS_MODULE_CVD_GENERIC; media_fmt_param_data->param_size = @@ -6197,6 +6523,15 @@ int voc_enable_device(uint32_t session_id) goto done; } + /* Send MFC config only when the no of channels are > 1 */ + if (v->dev_rx.no_of_channels > NUM_CHANNELS_MONO) { + ret = voice_send_cvp_mfc_config_cmd(v); + if (ret < 0) { + pr_warn("%s: Set mfc config failed err: %d\n", + __func__, ret); + } + } + voice_send_cvp_register_dev_cfg_cmd(v); voice_send_cvp_register_cal_cmd(v); voice_send_cvp_register_vol_cal_cmd(v); @@ -7054,7 +7389,8 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) case VSS_ICOMMON_CMD_SET_PARAM_V2: switch (data->token) { case VOC_SET_MEDIA_FORMAT_PARAM_TOKEN: - pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by voice_send_cvp_media_format_cmd\n", + case VOC_GENERIC_SET_PARAM_TOKEN: + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called\n", __func__); v->cvp_state = CMD_STATUS_SUCCESS; v->async_err = ptr[1]; @@ -8566,7 +8902,8 @@ static int __init voice_init(void) common.default_vol_step_val = 0; common.default_vol_ramp_duration_ms = DEFAULT_VOLUME_RAMP_DURATION; common.default_mute_ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION; - + common.cvp_version = 0; + common.is_avcs_version_queried = false; /* Initialize EC Ref media format info */ common.ec_ref_ext = false; common.ec_media_fmt_info.port_id = AFE_PORT_INVALID; diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 7fb2256bff8b..66d6e475e896 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -8537,6 +8537,8 @@ struct asm_eq_params { #define VSS_ICOMMON_CMD_GET_PARAM_V2 0x0001133E #define VSS_ICOMMON_RSP_GET_PARAM 0x00011008 +#define VSS_MAX_AVCS_NUM_SERVICES 25 + /* ID of the Bass Boost module. * This module supports the following parameter IDs: * - #AUDPROC_PARAM_ID_BASS_BOOST_ENABLE @@ -9197,6 +9199,74 @@ struct asm_aptx_dec_fmt_blk_v2 { */ } __packed; +/* Q6Core Specific */ +#define AVCS_CMD_GET_FWK_VERSION (0x0001292C) +#define AVCS_CMDRSP_GET_FWK_VERSION (0x0001292D) + +#define AVCS_SERVICE_ID_ALL (0xFFFFFFFF) +#define APRV2_IDS_SERVICE_ID_ADSP_CVP_V (0xB) + +struct avcs_get_fwk_version { + /* + * Indicates the major version of the AVS build. + * This value is incremented on chipset family boundaries. + */ + uint32_t build_major_version; + + /* + * Minor version of the AVS build. + * This value represents the mainline to which the AVS build belongs. + */ + uint32_t build_minor_version; + + /* Indicates the AVS branch version to which the image belongs. */ + uint32_t build_branch_version; + + /* Indicates the AVS sub-branch or customer product line information. */ + uint32_t build_subbranch_version; + + /* Number of supported AVS services in the current build. */ + uint32_t num_services; +}; + +struct avs_svc_api_info { + /* + * APRV2 service IDs for the individual static services. + * + * @values + * - APRV2_IDS_SERVICE_ID_ADSP_CORE_V + * - APRV2_IDS_SERVICE_ID_ADSP_AFE_V + * - APRV2_IDS_SERVICE_ID_ADSP_ASM_V + * - APRV2_IDS_SERVICE_ID_ADSP_ADM_V + * - APRV2_IDS_SERVICE_ID_ADSP_MVM_V + * - APRV2_IDS_SERVICE_ID_ADSP_CVS_V + * - APRV2_IDS_SERVICE_ID_ADSP_CVP_V + * - APRV2_IDS_SERVICE_ID_ADSP_LSM_V + */ + uint32_t service_id; + + /* + * Indicates the API version of the service. + * + * Each new API update that warrants a change on the HLOS side triggers + * an increment in the version. + */ + uint32_t api_version; + + /* + * Indicates the API increments on a sub-branch (not on the mainline). + * + * API branch version numbers can increment independently on different + * sub-branches. + */ + uint32_t api_branch_version; +}; + +struct avcs_fwk_ver_info { + struct avcs_get_fwk_version avcs_fwk_version; + struct avs_svc_api_info *services; +} __packed; + /* LSM Specific */ #define VW_FEAT_DIM (39) diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index c0327ae1f77e..1f1adad031e3 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -13,6 +13,7 @@ #ifndef __Q6CORE_H__ #define __Q6CORE_H__ #include +#include @@ -21,6 +22,11 @@ bool q6core_is_adsp_ready(void); +int q6core_get_service_version(uint32_t service_id, + struct avcs_fwk_ver_info *ver_info, + size_t size); +size_t q6core_get_avcs_service_size(uint32_t service_id); + #define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919 #define DTS_EAGLE_LICENSE_ID 0x00028346 struct adsp_dts_eagle { diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h index 56326b174b38..f6f0d8c80591 100644 --- a/include/dsp/q6voice.h +++ b/include/dsp/q6voice.h @@ -124,7 +124,7 @@ struct media_format_info { }; enum { - VOC_NO_SET_PARAM_TOKEN = 0, + VOC_GENERIC_SET_PARAM_TOKEN = 0, VOC_RTAC_SET_PARAM_TOKEN, VOC_SET_MEDIA_FORMAT_PARAM_TOKEN, VOC_SET_PARAM_TOKEN_MAX @@ -239,6 +239,19 @@ struct vss_param_endpoint_media_format_info_t { uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX]; } __packed; +struct vss_param_vocproc_dev_channel_info_t { + uint32_t num_channels; + uint32_t bits_per_sample; + uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX]; +} __packed; + +struct vss_param_mfc_config_info_t { + uint32_t sample_rate; + uint16_t bits_per_sample; + uint16_t num_channels; + uint16_t channel_type[VSS_NUM_CHANNELS_MAX]; +} __packed; + struct vss_icommon_param_data_t { /* Valid ID of the module. */ uint32_t module_id; @@ -260,6 +273,88 @@ struct vss_icommon_param_data_t { }; } __packed; +struct vss_icommon_param_data_channel_info_v2_t { + /* Valid ID of the module. */ + uint32_t module_id; + /* Valid ID of the parameter. */ + uint32_t param_id; + /* + * Data size of the structure relating to the param_id/module_id + * combination in uint8_t bytes. + */ + uint16_t param_size; + /* This field must be set to zero. */ + uint16_t reserved; + struct vss_param_vocproc_dev_channel_info_t channel_info; +} __packed; + +struct vss_icommon_cmd_set_param_channel_info_v2_t { + /* + * Pointer to the unique identifier for an address (physical/virtual). + * + * If the parameter data payload is within the message payload + * (in-band), set this field to 0. The parameter data begins at the + * specified data payload address. + * + * If the parameter data is out-of-band, this field is the handle to + * the physical address in the shared memory that holds the parameter + * data. + */ + uint32_t mem_handle; + /* + * Location of the parameter data payload. + * + * The payload is an array of vss_icommon_param_data_t. If the + * mem_handle is 0, this field is ignored. + */ + uint64_t mem_address; + /* Size of the parameter data payload in bytes. */ + uint32_t mem_size; + struct vss_icommon_param_data_channel_info_v2_t param_data; +} __packed; + +struct vss_icommon_param_data_mfc_config_v2_t { + /* Valid ID of the module. */ + uint32_t module_id; + /* Valid ID of the parameter. */ + uint32_t param_id; + /* + * Data size of the structure relating to the param_id/module_id + * combination in uint8_t bytes. + */ + uint16_t param_size; + /* This field must be set to zero. */ + uint16_t reserved; + struct vss_param_mfc_config_info_t mfc_config_info; +} __packed; + +struct vss_icommon_cmd_set_param_mfc_config_v2_t { + /* + * Pointer to the unique identifier for an address (physical/virtual). + * + * If the parameter data payload is within the message payload + * (in-band), set this field to 0. The parameter data begins at the + * specified data payload address. + * + * If the parameter data is out-of-band, this field is the handle to + * the physical address in the shared memory that holds the parameter + * data. + */ + + uint32_t mem_handle; + /* + * Location of the parameter data payload. + * + * The payload is an array of vss_icommon_param_data_t. If the + * mem_handle is 0, this field is ignored. + */ + uint64_t mem_address; + /* Size of the parameter data payload in bytes. */ + uint32_t mem_size; + + struct vss_icommon_param_data_mfc_config_v2_t param_data; +} __packed; + /* Payload structure for the VSS_ICOMMON_CMD_SET_PARAM_V2 command. */ struct vss_icommon_cmd_set_param_v2_t { /* @@ -674,6 +769,12 @@ struct vss_imemory_cmd_unmap_t { #define VSS_IRECORD_MODE_TX_RX_MIXING 0x00010F7B /* Select mixed Tx and Rx paths. */ +#define VSS_PARAM_VOCPROC_TX_CHANNEL_INFO 0x0001328E + +#define VSS_PARAM_VOCPROC_RX_CHANNEL_INFO 0x0001328F + +#define VSS_PARAM_VOCPROC_EC_REF_CHANNEL_INFO 0x00013290 + #define VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO 0x00013253 #define VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO 0x00013254 @@ -1485,7 +1586,18 @@ struct cvp_set_dev_channels_cmd { struct cvp_set_media_format_cmd { struct apr_hdr hdr; - struct vss_icommon_cmd_set_param_v2_t cvp_set_param_v2; + struct vss_icommon_cmd_set_param_v2_t cvp_set_media_param_v2; +} __packed; + +struct cvp_set_channel_info_cmd_v2 { + struct apr_hdr hdr; + struct vss_icommon_cmd_set_param_channel_info_v2_t + cvp_set_ch_info_param_v2; +} __packed; + +struct cvp_set_mfc_config_cmd_v2 { + struct apr_hdr hdr; + struct vss_icommon_cmd_set_param_mfc_config_v2_t cvp_set_mfc_param_v2; } __packed; struct cvp_set_vp3_data_cmd { @@ -1756,6 +1868,8 @@ struct common_data { bool srvcc_rec_flag; bool is_destroy_cvd; char cvd_version[CVD_VERSION_STRING_MAX_SIZE]; + int cvp_version; + bool is_avcs_version_queried; bool is_per_vocoder_cal_enabled; bool is_sound_focus_resp_success; bool is_source_tracking_resp_success; diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c index db5a9e5a4d02..1e7ead817399 100644 --- a/soc/pinctrl-lpi.c +++ b/soc/pinctrl-lpi.c @@ -26,7 +26,7 @@ #include "core.h" #include "pinctrl-utils.h" -#define LPI_ADDRESS_SIZE 0xC000 +#define LPI_ADDRESS_SIZE 0x20000 #define LPI_GPIO_REG_VAL_CTL 0x00 #define LPI_GPIO_REG_DIR_CTL 0x04 @@ -109,35 +109,35 @@ static const u32 lpi_offset[] = { 0x00000000, 0x00001000, 0x00002000, - 0x00002010, 0x00003000, - 0x00003010, 0x00004000, - 0x00004010, 0x00005000, - 0x00005010, - 0x00005020, - 0x00005030, 0x00006000, - 0x00006010, 0x00007000, - 0x00007010, - 0x00005040, - 0x00005050, 0x00008000, - 0x00008010, - 0x00008020, - 0x00008030, - 0x00008040, - 0x00008050, - 0x00008060, - 0x00008070, 0x00009000, - 0x00009010, 0x0000A000, - 0x0000A010, 0x0000B000, - 0x0000B010, + 0x0000C000, + 0x0000D000, + 0x0000E000, + 0x0000F000, + 0x00010000, + 0x00011000, + 0x00012000, + 0x00013000, + 0x00014000, + 0x00015000, + 0x00016000, + 0x00017000, + 0x00018000, + 0x00019000, + 0x0001A000, + 0x0001B000, + 0x0001C000, + 0x0001D000, + 0x0001E000, + 0x0001F000, }; static const char *const lpi_gpio_functions[] = {