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

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

Merge "ASoC: sdm845: update TDM configurations for TX and RX"

parents 73780981 04d19310
Loading
Loading
Loading
Loading
+5 −19
Original line number Diff line number Diff line
@@ -6535,26 +6535,12 @@ static int msm_dai_q6_tdm_set_sysclk(struct snd_soc_dai *dai,
	struct msm_dai_q6_tdm_dai_data *dai_data =
		dev_get_drvdata(dai->dev);

	switch (dai->id) {
	case AFE_PORT_ID_QUATERNARY_TDM_RX:
	case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
	case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
	case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
	case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
	case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
	case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
	case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
	case AFE_PORT_ID_QUATERNARY_TDM_TX:
	case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
	case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
	case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
	case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
	case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
	case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
	case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
	if ((dai->id >= AFE_PORT_ID_PRIMARY_TDM_RX) &&
		(dai->id <= AFE_PORT_ID_QUINARY_TDM_TX_7)) {
		dai_data->clk_set.clk_freq_in_hz = freq;
		break;
	default:
	} else {
		dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
			__func__, dai->id);
		return -EINVAL;
	}

+66 −211
Original line number Diff line number Diff line
@@ -70,7 +70,6 @@
#define WCN_CDC_SLIM_TX_CH_MAX 3

#define TDM_CHANNEL_MAX 8
#define TDM_SLOT_OFFSET_MAX 8

#define MSM_HIFI_ON 1

@@ -311,17 +310,6 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
	}
};

/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */
static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = {
	{0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */
	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */
	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */
	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */
	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */
	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */
	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */
	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */
};

/* Default configuration of slimbus channels */
static struct dev_config slim_rx_cfg[] = {
@@ -432,8 +420,8 @@ static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four",
				    "Five", "Six", "Seven", "Eight"};
static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"};
static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32",
					     "KHZ_44P1", "KHZ_48", "KHZ_96",
					     "KHZ_192", "KHZ_352P8", "KHZ_384"};
					     "KHZ_48", "KHZ_176P4",
					     "KHZ_352P8"};
static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"};
static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
				      "KHZ_32", "KHZ_44P1", "KHZ_48",
@@ -1620,23 +1608,14 @@ static int tdm_get_sample_rate(int value)
		sample_rate = SAMPLING_RATE_32KHZ;
		break;
	case 3:
		sample_rate = SAMPLING_RATE_44P1KHZ;
		sample_rate = SAMPLING_RATE_48KHZ;
		break;
	case 4:
		sample_rate = SAMPLING_RATE_48KHZ;
		sample_rate = SAMPLING_RATE_176P4KHZ;
		break;
	case 5:
		sample_rate = SAMPLING_RATE_96KHZ;
		break;
	case 6:
		sample_rate = SAMPLING_RATE_192KHZ;
		break;
	case 7:
		sample_rate = SAMPLING_RATE_352P8KHZ;
		break;
	case 8:
		sample_rate = SAMPLING_RATE_384KHZ;
		break;
	default:
		sample_rate = SAMPLING_RATE_48KHZ;
		break;
@@ -1674,26 +1653,17 @@ static int tdm_get_sample_rate_val(int sample_rate)
	case SAMPLING_RATE_32KHZ:
		sample_rate_val = 2;
		break;
	case SAMPLING_RATE_44P1KHZ:
	case SAMPLING_RATE_48KHZ:
		sample_rate_val = 3;
		break;
	case SAMPLING_RATE_48KHZ:
	case SAMPLING_RATE_176P4KHZ:
		sample_rate_val = 4;
		break;
	case SAMPLING_RATE_96KHZ:
		sample_rate_val = 5;
		break;
	case SAMPLING_RATE_192KHZ:
		sample_rate_val = 6;
		break;
	case SAMPLING_RATE_352P8KHZ:
		sample_rate_val = 7;
		break;
	case SAMPLING_RATE_384KHZ:
		sample_rate_val = 8;
		sample_rate_val = 5;
		break;
	default:
		sample_rate_val = 4;
		sample_rate_val = 3;
		break;
	}
	return sample_rate_val;
@@ -4497,15 +4467,46 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	int ret = 0;
	int channels, slot_width, slots;
	int slot_width = 32;
	int channels, slots;
	unsigned int slot_mask, rate, clk_freq;
	unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};

	slot_width = 32;
	pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
	/* currently only supporting TDM_RX_0 and TDM_TX_0 */
	switch (cpu_dai->id) {
	case AFE_PORT_ID_PRIMARY_TDM_RX:
		slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels;
		break;
	case AFE_PORT_ID_SECONDARY_TDM_RX:
		slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels;
		break;
	case AFE_PORT_ID_TERTIARY_TDM_RX:
		slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels;
		break;
	case AFE_PORT_ID_QUATERNARY_TDM_RX:
		slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
		break;
	case AFE_PORT_ID_PRIMARY_TDM_TX:
		slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels;
		break;
	case AFE_PORT_ID_SECONDARY_TDM_TX:
		slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels;
		break;
	case AFE_PORT_ID_TERTIARY_TDM_TX:
		slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels;
		break;
	case AFE_PORT_ID_QUATERNARY_TDM_TX:
		slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
		break;
	default:
		pr_err("%s: dai id 0x%x not supported\n",
			__func__, cpu_dai->id);
		return -EINVAL;
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		/*2 slot config - bits 0 and 1 set for the first two slots */
		slot_mask = 0x0000FFFF >> (16-slots);
		channels = slots;
@@ -4529,7 +4530,6 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
			goto end;
		}
	} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
		slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
		/*2 slot config - bits 0 and 1 set for the first two slots */
		slot_mask = 0x0000FFFF >> (16-slots);
		channels = slots;
@@ -4574,14 +4574,19 @@ static int sdm845_tdm_snd_startup(struct snd_pcm_substream *substream)
{
	int ret = 0;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	struct snd_soc_card *card = rtd->card;
	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
	struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;

	/* currently only supporting TDM_RX_0 and TDM_TX_0 */
	if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
		(cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
		ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE);
		if (ret)
			pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
				__func__, ret);
	}

	return ret;
}
@@ -4590,15 +4595,19 @@ static void sdm845_tdm_snd_shutdown(struct snd_pcm_substream *substream)
{
	int ret = 0;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	struct snd_soc_card *card = rtd->card;
	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
	struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;

	/* currently only supporting TDM_RX_0 and TDM_TX_0 */
	if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
		(cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
		ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
		if (ret)
			pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
				__func__, ret);

	}
}

static struct snd_soc_ops sdm845_tdm_be_ops = {
@@ -4732,157 +4741,6 @@ static struct snd_soc_ops msm_aux_pcm_be_ops = {
	.shutdown = msm_aux_pcm_snd_shutdown,
};

static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width,
					    int slots)
{
	unsigned int slot_mask = 0;
	int i, j;
	unsigned int *slot_offset;

	for (i = TDM_0; i < TDM_PORT_MAX; i++) {
		slot_offset = tdm_slot_offset[i];

		for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
			if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID)
				slot_mask |=
				(1 << ((slot_offset[j] * 8) / slot_width));
			else
				break;
		}
	}

	return slot_mask;
}

static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream,
				     struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	int ret = 0;
	int channels, slot_width, slots;
	unsigned int slot_mask;
	unsigned int *slot_offset;
	int offset_channels = 0;
	int i;

	pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);

	channels = params_channels(params);
	switch (channels) {
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
	case 7:
	case 8:
		switch (params_format(params)) {
		case SNDRV_PCM_FORMAT_S32_LE:
		case SNDRV_PCM_FORMAT_S24_LE:
		case SNDRV_PCM_FORMAT_S16_LE:
		/*
		 * Up to 8 channels HW config should
		 * use 32 bit slot width for max support of
		 * stream bit width. (slot_width > bit_width)
		 */
			slot_width = 32;
			break;
		default:
			pr_err("%s: invalid param format 0x%x\n",
				__func__, params_format(params));
			return -EINVAL;
		}
		slots = 8;
		slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
						    slot_width,
						    slots);
		if (!slot_mask) {
			pr_err("%s: invalid slot_mask 0x%x\n",
				__func__, slot_mask);
			return -EINVAL;
		}
		break;
	default:
		pr_err("%s: invalid param channels %d\n",
			__func__, channels);
		return -EINVAL;
	}
	/* currently only supporting TDM_RX_0 and TDM_TX_0 */
	switch (cpu_dai->id) {
	case AFE_PORT_ID_PRIMARY_TDM_RX:
	case AFE_PORT_ID_SECONDARY_TDM_RX:
	case AFE_PORT_ID_TERTIARY_TDM_RX:
	case AFE_PORT_ID_QUATERNARY_TDM_RX:
	case AFE_PORT_ID_PRIMARY_TDM_TX:
	case AFE_PORT_ID_SECONDARY_TDM_TX:
	case AFE_PORT_ID_TERTIARY_TDM_TX:
	case AFE_PORT_ID_QUATERNARY_TDM_TX:
		slot_offset = tdm_slot_offset[TDM_0];
		break;
	default:
		pr_err("%s: dai id 0x%x not supported\n",
			__func__, cpu_dai->id);
		return -EINVAL;
	}

	for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
		if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
			offset_channels++;
		else
			break;
	}

	if (offset_channels == 0) {
		pr_err("%s: slot offset not supported, offset_channels %d\n",
			__func__, offset_channels);
		return -EINVAL;
	}

	if (channels > offset_channels) {
		pr_err("%s: channels %d exceed offset_channels %d\n",
			__func__, channels, offset_channels);
		return -EINVAL;
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
					       slots, slot_width);
		if (ret < 0) {
			pr_err("%s: failed to set tdm slot, err:%d\n",
				__func__, ret);
			goto err;
		}

		ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
						  channels, slot_offset);
		if (ret < 0) {
			pr_err("%s: failed to set channel map, err:%d\n",
				__func__, ret);
			goto err;
		}
	} else {
		ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
					       slots, slot_width);
		if (ret < 0) {
			pr_err("%s: failed to set tdm slot, err:%d\n",
				__func__, ret);
			goto err;
		}

		ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
						  slot_offset, 0, NULL);
		if (ret < 0) {
			pr_err("%s: failed to set channel map, err:%d\n",
				__func__, ret);
			goto err;
		}
	}
err:
	return ret;
}

static struct snd_soc_ops msm_be_ops = {
	.hw_params = msm_snd_hw_params,
};
@@ -4895,9 +4753,6 @@ static struct snd_soc_ops msm_wcn_ops = {
	.hw_params = msm_wcn_hw_params,
};

static struct snd_soc_ops msm_tdm_be_ops = {
	.hw_params = msm_tdm_snd_hw_params
};

/* Digital audio interface glue - connects codec <---> CPU */
static struct snd_soc_dai_link msm_common_dai_links[] = {
@@ -5676,7 +5531,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
		.dpcm_playback = 1,
		.id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
		.be_hw_params_fixup = msm_be_hw_params_fixup,
		.ops = &msm_tdm_be_ops,
		.ops = &sdm845_tdm_be_ops,
		.ignore_suspend = 1,
	},
	{
@@ -5690,7 +5545,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
		.dpcm_capture = 1,
		.id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
		.be_hw_params_fixup = msm_be_hw_params_fixup,
		.ops = &msm_tdm_be_ops,
		.ops = &sdm845_tdm_be_ops,
		.ignore_suspend = 1,
	},
	{
@@ -5704,7 +5559,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
		.dpcm_playback = 1,
		.id = MSM_BACKEND_DAI_SEC_TDM_RX_0,
		.be_hw_params_fixup = msm_be_hw_params_fixup,
		.ops = &msm_tdm_be_ops,
		.ops = &sdm845_tdm_be_ops,
		.ignore_suspend = 1,
	},
	{
@@ -5718,7 +5573,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
		.dpcm_capture = 1,
		.id = MSM_BACKEND_DAI_SEC_TDM_TX_0,
		.be_hw_params_fixup = msm_be_hw_params_fixup,
		.ops = &msm_tdm_be_ops,
		.ops = &sdm845_tdm_be_ops,
		.ignore_suspend = 1,
	},
	{
@@ -5732,7 +5587,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
		.dpcm_playback = 1,
		.id = MSM_BACKEND_DAI_TERT_TDM_RX_0,
		.be_hw_params_fixup = msm_be_hw_params_fixup,
		.ops = &msm_tdm_be_ops,
		.ops = &sdm845_tdm_be_ops,
		.ignore_suspend = 1,
	},
	{
@@ -5746,7 +5601,7 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
		.dpcm_capture = 1,
		.id = MSM_BACKEND_DAI_TERT_TDM_TX_0,
		.be_hw_params_fixup = msm_be_hw_params_fixup,
		.ops = &msm_tdm_be_ops,
		.ops = &sdm845_tdm_be_ops,
		.ignore_suspend = 1,
	},
	{