Loading include/sound/apr_audio-v2.h +42 −0 Original line number Diff line number Diff line Loading @@ -787,6 +787,7 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_SECONDARY_PCM_RX 0x100C #define AFE_PORT_ID_SECONDARY_PCM_TX 0x100D #define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E #define AFE_PORT_ID_SECONDARY_MI2S_RX_VIBRA 0x1010 #define AFE_PORT_ID_SPDIF_RX 0x5000 #define AFE_PORT_ID_RT_PROXY_PORT_001_RX 0x2000 #define AFE_PORT_ID_RT_PROXY_PORT_001_TX 0x2001 Loading Loading @@ -7337,4 +7338,45 @@ struct afe_svc_cmd_set_clip_bank_selection { #define US_RAW_SYNC_FORMAT 0x0001272F #define US_GES_SYNC_FORMAT 0x00012730 #define AFE_MODULE_GROUP_DEVICE 0x00010254 #define AFE_PARAM_ID_GROUP_DEVICE_CFG 0x00010255 #define AFE_PARAM_ID_GROUP_DEVICE_ENABLE 0x00010256 #define AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX 0x1102 /* Payload of the #AFE_PARAM_ID_GROUP_DEVICE_CFG * parameter, which configures max of 8 AFE ports * into a group. * The fixed size of this structure is sixteen bytes. */ struct afe_group_device_group_cfg { u32 minor_version; u16 group_id; u16 num_channels; u16 port_id[8]; } __packed; /* Payload of the #AFE_PARAM_ID_GROUP_DEVICE_ENABLE * parameter, which enables or * disables any module. * The fixed size of this structure is four bytes. */ struct afe_group_device_enable { u16 group_id; /* valid value is AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX */ u16 enable; /* Enables (1) or disables (0) the module. */ } __packed; struct afe_port_group_create { struct apr_hdr hdr; struct afe_svc_cmd_set_param param; struct afe_port_param_data_v2 pdata; union { struct afe_group_device_group_cfg group_cfg; struct afe_group_device_enable group_enable; } __packed data; } __packed; #endif /*_APR_AUDIO_V2_H_ */ include/sound/msm-dai-q6-v2.h +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #define MSM_SEC_MI2S 1 #define MSM_TERT_MI2S 2 #define MSM_QUAT_MI2S 3 #define MSM_SEC_MI2S_VIBRA 4 struct msm_dai_auxpcm_config { u16 mode; Loading include/sound/q6afe-v2.h +3 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ enum { IDX_SPDIF_RX = 47, IDX_GLOBAL_CFG, IDX_AUDIO_PORT_ID_I2S_RX, IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_VIBRA, AFE_MAX_PORTS }; Loading Loading @@ -218,4 +219,6 @@ void afe_clear_config(enum afe_config_type config); bool afe_has_config(enum afe_config_type config); void afe_set_aanc_info(struct aanc_data *aanc_info); int afe_port_group_set_param(u16 *port_id, int channel_count); int afe_port_group_enable(u16 enable); #endif /* __Q6AFE_V2_H__ */ sound/soc/codecs/msm8x10-wcd.c +16 −1 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ enum { enum { AIF1_PB = 0, AIF1_CAP, AIF2_PB, NUM_CODEC_DAIS, }; Loading Loading @@ -2352,6 +2353,20 @@ static struct snd_soc_dai_driver msm8x10_wcd_i2s_dai[] = { }, .ops = &msm8x10_wcd_dai_ops, }, { .name = "msm8x10_wcd_i2s_rx2", .id = AIF2_PB, .playback = { .stream_name = "AIF2 Playback", .rates = MSM8X10_WCD_RATES, .formats = MSM8X10_WCD_FORMATS, .rate_max = 192000, .rate_min = 8000, .channels_min = 1, .channels_max = 3, }, .ops = &msm8x10_wcd_dai_ops, }, }; static int msm8x10_wcd_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, Loading Loading @@ -2389,7 +2404,7 @@ static const struct snd_soc_dapm_widget msm8x10_wcd_dapm_widgets[] = { SND_SOC_DAPM_AIF_IN("I2S RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("I2S RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("I2S RX3", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_SUPPLY("INT_LDO_H", SND_SOC_NOPM, 1, 0, NULL, 0), Loading sound/soc/msm/msm8x10.c +160 −2 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ static int msm_btsco_rate = BTSCO_RATE_8KHZ; static int msm_btsco_ch = 1; static int msm_sec_mi2s_rx2_group; static int msm_proxy_rx_ch = 2; static struct platform_device *spdev; static int ext_spk_amp_gpio = -1; Loading @@ -55,6 +57,7 @@ static void __iomem *pcbcr; static void __iomem *prcgr; static int msm_sec_mi2s_rx_ch = 1; static int msm_sec_mi2s_rx2_ch = 1; static int msm_pri_mi2s_tx_ch = 1; static int msm_sec_mi2s_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; Loading Loading @@ -275,6 +278,21 @@ static int msm_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } static int msm_rx2_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); pr_debug("%s(): channel:%d\n", __func__, msm_sec_mi2s_rx2_ch); rate->min = rate->max = 48000; channels->min = channels->max = msm_sec_mi2s_rx2_ch; return 0; } static int msm_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { Loading Loading @@ -328,6 +346,23 @@ static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol, return 0; } static int msm_mi2s_rx2_init(void) { int ret = 0; pr_debug("%s()\n", __func__); if (msm_sec_mi2s_rx2_group) { u16 port_id[8] = { AFE_PORT_ID_SECONDARY_MI2S_RX, AFE_PORT_ID_SECONDARY_MI2S_RX_VIBRA, 0, 0, 0, 0, 0, 0}; ret = afe_port_group_set_param(port_id, 4); } if (!ret) return afe_port_group_enable(msm_sec_mi2s_rx2_group); return 0; } static int msm_sec_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { Loading @@ -347,6 +382,25 @@ static int msm_sec_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, return 1; } static int msm_sec_mi2s_rx2_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { pr_debug("%s: msm_sec_mi2s_rx2_ch = %d\n", __func__, msm_sec_mi2s_rx2_ch); ucontrol->value.integer.value[0] = msm_sec_mi2s_rx2_ch - 1; return 0; } static int msm_sec_mi2s_rx2_ch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { msm_sec_mi2s_rx2_ch = ucontrol->value.integer.value[0] + 1; pr_debug("%s: msm_sec_mi2s_rx2_ch = %d\n", __func__, msm_sec_mi2s_rx2_ch); return 1; } static int msm_pri_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { Loading Loading @@ -388,6 +442,42 @@ static int msm_mi2s_snd_hw_params(struct snd_pcm_substream *substream, return 0; } static int mi2s_clk_ctl_vibra(struct snd_pcm_substream *substream, bool enable) { int ret = 0; if (enable) { digital_cdc_clk.clk_val = 9600000; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { mi2s_rx_clk.clk_val2 = Q6AFE_LPASS_OSR_CLK_12_P288_MHZ; mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock( AFE_PORT_ID_SECONDARY_MI2S_RX_VIBRA, &mi2s_rx_clk); } else pr_err("%s:Not valid substream.\n", __func__); if (ret < 0) pr_err("%s:afe_set_lpass_clock failed\n", __func__); } else { digital_cdc_clk.clk_val = 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { mi2s_rx_clk.clk_val2 = Q6AFE_LPASS_OSR_CLK_DISABLE; mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock( AFE_PORT_ID_SECONDARY_MI2S_RX_VIBRA, &mi2s_rx_clk); } else pr_err("%s:Not valid substream.\n", __func__); if (ret < 0) pr_err("%s:afe_set_lpass_clock failed\n", __func__); } return ret; } static int mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) { int ret = 0; Loading Loading @@ -474,15 +564,44 @@ static int msm8x10_mclk_event(struct snd_soc_dapm_widget *w, } } static void msm_mi2s_sec_snd_shutdown(struct snd_pcm_substream *substream) { int ret = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); ret = mi2s_clk_ctl_vibra(substream, false); if (ret < 0) pr_err("%s:clock disable failed\n", __func__); } static int msm_mi2s_sec_snd_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); ret = mi2s_clk_ctl_vibra(substream, true); ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) pr_err("set fmt cpu dai failed\n"); return ret; } static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) { int ret; int ret = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); ret = mi2s_clk_ctl(substream, false); if (ret < 0) pr_err("%s:clock disable failed\n", __func__); pr_err("%s:clock disable failed ret(%d)\n", __func__, ret); } static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) Loading Loading @@ -515,6 +634,8 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_sec_mi2s_rx_ch_get, msm_sec_mi2s_rx_ch_put), SOC_ENUM_EXT("MI2S_TX Channels", msm_snd_enum[1], msm_pri_mi2s_tx_ch_get, msm_pri_mi2s_tx_ch_put), SOC_ENUM_EXT("MI2S_RX_VIBRA Channels", msm_snd_enum[0], msm_sec_mi2s_rx2_ch_get, msm_sec_mi2s_rx2_ch_put), }; static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) Loading Loading @@ -664,6 +785,13 @@ static int msm_proxy_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = 48000; return 0; } static struct snd_soc_ops msm8x10_mi2s_sec_be_ops = { .startup = msm_mi2s_sec_snd_startup, .hw_params = msm_mi2s_snd_hw_params, .shutdown = msm_mi2s_sec_snd_shutdown, }; static struct snd_soc_ops msm8x10_mi2s_be_ops = { .startup = msm_mi2s_snd_startup, .hw_params = msm_mi2s_snd_hw_params, Loading Loading @@ -906,6 +1034,21 @@ static struct snd_soc_dai_link msm8x10_dai[] = { .codec_name = "snd-soc-dummy", .be_id = MSM_FRONTEND_DAI_QCHAT, }, {/* hw:x,16 */ .name = "MSM8x10 Vibra", .stream_name = "MultiMedia6", .cpu_dai_name = "MultiMedia6", .platform_name = "msm-pcm-dsp.2", .dynamic = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .ignore_suspend = 1, /* this dainlink has playback support */ .ignore_pmdown_time = 1, .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6, }, /* Backend I2S DAI Links */ { .name = LPASS_BE_SEC_MI2S_RX, Loading @@ -921,6 +1064,19 @@ static struct snd_soc_dai_link msm8x10_dai[] = { .ops = &msm8x10_mi2s_be_ops, .ignore_suspend = 1, }, { .name = LPASS_BE_SEC_MI2S_RX_VIBRA, .stream_name = "Secondary MI2S Playback Vibra", .cpu_dai_name = "msm-dai-q6-mi2s.4", .platform_name = "msm-pcm-routing", .codec_name = MSM8X10_CODEC_NAME, .codec_dai_name = "msm8x10_wcd_i2s_rx2", .no_pcm = 1, .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX_VIBRA, .be_hw_params_fixup = msm_rx2_be_hw_params_fixup, .ops = &msm8x10_mi2s_sec_be_ops, .ignore_suspend = 1, }, { .name = LPASS_BE_PRI_MI2S_TX, .stream_name = "Primary MI2S Capture", Loading Loading @@ -1142,6 +1298,8 @@ static int msm8x10_asoc_machine_probe(struct platform_device *pdev) goto err; } atomic_set(&mclk_rsc_ref, 0); if (msm_sec_mi2s_rx2_group) msm_mi2s_rx2_init(); return 0; err: return ret; Loading Loading
include/sound/apr_audio-v2.h +42 −0 Original line number Diff line number Diff line Loading @@ -787,6 +787,7 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_SECONDARY_PCM_RX 0x100C #define AFE_PORT_ID_SECONDARY_PCM_TX 0x100D #define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E #define AFE_PORT_ID_SECONDARY_MI2S_RX_VIBRA 0x1010 #define AFE_PORT_ID_SPDIF_RX 0x5000 #define AFE_PORT_ID_RT_PROXY_PORT_001_RX 0x2000 #define AFE_PORT_ID_RT_PROXY_PORT_001_TX 0x2001 Loading Loading @@ -7337,4 +7338,45 @@ struct afe_svc_cmd_set_clip_bank_selection { #define US_RAW_SYNC_FORMAT 0x0001272F #define US_GES_SYNC_FORMAT 0x00012730 #define AFE_MODULE_GROUP_DEVICE 0x00010254 #define AFE_PARAM_ID_GROUP_DEVICE_CFG 0x00010255 #define AFE_PARAM_ID_GROUP_DEVICE_ENABLE 0x00010256 #define AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX 0x1102 /* Payload of the #AFE_PARAM_ID_GROUP_DEVICE_CFG * parameter, which configures max of 8 AFE ports * into a group. * The fixed size of this structure is sixteen bytes. */ struct afe_group_device_group_cfg { u32 minor_version; u16 group_id; u16 num_channels; u16 port_id[8]; } __packed; /* Payload of the #AFE_PARAM_ID_GROUP_DEVICE_ENABLE * parameter, which enables or * disables any module. * The fixed size of this structure is four bytes. */ struct afe_group_device_enable { u16 group_id; /* valid value is AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX */ u16 enable; /* Enables (1) or disables (0) the module. */ } __packed; struct afe_port_group_create { struct apr_hdr hdr; struct afe_svc_cmd_set_param param; struct afe_port_param_data_v2 pdata; union { struct afe_group_device_group_cfg group_cfg; struct afe_group_device_enable group_enable; } __packed data; } __packed; #endif /*_APR_AUDIO_V2_H_ */
include/sound/msm-dai-q6-v2.h +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #define MSM_SEC_MI2S 1 #define MSM_TERT_MI2S 2 #define MSM_QUAT_MI2S 3 #define MSM_SEC_MI2S_VIBRA 4 struct msm_dai_auxpcm_config { u16 mode; Loading
include/sound/q6afe-v2.h +3 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ enum { IDX_SPDIF_RX = 47, IDX_GLOBAL_CFG, IDX_AUDIO_PORT_ID_I2S_RX, IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_VIBRA, AFE_MAX_PORTS }; Loading Loading @@ -218,4 +219,6 @@ void afe_clear_config(enum afe_config_type config); bool afe_has_config(enum afe_config_type config); void afe_set_aanc_info(struct aanc_data *aanc_info); int afe_port_group_set_param(u16 *port_id, int channel_count); int afe_port_group_enable(u16 enable); #endif /* __Q6AFE_V2_H__ */
sound/soc/codecs/msm8x10-wcd.c +16 −1 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ enum { enum { AIF1_PB = 0, AIF1_CAP, AIF2_PB, NUM_CODEC_DAIS, }; Loading Loading @@ -2352,6 +2353,20 @@ static struct snd_soc_dai_driver msm8x10_wcd_i2s_dai[] = { }, .ops = &msm8x10_wcd_dai_ops, }, { .name = "msm8x10_wcd_i2s_rx2", .id = AIF2_PB, .playback = { .stream_name = "AIF2 Playback", .rates = MSM8X10_WCD_RATES, .formats = MSM8X10_WCD_FORMATS, .rate_max = 192000, .rate_min = 8000, .channels_min = 1, .channels_max = 3, }, .ops = &msm8x10_wcd_dai_ops, }, }; static int msm8x10_wcd_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, Loading Loading @@ -2389,7 +2404,7 @@ static const struct snd_soc_dapm_widget msm8x10_wcd_dapm_widgets[] = { SND_SOC_DAPM_AIF_IN("I2S RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("I2S RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("I2S RX3", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_SUPPLY("INT_LDO_H", SND_SOC_NOPM, 1, 0, NULL, 0), Loading
sound/soc/msm/msm8x10.c +160 −2 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ static int msm_btsco_rate = BTSCO_RATE_8KHZ; static int msm_btsco_ch = 1; static int msm_sec_mi2s_rx2_group; static int msm_proxy_rx_ch = 2; static struct platform_device *spdev; static int ext_spk_amp_gpio = -1; Loading @@ -55,6 +57,7 @@ static void __iomem *pcbcr; static void __iomem *prcgr; static int msm_sec_mi2s_rx_ch = 1; static int msm_sec_mi2s_rx2_ch = 1; static int msm_pri_mi2s_tx_ch = 1; static int msm_sec_mi2s_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE; Loading Loading @@ -275,6 +278,21 @@ static int msm_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } static int msm_rx2_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); pr_debug("%s(): channel:%d\n", __func__, msm_sec_mi2s_rx2_ch); rate->min = rate->max = 48000; channels->min = channels->max = msm_sec_mi2s_rx2_ch; return 0; } static int msm_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { Loading Loading @@ -328,6 +346,23 @@ static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol, return 0; } static int msm_mi2s_rx2_init(void) { int ret = 0; pr_debug("%s()\n", __func__); if (msm_sec_mi2s_rx2_group) { u16 port_id[8] = { AFE_PORT_ID_SECONDARY_MI2S_RX, AFE_PORT_ID_SECONDARY_MI2S_RX_VIBRA, 0, 0, 0, 0, 0, 0}; ret = afe_port_group_set_param(port_id, 4); } if (!ret) return afe_port_group_enable(msm_sec_mi2s_rx2_group); return 0; } static int msm_sec_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { Loading @@ -347,6 +382,25 @@ static int msm_sec_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol, return 1; } static int msm_sec_mi2s_rx2_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { pr_debug("%s: msm_sec_mi2s_rx2_ch = %d\n", __func__, msm_sec_mi2s_rx2_ch); ucontrol->value.integer.value[0] = msm_sec_mi2s_rx2_ch - 1; return 0; } static int msm_sec_mi2s_rx2_ch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { msm_sec_mi2s_rx2_ch = ucontrol->value.integer.value[0] + 1; pr_debug("%s: msm_sec_mi2s_rx2_ch = %d\n", __func__, msm_sec_mi2s_rx2_ch); return 1; } static int msm_pri_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { Loading Loading @@ -388,6 +442,42 @@ static int msm_mi2s_snd_hw_params(struct snd_pcm_substream *substream, return 0; } static int mi2s_clk_ctl_vibra(struct snd_pcm_substream *substream, bool enable) { int ret = 0; if (enable) { digital_cdc_clk.clk_val = 9600000; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { mi2s_rx_clk.clk_val2 = Q6AFE_LPASS_OSR_CLK_12_P288_MHZ; mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ; ret = afe_set_lpass_clock( AFE_PORT_ID_SECONDARY_MI2S_RX_VIBRA, &mi2s_rx_clk); } else pr_err("%s:Not valid substream.\n", __func__); if (ret < 0) pr_err("%s:afe_set_lpass_clock failed\n", __func__); } else { digital_cdc_clk.clk_val = 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { mi2s_rx_clk.clk_val2 = Q6AFE_LPASS_OSR_CLK_DISABLE; mi2s_rx_clk.clk_val1 = Q6AFE_LPASS_IBIT_CLK_DISABLE; ret = afe_set_lpass_clock( AFE_PORT_ID_SECONDARY_MI2S_RX_VIBRA, &mi2s_rx_clk); } else pr_err("%s:Not valid substream.\n", __func__); if (ret < 0) pr_err("%s:afe_set_lpass_clock failed\n", __func__); } return ret; } static int mi2s_clk_ctl(struct snd_pcm_substream *substream, bool enable) { int ret = 0; Loading Loading @@ -474,15 +564,44 @@ static int msm8x10_mclk_event(struct snd_soc_dapm_widget *w, } } static void msm_mi2s_sec_snd_shutdown(struct snd_pcm_substream *substream) { int ret = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); ret = mi2s_clk_ctl_vibra(substream, false); if (ret < 0) pr_err("%s:clock disable failed\n", __func__); } static int msm_mi2s_sec_snd_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); ret = mi2s_clk_ctl_vibra(substream, true); ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) pr_err("set fmt cpu dai failed\n"); return ret; } static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) { int ret; int ret = 0; pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); ret = mi2s_clk_ctl(substream, false); if (ret < 0) pr_err("%s:clock disable failed\n", __func__); pr_err("%s:clock disable failed ret(%d)\n", __func__, ret); } static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) Loading Loading @@ -515,6 +634,8 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_sec_mi2s_rx_ch_get, msm_sec_mi2s_rx_ch_put), SOC_ENUM_EXT("MI2S_TX Channels", msm_snd_enum[1], msm_pri_mi2s_tx_ch_get, msm_pri_mi2s_tx_ch_put), SOC_ENUM_EXT("MI2S_RX_VIBRA Channels", msm_snd_enum[0], msm_sec_mi2s_rx2_ch_get, msm_sec_mi2s_rx2_ch_put), }; static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) Loading Loading @@ -664,6 +785,13 @@ static int msm_proxy_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = 48000; return 0; } static struct snd_soc_ops msm8x10_mi2s_sec_be_ops = { .startup = msm_mi2s_sec_snd_startup, .hw_params = msm_mi2s_snd_hw_params, .shutdown = msm_mi2s_sec_snd_shutdown, }; static struct snd_soc_ops msm8x10_mi2s_be_ops = { .startup = msm_mi2s_snd_startup, .hw_params = msm_mi2s_snd_hw_params, Loading Loading @@ -906,6 +1034,21 @@ static struct snd_soc_dai_link msm8x10_dai[] = { .codec_name = "snd-soc-dummy", .be_id = MSM_FRONTEND_DAI_QCHAT, }, {/* hw:x,16 */ .name = "MSM8x10 Vibra", .stream_name = "MultiMedia6", .cpu_dai_name = "MultiMedia6", .platform_name = "msm-pcm-dsp.2", .dynamic = 1, .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .ignore_suspend = 1, /* this dainlink has playback support */ .ignore_pmdown_time = 1, .be_id = MSM_FRONTEND_DAI_MULTIMEDIA6, }, /* Backend I2S DAI Links */ { .name = LPASS_BE_SEC_MI2S_RX, Loading @@ -921,6 +1064,19 @@ static struct snd_soc_dai_link msm8x10_dai[] = { .ops = &msm8x10_mi2s_be_ops, .ignore_suspend = 1, }, { .name = LPASS_BE_SEC_MI2S_RX_VIBRA, .stream_name = "Secondary MI2S Playback Vibra", .cpu_dai_name = "msm-dai-q6-mi2s.4", .platform_name = "msm-pcm-routing", .codec_name = MSM8X10_CODEC_NAME, .codec_dai_name = "msm8x10_wcd_i2s_rx2", .no_pcm = 1, .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX_VIBRA, .be_hw_params_fixup = msm_rx2_be_hw_params_fixup, .ops = &msm8x10_mi2s_sec_be_ops, .ignore_suspend = 1, }, { .name = LPASS_BE_PRI_MI2S_TX, .stream_name = "Primary MI2S Capture", Loading Loading @@ -1142,6 +1298,8 @@ static int msm8x10_asoc_machine_probe(struct platform_device *pdev) goto err; } atomic_set(&mclk_rsc_ref, 0); if (msm_sec_mi2s_rx2_group) msm_mi2s_rx2_init(); return 0; err: return ret; Loading