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

Commit dfb7689c authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "asoc: qcs405: add support for dsd input"

parents e25bc7ed 94ebdd1b
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
 */


@@ -81,6 +81,8 @@ const DECLARE_TLV_DB_LINEAR(msm_compr_vol_gain, 0,
#define COMPRESSED_PERF_MODE_FLAG 0
#endif

#define DSD_BLOCK_SIZE_4 4

struct msm_compr_gapless_state {
	bool set_next_stream_id;
	int32_t stream_opened[MAX_NUMBER_OF_STREAMS];
@@ -1240,6 +1242,11 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
		dsd_cfg.num_version = 0;
		dsd_cfg.is_bitwise_big_endian = 1;
		dsd_cfg.dsd_channel_block_size = 1;

		if (codec_options->dsd_dec.blk_size == DSD_BLOCK_SIZE_4)
			dsd_cfg.dsd_channel_block_size =
				codec_options->dsd_dec.blk_size;

		ret = q6asm_media_format_block_dsd(prtd->audio_client,
						   &dsd_cfg, stream_id);
		if (ret < 0)
+4 −2
Original line number Diff line number Diff line
@@ -329,7 +329,8 @@ static const char *const mi2s_format[] = {
	"NA6",
	"NA7",
	"NA8",
	"DSD_DOP_W_MARKER"
	"DSD_DOP_W_MARKER",
	"NATIVE_DSD_DATA"
};

static const char *const mi2s_vi_feed_mono[] = {
@@ -338,7 +339,7 @@ static const char *const mi2s_vi_feed_mono[] = {
};

static const struct soc_enum mi2s_config_enum[] = {
	SOC_ENUM_SINGLE_EXT(10, mi2s_format),
	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mi2s_format), mi2s_format),
	SOC_ENUM_SINGLE_EXT(2, mi2s_vi_feed_mono),
};

@@ -5624,6 +5625,7 @@ static int msm_dai_q6_mi2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
	case SND_SOC_DAIFMT_CBM_CFS:
		mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1;
		mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.ws_src = 1;
		break;
+4 −4
Original line number Diff line number Diff line
@@ -1554,7 +1554,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
				adm_open(port_id, path_type, sample_rate,
					 channels, topology, perf_mode,
					 bit_width, app_type, acdb_dev_id,
					 session_type);
					 session_type, passthr_mode);
			if ((copp_idx < 0) ||
				(copp_idx >= MAX_COPPS_PER_PORT)) {
				pr_err("%s:adm open failed coppid:%d\n",
@@ -1906,7 +1906,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
					    sample_rate, channels, topology,
					    perf_mode, bits_per_sample,
					    app_type, acdb_dev_id,
					    session_type);
					    session_type, passthr_mode);
			if ((copp_idx < 0) ||
				(copp_idx >= MAX_COPPS_PER_PORT)) {
				pr_err("%s: adm open failed copp_idx:%d\n",
@@ -2187,7 +2187,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
					    sample_rate, channels, topology,
					    fdai->perf_mode, bits_per_sample,
					    app_type, acdb_dev_id,
					    session_type);
					    session_type, passthr_mode);
			if ((copp_idx < 0) ||
			    (copp_idx >= MAX_COPPS_PER_PORT)) {
				pr_err("%s: adm open failed\n", __func__);
@@ -29738,7 +29738,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
					    sample_rate, channels, topology,
					    fdai->perf_mode, bits_per_sample,
					    app_type, acdb_dev_id,
					    session_type);
					    session_type, fdai->passthr_mode);
			if ((copp_idx < 0) ||
				(copp_idx >= MAX_COPPS_PER_PORT)) {
				pr_err("%s: adm open failed\n", __func__);
+187 −5
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */
#include <linux/clk.h>
#include <linux/delay.h>
@@ -21,6 +21,7 @@
#include <sound/pcm_params.h>
#include <sound/info.h>
#include <dsp/audio_notifier.h>
#include <dsp/apr_audio-v2.h>
#include <dsp/q6afe-v2.h>
#include <dsp/q6core.h>
#include <dsp/msm_mdf.h>
@@ -173,6 +174,7 @@ struct dev_config {
	u32 sample_rate;
	u32 bit_format;
	u32 channels;
	u32 data_format;
};

struct msm_wsa881x_dev_info {
@@ -201,6 +203,7 @@ struct msm_asoc_mach_data {
	u32 tdm_micb_voltage;
	u32 tdm_micb_current;
	bool codec_is_csra;
	void __iomem *mi2s_dsd_mode[MI2S_MAX];
};

struct msm_asoc_wcd93xx_codec {
@@ -471,6 +474,19 @@ static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four",
static const char *const vi_feed_ch_text[] = {"One", "Two"};
static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
					  "S32_LE"};
static const char *const data_format_text[] = {
	"LPCM",
	"Compr",
	"LPCM-60958",
	"Compr-60958",
	"NA4",
	"NA5",
	"NA6",
	"NA7",
	"NA8",
	"DSD_DOP_W_MARKER",
	"NATIVE_DSD_DATA"
};
static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16",
					"KHZ_32", "KHZ_44P1", "KHZ_48",
					"KHZ_88P2", "KHZ_96", "KHZ_176P4",
@@ -599,6 +615,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_rx_chs, mi2s_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_tx_chs, mi2s_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_data_format, data_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_data_format, data_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 SOC_ENUM_SINGLE_EXT_DECL(prim_meta_mi2s_rx_sample_rate, mi2s_rate_text);
@@ -3049,7 +3067,8 @@ static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol,
		return idx;

	/* check for PRIM_MI2S and CSRAx config to allow 24bit BE config only */
	if ((PRIM_MI2S == idx) && (true==pdata->codec_is_csra))
	if ((idx == PRIM_MI2S) && (pdata->codec_is_csra == true)
			&& mi2s_rx_cfg[idx].data_format != AFE_DSD_DATA)
	{
		mi2s_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE;
		pr_debug("%s: Keeping default format idx[%d]_rx_format = %d, item = %d\n",
@@ -3103,6 +3122,74 @@ static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol,
	return 0;
}

static int msm_mi2s_tx_data_format_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int idx = mi2s_get_port_idx(kcontrol);

	if (idx < 0)
		return idx;

	mi2s_tx_cfg[idx].data_format = ucontrol->value.enumerated.item[0];

	pr_debug("%s: idx[%d]_data_format = %d, item = %d\n", __func__,
		  idx, mi2s_tx_cfg[idx].data_format,
		  ucontrol->value.enumerated.item[0]);

	return 0;
}

static int msm_mi2s_rx_data_format_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int idx = mi2s_get_port_idx(kcontrol);

	if (idx < 0)
		return idx;

	mi2s_rx_cfg[idx].data_format = ucontrol->value.enumerated.item[0];

	pr_debug("%s: idx[%d]_data_format = %d, item = %d\n", __func__,
		  idx, mi2s_rx_cfg[idx].data_format,
		  ucontrol->value.enumerated.item[0]);

	return 0;
}

static int msm_mi2s_tx_data_format_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int idx = mi2s_get_port_idx(kcontrol);

	if (idx < 0)
		return idx;

	ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].data_format;

	pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
		idx, mi2s_tx_cfg[idx].data_format,
		ucontrol->value.enumerated.item[0]);

	return 0;
}

static int msm_mi2s_rx_data_format_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int idx = mi2s_get_port_idx(kcontrol);

	if (idx < 0)
		return idx;

	ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].data_format;

	pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
		idx, mi2s_rx_cfg[idx].data_format,
		ucontrol->value.enumerated.item[0]);

	return 0;
}

static int msm_meta_mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
{
	int idx = 0;
@@ -4125,6 +4212,18 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
			msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
	SOC_ENUM_EXT("SEN_MI2S_TX Channels", sen_mi2s_tx_chs,
			msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
	SOC_ENUM_EXT("PRIM_MI2S_TX DataFormat", mi2s_tx_data_format,
			msm_mi2s_tx_data_format_get,
				msm_mi2s_tx_data_format_put),
	SOC_ENUM_EXT("QUAT_MI2S_TX DataFormat", mi2s_tx_data_format,
			msm_mi2s_tx_data_format_get,
				msm_mi2s_tx_data_format_put),
	SOC_ENUM_EXT("PRIM_MI2S_RX DataFormat", mi2s_rx_data_format,
			msm_mi2s_rx_data_format_get,
				msm_mi2s_rx_data_format_put),
	SOC_ENUM_EXT("QUAT_MI2S_RX DataFormat", mi2s_rx_data_format,
			msm_mi2s_rx_data_format_get,
				msm_mi2s_rx_data_format_put),
	SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format,
			msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
	SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format,
@@ -6107,7 +6206,7 @@ static struct snd_soc_ops msm_fe_qos_ops = {

static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
{
	int ret = 0;
	int ret = 0, val = 0;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	struct snd_soc_dai_link *dai_link = rtd->dai_link;
@@ -6115,6 +6214,12 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
	unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
	struct snd_soc_card *card = rtd->card;
	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
	int data_format;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		data_format = mi2s_rx_cfg[index].data_format;
	else
		data_format = mi2s_tx_cfg[index].data_format;

	dev_dbg(rtd->card->dev,
		"%s: substream = %s  stream = %d, dai name %s, dai ID %d\n",
@@ -6140,6 +6245,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
			mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
			fmt = SND_SOC_DAIFMT_CBM_CFM;
		}

		if (data_format == AFE_DSD_DATA)
			fmt = SND_SOC_DAIFMT_CBM_CFS;
		ret = msm_mi2s_set_sclk(substream, true);
		if (ret < 0) {
			dev_err(rtd->card->dev,
@@ -6154,10 +6262,35 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
				__func__, index, ret);
			goto clk_off;
		}
		if (pdata->mi2s_gpio_p[index])

		if (pdata->mi2s_gpio_p[index]) {
			if ((data_format == AFE_DSD_DATA) &&
					((index == QUAT_MI2S) ||
						(index == PRIM_MI2S))) {
				msm_cdc_pinctrl_select_alt_active_state(
						pdata->mi2s_gpio_p[index]);
			} else {
				msm_cdc_pinctrl_select_active_state(
					pdata->mi2s_gpio_p[index]);
			}
		}

		if (index == QUAT_MI2S || index == PRIM_MI2S) {
			switch (data_format) {
			case AFE_DSD_DATA:
				if (pdata->mi2s_dsd_mode[index]) {
					val = ioread32(
						pdata->mi2s_dsd_mode[index]);
					val = val | 0x1;
					iowrite32(val,
						pdata->mi2s_dsd_mode[index]);
				}
				break;
			default:
				break;
			}
		}
	}

	ret = qcs405_send_island_vad_config(dai_link->id);
	if (ret) {
@@ -6180,11 +6313,18 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
{
	int ret;
	int val;
	int data_format;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	int index = rtd->cpu_dai->id;
	struct snd_soc_card *card = rtd->card;
	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		data_format = mi2s_rx_cfg[index].data_format;
	else
		data_format = mi2s_tx_cfg[index].data_format;

	pr_debug("%s(): substream = %s  stream = %d\n", __func__,
		 substream->name, substream->stream);
	if (index < PRIM_MI2S || index >= MI2S_MAX) {
@@ -6198,6 +6338,22 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
			msm_cdc_pinctrl_select_sleep_state(
					pdata->mi2s_gpio_p[index]);

		if (index == QUAT_MI2S || index == PRIM_MI2S) {
			switch (data_format) {
			case AFE_DSD_DATA:
				if (pdata->mi2s_dsd_mode[index]) {
					val = ioread32(
						pdata->mi2s_dsd_mode[index]);
					val = val & ~1;
					iowrite32(val,
						pdata->mi2s_dsd_mode[index]);
				}
				break;
			default:
				break;
			}
		}

		ret = msm_mi2s_set_sclk(substream, false);
		if (ret < 0)
			pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n",
@@ -9436,6 +9592,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
	const char *micb_supply_str1 = "tdm-vdd-micb";
	const char *micb_voltage_str = "qcom,tdm-vdd-micb-voltage";
	const char *micb_current_str = "qcom,tdm-vdd-micb-current";
	u32 v_base_addr;

	if (!pdev->dev.of_node) {
		dev_err(&pdev->dev, "No platform supplied from device tree\n");
@@ -9447,6 +9604,31 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
	if (!pdata)
		return -ENOMEM;

	ret = of_property_read_u32(
		pdev->dev.of_node, "tcsr_i2s_dsd_prim", &v_base_addr);
	if (ret) {
		dev_err(&pdev->dev, "MUX addr invalid for MI2S dsd prim\n");
	} else {
		pdata->mi2s_dsd_mode[PRIM_MI2S] =
			devm_ioremap(&pdev->dev, v_base_addr, 4);
		if (pdata->mi2s_dsd_mode[PRIM_MI2S] == NULL) {
			pr_err("%s ioremap failure for muxsel virt addr dsd prim\n",
				__func__);
		}
	}
	ret = of_property_read_u32(
		pdev->dev.of_node, "tcsr_i2s_dsd_quat", &v_base_addr);
	if (ret) {
		dev_err(&pdev->dev, "MUX addr invalid for MI2S dsd quat\n");
	} else {
		pdata->mi2s_dsd_mode[QUAT_MI2S] =
			devm_ioremap(&pdev->dev, v_base_addr, 4);
		if (pdata->mi2s_dsd_mode[QUAT_MI2S] == NULL) {
			pr_err("%s ioremap failure for muxsel virt addr dsd quat\n",
				__func__);
		}
	}

	/* test for ep92 HDMI bridge and update dai links accordingly */
	ret = msm_detect_ep92_dev(pdev, card);
	if (ret)
+4 −2
Original line number Diff line number Diff line
@@ -2986,7 +2986,7 @@ static int adm_copp_set_ec_ref_mfc_cfg(int port_id, int copp_idx,
 */
int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
	     int perf_mode, uint16_t bit_width, int app_type, int acdb_id,
	     int session_type)
	     int session_type, uint32_t passthr_mode)
{
	struct adm_cmd_device_open_v5	open;
	struct adm_cmd_device_open_v6	open_v6;
@@ -3199,7 +3199,9 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
			}

			open_v8.topology_id = topology;
			open_v8.reserved = 0;
			open_v8.compressed_data_type = 0;
			if (passthr_mode == COMPRESSED_PASSTHROUGH_DSD)
				open_v8.compressed_data_type = 1;

			/* variable endpoint payload */
			ep1_payload.dev_num_channel = channel_mode & 0x00FF;
Loading