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

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

Merge "ASoC: msm8996: Add CPE ECPP DAI instance for ECPP path"

parents 66001880 3110f07b
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -370,6 +370,9 @@ Required properties:
Required properties:

 - compatible : "qcom,msm-cpe-lsm"
 - qcom,msm-cpe-lsm-id : lsm afe port ID. CPE lsm driver uses
   this property to find out the input afe port ID. Currently
   only supported values are 1 and 3.

* msm-dai-slim

@@ -1392,12 +1395,12 @@ Example:
	qcom,mbhc-audio-jack-type = "6-pole-jack";
		asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
				<&loopback>, <&compress>, <&hostless>,
				<&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>;
				<&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>, <&cpe3>;
		asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", "msm-pcm-dsp.2",
				"msm-voip-dsp", "msm-pcm-voice", "msm-pcm-loopback",
				"msm-compress-dsp", "msm-pcm-hostless", "msm-pcm-afe",
				"msm-lsm-client", "msm-pcm-routing", "msm-cpe-lsm",
				"msm-compr-dsp";
				"msm-compr-dsp", "msm-cpe-lsm.3";
		asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>, <&dai_mi2s>,
				<&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>,
				<&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>,
+77 −9
Original line number Diff line number Diff line
@@ -367,6 +367,7 @@ enum {
	AIF_MIX1_PB,
	AIF4_MAD_TX,
	AIF4_VIFEED,
	AIF5_CPE_TX,
	NUM_CODEC_DAIS,
};

@@ -475,15 +476,18 @@ static const struct wcd9xxx_ch tasha_tx_chs[TASHA_TX_MAX] = {
};

static const u32 vport_slim_check_table[NUM_CODEC_DAIS] = {
	0,							/* AIF1_PB */
	BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX),	/* AIF1_CAP */
	0,							/* AIF2_PB */
	BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX),	/* AIF2_CAP */
	0,							/* AIF3_PB */
	BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX),	/* AIF3_CAP */
	0,						     /* AIF4_PB */
	0,						     /* AIF_MIX1_PB */
	BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP),	     /* AIF4_MAD_TX */
	/* Needs to define in the same order of DAI enum definitions */
	0,
	BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
	0,
	BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
	0,
	BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX) | BIT(AIF5_CPE_TX),
	0,
	0,
	BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF5_CPE_TX),
	0,
	BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX),
};

static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = {
@@ -2318,6 +2322,7 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
		}
		break;
	case AIF4_MAD_TX:
	case AIF5_CPE_TX:
		break;
	default:
		pr_err("Unknown AIF %d\n", dai_id);
@@ -6023,6 +6028,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
	{"AIF4 MAD", NULL, "AIF4_MAD Mixer"},
	{"AIF4 MAD", NULL, "AIF4"},

	{"EC BUF MUX INP", "DEC1", "ADC MUX1"},
	{"AIF5 CPE", NULL, "EC BUF MUX INP"},

	/* SLIMBUS Connections */
	{"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
	{"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
@@ -9783,6 +9791,45 @@ static const struct snd_kcontrol_new anc0_fb_mux =
static const struct snd_kcontrol_new anc1_fb_mux =
	SOC_DAPM_ENUM("ANC1 FB MUX Mux", anc1_fb_mux_enum);

static int tasha_codec_ec_buf_mux_enable(struct snd_soc_dapm_widget *w,
					 struct snd_kcontrol *kcontrol,
					 int event)
{
	struct snd_soc_codec *codec = w->codec;

	dev_dbg(codec->dev, "%s: event = %d name = %s\n",
		__func__, event, w->name);

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x3B);
		snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x68, 0x28);
		snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0,
				    0x08, 0x08);
		break;
	case SND_SOC_DAPM_POST_PMD:
		snd_soc_update_bits(codec, WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0,
				    0x08, 0x00);
		snd_soc_update_bits(codec, WCD9335_CPE_SS_CFG, 0x68, 0x40);
		snd_soc_write(codec, WCD9335_CPE_SS_EC_BUF_INT_PERIOD, 0x00);
		break;
	}

	return 0;
};

static const char * const ec_buf_mux_text[] = {
	"ZERO", "RXMIXEC", "SB_RX0", "SB_RX1", "SB_RX2", "SB_RX3",
	"I2S_RX_SD0_L", "I2S_RX_SD0_R", "I2S_RX_SD1_L", "I2S_RX_SD1_R",
	"DEC1"
};

static SOC_ENUM_SINGLE_DECL(ec_buf_mux_enum, WCD9335_CPE_SS_US_EC_MUX_CFG,
			    0, ec_buf_mux_text);

static const struct snd_kcontrol_new ec_buf_mux =
	SOC_DAPM_ENUM("EC BUF Mux", ec_buf_mux_enum);

static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
	SND_SOC_DAPM_OUTPUT("EAR"),
	SND_SOC_DAPM_OUTPUT("ANC EAR"),
@@ -10272,6 +10319,14 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
		aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)),

	SND_SOC_DAPM_INPUT("VIINPUT"),

	SND_SOC_DAPM_AIF_OUT("AIF5 CPE", "AIF5 CPE TX", 0, SND_SOC_NOPM,
			     AIF5_CPE_TX, 0),

	SND_SOC_DAPM_MUX_E("EC BUF MUX INP", SND_SOC_NOPM, 0, 0, &ec_buf_mux,
		tasha_codec_ec_buf_mux_enable,
		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),

	/* Digital Mic Inputs */
	SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0,
		tasha_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
@@ -11255,6 +11310,19 @@ static struct snd_soc_dai_driver tasha_dai[] = {
		 },
		.ops = &tasha_dai_ops,
	},
	{
		.name = "tasha_cpe",
		.id = AIF5_CPE_TX,
		.capture = {
			.stream_name = "AIF5 CPE TX",
			.rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
			.formats = TASHA_FORMATS_S16_S24_S32_LE,
			.rate_min = 16000,
			.rate_max = 48000,
			.channels_min = 1,
			.channels_max = 1,
		},
	},
};

static struct snd_soc_dai_driver tasha_i2s_dai[] = {
+78 −22
Original line number Diff line number Diff line
@@ -28,7 +28,11 @@
#include <sound/pcm_params.h>
#include <sound/msm-slim-dma.h>

#define SAMPLE_RATE_48KHZ 48000
#define SAMPLE_RATE_16KHZ 16000
#define LSM_VOICE_WAKEUP_APP_V2 2
#define AFE_PORT_ID_1 1
#define AFE_PORT_ID_3 3
#define AFE_OUT_PORT_2 2
#define LISTEN_MIN_NUM_PERIODS     2
#define LISTEN_MAX_NUM_PERIODS     12
@@ -135,6 +139,7 @@ struct cpe_priv {
	struct wcd_cpe_lsm_ops lsm_ops;
	struct wcd_cpe_afe_ops afe_ops;
	bool afe_mad_ctl;
	u32 input_port_id;
};

struct cpe_lsm_data {
@@ -1167,12 +1172,6 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
					__func__, rc);
				return rc;
			}
			rc = lsm_ops->lsm_lab_control(cpe->core_handle,
					session, false);
			if (IS_ERR_VALUE(rc))
				dev_err(rtd->dev,
					"%s: Lab Disable Failed rc %d\n",
				       __func__, rc);
			/*
			 * Buffer has to be de-allocated even if
			 * lab_control failed.
@@ -1401,14 +1400,6 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
		dev_dbg(rtd->dev,
			"%s: %s\n",
			__func__, "SNDRV_LSM_START");
		rc = lsm_ops->lsm_get_afe_out_port_id(cpe->core_handle,
						      session);
		if (rc != 0) {
			dev_err(rtd->dev,
				"%s: failed to get port id, err = %d\n",
				__func__, rc);
			return rc;
		}
		rc = lsm_ops->lsm_start(cpe->core_handle, session);
		if (rc != 0) {
			dev_err(rtd->dev,
@@ -2691,6 +2682,8 @@ static int msm_cpe_lsm_prepare(struct snd_pcm_substream *substream)
	struct cpe_lsm_session *lsm_session;
	struct cpe_lsm_lab *lab_d = &lsm_d->lab;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct lsm_hw_params lsm_param;
	struct wcd_cpe_lsm_ops *lsm_ops;

	if (!cpe || !cpe->core_handle) {
		dev_err(rtd->dev,
@@ -2723,23 +2716,74 @@ static int msm_cpe_lsm_prepare(struct snd_pcm_substream *substream)
		return 0;
	}

	lsm_ops = &cpe->lsm_ops;
	afe_ops = &cpe->afe_ops;
	afe_cfg = &(lsm_d->lsm_session->afe_port_cfg);

	afe_cfg->port_id = 1;
	switch (cpe->input_port_id) {
	case AFE_PORT_ID_3:
		afe_cfg->port_id = AFE_PORT_ID_3;
		afe_cfg->bit_width = 16;
		afe_cfg->num_channels = 1;
	afe_cfg->sample_rate = 16000;

		afe_cfg->sample_rate = SAMPLE_RATE_48KHZ;
		rc = afe_ops->afe_port_cmd_cfg(cpe->core_handle, afe_cfg);
		break;
	case AFE_PORT_ID_1:
	default:
		afe_cfg->port_id = AFE_PORT_ID_1;
		afe_cfg->bit_width = 16;
		afe_cfg->num_channels = 1;
		afe_cfg->sample_rate = SAMPLE_RATE_16KHZ;
		rc = afe_ops->afe_set_params(cpe->core_handle,
					     afe_cfg, cpe->afe_mad_ctl);
		break;
	}

	if (rc != 0) {
		dev_err(rtd->dev,
			"%s: cpe afe params failed, err = %d\n",
			"%s: cpe afe params failed for port = %d, err = %d\n",
			 __func__, afe_cfg->port_id, rc);
		return rc;
	}
	lsm_param.sample_rate = afe_cfg->sample_rate;
	lsm_param.num_chs = afe_cfg->num_channels;
	lsm_param.bit_width = afe_cfg->bit_width;
	rc = lsm_ops->lsm_set_media_fmt_params(cpe->core_handle, lsm_session,
					       &lsm_param);
	if (rc)
		dev_dbg(rtd->dev,
			"%s: failed to set lsm media fmt params, err = %d\n",
			__func__, rc);

	/* Send connect to port (input) */
	rc = lsm_ops->lsm_set_port(cpe->core_handle, lsm_session,
				   &cpe->input_port_id);
	if (rc) {
		dev_err(rtd->dev,
			"%s: Failed to set connect input port, err=%d\n",
			__func__, rc);
		return rc;
	}

	if (cpe->input_port_id != 3) {
		rc = lsm_ops->lsm_get_afe_out_port_id(cpe->core_handle,
						      lsm_session);
		if (rc != 0) {
			dev_err(rtd->dev,
				"%s: failed to get port id, err = %d\n",
				__func__, rc);
			return rc;
		}
		/* Send connect to port (output) */
		rc = lsm_ops->lsm_set_port(cpe->core_handle, lsm_session,
					   &lsm_session->afe_out_port_id);
		if (rc) {
			dev_err(rtd->dev,
				"%s: Failed to set connect output port, err=%d\n",
				__func__, rc);
			return rc;
		}
	}
	rc = msm_cpe_afe_port_cntl(substream,
				   cpe->core_handle,
				   afe_ops, afe_cfg,
@@ -2989,6 +3033,9 @@ static int msm_asoc_cpe_lsm_probe(struct snd_soc_platform *platform)
	struct cpe_priv *cpe_priv;
	const struct snd_kcontrol_new *kcontrol;
	bool found_runtime = false;
	const char *cpe_dev_id = "qcom,msm-cpe-lsm-id";
	u32 port_id = 0;
	int ret = 0;
	int i;

	if (!platform || !platform->component.card) {
@@ -3018,6 +3065,14 @@ static int msm_asoc_cpe_lsm_probe(struct snd_soc_platform *platform)
		return -EINVAL;
	}

	ret = of_property_read_u32(platform->dev->of_node, cpe_dev_id,
				  &port_id);
	if (ret) {
		dev_dbg(platform->dev,
			"%s: missing 0x%x in dt node\n", __func__, port_id);
		port_id = 1;
	}

	codec = rtd->codec;

	cpe_priv = kzalloc(sizeof(struct cpe_priv),
@@ -3030,6 +3085,7 @@ static int msm_asoc_cpe_lsm_probe(struct snd_soc_platform *platform)
	}

	cpe_priv->codec = codec;
	cpe_priv->input_port_id = port_id;
	wcd_cpe_get_lsm_ops(&cpe_priv->lsm_ops);
	wcd_cpe_get_afe_ops(&cpe_priv->afe_ops);

+14 −0
Original line number Diff line number Diff line
@@ -3001,6 +3001,20 @@ static struct snd_soc_dai_link msm8996_tasha_fe_dai_links[] = {
		.codec_dai_name = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
	},
	/* CPE LSM EC PP direct dai-link */
	{
		.name = "CPE Listen service ECPP",
		.stream_name = "CPE Listen Audio Service ECPP",
		.cpu_dai_name = "CPE_LSM_NOHOST",
		.platform_name = "msm-cpe-lsm.3",
		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
			    SND_SOC_DPCM_TRIGGER_POST},
		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
		.ignore_suspend = 1,
		.ignore_pmdown_time = 1,
		.codec_dai_name = "tasha_cpe",
		.codec_name = "tasha_codec",
	},
};

static struct snd_soc_dai_link msm8996_common_be_dai_links[] = {