Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbbcd776 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: msm8x10: add support to split SD0/1 as two seperate BE"

parents ccda0328 47b7ce98
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -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
@@ -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_ */
+1 −0
Original line number Diff line number Diff line
@@ -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;
+3 −0
Original line number Diff line number Diff line
@@ -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
};

@@ -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__ */
+16 −1
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ enum {
enum {
	AIF1_PB = 0,
	AIF1_CAP,
	AIF2_PB,
	NUM_CODEC_DAIS,
};

@@ -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,
@@ -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),

+160 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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)
{
@@ -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)
{
@@ -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)
{
@@ -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;
@@ -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)
@@ -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)
@@ -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,
@@ -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,
@@ -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",
@@ -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