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

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

Merge "soc: pcm: add qtime mixer control"

parents b2b8bf9d 0a4cef07
Loading
Loading
Loading
Loading
+114 −14
Original line number Diff line number Diff line
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, 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
@@ -632,8 +632,17 @@ static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (prtd->qtime_lsw) {
			pr_debug("%s: Trigger start at msw: %u, lsw: %u msec",
				__func__, prtd->qtime_msw, prtd->qtime_lsw);
			ret = q6asm_run_nowait(prtd->audio_client, 1,
					prtd->qtime_msw, prtd->qtime_lsw);
			prtd->qtime_lsw = 0;
			prtd->qtime_msw = 0;
		} else {
			pr_debug("%s: Trigger start\n", __func__);
			ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
		}
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
@@ -1164,7 +1173,8 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
		goto done;
	}

	substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
	substream = pdata->pcm[kcontrol->private_value]->
			streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
	if (!substream) {
		pr_err("%s substream not found\n", __func__);
		ret = -EINVAL;
@@ -1434,7 +1444,8 @@ static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol,
		pr_err("%s pdata is NULL\n", __func__);
		return -ENODEV;
	}
	substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
	substream = pdata->pcm[kcontrol->private_value]->
			streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
	if (!substream) {
		pr_err("%s substream not found\n", __func__);
		return -EINVAL;
@@ -1464,7 +1475,8 @@ static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol,
		pr_err("%s pdata is NULL\n", __func__);
		return -ENODEV;
	}
	substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
	substream = pdata->pcm[kcontrol->private_value]->
			streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
	pr_debug("%s: compress : 0x%x\n", __func__, compress);
	if (!substream) {
		pr_err("%s substream not found\n", __func__);
@@ -1524,15 +1536,13 @@ static int msm_pcm_add_compress_control(struct snd_soc_pcm_runtime *rtd)
	pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
	pdata = dev_get_drvdata(rtd->platform->dev);
	if (pdata) {
		if (!pdata->pcm) {
			pdata->pcm = rtd->pcm;
		pdata->pcm[rtd->dai_link->id] = rtd->pcm;
		snd_soc_add_platform_controls(rtd->platform,
					      pcm_compress_control,
					      ARRAY_SIZE
					      (pcm_compress_control));
		pr_debug("%s: add control success plt = %pK\n",
				 __func__, rtd->platform);
		}
	} else {
		pr_err("%s: NULL pdata\n", __func__);
		ret = -EINVAL;
@@ -1786,6 +1796,90 @@ static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd)
	return 0;
}

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

static int msm_pcm_qtimer_ctl_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
	struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
	struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
	struct snd_pcm_substream *substream;
	struct msm_audio *prtd;

	if (!pdata) {
		pr_err("%s pdata is NULL\n", __func__);
		return -ENODEV;
	}

	substream = pdata->pcm[kcontrol->private_value]->
			streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
	if (!substream) {
		pr_err("%s substream not found\n", __func__);
		return -EINVAL;
	}

	if (!substream->runtime) {
		pr_err("%s substream runtime not found\n", __func__);
		return 0;
	}

	prtd = substream->runtime->private_data;
	if (prtd) {
		prtd->qtime_lsw = ucontrol->value.integer.value[0];
		prtd->qtime_msw = ucontrol->value.integer.value[1];
	}

	return 0;
}

static int msm_pcm_add_qtimer_control(struct snd_soc_pcm_runtime *rtd)
{
	const char *mixer_ctl_name = "QTimer";
	const char *deviceNo = "NN";
	char *mixer_str = NULL;
	int ctl_len = 0, ret = 0;
	struct snd_kcontrol_new qtimer_control[1] = {
		{
		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
		.name = "?",
		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
		.info = msm_pcm_qtimer_ctl_info,
		.put = msm_pcm_qtimer_ctl_put,
		.private_value = 0,
		}
	};

	ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
	mixer_str = kzalloc(ctl_len, GFP_KERNEL);
	if (!mixer_str) {
		ret = -ENOMEM;
		goto done;
	}

	snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
	qtimer_control[0].name = mixer_str;
	qtimer_control[0].private_value = rtd->dai_link->id;
	ret = snd_soc_add_platform_controls(rtd->platform,
		qtimer_control,
		ARRAY_SIZE(qtimer_control));
	if (ret < 0)
		pr_err("%s: failed add ctl %s. err = %d\n",
			__func__, mixer_str, ret);

	kfree(mixer_str);
done:
	return ret;
}

static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
{
	int ret = 0;
@@ -1798,6 +1892,12 @@ static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
	if (ret)
		pr_err("%s: pcm add app type controls failed:%d\n",
			__func__, ret);

	ret = msm_pcm_add_qtimer_control(rtd);
	if (ret)
		pr_err("%s: pcm add qtimer controls failed:%d\n",
			__func__, ret);

	return ret;
}

+4 −2
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 Google, Inc.
 * Copyright (C) 2008 HTC Corporation
 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2017,2019 The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
@@ -110,6 +110,8 @@ struct msm_audio {
	bool meta_data_mode;
	uint32_t volume;
	bool compress_enable;
	uint32_t qtime_lsw;
	uint32_t qtime_msw;
	/* array of frame info */
	struct msm_audio_in_frame_info in_frame_info[CAPTURE_MAX_NUM_PERIODS];
};
@@ -124,7 +126,7 @@ struct output_meta_data_st {

struct msm_plat_data {
	int perf_mode;
	struct snd_pcm *pcm;
	struct snd_pcm *pcm[MSM_FRONTEND_DAI_MAX];
	struct msm_pcm_ch_map *ch_map[MSM_FRONTEND_DAI_MAX];
};