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

Commit 4169df50 authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge 965a68a2 on remote branch

Change-Id: Ie935308d55bb83183860a9c9b29ed67659e52c80
parents d7e8205d 965a68a2
Loading
Loading
Loading
Loading

asoc/msm-pcm-routing-v2.c

100644 → 100755
+99 −12
Original line number Diff line number Diff line
@@ -1866,6 +1866,11 @@ static int msm_pcm_routing_channel_mixer_v2(int fe_id, bool perf_mode,
	}
	be_id = channel_mixer_v2[fe_id][sess_type].port_idx - 1;
        if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) {
		pr_err("%s: Received out of bounds be_id %d\n",
				__func__, be_id);
		return -EINVAL;
	}
	channel_mixer_v2[fe_id][sess_type].input_channels[0] =
		channel_mixer_v2[fe_id][sess_type].input_channel;
@@ -1930,6 +1935,11 @@ static int msm_pcm_routing_channel_mixer(int fe_id, bool perf_mode,
	for (i = 0; i < ADM_MAX_CHANNELS && channel_input[fe_id][i] > 0;
		++i) {
		be_id = channel_input[fe_id][i] - 1;
		if (be_id < 0 || be_id >= MSM_BACKEND_DAI_MAX) {
			pr_err("%s: Received out of bounds be_id %d\n",
					__func__, be_id);
			return -EINVAL;
		}
		channel_mixer[fe_id].input_channels[i] =
						msm_bedais[be_id].channel;
@@ -3680,10 +3690,10 @@ static int msm_pcm_get_out_chs(struct snd_kcontrol *kcontrol,
static int msm_pcm_put_out_chs(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	u16 fe_id = 0;
	u16 fe_id = 0, out_ch = 0;
	fe_id = ((struct soc_multi_mixer_control *)
			kcontrol->private_value)->shift;
	out_ch = ucontrol->value.integer.value[0];
	if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
		pr_err("%s: invalid FE %d\n", __func__, fe_id);
		return -EINVAL;
@@ -3692,6 +3702,12 @@ static int msm_pcm_put_out_chs(struct snd_kcontrol *kcontrol,
	pr_debug("%s: fe_id is %d, output channels = %d\n", __func__,
			fe_id,
			(unsigned int)(ucontrol->value.integer.value[0]));
	if (out_ch < 0 ||
		out_ch > ADM_MAX_CHANNELS) {
		pr_err("%s: invalid output channel %d\n", __func__,
				out_ch);
		return -EINVAL;
	}
	channel_mixer[fe_id].output_channel =
			(unsigned int)(ucontrol->value.integer.value[0]);
@@ -5554,21 +5570,24 @@ static int msm_ec_ref_rate_put(struct snd_kcontrol *kcontrol,
		msm_ec_ref_sampling_rate = 16000;
		break;
	case 3:
		msm_ec_ref_sampling_rate = 32000;
		msm_ec_ref_sampling_rate = 24000;
		break;
	case 4:
		msm_ec_ref_sampling_rate = 44100;
		msm_ec_ref_sampling_rate = 32000;
		break;
	case 5:
		msm_ec_ref_sampling_rate = 48000;
		msm_ec_ref_sampling_rate = 44100;
		break;
	case 6:
		msm_ec_ref_sampling_rate = 96000;
		msm_ec_ref_sampling_rate = 48000;
		break;
	case 7:
		msm_ec_ref_sampling_rate = 192000;
		msm_ec_ref_sampling_rate = 96000;
		break;
	case 8:
		msm_ec_ref_sampling_rate = 192000;
		break;
	case 9:
		msm_ec_ref_sampling_rate = 384000;
		break;
	default:
@@ -5791,7 +5810,7 @@ static int msm_routing_afe_lb_tx_port_put(struct snd_kcontrol *kcontrol,
}
static const char *const ec_ref_rate_text[] = {"0", "8000", "16000",
	"32000", "44100", "48000", "96000", "192000", "384000"};
	"24000", "32000", "44100", "48000", "96000", "192000", "384000"};
static const struct soc_enum msm_route_ec_ref_params_enum[] = {
	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ec_ref_ch_text), ec_ref_ch_text),
@@ -31793,9 +31812,9 @@ static int asrc_get_module_location(struct asrc_module_config_params *params,
					int *copp_index, int *port_id)
{
	int ret = 0;
	int fe_id = params->fe_id;
	int dir = params->dir;
	int be_id = params->be_id;
	int fe_id = 0;
	int dir = 0;
	int be_id = 0;
	int copp_idx = 0;
	unsigned long copp = -1;
	bool copp_is_found = false;
@@ -31811,6 +31830,9 @@ static int asrc_get_module_location(struct asrc_module_config_params *params,
		goto done;
	}
	fe_id = params->fe_id;
	dir = params->dir;
	be_id = params->be_id;
	bedai = &msm_bedais[be_id];
	if (afe_get_port_type(bedai->port_id) != port_type) {
		pr_err("%s: port_type not match: be_dai %d type %d\n",
@@ -31977,7 +31999,7 @@ static void get_drift_and_put_asrc(struct work_struct *work)
	struct asrc_config *p_asrc_cfg = NULL;
	struct afe_param_id_dev_timing_stats timing_stats = {0};
	struct asrc_module_config_node *config_node = NULL;
	struct list_head *ptr, *next;
	struct list_head *ptr = NULL, *next = NULL;
	delayed_drift_work = to_delayed_work(work);
	if (NULL == delayed_drift_work) {
@@ -32154,6 +32176,11 @@ static int msm_dai_q6_asrc_config_put(
		break;
	case ENABLE_ASRC_DRIFT_HW:
		idx = get_drift_src_idx(param & ~0x0100); /* group device */
		if (idx < 0 || idx >= DRIFT_SRC_MAX) {
			pr_err("%s Invalid index: %d\n", __func__, idx);
			ret = -EINVAL;
			goto done;
		}
		mutex_lock(&asrc_cfg[idx].lock);
		asrc_cfg[idx].drift_src = param & ~0x0100;
		mutex_unlock(&asrc_cfg[idx].lock);
@@ -32224,6 +32251,62 @@ static const struct snd_kcontrol_new asrc_config_controls[] = {
				 msm_dai_q6_asrc_config_put),
};
enum {
	IDX_MCLK1 = 1,
	IDX_MCLK2,
};
/* default internal mclk config. Only MCLK2 is needed now */
static struct afe_clk_set internal_mclk = {
	AFE_API_VERSION_CLOCK_SET_V2,
	Q6AFE_LPASS_CLK_ID_MCLK_2,
	Q6AFE_LPASS_IBIT_CLK_12_P288_MHZ,
	Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
	Q6AFE_LPASS_CLK_ROOT_DEFAULT,
	1,
};
static int msm_internal_mclk_ctl_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	/* default mclk id is 2 */
	ucontrol->value.integer.value[0] = 2;
	ucontrol->value.integer.value[1] = internal_mclk.clk_freq_in_hz;
	ucontrol->value.integer.value[2] = internal_mclk.enable;
	return 0;
}
static int msm_internal_mclk_ctl_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	int ret = -EINVAL;
	int32_t mclk_id = 0;
	mclk_id = ucontrol->value.integer.value[0];
	if (mclk_id != IDX_MCLK2) {
		pr_err("%s: invalid mclk id: %d, only mclk2 is supported now\n",
			__func__, mclk_id);
		return -EINVAL;
	}
	internal_mclk.clk_freq_in_hz = ucontrol->value.integer.value[1];
	internal_mclk.enable = ucontrol->value.integer.value[2];
	ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TDM_PORT_RANGE_START,
				     &internal_mclk);
	if (ret)
		pr_err("%s: mclk enable failed %d\n", __func__, ret);
	return ret;
}
static const struct snd_kcontrol_new internal_mclk_control[] = {
	SOC_SINGLE_MULTI_EXT("internal mclk enable", SND_SOC_NOPM, 0,
				 0x7FFFFFFF, 0, 3,
				 msm_internal_mclk_ctl_get,
				 msm_internal_mclk_ctl_put),
};
static const struct snd_pcm_ops msm_routing_pcm_ops = {
	.hw_params	= msm_pcm_routing_hw_params,
	.close          = msm_pcm_routing_close,
@@ -32418,6 +32501,10 @@ static int msm_routing_probe(struct snd_soc_component *component)
				      ARRAY_SIZE(mclk_src_controls));
	snd_soc_add_component_controls(component, asrc_config_controls,
				      ARRAY_SIZE(asrc_config_controls));
#ifdef CONFIG_MSM_INTERNAL_MCLK
	snd_soc_add_component_controls(component, internal_mclk_control,
				      ARRAY_SIZE(internal_mclk_control));
#endif
	return 0;
}
+112 −20
Original line number Diff line number Diff line
@@ -140,6 +140,8 @@ static const char *const tdm_gpio_phandle[] = {"qcom,pri-tdm-gpios",
						"qcom,quat-tdm-gpios",
						"qcom,quin-tdm-gpios"};

static const char *const mclk_gpio_phandle[] = { "qcom,internal-mclk2-gpios" };

enum {
	TDM_0 = 0,
	TDM_1,
@@ -161,6 +163,16 @@ enum {
	TDM_INTERFACE_MAX,
};

enum {
	MCLK2 = 0,
	MCLK_MAX,
};

enum pinctrl_mode {
	TDM_PINCTRL,
	MCLK_PINCTRL,
};

struct tdm_port {
	u32 mode;
	u32 channel;
@@ -701,6 +713,17 @@ static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text);

static struct afe_clk_set internal_mclk[MCLK_MAX] = {
	{
		AFE_API_VERSION_CLOCK_SET_V2,
		Q6AFE_LPASS_CLK_ID_MCLK_2,
		Q6AFE_LPASS_IBIT_CLK_12_P288_MHZ,
		Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
		Q6AFE_LPASS_CLK_ROOT_DEFAULT,
		1,
	}
};

static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
	{
		AFE_API_VERSION_I2S_CONFIG,
@@ -747,6 +770,7 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = {

struct msm_asoc_mach_data {
	struct msm_pinctrl_info pinctrl_info[TDM_INTERFACE_MAX];
	struct msm_pinctrl_info mclk_pinctrl_info[MCLK_MAX];
	struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
	struct tdm_conf tdm_intf_conf[TDM_INTERFACE_MAX];
};
@@ -3857,18 +3881,29 @@ static void msm_release_pinctrl(struct platform_device *pdev)
	}
}

static int msm_get_pinctrl(struct platform_device *pdev)
static int msm_pinctrl_init(struct platform_device *pdev, enum pinctrl_mode mode)
{
	struct snd_soc_card *card = platform_get_drvdata(pdev);
	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
	struct msm_pinctrl_info *pinctrl_info = NULL;
	struct pinctrl *pinctrl = NULL;
	int pinctrl_num;
	int i, j;
	struct device_node *np = NULL;
	struct platform_device *pdev_np = NULL;
	int ret = 0;

	for (i = TDM_PRI; i < TDM_INTERFACE_MAX; i++) {
	if (mode == TDM_PINCTRL) {
		pinctrl_num = TDM_INTERFACE_MAX;
	} else if (mode == MCLK_PINCTRL) {
		pinctrl_num = MCLK_MAX;
	} else {
		pr_err("%s: invalid mode %d\n", __func__, mode);
		return -EINVAL;
	}

	for (i = 0; i < pinctrl_num; i++) {
		if (mode == TDM_PINCTRL) {
			np = of_parse_phandle(pdev->dev.of_node,
				tdm_gpio_phandle[i], 0);
			if (!np) {
@@ -3876,6 +3911,16 @@ static int msm_get_pinctrl(struct platform_device *pdev)
					__func__, tdm_gpio_phandle[i]);
				continue;
			}
		}
		else {
			np = of_parse_phandle(pdev->dev.of_node,
				mclk_gpio_phandle[i], 0);
			if (!np) {
				pr_debug("%s: device node %s is null\n",
					__func__, mclk_gpio_phandle[i]);
				continue;
			}
		}

		pdev_np = of_find_device_by_node(np);
		if (!pdev_np) {
@@ -3883,7 +3928,10 @@ static int msm_get_pinctrl(struct platform_device *pdev)
			continue;
		}

		if (mode == TDM_PINCTRL)
			pinctrl_info = &pdata->pinctrl_info[i];
		else
			pinctrl_info = &pdata->mclk_pinctrl_info[i];
		if (pinctrl_info == NULL) {
			pr_err("%s: pinctrl info is null\n", __func__);
			continue;
@@ -3911,9 +3959,9 @@ static int msm_get_pinctrl(struct platform_device *pdev)
			goto err;
		}

		if (mode == TDM_PINCTRL) {
			/* Reset the TLMM pins to a sleep state */
		ret = pinctrl_select_state(pinctrl_info->pinctrl,
						pinctrl_info->sleep);
			ret = pinctrl_select_state(pinctrl_info->pinctrl, pinctrl_info->sleep);
			if (ret != 0) {
				pr_err("%s: set pin state to sleep failed with %d\n",
					__func__, ret);
@@ -3922,11 +3970,35 @@ static int msm_get_pinctrl(struct platform_device *pdev)
			}
			pinctrl_info->curr_state = STATE_SLEEP;
		}
		else {
			/* Reset the mclk pins to a active state */
			ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TDM_PORT_RANGE_START,
				&internal_mclk[i]);
			if (ret < 0) {
				pr_err("%s: afe lpass clock failed to enable clock, err:%d\n",
					__func__, ret);
				ret = -EIO;
				goto err;
			}

			ret = pinctrl_select_state(pinctrl_info->pinctrl, pinctrl_info->active);
			if (ret != 0) {
				pr_err("%s: set pin state to active failed with %d\n",
					__func__, ret);
				ret = -EIO;
				goto err;
			}
			pinctrl_info->curr_state = STATE_ACTIVE;
		}
	}
	return 0;

err:
	for (j = i; j >= 0; j--) {
		pinctrl_info = &pdata->pinctrl_info[j];
		if (mode == TDM_PINCTRL)
			pinctrl_info = &pdata->pinctrl_info[i];
		else
			pinctrl_info = &pdata->mclk_pinctrl_info[i];
		if (pinctrl_info == NULL)
			continue;
		if (pinctrl_info->pinctrl) {
@@ -3937,6 +4009,26 @@ static int msm_get_pinctrl(struct platform_device *pdev)
	return -EINVAL;
}

static int msm_get_pinctrl(struct platform_device *pdev)
{
	int ret = 0;

	ret = msm_pinctrl_init(pdev, TDM_PINCTRL);
	if (ret != 0) {
		pr_err("%s: set tdm pin state to sleep failed with %d\n",
			__func__, ret);
		return -EIO;
	}

	ret = msm_pinctrl_init(pdev, MCLK_PINCTRL);
	if (ret != 0) {
		pr_err("%s: set mclk pin state to active failed with %d\n",
			__func__, ret);
		return -EIO;
	}
	return ret;
}

static int msm_tdm_get_intf_idx(u16 id)
{
	switch (id) {
+1 −0
Original line number Diff line number Diff line
@@ -16,3 +16,4 @@ export CONFIG_SND_SOC_SA6155=m
export CONFIG_SOUNDWIRE=m
export CONFIG_SOUNDWIRE_MSTR_CTRL=m
export CONFIG_SND_EVENT=m
export CONFIG_MSM_INTERNAL_MCLK=m
+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2019, 2021, 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
@@ -28,3 +28,4 @@
#define CONFIG_SOUNDWIRE 1
#define CONFIG_SOUNDWIRE_MSTR_CTRL 1
#define CONFIG_SND_EVENT 1
#define CONFIG_MSM_INTERNAL_MCLK 1
+3 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2008 Google, Inc.
 * Copyright (C) 2008 HTC Corporation
 * Copyright (c) 2009-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2009-2021, 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
@@ -1340,6 +1340,7 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file)
	audio->pcm_cfg.sample_rate = 48000;
	audio->pcm_cfg.channel_count = 2;

	audio->wake_event_initialized = false;
	/* Only AIO interface */
	if (file->f_flags & O_NONBLOCK) {
		pr_debug("%s[%pK]:set to aio interface\n", __func__, audio);
@@ -1373,6 +1374,7 @@ int audio_aio_open(struct q6audio_aio *audio, struct file *file)
	audio->drv_ops.out_flush(audio);
	audio->opened = 1;
	audio->reset_event = false;
	audio->wake_event_initialized = true;
	file->private_data = audio;
	audio->codec_ioctl = audio_aio_ioctl;
	audio->codec_compat_ioctl = audio_aio_compat_ioctl;
Loading