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

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

Merge "asoc: qcs405: Use changed clock for SPDIF interfaces"

parents 5ce5240a 3cd7e58e
Loading
Loading
Loading
Loading
+43 −16
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include <dsp/msm_audio_ion.h>
#include <dsp/apr_audio-v2.h>
#include <dsp/q6asm-v2.h>
#include <dsp/q6core.h>
#include <dsp/msm-audio-effects-q6-v2.h>
#include "msm-pcm-routing-v2.h"
#include "msm-qti-pp-config.h"
@@ -204,7 +205,7 @@ struct msm_compr_dec_params {

struct msm_compr_ch_map {
	bool set_ch_map;
	char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL];
	char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8];
};

static int msm_compr_send_dec_params(struct snd_compr_stream *cstream,
@@ -1012,6 +1013,21 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
			sample_word_size = 16;
			break;
		}

		if (q6core_get_avcs_api_version_per_service(
					APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
					ADSP_ASM_API_VERSION_V2) {
			ret = q6asm_media_format_block_pcm_format_support_v5(
					prtd->audio_client,
					prtd->sample_rate,
					prtd->num_channels,
					bit_width, stream_id,
					use_default_chmap,
					chmap,
					sample_word_size,
					ASM_LITTLE_ENDIAN,
					DEFAULT_QF);
		} else {
			ret = q6asm_media_format_block_pcm_format_support_v4(
					prtd->audio_client,
					prtd->sample_rate,
@@ -1022,6 +1038,7 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
					sample_word_size,
					ASM_LITTLE_ENDIAN,
					DEFAULT_QF);
		}
		if (ret < 0)
			pr_err("%s: CMD Format block failed\n", __func__);

@@ -1336,6 +1353,15 @@ static int msm_compr_configure_dsp_for_playback
	} else {
		pr_debug("%s: stream_id %d bits_per_sample %d\n",
				__func__, ac->stream_id, bits_per_sample);

		if (q6core_get_avcs_api_version_per_service(
					APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
					ADSP_ASM_API_VERSION_V2)
			ret = q6asm_stream_open_write_v5(ac,
				prtd->codec, bits_per_sample,
				ac->stream_id,
				prtd->gapless_state.use_dsp_gapless_mode);
		else
			ret = q6asm_stream_open_write_v4(ac,
				prtd->codec, bits_per_sample,
				ac->stream_id,
@@ -3640,7 +3666,7 @@ static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol,

	if (pdata->ch_map[fe_id]) {
		pdata->ch_map[fe_id]->set_ch_map = true;
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
			pdata->ch_map[fe_id]->channel_map[i] =
				(char)(ucontrol->value.integer.value[i]);
	} else {
@@ -3669,7 +3695,7 @@ static int msm_compr_channel_map_get(struct snd_kcontrol *kcontrol,
		goto end;
	}
	if (pdata->ch_map[fe_id]) {
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
			ucontrol->value.integer.value[i] =
				pdata->ch_map[fe_id]->channel_map[i];
	}
@@ -3983,9 +4009,10 @@ static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 8;
	uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 0xFFFFFFFF;
	/* See PCM_CHANNEL_RSD=34 in apr_audio-v2.h */
	uinfo->value.integer.max = 34;
	return 0;
}

+3 −3
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
						SNDRV_PCM_FMTBIT_S24_3LE |
						SNDRV_PCM_FMTBIT_S32_LE),
			.channels_min = 1,
			.channels_max = 8,
			.channels_max = 16,
			.rate_min =     8000,
			.rate_max =	384000,
		},
@@ -113,7 +113,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
				    SNDRV_PCM_FMTBIT_S24_3LE |
				    SNDRV_PCM_FMTBIT_S32_LE),
			.channels_min = 1,
			.channels_max = 8,
			.channels_max = 16,
			.rate_min =     8000,
			.rate_max =	48000,
		},
@@ -311,7 +311,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
						SNDRV_PCM_FMTBIT_S24_3LE |
						SNDRV_PCM_FMTBIT_S32_LE),
			.channels_min = 1,
			.channels_max = 8,
			.channels_max = 16,
			.rate_min =	8000,
			.rate_max = 384000,
		},
+278 −87
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#define CHANNEL_STATUS_MASK_INIT 0x0
#define CHANNEL_STATUS_MASK 0x4
#define AFE_API_VERSION_CLOCK_SET 1
#define MSM_DAI_SYSFS_ENTRY_MAX_LEN 64

#define DAI_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \
				    SNDRV_PCM_FMTBIT_S24_LE | \
@@ -218,6 +219,7 @@ struct msm_dai_q6_spdif_dai_data {
	u16 port_id;
	struct afe_spdif_port_config spdif_port;
	struct afe_event_fmt_update fmt_event;
	struct kobject *kobj;
};

struct msm_dai_q6_spdif_event_msg {
@@ -1459,39 +1461,6 @@ static int msm_dai_q6_spdif_source_get(struct snd_kcontrol *kcontrol,
	return 0;
}

static int msm_dai_q6_spdif_ext_state_get(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{

	struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;

	ucontrol->value.integer.value[0] =
		dai_data->fmt_event.status & 0x3;
	return 0;
}

static int msm_dai_q6_spdif_ext_format_get(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{

	struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;

	ucontrol->value.integer.value[0] =
		dai_data->fmt_event.data_format & 0x1;
	return 0;
}

static int msm_dai_q6_spdif_ext_rate_get(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{

	struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;

	ucontrol->value.integer.value[0] =
		dai_data->fmt_event.sample_rate;
	return 0;
}

static const char * const spdif_format[] = {
	"LPCM",
	"Compr"
@@ -1501,10 +1470,6 @@ static const char * const spdif_source[] = {
	"Optical", "EXT-ARC", "Coaxial", "VT-ARC"
};

static const char * const spdif_state[] = {
	"Inactive", "Active", "EOS"
};

static const struct soc_enum spdif_rx_config_enum[] = {
	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format),
};
@@ -1514,11 +1479,6 @@ static const struct soc_enum spdif_tx_config_enum[] = {
	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format),
};

static const struct soc_enum spdif_tx_status_enum[] = {
	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_state), spdif_state),
	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format),
 };

static int msm_dai_q6_spdif_chstatus_put(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
@@ -1609,21 +1569,6 @@ static const struct snd_kcontrol_new spdif_tx_config_controls[] = {
			msm_dai_q6_spdif_format_put)
};

static const struct snd_kcontrol_new spdif_tx_status_controls[] = {
	SOC_ENUM_EXT("PRI SPDIF TX EXT State", spdif_tx_status_enum[0],
			msm_dai_q6_spdif_ext_state_get, NULL),
	SOC_ENUM_EXT("PRI SPDIF TX EXT Format", spdif_tx_status_enum[1],
			msm_dai_q6_spdif_ext_format_get, NULL),
	SOC_SINGLE_EXT("PRI SPDIF TX EXT Rate", 0, 0, 192000, 0,
			msm_dai_q6_spdif_ext_rate_get, NULL),
	SOC_ENUM_EXT("SEC SPDIF TX EXT State", spdif_tx_status_enum[0],
			msm_dai_q6_spdif_ext_state_get, NULL),
	SOC_ENUM_EXT("SEC SPDIF TX EXT Format", spdif_tx_status_enum[1],
			msm_dai_q6_spdif_ext_format_get, NULL),
	SOC_SINGLE_EXT("SEC SPDIF TX EXT Rate", 0, 0, 192000, 0,
			msm_dai_q6_spdif_ext_rate_get, NULL)
};

static void msm_dai_q6_spdif_process_event(uint32_t opcode, uint32_t token,
		uint32_t *payload, void *private_data)
{
@@ -1734,6 +1679,102 @@ static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream,
	return rc;
}

static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_state(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	ssize_t ret;
	struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev);

	if (!dai_data) {
		pr_err("%s: invalid input\n", __func__);
		return -EINVAL;
	}

	ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n",
		dai_data->fmt_event.status);
	pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.status);

	return ret;
}

static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_format(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	ssize_t ret;
	struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev);

	if (!dai_data) {
		pr_err("%s: invalid input\n", __func__);
		return -EINVAL;
	}

	ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n",
		dai_data->fmt_event.data_format);
	pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.data_format);

	return ret;
}

static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_rate(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	ssize_t ret;
	struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev);

	if (!dai_data) {
		pr_err("%s: invalid input\n", __func__);
		return -EINVAL;
	}

	ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n",
		dai_data->fmt_event.sample_rate);
	pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.sample_rate);

	return ret;
}

static DEVICE_ATTR(audio_state, 0444, msm_dai_q6_spdif_sysfs_rda_audio_state,
	NULL);
static DEVICE_ATTR(audio_format, 0444, msm_dai_q6_spdif_sysfs_rda_audio_format,
	NULL);
static DEVICE_ATTR(audio_rate, 0444, msm_dai_q6_spdif_sysfs_rda_audio_rate,
	NULL);

static struct attribute *msm_dai_q6_spdif_fs_attrs[] = {
	&dev_attr_audio_state.attr,
	&dev_attr_audio_format.attr,
	&dev_attr_audio_rate.attr,
	NULL,
};
static struct attribute_group msm_dai_q6_spdif_fs_attrs_group = {
	.attrs = msm_dai_q6_spdif_fs_attrs,
};

static int msm_dai_q6_spdif_sysfs_create(struct snd_soc_dai *dai,
	struct msm_dai_q6_spdif_dai_data *dai_data)
{
	int rc;

	rc = sysfs_create_group(&dai->dev->kobj,
		&msm_dai_q6_spdif_fs_attrs_group);
	if (rc) {
		pr_err("%s: failed, rc=%d\n", __func__, rc);
		return rc;
	}
	dai_data->kobj = &dai->dev->kobj;

	return 0;
}

static void msm_dai_q6_spdif_sysfs_remove(struct snd_soc_dai *dai,
	struct msm_dai_q6_spdif_dai_data *dai_data)
{
	if (dai_data->kobj)
		sysfs_remove_group(dai_data->kobj,
			&msm_dai_q6_spdif_fs_attrs_group);
	dai_data->kobj = NULL;
}

static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai)
{
	struct msm_dai_q6_spdif_dai_data *dai_data;
@@ -1773,40 +1814,24 @@ static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai)
				 dai_data));
		break;
	case AFE_PORT_ID_PRIMARY_SPDIF_TX:
		rc = msm_dai_q6_spdif_sysfs_create(dai, dai_data);

		rc = snd_ctl_add(dai->component->card->snd_card,
				snd_ctl_new1(&spdif_tx_config_controls[0],
				dai_data));
		rc = snd_ctl_add(dai->component->card->snd_card,
				snd_ctl_new1(&spdif_tx_config_controls[1],
				dai_data));

		rc = snd_ctl_add(dai->component->card->snd_card,
				snd_ctl_new1(&spdif_tx_status_controls[0],
				dai_data));
		rc = snd_ctl_add(dai->component->card->snd_card,
				snd_ctl_new1(&spdif_tx_status_controls[1],
				dai_data));
		rc = snd_ctl_add(dai->component->card->snd_card,
				snd_ctl_new1(&spdif_tx_status_controls[2],
				dai_data));
		break;
	case AFE_PORT_ID_SECONDARY_SPDIF_TX:
		rc = msm_dai_q6_spdif_sysfs_create(dai, dai_data);

		rc = snd_ctl_add(dai->component->card->snd_card,
				snd_ctl_new1(&spdif_tx_config_controls[2],
				dai_data));
		rc = snd_ctl_add(dai->component->card->snd_card,
				snd_ctl_new1(&spdif_tx_config_controls[3],
				dai_data));

		rc = snd_ctl_add(dai->component->card->snd_card,
				snd_ctl_new1(&spdif_tx_status_controls[3],
				dai_data));
		rc = snd_ctl_add(dai->component->card->snd_card,
				snd_ctl_new1(&spdif_tx_status_controls[4],
				dai_data));
		rc = snd_ctl_add(dai->component->card->snd_card,
				snd_ctl_new1(&spdif_tx_status_controls[5],
				dai_data));
		break;
	}
	if (rc < 0)
@@ -1866,6 +1891,9 @@ static int msm_dai_q6_spdif_dai_remove(struct snd_soc_dai *dai)

		clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
	}

	msm_dai_q6_spdif_sysfs_remove(dai, dai_data);

	kfree(dai_data);

	return 0;
@@ -2095,7 +2123,7 @@ static int msm_dai_q6_cdc_hw_params(struct snd_pcm_hw_params *params,
	return 0;
}

static u8 num_of_bits_set(u8 sd_line_mask)
static u16 num_of_bits_set(u16 sd_line_mask)
{
	u8 num_bits_set = 0;

@@ -4644,11 +4672,68 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream,

	dai_data->channels = params_channels(params);
	switch (dai_data->channels) {
	case 15:
	case 16:
		switch (mi2s_dai_config->pdata_mi2s_lines) {
		case AFE_PORT_I2S_16CHS:
			dai_data->port_config.i2s.channel_mode
				= AFE_PORT_I2S_16CHS;
			break;
		default:
			goto error_invalid_data;
		};
		break;
	case 13:
	case 14:
		switch (mi2s_dai_config->pdata_mi2s_lines) {
		case AFE_PORT_I2S_14CHS:
		case AFE_PORT_I2S_16CHS:
			dai_data->port_config.i2s.channel_mode
				= AFE_PORT_I2S_14CHS;
			break;
		default:
			goto error_invalid_data;
		};
		break;
	case 11:
	case 12:
		switch (mi2s_dai_config->pdata_mi2s_lines) {
		case AFE_PORT_I2S_12CHS:
		case AFE_PORT_I2S_14CHS:
		case AFE_PORT_I2S_16CHS:
			dai_data->port_config.i2s.channel_mode
				= AFE_PORT_I2S_12CHS;
			break;
		default:
			goto error_invalid_data;
		};
		break;
	case 9:
	case 10:
		switch (mi2s_dai_config->pdata_mi2s_lines) {
		case AFE_PORT_I2S_10CHS:
		case AFE_PORT_I2S_12CHS:
		case AFE_PORT_I2S_14CHS:
		case AFE_PORT_I2S_16CHS:
			dai_data->port_config.i2s.channel_mode
				= AFE_PORT_I2S_10CHS;
			break;
		default:
			goto error_invalid_data;
		};
		break;
	case 8:
	case 7:
		if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_8CHS)
			goto error_invalid_data;
		dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS;
		else
			if (mi2s_dai_config->pdata_mi2s_lines
					== AFE_PORT_I2S_8CHS_2)
				dai_data->port_config.i2s.channel_mode =
						AFE_PORT_I2S_8CHS_2;
			else
				dai_data->port_config.i2s.channel_mode =
						AFE_PORT_I2S_8CHS;
		break;
	case 6:
	case 5:
@@ -4658,15 +4743,34 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream,
		break;
	case 4:
	case 3:
		if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_QUAD01)
		switch (mi2s_dai_config->pdata_mi2s_lines) {
		case AFE_PORT_I2S_SD0:
		case AFE_PORT_I2S_SD1:
		case AFE_PORT_I2S_SD2:
		case AFE_PORT_I2S_SD3:
		case AFE_PORT_I2S_SD4:
		case AFE_PORT_I2S_SD5:
		case AFE_PORT_I2S_SD6:
		case AFE_PORT_I2S_SD7:
			goto error_invalid_data;
		if (mi2s_dai_config->pdata_mi2s_lines == AFE_PORT_I2S_QUAD23)
			break;
		case AFE_PORT_I2S_QUAD01:
		case AFE_PORT_I2S_QUAD23:
		case AFE_PORT_I2S_QUAD45:
		case AFE_PORT_I2S_QUAD67:
			dai_data->port_config.i2s.channel_mode =
				mi2s_dai_config->pdata_mi2s_lines;
		else
			break;
		case AFE_PORT_I2S_8CHS_2:
			dai_data->port_config.i2s.channel_mode =
					AFE_PORT_I2S_QUAD45;
			break;
		default:
			dai_data->port_config.i2s.channel_mode =
					AFE_PORT_I2S_QUAD01;
			break;
		};
		break;
	case 2:
	case 1:
		if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_SD0)
@@ -4676,12 +4780,20 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream,
		case AFE_PORT_I2S_SD1:
		case AFE_PORT_I2S_SD2:
		case AFE_PORT_I2S_SD3:
		case AFE_PORT_I2S_SD4:
		case AFE_PORT_I2S_SD5:
		case AFE_PORT_I2S_SD6:
		case AFE_PORT_I2S_SD7:
			dai_data->port_config.i2s.channel_mode =
				mi2s_dai_config->pdata_mi2s_lines;
			break;
		case AFE_PORT_I2S_QUAD01:
		case AFE_PORT_I2S_6CHS:
		case AFE_PORT_I2S_8CHS:
		case AFE_PORT_I2S_10CHS:
		case AFE_PORT_I2S_12CHS:
		case AFE_PORT_I2S_14CHS:
		case AFE_PORT_I2S_16CHS:
			if (dai_data->vi_feed_mono == SPKR_1)
				dai_data->port_config.i2s.channel_mode =
							AFE_PORT_I2S_SD0;
@@ -4693,6 +4805,14 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream,
			dai_data->port_config.i2s.channel_mode =
						AFE_PORT_I2S_SD2;
			break;
		case AFE_PORT_I2S_QUAD45:
			dai_data->port_config.i2s.channel_mode =
						AFE_PORT_I2S_SD4;
			break;
		case AFE_PORT_I2S_QUAD67:
			dai_data->port_config.i2s.channel_mode =
						AFE_PORT_I2S_SD6;
			break;
		}
		if (dai_data->channels == 2)
			dai_data->port_config.i2s.mono_stereo =
@@ -4866,13 +4986,15 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
				SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
				SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
				 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
				 SNDRV_PCM_RATE_192000,
				SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
				SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
				SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 |
				SNDRV_PCM_RATE_384000,
			.formats = SNDRV_PCM_FMTBIT_S16_LE |
				SNDRV_PCM_FMTBIT_S24_LE |
				SNDRV_PCM_FMTBIT_S24_3LE,
			.rate_min =     8000,
			.rate_max =     192000,
			.rate_max =     384000,
		},
		.capture = {
			.stream_name = "Primary MI2S Capture",
@@ -5257,6 +5379,18 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr,
		case MSM_MI2S_SD3:
			*config_ptr = AFE_PORT_I2S_SD3;
			break;
		case MSM_MI2S_SD4:
			*config_ptr = AFE_PORT_I2S_SD4;
			break;
		case MSM_MI2S_SD5:
			*config_ptr = AFE_PORT_I2S_SD5;
			break;
		case MSM_MI2S_SD6:
			*config_ptr = AFE_PORT_I2S_SD6;
			break;
		case MSM_MI2S_SD7:
			*config_ptr = AFE_PORT_I2S_SD7;
			break;
		default:
			pr_err("%s: invalid SD lines %d\n",
				   __func__, sd_lines);
@@ -5271,6 +5405,12 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr,
		case MSM_MI2S_SD2 | MSM_MI2S_SD3:
			*config_ptr = AFE_PORT_I2S_QUAD23;
			break;
		case MSM_MI2S_SD4 | MSM_MI2S_SD5:
			*config_ptr = AFE_PORT_I2S_QUAD45;
			break;
		case MSM_MI2S_SD6 | MSM_MI2S_SD7:
			*config_ptr = AFE_PORT_I2S_QUAD67;
			break;
		default:
			pr_err("%s: invalid SD lines %d\n",
				   __func__, sd_lines);
@@ -5293,6 +5433,57 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr,
		case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3:
			*config_ptr = AFE_PORT_I2S_8CHS;
			break;
		case MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6 | MSM_MI2S_SD7:
			*config_ptr = AFE_PORT_I2S_8CHS_2;
			break;
		default:
			pr_err("%s: invalid SD lines %d\n",
				   __func__, sd_lines);
			goto error_invalid_data;
		}
		break;
	case 5:
		switch (sd_lines) {
		case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2
		   | MSM_MI2S_SD3 | MSM_MI2S_SD4:
			*config_ptr = AFE_PORT_I2S_10CHS;
			break;
		default:
			pr_err("%s: invalid SD lines %d\n",
				   __func__, sd_lines);
			goto error_invalid_data;
		}
		break;
	case 6:
		switch (sd_lines) {
		case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2
		   | MSM_MI2S_SD3 | MSM_MI2S_SD4 | MSM_MI2S_SD5:
			*config_ptr = AFE_PORT_I2S_12CHS;
			break;
		default:
			pr_err("%s: invalid SD lines %d\n",
				   __func__, sd_lines);
			goto error_invalid_data;
		}
		break;
	case 7:
		switch (sd_lines) {
		case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3
		   | MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6:
			*config_ptr = AFE_PORT_I2S_14CHS;
			break;
		default:
			pr_err("%s: invalid SD lines %d\n",
				   __func__, sd_lines);
			goto error_invalid_data;
		}
		break;
	case 8:
		switch (sd_lines) {
		case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3
		   | MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6 | MSM_MI2S_SD7:
			*config_ptr = AFE_PORT_I2S_16CHS;
			break;
		default:
			pr_err("%s: invalid SD lines %d\n",
				   __func__, sd_lines);
+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,11 @@
#define MSM_MI2S_SD1 (1 << 1)
#define MSM_MI2S_SD2 (1 << 2)
#define MSM_MI2S_SD3 (1 << 3)
#define MSM_MI2S_SD4 (1 << 4)
#define MSM_MI2S_SD5 (1 << 5)
#define MSM_MI2S_SD6 (1 << 6)
#define MSM_MI2S_SD7 (1 << 7)

#define MSM_MI2S_CAP_RX 0
#define MSM_MI2S_CAP_TX 1

+60 −16
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@
#include <sound/pcm_params.h>
#include <dsp/msm_audio_ion.h>
#include <dsp/q6audio-v2.h>
#include <dsp/q6core.h>
#include <dsp/q6asm-v2.h>

#include "msm-pcm-q6-v2.h"
#include "msm-pcm-routing-v2.h"
@@ -384,11 +386,17 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
			return -ENOMEM;
		}
	} else {
		if (q6core_get_avcs_api_version_per_service(
				APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
				ADSP_ASM_API_VERSION_V2)
			ret = q6asm_open_write_v5(prtd->audio_client,
				fmt_type, bits_per_sample);
		else
			ret = q6asm_open_write_v4(prtd->audio_client,
				fmt_type, bits_per_sample);

		if (ret < 0) {
			pr_err("%s: q6asm_open_write_v4 failed (%d)\n",
			pr_err("%s: q6asm_open_write failed (%d)\n",
			__func__, ret);
			q6asm_audio_client_free(prtd->audio_client);
			prtd->audio_client = NULL;
@@ -425,6 +433,18 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
			runtime->channels, !prtd->set_channel_map,
			prtd->channel_map, bits_per_sample);
	} else {

		if (q6core_get_avcs_api_version_per_service(
				APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
				ADSP_ASM_API_VERSION_V2) {

			ret = q6asm_media_format_block_multi_ch_pcm_v5(
				prtd->audio_client, runtime->rate,
				runtime->channels, !prtd->set_channel_map,
				prtd->channel_map, bits_per_sample,
				sample_word_size, ASM_LITTLE_ENDIAN,
				DEFAULT_QF);
		} else {
			ret = q6asm_media_format_block_multi_ch_pcm_v4(
				prtd->audio_client, runtime->rate,
				runtime->channels, !prtd->set_channel_map,
@@ -432,6 +452,7 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
				sample_word_size, ASM_LITTLE_ENDIAN,
				DEFAULT_QF);
		}
	}
	if (ret < 0)
		pr_info("%s: CMD Format block failed\n", __func__);

@@ -489,7 +510,15 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
				__func__, params_channels(params),
				prtd->audio_client->perf_mode);

		ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
		if (q6core_get_avcs_api_version_per_service(
				APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
				ADSP_ASM_API_VERSION_V2)
			ret = q6asm_open_read_v5(prtd->audio_client,
				FORMAT_LINEAR_PCM,
				bits_per_sample, false, ENC_CFG_ID_NONE);
		else
			ret = q6asm_open_read_v4(prtd->audio_client,
				FORMAT_LINEAR_PCM,
				bits_per_sample, false, ENC_CFG_ID_NONE);
		if (ret < 0) {
			pr_err("%s: q6asm_open_read failed\n", __func__);
@@ -557,13 +586,28 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
	pr_debug("%s: Samp_rate = %d Channel = %d bit width = %d, word size = %d\n",
			__func__, prtd->samp_rate, prtd->channel_mode,
			bits_per_sample, sample_word_size);
	ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client,

	if (q6core_get_avcs_api_version_per_service(
			APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
			ADSP_ASM_API_VERSION_V2)
		ret = q6asm_enc_cfg_blk_pcm_format_support_v5(
						prtd->audio_client,
						prtd->samp_rate,
						prtd->channel_mode,
						bits_per_sample,
						sample_word_size,
						ASM_LITTLE_ENDIAN,
						DEFAULT_QF);
	else
		ret = q6asm_enc_cfg_blk_pcm_format_support_v4(
						prtd->audio_client,
						prtd->samp_rate,
						prtd->channel_mode,
						bits_per_sample,
						sample_word_size,
						ASM_LITTLE_ENDIAN,
						DEFAULT_QF);

	if (ret < 0)
		pr_debug("%s: cmd cfg pcm was block failed", __func__);

@@ -1508,7 +1552,7 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol,
	prtd = substream->runtime->private_data;
	if (prtd) {
		prtd->set_channel_map = true;
			for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
			for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
				prtd->channel_map[i] =
				(char)(ucontrol->value.integer.value[i]);
	}
@@ -1536,11 +1580,11 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol,
	prtd = substream->runtime->private_data;

	if (prtd && prtd->set_channel_map == true) {
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
			ucontrol->value.integer.value[i] =
					(int)prtd->channel_map[i];
	} else {
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
		for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
			ucontrol->value.integer.value[i] = 0;
	}

@@ -1558,7 +1602,7 @@ static int msm_pcm_add_chmap_controls(struct snd_soc_pcm_runtime *rtd)
	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,
				     PCM_FORMAT_MAX_NUM_CHANNEL_V8, 0,
				     &chmap_info);
	if (ret < 0) {
		pr_err("%s, channel map cntrl add failed\n", __func__);
Loading