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

Commit 045066ae authored by Subhash Chandra Bose Naripeddy's avatar Subhash Chandra Bose Naripeddy Committed by Jayasena Sangaraboina
Browse files

ASoC: msm: qdsp6v2: Add support to update the app type config



For the usecases where individual streams have to be routed to
different outputs on DSP, app type and acdb device of the stream
are utilized. App type configuration is cached post boot and
based on the playback's stream app type, configuration is
extracted to setup the new ADM session in DSP.

Change-Id: Ic9de561273b6114e03a2d14138c3fdb2abf6990f
Signed-off-by: default avatarJayasena Sangaraboina <jsanga@codeaurora.org>
parent cda3673c
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
@@ -1866,6 +1866,35 @@ static int msm_compr_dec_params_get(struct snd_kcontrol *kcontrol,
	return 0;
}

static int msm_compr_app_type_cfg_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	u64 fe_id = kcontrol->private_value;
	int app_type;
	int acdb_dev_id;

	pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
	if (fe_id >= MSM_FRONTEND_DAI_MAX) {
		pr_err("%s Received out of bounds fe_id %llu\n",
			__func__, fe_id);
		return -EINVAL;
	}

	app_type = ucontrol->value.integer.value[0];
	acdb_dev_id = ucontrol->value.integer.value[1];
	pr_debug("%s: app_type- %d\n", __func__, app_type);
	pr_debug("%s: acdb_dev_id- %d\n", __func__, acdb_dev_id);
	msm_pcm_routing_reg_stream_app_type_cfg(fe_id, app_type, acdb_dev_id);

	return 0;
}

static int msm_compr_app_type_cfg_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	return 0;
}

static int msm_compr_probe(struct snd_soc_platform *platform)
{
	struct msm_compr_pdata *pdata;
@@ -1929,6 +1958,16 @@ static int msm_compr_dec_params_info(struct snd_kcontrol *kcontrol,
	return 0;
}

static int msm_compr_app_type_cfg_info(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 4;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 0xFFFFFFFF;
	return 0;
}

static int msm_compr_add_volume_control(struct snd_soc_pcm_runtime *rtd)
{
	const char *mixer_ctl_name = "Compress Playback";
@@ -2106,6 +2145,55 @@ static int msm_compr_add_dec_runtime_params_control(
	return 0;
}

static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd)
{
	const char *mixer_ctl_name	= "Audio Stream";
	const char *deviceNo		= "NN";
	const char *suffix		= "App Type Cfg";
	char *mixer_str = NULL;
	int ctl_len;
	struct snd_kcontrol_new fe_app_type_cfg_control[1] = {
		{
		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
		.name = "?",
		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
		.info = msm_compr_app_type_cfg_info,
		.put = msm_compr_app_type_cfg_put,
		.get = msm_compr_app_type_cfg_get,
		.private_value = 0,
		}
	};

	if (!rtd) {
		pr_err("%s NULL rtd\n", __func__);
		return 0;
	}

	pr_debug("%s: added new compr FE ctl with name %s, id %d, cpu dai %s, device no %d\n",
		 __func__, rtd->dai_link->name, rtd->dai_link->be_id,
		 rtd->dai_link->cpu_dai_name, rtd->pcm->device);

	ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
		  strlen(suffix) + 1;
	mixer_str = kzalloc(ctl_len, GFP_KERNEL);

	if (!mixer_str) {
		pr_err("failed to allocate mixer ctrl str of len %d", ctl_len);
		return 0;
	}

	snprintf(mixer_str, ctl_len, "%s %d %s", mixer_ctl_name,
		 rtd->pcm->device, suffix);
	fe_app_type_cfg_control[0].name = mixer_str;
	fe_app_type_cfg_control[0].private_value = rtd->dai_link->be_id;
	pr_debug("Registering new mixer ctl %s", mixer_str);
	snd_soc_add_platform_controls(rtd->platform,
				      fe_app_type_cfg_control,
				      ARRAY_SIZE(fe_app_type_cfg_control));
	kfree(mixer_str);
	return 0;
}

static int msm_compr_new(struct snd_soc_pcm_runtime *rtd)
{
	int rc;
@@ -2118,6 +2206,10 @@ static int msm_compr_new(struct snd_soc_pcm_runtime *rtd)
		pr_err("%s: Could not add Compr Audio Effects Control\n",
			__func__);
	rc = msm_compr_add_dec_runtime_params_control(rtd);
	if (rc)
		pr_err("%s: Could not add Compr Dec runtime params Control\n",
			__func__);
	rc = msm_compr_add_app_type_cfg_control(rtd);
	if (rc)
		pr_err("%s: Could not add Compr Dec runtime params Control\n",
			__func__);
+93 −7
Original line number Diff line number Diff line
@@ -896,34 +896,120 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol,
	return 0;
}

static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
static int msm_pcm_add_chmap_controls(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_card *card = rtd->card->snd_card;
	struct snd_pcm *pcm = rtd->pcm;
	struct snd_pcm_chmap *chmap_info;
	struct snd_kcontrol *kctl;
	char device_num[12];
	int i, ret = 0;

	if (!card->dev->coherent_dma_mask)
		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);

	pr_debug("%s, Channel map cntrl add\n", __func__);
	ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
				     snd_pcm_std_chmaps,
				     PCM_FORMAT_MAX_NUM_CHANNEL, 0,
				     &chmap_info);
	if (ret < 0)
	if (ret < 0) {
		pr_err("%s, channel map cntrl add failed\n", __func__);
		return ret;
	}
	kctl = chmap_info->kctl;
	for (i = 0; i < kctl->count; i++)
		kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
	snprintf(device_num, sizeof(device_num), "%d", pcm->device);
	strlcat(kctl->id.name, device_num, sizeof(kctl->id.name));
	pr_debug("%s, Overwriting channel map control name to: %s",
	pr_debug("%s, Overwriting channel map control name to: %s\n",
		__func__, kctl->id.name);
	kctl->put = msm_pcm_chmap_ctl_put;
	kctl->get = msm_pcm_chmap_ctl_get;
	return 0;
}

static int msm_pcm_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	u64 fe_id = kcontrol->private_value;
	int app_type;
	int acdb_dev_id;

	pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
	if (fe_id >= MSM_FRONTEND_DAI_MAX) {
		pr_err("%s Received out of bounds fe_id %llu\n",
			__func__, fe_id);
		return -EINVAL;
	}

	app_type = ucontrol->value.integer.value[0];
	acdb_dev_id = ucontrol->value.integer.value[1];
	pr_debug("%s: app_type- %d\n", __func__, app_type);
	pr_debug("%s: acdb_dev_id- %d\n", __func__, acdb_dev_id);
	msm_pcm_routing_reg_stream_app_type_cfg(fe_id, app_type, acdb_dev_id);

	return 0;
}

static int msm_pcm_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	return 0;
}

static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_pcm *pcm = rtd->pcm;
	struct snd_pcm_usr *app_type_info;
	struct snd_kcontrol *kctl;
	const char *mixer_ctl_name	= "Audio Stream";
	const char *deviceNo		= "NN";
	const char *suffix		= "App Type Cfg";
	int ctl_len, ret = 0;

	ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
		  strlen(suffix) + 1;
	pr_debug("%s, App type cntrl add\n", __func__);
	ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
				   NULL, 1, ctl_len, rtd->dai_link->be_id,
				   &app_type_info);
	if (ret < 0) {
		pr_err("%s, app type cntrl add failed:%d\n", __func__, ret);
		return ret;
	}
	kctl = app_type_info->kctl;
	snprintf(kctl->id.name, ctl_len, "%s %d %s", mixer_ctl_name,
		 rtd->pcm->device, suffix);
	kctl = app_type_info->kctl;
	kctl->put = msm_pcm_app_type_cfg_ctl_put;
	kctl->get = msm_pcm_app_type_cfg_ctl_get;

	return 0;
}

static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
{
	int ret = 0;
	pr_debug("%s\n", __func__);
	ret = msm_pcm_add_chmap_controls(rtd);
	if (ret)
		pr_err("%s: pcm add controls failed:%d\n", __func__, ret);
	ret = msm_pcm_add_app_type_controls(rtd);
	if (ret)
		pr_err("%s: pcm add app type controls failed:%d\n",
			__func__, ret);
	return ret;
}

static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_card *card = rtd->card->snd_card;
	int ret = 0;

	if (!card->dev->coherent_dma_mask)
		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);

	ret = msm_pcm_add_controls(rtd);
	if (ret)
		pr_err("%s, kctl add failed:%d\n", __func__, ret);

	return ret;
}

+60 −1
Original line number Diff line number Diff line
@@ -237,6 +237,11 @@ static struct msm_pcm_routing_fdai_data
 */
static int fe_dai_perf_mode[MSM_FRONTEND_DAI_MM_SIZE][2];

static struct msm_pcm_stream_app_type_cfg
			 fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MM_SIZE];

static struct msm_pcm_routing_app_type_data app_type_cfg[MAX_APP_TYPES];

/* The caller of this should aqcuire routing lock */
void msm_pcm_routing_get_bedai_info(int be_idx,
				    struct msm_pcm_routing_bdai_data *be_dai)
@@ -268,6 +273,18 @@ void msm_pcm_routing_release_lock(void)
	mutex_unlock(&routing_lock);
}

void msm_pcm_routing_reg_stream_app_type_cfg(int fedai_id, int app_type,
	int acdb_dev_id)
{
	if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
		/* bad ID assigned in machine driver */
		pr_err("%s: bad MM ID %d\n", __func__, fedai_id);
		return;
	}
	fe_dai_app_type_cfg[fedai_id].app_type = app_type;
	fe_dai_app_type_cfg[fedai_id].acdb_dev_id = acdb_dev_id;
}

static uint8_t is_be_dai_extproc(int be_dai)
{
	if (be_dai == MSM_BACKEND_DAI_EXTPROC_RX ||
@@ -2806,6 +2823,45 @@ static const struct snd_kcontrol_new stereo_to_custom_stereo_controls[] = {
	msm_routing_put_stereo_to_custom_stereo_control),
};

static int msm_routing_get_app_type_cfg_control(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_value *ucontrol)
{
	return 0;
}

static int msm_routing_put_app_type_cfg_control(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_value *ucontrol)
{
	int i = 0, j;
	int num_app_types = ucontrol->value.integer.value[i++];

	pr_debug("%s\n", __func__);

	memset(app_type_cfg, 0, MAX_APP_TYPES*
				sizeof(struct msm_pcm_routing_app_type_data));
	if (num_app_types > MAX_APP_TYPES) {
		pr_err("%s: number of app types exceed the max supported\n",
			__func__);
		return -EINVAL;
	}
	for (j = 0; j < num_app_types; j++) {
		app_type_cfg[j].app_type =
				ucontrol->value.integer.value[i++];
		app_type_cfg[j].sample_rate =
				ucontrol->value.integer.value[i++];
		app_type_cfg[j].bit_width =
				ucontrol->value.integer.value[i++];
	}

	return 0;
}

static const struct snd_kcontrol_new app_type_cfg_controls[] = {
	SOC_SINGLE_MULTI_EXT("App Type Config", SND_SOC_NOPM, 0,
	0xFFFFFFFF, 0, 128, msm_routing_get_app_type_cfg_control,
	msm_routing_put_app_type_cfg_control),
};

int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol) {
	int rc = 0;
@@ -2829,7 +2885,7 @@ int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol,
				param_length + param_payload_len,
				param_value);
		if (rc) {
			pr_err("%s: get parameters failed\n", __func__);
			pr_err("%s: get parameters failed:%d\n", __func__, rc);
			kfree(param_value);
			return -EINVAL;
		}
@@ -4224,6 +4280,9 @@ static int msm_routing_probe(struct snd_soc_platform *platform)
	snd_soc_add_platform_controls(platform, msm_voc_session_controls,
				      ARRAY_SIZE(msm_voc_session_controls));

	snd_soc_add_platform_controls(platform, app_type_cfg_controls,
				      ARRAY_SIZE(app_type_cfg_controls));

	snd_soc_add_platform_controls(platform,
				stereo_to_custom_stereo_controls,
			ARRAY_SIZE(stereo_to_custom_stereo_controls));
+15 −0
Original line number Diff line number Diff line
@@ -189,6 +189,18 @@ struct msm_pcm_routing_fdai_data {
	struct msm_pcm_routing_evt event_info;
};

#define MAX_APP_TYPES	16
struct msm_pcm_routing_app_type_data {
	int app_type;
	u32 sample_rate;
	int bit_width;
};

struct msm_pcm_stream_app_type_cfg {
	int app_type;
	int acdb_dev_id;
};

/* dai_id: front-end ID,
 * dspst_id:  DSP audio stream ID
 * stream_type: playback or capture
@@ -219,4 +231,7 @@ void msm_pcm_routing_get_fedai_info(int fe_idx, int sess_type,
				    int *fe_perf_mode);
void msm_pcm_routing_acquire_lock(void);
void msm_pcm_routing_release_lock(void);

void msm_pcm_routing_reg_stream_app_type_cfg(int fedai_id, int app_type,
						int acdb_dev_id);
#endif /*_MSM_PCM_H*/