Merge "asoc: qcs405: Use changed clock for SPDIF interfaces"
This commit is contained in:

کامیت شده توسط
Gerrit - the friendly Code Review server

کامیت
1929529772
@@ -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,16 +1013,32 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
|
||||
sample_word_size = 16;
|
||||
break;
|
||||
}
|
||||
ret = q6asm_media_format_block_pcm_format_support_v4(
|
||||
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);
|
||||
|
||||
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,
|
||||
prtd->num_channels,
|
||||
bit_width, stream_id,
|
||||
use_default_chmap,
|
||||
chmap,
|
||||
sample_word_size,
|
||||
ASM_LITTLE_ENDIAN,
|
||||
DEFAULT_QF);
|
||||
}
|
||||
if (ret < 0)
|
||||
pr_err("%s: CMD Format block failed\n", __func__);
|
||||
|
||||
@@ -1336,7 +1353,16 @@ 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);
|
||||
ret = q6asm_stream_open_write_v4(ac,
|
||||
|
||||
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,
|
||||
prtd->gapless_state.use_dsp_gapless_mode);
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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,
|
||||
},
|
||||
|
@@ -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,14 +4743,33 @@ 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:
|
||||
@@ -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 =
|
||||
@@ -4864,15 +4984,17 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
|
||||
.stream_name = "Primary MI2S Playback",
|
||||
.aif_name = "PRI_MI2S_RX",
|
||||
.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_16000 | SNDRV_PCM_RATE_22050 |
|
||||
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
|
||||
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);
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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 {
|
||||
ret = q6asm_open_write_v4(prtd->audio_client,
|
||||
fmt_type, 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_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,12 +433,25 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
|
||||
runtime->channels, !prtd->set_channel_map,
|
||||
prtd->channel_map, bits_per_sample);
|
||||
} else {
|
||||
ret = q6asm_media_format_block_multi_ch_pcm_v4(
|
||||
|
||||
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,
|
||||
prtd->channel_map, bits_per_sample,
|
||||
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,
|
||||
prtd->samp_rate,
|
||||
prtd->channel_mode,
|
||||
bits_per_sample,
|
||||
sample_word_size,
|
||||
ASM_LITTLE_ENDIAN,
|
||||
DEFAULT_QF);
|
||||
|
||||
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__);
|
||||
|
@@ -105,7 +105,7 @@ struct msm_audio {
|
||||
int mmap_flag;
|
||||
atomic_t pending_buffer;
|
||||
bool set_channel_map;
|
||||
char channel_map[8];
|
||||
char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8];
|
||||
int cmd_interrupt;
|
||||
bool meta_data_mode;
|
||||
uint32_t volume;
|
||||
|
@@ -591,6 +591,12 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
|
||||
LPASS_BE_INT6_MI2S_RX},
|
||||
{ AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0,
|
||||
LPASS_BE_INT6_MI2S_TX},
|
||||
{ AFE_PORT_ID_SENARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0,
|
||||
LPASS_BE_SEN_AUXPCM_RX},
|
||||
{ AFE_PORT_ID_SENARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0,
|
||||
LPASS_BE_SEN_AUXPCM_TX},
|
||||
{ AFE_PORT_ID_SENARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
|
||||
LPASS_BE_SENARY_MI2S_RX},
|
||||
{ AFE_PORT_ID_WSA_CODEC_DMA_RX_0, 0, {0}, {0}, 0, 0, 0, 0,
|
||||
LPASS_BE_WSA_CDC_DMA_RX_0},
|
||||
{ AFE_PORT_ID_WSA_CODEC_DMA_TX_0, 0, {0}, {0}, 0, 0, 0, 0,
|
||||
|
@@ -43,6 +43,8 @@
|
||||
#define LPASS_BE_QUAT_AUXPCM_TX "QUAT_AUX_PCM_TX"
|
||||
#define LPASS_BE_QUIN_AUXPCM_RX "QUIN_AUX_PCM_RX"
|
||||
#define LPASS_BE_QUIN_AUXPCM_TX "QUIN_AUX_PCM_TX"
|
||||
#define LPASS_BE_SEN_AUXPCM_RX "SEN_AUX_PCM_RX"
|
||||
#define LPASS_BE_SEN_AUXPCM_TX "SEN_AUX_PCM_TX"
|
||||
#define LPASS_BE_VOICE_PLAYBACK_TX "VOICE_PLAYBACK_TX"
|
||||
#define LPASS_BE_VOICE2_PLAYBACK_TX "VOICE2_PLAYBACK_TX"
|
||||
#define LPASS_BE_INCALL_RECORD_RX "INCALL_RECORD_RX"
|
||||
@@ -84,6 +86,7 @@
|
||||
#define LPASS_BE_QUIN_MI2S_RX "QUIN_MI2S_RX"
|
||||
#define LPASS_BE_QUIN_MI2S_TX "QUIN_MI2S_TX"
|
||||
#define LPASS_BE_SENARY_MI2S_TX "SENARY_MI2S_TX"
|
||||
#define LPASS_BE_SENARY_MI2S_RX "SENARY_MI2S_RX"
|
||||
|
||||
#define LPASS_BE_PRI_TDM_RX_0 "PRI_TDM_RX_0"
|
||||
#define LPASS_BE_PRI_TDM_TX_0 "PRI_TDM_TX_0"
|
||||
@@ -431,6 +434,9 @@ enum {
|
||||
MSM_BACKEND_DAI_INT5_MI2S_TX,
|
||||
MSM_BACKEND_DAI_INT6_MI2S_RX,
|
||||
MSM_BACKEND_DAI_INT6_MI2S_TX,
|
||||
MSM_BACKEND_DAI_SEN_AUXPCM_RX,
|
||||
MSM_BACKEND_DAI_SEN_AUXPCM_TX,
|
||||
MSM_BACKEND_DAI_SENARY_MI2S_RX,
|
||||
MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0,
|
||||
MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0,
|
||||
MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1,
|
||||
|
@@ -809,11 +809,11 @@ static int msm_qti_pp_set_sec_auxpcm_lb_vol_mixer(
|
||||
static int msm_qti_pp_get_channel_map_mixer(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL] = {0};
|
||||
char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8] = {0};
|
||||
int i;
|
||||
|
||||
adm_get_multi_ch_map(channel_map, ADM_PATH_PLAYBACK);
|
||||
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] =
|
||||
(unsigned int) channel_map[i];
|
||||
return 0;
|
||||
@@ -822,10 +822,10 @@ static int msm_qti_pp_get_channel_map_mixer(struct snd_kcontrol *kcontrol,
|
||||
static int msm_qti_pp_put_channel_map_mixer(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL];
|
||||
char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
|
||||
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
|
||||
channel_map[i] = (char)(ucontrol->value.integer.value[i]);
|
||||
adm_set_multi_ch_map(channel_map, ADM_PATH_PLAYBACK);
|
||||
|
||||
@@ -1414,8 +1414,8 @@ static const struct snd_kcontrol_new sec_auxpcm_lb_vol_mixer_controls[] = {
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new multi_ch_channel_map_mixer_controls[] = {
|
||||
SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 16,
|
||||
0, 8, msm_qti_pp_get_channel_map_mixer,
|
||||
SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 34,
|
||||
0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_mixer,
|
||||
msm_qti_pp_put_channel_map_mixer),
|
||||
};
|
||||
|
||||
|
151
asoc/qcs405.c
151
asoc/qcs405.c
@@ -9,7 +9,6 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
@@ -64,7 +63,7 @@
|
||||
#define SAMPLING_RATE_352P8KHZ 352800
|
||||
#define SAMPLING_RATE_384KHZ 384000
|
||||
|
||||
#define SPDIF_TX_CORE_CLK_204_P8_MHZ 204800000
|
||||
#define SPDIF_TX_CORE_CLK_163_P84_MHZ 163840000
|
||||
#define TLMM_EAST_SPARE 0x07BA0000
|
||||
#define TLMM_SPDIF_HDMI_ARC_CTL 0x07BA2000
|
||||
|
||||
@@ -108,6 +107,7 @@ enum {
|
||||
TERT_MI2S,
|
||||
QUAT_MI2S,
|
||||
QUIN_MI2S,
|
||||
SEN_MI2S,
|
||||
MI2S_MAX,
|
||||
};
|
||||
|
||||
@@ -117,6 +117,7 @@ enum {
|
||||
TERT_AUX_PCM,
|
||||
QUAT_AUX_PCM,
|
||||
QUIN_AUX_PCM,
|
||||
SEN_AUX_PCM,
|
||||
AUX_PCM_MAX,
|
||||
};
|
||||
|
||||
@@ -158,7 +159,8 @@ static u32 mi2s_ebit_clk[MI2S_MAX] = {
|
||||
Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT,
|
||||
Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT,
|
||||
Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT,
|
||||
Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT
|
||||
Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT,
|
||||
Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT
|
||||
};
|
||||
|
||||
struct dev_config {
|
||||
@@ -191,6 +193,7 @@ struct msm_asoc_mach_data {
|
||||
struct regulator *tdm_micb_supply;
|
||||
u32 tdm_micb_voltage;
|
||||
u32 tdm_micb_current;
|
||||
bool codec_is_csra;
|
||||
};
|
||||
|
||||
struct msm_asoc_wcd93xx_codec {
|
||||
@@ -279,7 +282,6 @@ static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
|
||||
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/* TDM default config */
|
||||
@@ -401,6 +403,7 @@ static struct dev_config mi2s_rx_cfg[] = {
|
||||
[TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
|
||||
[QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
|
||||
[QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
|
||||
[SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
|
||||
};
|
||||
|
||||
/* Default configuration of SPDIF channels */
|
||||
@@ -420,6 +423,7 @@ static struct dev_config mi2s_tx_cfg[] = {
|
||||
[TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
[QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
[QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
[SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
};
|
||||
|
||||
static struct dev_config aux_pcm_rx_cfg[] = {
|
||||
@@ -428,6 +432,7 @@ static struct dev_config aux_pcm_rx_cfg[] = {
|
||||
[TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
[QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
[QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
[SEN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
};
|
||||
|
||||
static struct dev_config aux_pcm_tx_cfg[] = {
|
||||
@@ -436,6 +441,7 @@ static struct dev_config aux_pcm_tx_cfg[] = {
|
||||
[TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
[QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
[QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
[SEN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
||||
};
|
||||
|
||||
static int msm_vi_feed_tx_ch = 2;
|
||||
@@ -472,10 +478,12 @@ static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32",
|
||||
static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"};
|
||||
static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16",
|
||||
"KHZ_22P05", "KHZ_32", "KHZ_44P1",
|
||||
"KHZ_48", "KHZ_96", "KHZ_192"};
|
||||
static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four",
|
||||
"Five", "Six", "Seven",
|
||||
"Eight"};
|
||||
"KHZ_48", "KHZ_96", "KHZ_192", "KHZ_384"};
|
||||
static const char *const mi2s_ch_text[] = {
|
||||
"One", "Two", "Three", "Four", "Five", "Six", "Seven",
|
||||
"Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen",
|
||||
"Fourteen", "Fifteen", "Sixteen"
|
||||
};
|
||||
static const char *const qos_text[] = {"Disable", "Enable"};
|
||||
|
||||
static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"};
|
||||
@@ -529,21 +537,25 @@ static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(sen_aux_pcm_rx_sample_rate, auxpcm_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(sen_aux_pcm_tx_sample_rate, auxpcm_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_rx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_tx_sample_rate, mi2s_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text);
|
||||
@@ -554,6 +566,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text);
|
||||
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(aux_pcm_rx_format, bit_format_text);
|
||||
@@ -653,6 +667,14 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
|
||||
Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
|
||||
Q6AFE_LPASS_CLK_ROOT_DEFAULT,
|
||||
0,
|
||||
},
|
||||
{
|
||||
AFE_API_VERSION_I2S_CONFIG,
|
||||
Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT,
|
||||
Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
|
||||
Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
|
||||
Q6AFE_LPASS_CLK_ROOT_DEFAULT,
|
||||
0,
|
||||
}
|
||||
|
||||
};
|
||||
@@ -2420,6 +2442,9 @@ static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol)
|
||||
else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM",
|
||||
sizeof("QUIN_AUX_PCM")))
|
||||
idx = QUIN_AUX_PCM;
|
||||
else if (strnstr(kcontrol->id.name, "SEN_AUX_PCM",
|
||||
sizeof("SENN_AUX_PCM")))
|
||||
idx = SEN_AUX_PCM;
|
||||
else {
|
||||
pr_err("%s: unsupported port: %s",
|
||||
__func__, kcontrol->id.name);
|
||||
@@ -2520,6 +2545,9 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
|
||||
else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX",
|
||||
sizeof("QUIN_MI2S_RX")))
|
||||
idx = QUIN_MI2S;
|
||||
else if (strnstr(kcontrol->id.name, "SEN_MI2S_RX",
|
||||
sizeof("SEN_MI2S_RX")))
|
||||
idx = SEN_MI2S;
|
||||
else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX",
|
||||
sizeof("PRIM_MI2S_TX")))
|
||||
idx = PRIM_MI2S;
|
||||
@@ -2535,6 +2563,9 @@ static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
|
||||
else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX",
|
||||
sizeof("QUIN_MI2S_TX")))
|
||||
idx = QUIN_MI2S;
|
||||
else if (strnstr(kcontrol->id.name, "SEN_MI2S_TX",
|
||||
sizeof("SEN_MI2S_TX")))
|
||||
idx = SEN_MI2S;
|
||||
else {
|
||||
pr_err("%s: unsupported channel: %s",
|
||||
__func__, kcontrol->id.name);
|
||||
@@ -2576,6 +2607,9 @@ static int mi2s_get_sample_rate_val(int sample_rate)
|
||||
case SAMPLING_RATE_192KHZ:
|
||||
sample_rate_val = 8;
|
||||
break;
|
||||
case SAMPLING_RATE_384KHZ:
|
||||
sample_rate_val = 9;
|
||||
break;
|
||||
default:
|
||||
sample_rate_val = 6;
|
||||
break;
|
||||
@@ -2615,6 +2649,9 @@ static int mi2s_get_sample_rate(int value)
|
||||
case 8:
|
||||
sample_rate = SAMPLING_RATE_192KHZ;
|
||||
break;
|
||||
case 9:
|
||||
sample_rate = SAMPLING_RATE_384KHZ;
|
||||
break;
|
||||
default:
|
||||
sample_rate = SAMPLING_RATE_48KHZ;
|
||||
break;
|
||||
@@ -2823,17 +2860,34 @@ static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol,
|
||||
static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
||||
struct msm_asoc_mach_data *pdata = NULL;
|
||||
struct snd_soc_component *component = NULL;
|
||||
struct snd_soc_card *card = NULL;
|
||||
int idx = mi2s_get_port_idx(kcontrol);
|
||||
|
||||
component = snd_soc_kcontrol_component(kcontrol);
|
||||
card = kcontrol->private_data;
|
||||
pdata = snd_soc_card_get_drvdata(card);
|
||||
|
||||
if (idx < 0)
|
||||
return idx;
|
||||
|
||||
mi2s_rx_cfg[idx].bit_format =
|
||||
mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]);
|
||||
/* check for PRIM_MI2S and CSRAx config to allow 24bit BE config only */
|
||||
if ((PRIM_MI2S == idx) && (true==pdata->codec_is_csra))
|
||||
{
|
||||
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",
|
||||
__func__, idx, mi2s_rx_cfg[idx].bit_format,
|
||||
ucontrol->value.enumerated.item[0]);
|
||||
} else {
|
||||
mi2s_rx_cfg[idx].bit_format =
|
||||
mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]);
|
||||
|
||||
pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
|
||||
idx, mi2s_rx_cfg[idx].bit_format,
|
||||
ucontrol->value.enumerated.item[0]);
|
||||
pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
|
||||
idx, mi2s_rx_cfg[idx].bit_format,
|
||||
ucontrol->value.enumerated.item[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3512,6 +3566,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
|
||||
SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate,
|
||||
aux_pcm_tx_sample_rate_get,
|
||||
aux_pcm_tx_sample_rate_put),
|
||||
SOC_ENUM_EXT("SEN_AUX_PCM_TX SampleRate", sen_aux_pcm_tx_sample_rate,
|
||||
aux_pcm_tx_sample_rate_get,
|
||||
aux_pcm_tx_sample_rate_put),
|
||||
SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate,
|
||||
mi2s_rx_sample_rate_get,
|
||||
mi2s_rx_sample_rate_put),
|
||||
@@ -3527,6 +3584,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
|
||||
SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate,
|
||||
mi2s_rx_sample_rate_get,
|
||||
mi2s_rx_sample_rate_put),
|
||||
SOC_ENUM_EXT("SEN_MI2S_RX SampleRate", sen_mi2s_rx_sample_rate,
|
||||
mi2s_rx_sample_rate_get,
|
||||
mi2s_rx_sample_rate_put),
|
||||
SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate,
|
||||
mi2s_tx_sample_rate_get,
|
||||
mi2s_tx_sample_rate_put),
|
||||
@@ -3542,6 +3602,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
|
||||
SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate,
|
||||
mi2s_tx_sample_rate_get,
|
||||
mi2s_tx_sample_rate_put),
|
||||
SOC_ENUM_EXT("SEN_MI2S_TX SampleRate", sen_mi2s_tx_sample_rate,
|
||||
mi2s_tx_sample_rate_get,
|
||||
mi2s_tx_sample_rate_put),
|
||||
SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs,
|
||||
msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
|
||||
SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs,
|
||||
@@ -3562,6 +3625,10 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
|
||||
msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
|
||||
SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs,
|
||||
msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
|
||||
SOC_ENUM_EXT("SEN_MI2S_RX Channels", sen_mi2s_rx_chs,
|
||||
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_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,
|
||||
@@ -3582,6 +3649,10 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
|
||||
msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
|
||||
SOC_ENUM_EXT("QUIN_MI2S_TX Format", mi2s_tx_format,
|
||||
msm_mi2s_tx_format_get, msm_mi2s_tx_format_put),
|
||||
SOC_ENUM_EXT("SEN_MI2S_RX Format", mi2s_rx_format,
|
||||
msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
|
||||
SOC_ENUM_EXT("SEN_MI2S_TX Format", mi2s_tx_format,
|
||||
msm_mi2s_tx_format_get, msm_mi2s_tx_format_put),
|
||||
SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format,
|
||||
msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
|
||||
SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format,
|
||||
@@ -3602,6 +3673,10 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
|
||||
msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
|
||||
SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format,
|
||||
msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put),
|
||||
SOC_ENUM_EXT("SEN_AUX_PCM_RX Format", aux_pcm_rx_format,
|
||||
msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
|
||||
SOC_ENUM_EXT("SEN_AUX_PCM_TX Format", aux_pcm_tx_format,
|
||||
msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put),
|
||||
SOC_SINGLE_MULTI_EXT("VAD CFG", SND_SOC_NOPM, 0, 1000, 0, 3, NULL,
|
||||
msm_snd_vad_cfg_put),
|
||||
SOC_ENUM_EXT("PRIM_SPDIF_RX SampleRate", spdif_rx_sample_rate,
|
||||
@@ -4132,7 +4207,6 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
||||
rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate;
|
||||
break;
|
||||
|
||||
|
||||
case MSM_BACKEND_DAI_AUXPCM_RX:
|
||||
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
|
||||
aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format);
|
||||
@@ -4223,6 +4297,24 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
||||
aux_pcm_tx_cfg[QUIN_AUX_PCM].channels;
|
||||
break;
|
||||
|
||||
case MSM_BACKEND_DAI_SEN_AUXPCM_RX:
|
||||
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
|
||||
aux_pcm_rx_cfg[SEN_AUX_PCM].bit_format);
|
||||
rate->min = rate->max =
|
||||
aux_pcm_rx_cfg[SEN_AUX_PCM].sample_rate;
|
||||
channels->min = channels->max =
|
||||
aux_pcm_rx_cfg[SEN_AUX_PCM].channels;
|
||||
break;
|
||||
|
||||
case MSM_BACKEND_DAI_SEN_AUXPCM_TX:
|
||||
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
|
||||
aux_pcm_tx_cfg[SEN_AUX_PCM].bit_format);
|
||||
rate->min = rate->max =
|
||||
aux_pcm_tx_cfg[SEN_AUX_PCM].sample_rate;
|
||||
channels->min = channels->max =
|
||||
aux_pcm_tx_cfg[SEN_AUX_PCM].channels;
|
||||
break;
|
||||
|
||||
case MSM_BACKEND_DAI_PRI_MI2S_RX:
|
||||
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
|
||||
mi2s_rx_cfg[PRIM_MI2S].bit_format);
|
||||
@@ -4303,6 +4395,21 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
||||
mi2s_tx_cfg[QUIN_MI2S].channels;
|
||||
break;
|
||||
|
||||
case MSM_BACKEND_DAI_SENARY_MI2S_RX:
|
||||
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
|
||||
mi2s_rx_cfg[SEN_MI2S].bit_format);
|
||||
rate->min = rate->max = mi2s_rx_cfg[SEN_MI2S].sample_rate;
|
||||
channels->min = channels->max =
|
||||
mi2s_rx_cfg[SEN_MI2S].channels;
|
||||
break;
|
||||
|
||||
case MSM_BACKEND_DAI_SENARY_MI2S_TX:
|
||||
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
|
||||
mi2s_tx_cfg[SEN_MI2S].bit_format);
|
||||
rate->min = rate->max = mi2s_tx_cfg[SEN_MI2S].sample_rate;
|
||||
channels->min = channels->max =
|
||||
mi2s_tx_cfg[SEN_MI2S].channels;
|
||||
break;
|
||||
case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0:
|
||||
case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1:
|
||||
idx = msm_cdc_dma_get_idx_from_beid(dai_link->id);
|
||||
@@ -4984,6 +5091,12 @@ static int msm_get_port_id(int be_id)
|
||||
case MSM_BACKEND_DAI_QUINARY_MI2S_TX:
|
||||
afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
|
||||
break;
|
||||
case MSM_BACKEND_DAI_SENARY_MI2S_RX:
|
||||
afe_port_id = AFE_PORT_ID_SENARY_MI2S_RX;
|
||||
break;
|
||||
case MSM_BACKEND_DAI_SENARY_MI2S_TX:
|
||||
afe_port_id = AFE_PORT_ID_SENARY_MI2S_TX;
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: Invalid BE id: %d\n", __func__, be_id);
|
||||
afe_port_id = -EINVAL;
|
||||
@@ -5150,7 +5263,6 @@ static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
||||
case AFE_PORT_ID_QUINARY_TDM_TX:
|
||||
channels = tdm_tx_cfg[TDM_QUIN][TDM_0].channels;
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("%s: dai id 0x%x not supported\n",
|
||||
__func__, cpu_dai->id);
|
||||
@@ -5365,11 +5477,13 @@ static struct snd_soc_ops msm_fe_qos_ops = {
|
||||
.prepare = msm_fe_qos_prepare,
|
||||
};
|
||||
|
||||
|
||||
static int msm_mi2s_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;
|
||||
|
||||
int index = cpu_dai->id;
|
||||
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
@@ -5485,11 +5599,11 @@ static int msm_spdif_set_clk(struct snd_pcm_substream *substream, bool enable)
|
||||
break;
|
||||
case AFE_PORT_ID_PRIMARY_SPDIF_TX:
|
||||
clk_cfg.clk_id = AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE;
|
||||
clk_cfg.clk_freq_in_hz = SPDIF_TX_CORE_CLK_204_P8_MHZ;
|
||||
clk_cfg.clk_freq_in_hz = SPDIF_TX_CORE_CLK_163_P84_MHZ;
|
||||
break;
|
||||
case AFE_PORT_ID_SECONDARY_SPDIF_TX:
|
||||
clk_cfg.clk_id = AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE;
|
||||
clk_cfg.clk_freq_in_hz = SPDIF_TX_CORE_CLK_204_P8_MHZ;
|
||||
clk_cfg.clk_freq_in_hz = SPDIF_TX_CORE_CLK_163_P84_MHZ;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -8323,10 +8437,13 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
||||
val = 0;
|
||||
}
|
||||
if (val) {
|
||||
pdata->codec_is_csra = true;
|
||||
mi2s_rx_cfg[PRIM_MI2S].bit_format = SNDRV_PCM_FORMAT_S24_LE;
|
||||
ret = msm_init_csra_dev(pdev, card);
|
||||
if (ret)
|
||||
goto err;
|
||||
} else {
|
||||
pdata->codec_is_csra = false;
|
||||
ret = msm_init_wsa_dev(pdev, card);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
580
dsp/q6adm.c
580
dsp/q6adm.c
@@ -23,6 +23,7 @@
|
||||
#include <dsp/q6adm-v2.h>
|
||||
#include <dsp/q6audio-v2.h>
|
||||
#include <dsp/q6afe-v2.h>
|
||||
#include <dsp/q6core.h>
|
||||
#include <dsp/audio_cal_utils.h>
|
||||
#include <dsp/q6common.h>
|
||||
#include <ipc/apr.h>
|
||||
@@ -104,24 +105,32 @@ struct adm_ctl {
|
||||
int num_ec_ref_rx_chans;
|
||||
int ec_ref_rx_bit_width;
|
||||
int ec_ref_rx_sampling_rate;
|
||||
|
||||
int native_mode;
|
||||
};
|
||||
|
||||
static struct adm_ctl this_adm;
|
||||
|
||||
struct adm_multi_ch_map {
|
||||
bool set_channel_map;
|
||||
char channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL];
|
||||
char channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL_V8];
|
||||
};
|
||||
|
||||
#define ADM_MCH_MAP_IDX_PLAYBACK 0
|
||||
#define ADM_MCH_MAP_IDX_REC 1
|
||||
static struct adm_multi_ch_map multi_ch_maps[2] = {
|
||||
{ false,
|
||||
{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
},
|
||||
{ false,
|
||||
{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
}
|
||||
{ false,
|
||||
{0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0}
|
||||
},
|
||||
{ false,
|
||||
{0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0}
|
||||
}
|
||||
};
|
||||
|
||||
static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH];
|
||||
@@ -1303,7 +1312,7 @@ int adm_set_multi_ch_map(char *channel_map, int path)
|
||||
}
|
||||
|
||||
memcpy(multi_ch_maps[idx].channel_mapping, channel_map,
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL);
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL_V8);
|
||||
multi_ch_maps[idx].set_channel_map = true;
|
||||
|
||||
return 0;
|
||||
@@ -1334,7 +1343,7 @@ int adm_get_multi_ch_map(char *channel_map, int path)
|
||||
|
||||
if (multi_ch_maps[idx].set_channel_map) {
|
||||
memcpy(channel_map, multi_ch_maps[idx].channel_mapping,
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL);
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL_V8);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1581,6 +1590,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
|
||||
case ADM_CMD_DEVICE_OPEN_V5:
|
||||
case ADM_CMD_DEVICE_CLOSE_V5:
|
||||
case ADM_CMD_DEVICE_OPEN_V6:
|
||||
case ADM_CMD_DEVICE_OPEN_V8:
|
||||
pr_debug("%s: Basic callback received, wake up.\n",
|
||||
__func__);
|
||||
atomic_set(&this_adm.copp.stat[port_idx]
|
||||
@@ -1680,7 +1690,8 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
|
||||
|
||||
switch (data->opcode) {
|
||||
case ADM_CMDRSP_DEVICE_OPEN_V5:
|
||||
case ADM_CMDRSP_DEVICE_OPEN_V6: {
|
||||
case ADM_CMDRSP_DEVICE_OPEN_V6:
|
||||
case ADM_CMDRSP_DEVICE_OPEN_V8: {
|
||||
struct adm_cmd_rsp_device_open_v5 *open =
|
||||
(struct adm_cmd_rsp_device_open_v5 *)data->payload;
|
||||
|
||||
@@ -2514,6 +2525,225 @@ int adm_arrange_mch_ep2_map(struct adm_cmd_device_open_v6 *open_v6,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int adm_arrange_mch_map_v8(
|
||||
struct adm_device_endpoint_payload *ep_payload,
|
||||
int path,
|
||||
int channel_mode)
|
||||
{
|
||||
int rc = 0, idx;
|
||||
|
||||
memset(ep_payload->dev_channel_mapping,
|
||||
0, PCM_FORMAT_MAX_NUM_CHANNEL_V8);
|
||||
switch (path) {
|
||||
case ADM_PATH_PLAYBACK:
|
||||
idx = ADM_MCH_MAP_IDX_PLAYBACK;
|
||||
break;
|
||||
case ADM_PATH_LIVE_REC:
|
||||
case ADM_PATH_NONLIVE_REC:
|
||||
idx = ADM_MCH_MAP_IDX_REC;
|
||||
break;
|
||||
default:
|
||||
goto non_mch_path;
|
||||
};
|
||||
|
||||
if ((ep_payload->dev_num_channel > 2) &&
|
||||
multi_ch_maps[idx].set_channel_map) {
|
||||
memcpy(ep_payload->dev_channel_mapping,
|
||||
multi_ch_maps[idx].channel_mapping,
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL_V8);
|
||||
} else {
|
||||
if (channel_mode == 1) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC;
|
||||
} else if (channel_mode == 2) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
} else if (channel_mode == 3) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC;
|
||||
} else if (channel_mode == 4) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_RS;
|
||||
} else if (channel_mode == 5) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_RS;
|
||||
} else if (channel_mode == 6) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
|
||||
} else if (channel_mode == 7) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_LFE;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB;
|
||||
ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB;
|
||||
ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_CS;
|
||||
} else if (channel_mode == 8) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
|
||||
ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
|
||||
ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
|
||||
} else if (channel_mode == 10) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB;
|
||||
ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB;
|
||||
ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RS;
|
||||
ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL;
|
||||
ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR;
|
||||
} else if (channel_mode == 12) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB;
|
||||
ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB;
|
||||
ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RS;
|
||||
ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL;
|
||||
ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR;
|
||||
ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_TSL;
|
||||
ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_TSR;
|
||||
} else if (channel_mode == 16) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LB;
|
||||
ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RB;
|
||||
ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RS;
|
||||
ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL;
|
||||
ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR;
|
||||
ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_TSL;
|
||||
ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_TSR;
|
||||
ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC;
|
||||
ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC;
|
||||
ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC;
|
||||
ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC;
|
||||
} else {
|
||||
pr_err("%s: invalid num_chan %d\n", __func__,
|
||||
channel_mode);
|
||||
rc = -EINVAL;
|
||||
goto inval_ch_mod;
|
||||
}
|
||||
}
|
||||
|
||||
non_mch_path:
|
||||
inval_ch_mod:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int adm_arrange_mch_ep2_map_v8(
|
||||
struct adm_device_endpoint_payload *ep_payload,
|
||||
int channel_mode)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
memset(ep_payload->dev_channel_mapping, 0,
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL_V8);
|
||||
|
||||
if (channel_mode == 1) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC;
|
||||
} else if (channel_mode == 2) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
} else if (channel_mode == 3) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC;
|
||||
} else if (channel_mode == 4) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_RS;
|
||||
} else if (channel_mode == 5) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_RS;
|
||||
} else if (channel_mode == 6) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
|
||||
} else if (channel_mode == 8) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
|
||||
ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
|
||||
ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
|
||||
} else if (channel_mode == 10) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
|
||||
ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
|
||||
ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
|
||||
ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS;
|
||||
ep_payload->dev_channel_mapping[9] = PCM_CHANNELS;
|
||||
} else if (channel_mode == 12) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
|
||||
ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
|
||||
ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
|
||||
ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_TFL;
|
||||
ep_payload->dev_channel_mapping[9] = PCM_CHANNEL_TFR;
|
||||
ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_TSL;
|
||||
ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_TSR;
|
||||
} else if (channel_mode == 16) {
|
||||
ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
ep_payload->dev_channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
ep_payload->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
|
||||
ep_payload->dev_channel_mapping[3] = PCM_CHANNEL_FC;
|
||||
ep_payload->dev_channel_mapping[4] = PCM_CHANNEL_LS;
|
||||
ep_payload->dev_channel_mapping[5] = PCM_CHANNEL_RS;
|
||||
ep_payload->dev_channel_mapping[6] = PCM_CHANNEL_LB;
|
||||
ep_payload->dev_channel_mapping[7] = PCM_CHANNEL_RB;
|
||||
ep_payload->dev_channel_mapping[8] = PCM_CHANNEL_CS;
|
||||
ep_payload->dev_channel_mapping[9] = PCM_CHANNELS;
|
||||
ep_payload->dev_channel_mapping[10] = PCM_CHANNEL_CVH;
|
||||
ep_payload->dev_channel_mapping[11] = PCM_CHANNEL_MS;
|
||||
ep_payload->dev_channel_mapping[12] = PCM_CHANNEL_FLC;
|
||||
ep_payload->dev_channel_mapping[13] = PCM_CHANNEL_FRC;
|
||||
ep_payload->dev_channel_mapping[14] = PCM_CHANNEL_RLC;
|
||||
ep_payload->dev_channel_mapping[15] = PCM_CHANNEL_RRC;
|
||||
} else {
|
||||
pr_err("%s: invalid num_chan %d\n", __func__,
|
||||
channel_mode);
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
/**
|
||||
* adm_open -
|
||||
* command to send ADM open
|
||||
@@ -2535,10 +2765,17 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
|
||||
{
|
||||
struct adm_cmd_device_open_v5 open;
|
||||
struct adm_cmd_device_open_v6 open_v6;
|
||||
struct adm_cmd_device_open_v8 open_v8;
|
||||
struct adm_device_endpoint_payload ep1_payload;
|
||||
struct adm_device_endpoint_payload ep2_payload;
|
||||
int ep1_payload_size = 0;
|
||||
int ep2_payload_size = 0;
|
||||
int ret = 0;
|
||||
int port_idx, flags;
|
||||
int copp_idx = -1;
|
||||
int tmp_port = q6audio_get_port_id(port_id);
|
||||
void *adm_params = NULL;
|
||||
int param_size;
|
||||
|
||||
pr_debug("%s:port %#x path:%d rate:%d mode:%d perf_mode:%d,topo_id %d\n",
|
||||
__func__, port_id, path, rate, channel_mode, perf_mode,
|
||||
@@ -2550,6 +2787,11 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
|
||||
pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (channel_mode < 0 || channel_mode > 32) {
|
||||
pr_err("%s: Invalid channel number 0x%x\n",
|
||||
__func__, channel_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (this_adm.apr == NULL) {
|
||||
this_adm.apr = apr_register("ADSP", "ADM", adm_callback,
|
||||
@@ -2643,109 +2885,241 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
|
||||
if (atomic_read(&this_adm.copp.cnt[port_idx][copp_idx]) == 0) {
|
||||
pr_debug("%s: open ADM: port_idx: %d, copp_idx: %d\n", __func__,
|
||||
port_idx, copp_idx);
|
||||
if ((topology == SRS_TRUMEDIA_TOPOLOGY_ID) &&
|
||||
perf_mode == LEGACY_PCM_MODE) {
|
||||
int res;
|
||||
if ((topology == SRS_TRUMEDIA_TOPOLOGY_ID) &&
|
||||
perf_mode == LEGACY_PCM_MODE) {
|
||||
int res;
|
||||
|
||||
atomic_set(&this_adm.mem_map_index, ADM_SRS_TRUMEDIA);
|
||||
msm_dts_srs_tm_ion_memmap(&this_adm.outband_memmap);
|
||||
res = adm_memory_map_regions(&this_adm.outband_memmap.paddr, 0,
|
||||
(uint32_t *)&this_adm.outband_memmap.size, 1);
|
||||
if (res < 0) {
|
||||
pr_err("%s: SRS adm_memory_map_regions failed ! addr = 0x%pK, size = %d\n",
|
||||
__func__, (void *)this_adm.outband_memmap.paddr,
|
||||
(uint32_t)this_adm.outband_memmap.size);
|
||||
}
|
||||
}
|
||||
open.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
|
||||
APR_HDR_LEN(APR_HDR_SIZE),
|
||||
APR_PKT_VER);
|
||||
open.hdr.pkt_size = sizeof(open);
|
||||
open.hdr.src_svc = APR_SVC_ADM;
|
||||
open.hdr.src_domain = APR_DOMAIN_APPS;
|
||||
open.hdr.src_port = tmp_port;
|
||||
open.hdr.dest_svc = APR_SVC_ADM;
|
||||
open.hdr.dest_domain = APR_DOMAIN_ADSP;
|
||||
open.hdr.dest_port = tmp_port;
|
||||
open.hdr.token = port_idx << 16 | copp_idx;
|
||||
open.hdr.opcode = ADM_CMD_DEVICE_OPEN_V5;
|
||||
open.flags = flags;
|
||||
open.mode_of_operation = path;
|
||||
open.endpoint_id_1 = tmp_port;
|
||||
open.endpoint_id_2 = 0xFFFF;
|
||||
|
||||
if (this_adm.ec_ref_rx && (path != 1)) {
|
||||
open.endpoint_id_2 = this_adm.ec_ref_rx;
|
||||
this_adm.ec_ref_rx = -1;
|
||||
atomic_set(&this_adm.mem_map_index, ADM_SRS_TRUMEDIA);
|
||||
msm_dts_srs_tm_ion_memmap(&this_adm.outband_memmap);
|
||||
res = adm_memory_map_regions(
|
||||
&this_adm.outband_memmap.paddr, 0,
|
||||
(uint32_t *)&this_adm.outband_memmap.size, 1);
|
||||
if (res < 0) {
|
||||
pr_err("%s: SRS adm_memory_map_regions failed! addr = 0x%pK, size = %d\n",
|
||||
__func__,
|
||||
(void *)this_adm.outband_memmap.paddr,
|
||||
(uint32_t)this_adm.outband_memmap.size);
|
||||
}
|
||||
}
|
||||
|
||||
open.topology_id = topology;
|
||||
|
||||
open.dev_num_channel = channel_mode & 0x00FF;
|
||||
open.bit_width = bit_width;
|
||||
WARN_ON((perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) &&
|
||||
(rate != ULL_SUPPORTED_SAMPLE_RATE));
|
||||
open.sample_rate = rate;
|
||||
if (q6core_get_avcs_api_version_per_service(
|
||||
APRV2_IDS_SERVICE_ID_ADSP_ADM_V) >=
|
||||
ADSP_ADM_API_VERSION_V3) {
|
||||
memset(&open_v8, 0, sizeof(open_v8));
|
||||
memset(&ep1_payload, 0, sizeof(ep1_payload));
|
||||
memset(&ep2_payload, 0, sizeof(ep2_payload));
|
||||
|
||||
ret = adm_arrange_mch_map(&open, path, channel_mode);
|
||||
open_v8.hdr.hdr_field = APR_HDR_FIELD(
|
||||
APR_MSG_TYPE_SEQ_CMD,
|
||||
APR_HDR_LEN(APR_HDR_SIZE),
|
||||
APR_PKT_VER);
|
||||
open_v8.hdr.src_svc = APR_SVC_ADM;
|
||||
open_v8.hdr.src_domain = APR_DOMAIN_APPS;
|
||||
open_v8.hdr.src_port = tmp_port;
|
||||
open_v8.hdr.dest_svc = APR_SVC_ADM;
|
||||
open_v8.hdr.dest_domain = APR_DOMAIN_ADSP;
|
||||
open_v8.hdr.dest_port = tmp_port;
|
||||
open_v8.hdr.token = port_idx << 16 | copp_idx;
|
||||
open_v8.hdr.opcode = ADM_CMD_DEVICE_OPEN_V8;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pr_debug("%s: port_id=0x%x rate=%d topology_id=0x%X\n",
|
||||
__func__, open.endpoint_id_1, open.sample_rate,
|
||||
open.topology_id);
|
||||
|
||||
atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
|
||||
|
||||
if ((this_adm.num_ec_ref_rx_chans != 0) && (path != 1) &&
|
||||
(open.endpoint_id_2 != 0xFFFF)) {
|
||||
memset(&open_v6, 0,
|
||||
sizeof(struct adm_cmd_device_open_v6));
|
||||
memcpy(&open_v6, &open,
|
||||
sizeof(struct adm_cmd_device_open_v5));
|
||||
open_v6.hdr.opcode = ADM_CMD_DEVICE_OPEN_V6;
|
||||
open_v6.hdr.pkt_size = sizeof(open_v6);
|
||||
open_v6.dev_num_channel_eid2 =
|
||||
this_adm.num_ec_ref_rx_chans;
|
||||
this_adm.num_ec_ref_rx_chans = 0;
|
||||
|
||||
if (this_adm.ec_ref_rx_bit_width != 0) {
|
||||
open_v6.bit_width_eid2 =
|
||||
this_adm.ec_ref_rx_bit_width;
|
||||
this_adm.ec_ref_rx_bit_width = 0;
|
||||
if (this_adm.native_mode != 0) {
|
||||
open_v8.flags = flags |
|
||||
(this_adm.native_mode << 11);
|
||||
this_adm.native_mode = 0;
|
||||
} else {
|
||||
open_v6.bit_width_eid2 = bit_width;
|
||||
open_v8.flags = flags;
|
||||
}
|
||||
open_v8.mode_of_operation = path;
|
||||
open_v8.endpoint_id_1 = tmp_port;
|
||||
open_v8.endpoint_id_2 = 0xFFFF;
|
||||
open_v8.endpoint_id_3 = 0xFFFF;
|
||||
|
||||
if (this_adm.ec_ref_rx && (path != 1)) {
|
||||
open_v8.endpoint_id_2 = this_adm.ec_ref_rx;
|
||||
this_adm.ec_ref_rx = -1;
|
||||
}
|
||||
|
||||
if (this_adm.ec_ref_rx_sampling_rate != 0) {
|
||||
open_v6.sample_rate_eid2 =
|
||||
open_v8.topology_id = topology;
|
||||
open_v8.reserved = 0;
|
||||
|
||||
/* variable endpoint payload */
|
||||
ep1_payload.dev_num_channel = channel_mode & 0x00FF;
|
||||
ep1_payload.bit_width = bit_width;
|
||||
ep1_payload.sample_rate = rate;
|
||||
ret = adm_arrange_mch_map_v8(&ep1_payload, path,
|
||||
channel_mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pr_debug("%s: port_id=0x%x %x %x topology_id=0x%X flags %x ref_ch %x\n",
|
||||
__func__, open_v8.endpoint_id_1,
|
||||
open_v8.endpoint_id_2,
|
||||
open_v8.endpoint_id_3,
|
||||
open_v8.topology_id,
|
||||
open_v8.flags,
|
||||
this_adm.num_ec_ref_rx_chans);
|
||||
|
||||
ep1_payload_size = 8 +
|
||||
roundup(ep1_payload.dev_num_channel, 4);
|
||||
param_size = sizeof(struct adm_cmd_device_open_v8)
|
||||
+ ep1_payload_size;
|
||||
atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
|
||||
|
||||
if ((this_adm.num_ec_ref_rx_chans != 0) && (path != 1)
|
||||
&& (open_v8.endpoint_id_2 != 0xFFFF)) {
|
||||
ep2_payload.dev_num_channel =
|
||||
this_adm.num_ec_ref_rx_chans;
|
||||
this_adm.num_ec_ref_rx_chans = 0;
|
||||
|
||||
if (this_adm.ec_ref_rx_bit_width != 0) {
|
||||
ep2_payload.bit_width =
|
||||
this_adm.ec_ref_rx_bit_width;
|
||||
this_adm.ec_ref_rx_bit_width = 0;
|
||||
} else {
|
||||
ep2_payload.bit_width = bit_width;
|
||||
}
|
||||
|
||||
if (this_adm.ec_ref_rx_sampling_rate != 0) {
|
||||
ep2_payload.sample_rate =
|
||||
this_adm.ec_ref_rx_sampling_rate;
|
||||
this_adm.ec_ref_rx_sampling_rate = 0;
|
||||
} else {
|
||||
open_v6.sample_rate_eid2 = rate;
|
||||
this_adm.ec_ref_rx_sampling_rate = 0;
|
||||
} else {
|
||||
ep2_payload.sample_rate = rate;
|
||||
}
|
||||
|
||||
pr_debug("%s: adm open_v8 eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n",
|
||||
__func__,
|
||||
ep2_payload.dev_num_channel,
|
||||
ep2_payload.bit_width,
|
||||
ep2_payload.sample_rate);
|
||||
|
||||
ret = adm_arrange_mch_ep2_map_v8(&ep2_payload,
|
||||
ep2_payload.dev_num_channel);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
ep2_payload_size = 8 +
|
||||
roundup(ep2_payload.dev_num_channel, 4);
|
||||
param_size += ep2_payload_size;
|
||||
}
|
||||
|
||||
pr_debug("%s: eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n",
|
||||
__func__, open_v6.dev_num_channel_eid2,
|
||||
open_v6.bit_width_eid2,
|
||||
open_v6.sample_rate_eid2);
|
||||
adm_params = kzalloc(param_size, GFP_KERNEL);
|
||||
if (!adm_params)
|
||||
return -ENOMEM;
|
||||
open_v8.hdr.pkt_size = param_size;
|
||||
memcpy(adm_params, &open_v8, sizeof(open_v8));
|
||||
memcpy(adm_params + sizeof(open_v8),
|
||||
(void *)&ep1_payload,
|
||||
ep1_payload_size);
|
||||
memcpy(adm_params + sizeof(open_v8)
|
||||
+ ep1_payload_size,
|
||||
(void *)&ep2_payload,
|
||||
ep2_payload_size);
|
||||
|
||||
ret = adm_arrange_mch_ep2_map(&open_v6,
|
||||
open_v6.dev_num_channel_eid2);
|
||||
ret = apr_send_pkt(this_adm.apr,
|
||||
(uint32_t *)adm_params);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: port_id: 0x%x for[0x%x] failed %d for open_v8\n",
|
||||
__func__, tmp_port, port_id, ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
kfree(adm_params);
|
||||
} else {
|
||||
|
||||
open.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
|
||||
APR_HDR_LEN(APR_HDR_SIZE),
|
||||
APR_PKT_VER);
|
||||
open.hdr.pkt_size = sizeof(open);
|
||||
open.hdr.src_svc = APR_SVC_ADM;
|
||||
open.hdr.src_domain = APR_DOMAIN_APPS;
|
||||
open.hdr.src_port = tmp_port;
|
||||
open.hdr.dest_svc = APR_SVC_ADM;
|
||||
open.hdr.dest_domain = APR_DOMAIN_ADSP;
|
||||
open.hdr.dest_port = tmp_port;
|
||||
open.hdr.token = port_idx << 16 | copp_idx;
|
||||
open.hdr.opcode = ADM_CMD_DEVICE_OPEN_V5;
|
||||
open.flags = flags;
|
||||
open.mode_of_operation = path;
|
||||
open.endpoint_id_1 = tmp_port;
|
||||
open.endpoint_id_2 = 0xFFFF;
|
||||
|
||||
if (this_adm.ec_ref_rx && (path != 1)) {
|
||||
open.endpoint_id_2 = this_adm.ec_ref_rx;
|
||||
this_adm.ec_ref_rx = -1;
|
||||
}
|
||||
|
||||
open.topology_id = topology;
|
||||
|
||||
open.dev_num_channel = channel_mode & 0x00FF;
|
||||
open.bit_width = bit_width;
|
||||
WARN_ON((perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) &&
|
||||
(rate != ULL_SUPPORTED_SAMPLE_RATE));
|
||||
open.sample_rate = rate;
|
||||
|
||||
ret = adm_arrange_mch_map(&open, path, channel_mode);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = apr_send_pkt(this_adm.apr, (uint32_t *)&open_v6);
|
||||
} else {
|
||||
ret = apr_send_pkt(this_adm.apr, (uint32_t *)&open);
|
||||
}
|
||||
if (ret < 0) {
|
||||
pr_err("%s: port_id: 0x%x for[0x%x] failed %d\n",
|
||||
__func__, tmp_port, port_id, ret);
|
||||
return -EINVAL;
|
||||
pr_debug("%s: port_id=0x%x rate=%d topology_id=0x%X\n",
|
||||
__func__, open.endpoint_id_1, open.sample_rate,
|
||||
open.topology_id);
|
||||
|
||||
atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
|
||||
|
||||
if ((this_adm.num_ec_ref_rx_chans != 0) &&
|
||||
(path != 1) && (open.endpoint_id_2 != 0xFFFF)) {
|
||||
memset(&open_v6, 0,
|
||||
sizeof(struct adm_cmd_device_open_v6));
|
||||
memcpy(&open_v6, &open,
|
||||
sizeof(struct adm_cmd_device_open_v5));
|
||||
open_v6.hdr.opcode = ADM_CMD_DEVICE_OPEN_V6;
|
||||
open_v6.hdr.pkt_size = sizeof(open_v6);
|
||||
open_v6.dev_num_channel_eid2 =
|
||||
this_adm.num_ec_ref_rx_chans;
|
||||
this_adm.num_ec_ref_rx_chans = 0;
|
||||
|
||||
if (this_adm.ec_ref_rx_bit_width != 0) {
|
||||
open_v6.bit_width_eid2 =
|
||||
this_adm.ec_ref_rx_bit_width;
|
||||
this_adm.ec_ref_rx_bit_width = 0;
|
||||
} else {
|
||||
open_v6.bit_width_eid2 = bit_width;
|
||||
}
|
||||
|
||||
if (this_adm.ec_ref_rx_sampling_rate != 0) {
|
||||
open_v6.sample_rate_eid2 =
|
||||
this_adm.ec_ref_rx_sampling_rate;
|
||||
this_adm.ec_ref_rx_sampling_rate = 0;
|
||||
} else {
|
||||
open_v6.sample_rate_eid2 = rate;
|
||||
}
|
||||
|
||||
pr_debug("%s: eid2_channels=%d eid2_bit_width=%d eid2_rate=%d\n",
|
||||
__func__, open_v6.dev_num_channel_eid2,
|
||||
open_v6.bit_width_eid2,
|
||||
open_v6.sample_rate_eid2);
|
||||
|
||||
ret = adm_arrange_mch_ep2_map(&open_v6,
|
||||
open_v6.dev_num_channel_eid2);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = apr_send_pkt(this_adm.apr,
|
||||
(uint32_t *)&open_v6);
|
||||
} else {
|
||||
ret = apr_send_pkt(this_adm.apr,
|
||||
(uint32_t *)&open);
|
||||
}
|
||||
if (ret < 0) {
|
||||
pr_err("%s: port_id: 0x%x for[0x%x] failed %d\n",
|
||||
__func__, tmp_port, port_id, ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the callback with copp id */
|
||||
ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
|
||||
atomic_read(&this_adm.copp.stat
|
||||
@@ -3080,6 +3454,22 @@ void adm_ec_ref_rx_sampling_rate(int sampling_rate)
|
||||
}
|
||||
EXPORT_SYMBOL(adm_ec_ref_rx_sampling_rate);
|
||||
|
||||
/**
|
||||
* adm_set_native_mode -
|
||||
* Set adm channel native mode.
|
||||
* If enabled matrix mixer will be
|
||||
* running in native mode for channel
|
||||
* configuration for this device session.
|
||||
*
|
||||
*/
|
||||
void adm_set_native_mode(int mode)
|
||||
{
|
||||
this_adm.native_mode = mode;
|
||||
pr_debug("%s: enable native_mode :%d\n",
|
||||
__func__, this_adm.native_mode);
|
||||
}
|
||||
EXPORT_SYMBOL(adm_set_native_mode);
|
||||
|
||||
/**
|
||||
* adm_close -
|
||||
* command to close ADM copp
|
||||
|
143
dsp/q6afe.c
143
dsp/q6afe.c
@@ -110,12 +110,9 @@ struct afe_ctl {
|
||||
uint32_t token, uint32_t *payload, void *priv);
|
||||
void *pri_spdif_tx_private_data;
|
||||
void *sec_spdif_tx_private_data;
|
||||
struct afe_port_mod_evt_rsp_hdr pri_spdif_evt_pl;
|
||||
struct afe_event_fmt_update pri_spdif_fmt_event;
|
||||
struct afe_port_mod_evt_rsp_hdr sec_spdif_evt_pl;
|
||||
struct afe_event_fmt_update sec_spdif_fmt_event;
|
||||
struct work_struct afe_pri_spdif_work;
|
||||
struct work_struct afe_sec_spdif_work;
|
||||
int pri_spdif_config_change;
|
||||
int sec_spdif_config_change;
|
||||
struct work_struct afe_spdif_work;
|
||||
|
||||
int topology[AFE_MAX_PORTS];
|
||||
struct cal_type_data *cal_data[MAX_AFE_CAL_TYPES];
|
||||
@@ -387,107 +384,26 @@ static int afe_aud_event_notify(struct notifier_block *self,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *const afe_event_port_text[] = {
|
||||
"PORT=Primary",
|
||||
"PORT=Secondary",
|
||||
};
|
||||
|
||||
static const char * const afe_event_state_text[] = {
|
||||
"STATE=Inactive",
|
||||
"STATE=Active",
|
||||
"STATE=EOS",
|
||||
};
|
||||
|
||||
static const char *const afe_event_rate_text[] = {
|
||||
"RATE=32000",
|
||||
"RATE=44100",
|
||||
"RATE=48000",
|
||||
"RATE=88200",
|
||||
"RATE=96000",
|
||||
"RATE=176400",
|
||||
"RATE=192000",
|
||||
};
|
||||
|
||||
static const char *const afe_event_format_text[] = {
|
||||
"FORMAT=LPCM",
|
||||
"FORMAT=Compr",
|
||||
};
|
||||
|
||||
static void afe_notify_spdif_fmt_update_common(void *payload)
|
||||
static void afe_notify_spdif_fmt_update_work_fn(struct work_struct *work)
|
||||
{
|
||||
int ret = 0;
|
||||
char *env[6];
|
||||
struct afe_port_mod_evt_rsp_hdr *evt_pl;
|
||||
struct afe_event_fmt_update *fmt_event;
|
||||
char event_pri[] = "PRI_SPDIF_TX=MEDIA_CONFIG_CHANGE";
|
||||
char event_sec[] = "SEC_SPDIF_TX=MEDIA_CONFIG_CHANGE";
|
||||
|
||||
evt_pl = (struct afe_port_mod_evt_rsp_hdr *)payload;
|
||||
fmt_event = (struct afe_event_fmt_update *)
|
||||
(payload + sizeof(struct afe_port_mod_evt_rsp_hdr));
|
||||
|
||||
env[0] = "SPDIF_FMT_UPDATE=TRUE";
|
||||
if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX)
|
||||
env[1] = (char *)afe_event_port_text[0];
|
||||
else
|
||||
env[1] = (char *)afe_event_port_text[1];
|
||||
|
||||
switch (fmt_event->status) {
|
||||
case AFE_PORT_STATUS_AUDIO_ACTIVE:
|
||||
env[2] = (char *)afe_event_state_text[1];
|
||||
break;
|
||||
case AFE_PORT_STATUS_AUDIO_EOS:
|
||||
env[2] = (char *)afe_event_state_text[2];
|
||||
break;
|
||||
default:
|
||||
env[2] = (char *)afe_event_state_text[0];
|
||||
if (this_afe.pri_spdif_config_change) {
|
||||
this_afe.pri_spdif_config_change = 0;
|
||||
ret = q6core_send_uevent(this_afe.uevent_data, event_pri);
|
||||
if (ret)
|
||||
pr_err("%s: Send UEvent %s failed :%d\n",
|
||||
__func__, event_pri, ret);
|
||||
}
|
||||
|
||||
switch (fmt_event->sample_rate) {
|
||||
case 32000:
|
||||
env[3] = (char *)afe_event_rate_text[0];
|
||||
break;
|
||||
case 44100:
|
||||
env[3] = (char *)afe_event_rate_text[1];
|
||||
break;
|
||||
case 48000:
|
||||
env[3] = (char *)afe_event_rate_text[2];
|
||||
break;
|
||||
case 88200:
|
||||
env[3] = (char *)afe_event_rate_text[3];
|
||||
break;
|
||||
case 96000:
|
||||
env[3] = (char *)afe_event_rate_text[4];
|
||||
break;
|
||||
case 176400:
|
||||
env[3] = (char *)afe_event_rate_text[5];
|
||||
break;
|
||||
case 192000:
|
||||
env[3] = (char *)afe_event_rate_text[6];
|
||||
break;
|
||||
default:
|
||||
env[3] = (char *)afe_event_rate_text[2];
|
||||
if (this_afe.sec_spdif_config_change) {
|
||||
this_afe.sec_spdif_config_change = 0;
|
||||
ret = q6core_send_uevent(this_afe.uevent_data, event_sec);
|
||||
if (ret)
|
||||
pr_err("%s: Send UEvent %s failed :%d\n",
|
||||
__func__, event_sec, ret);
|
||||
}
|
||||
|
||||
if (fmt_event->data_format == AFE_NON_LINEAR_DATA)
|
||||
env[4] = (char *)afe_event_format_text[1];
|
||||
else
|
||||
env[4] = (char *)afe_event_format_text[0];
|
||||
|
||||
env[5] = NULL;
|
||||
|
||||
ret = q6core_send_uevent_env(this_afe.uevent_data, env);
|
||||
if (ret)
|
||||
pr_err("%s: Send UEvent %s failed: %d\n", __func__,
|
||||
env[0], ret);
|
||||
}
|
||||
|
||||
static void afe_notify_pri_spdif_fmt_update_work_fn(struct work_struct *work)
|
||||
{
|
||||
afe_notify_spdif_fmt_update_common(&this_afe.pri_spdif_evt_pl);
|
||||
}
|
||||
|
||||
static void afe_notify_sec_spdif_fmt_update_work_fn(struct work_struct *work)
|
||||
{
|
||||
afe_notify_spdif_fmt_update_common(&this_afe.sec_spdif_evt_pl);
|
||||
}
|
||||
|
||||
static void afe_notify_spdif_fmt_update(void *payload)
|
||||
@@ -495,17 +411,12 @@ static void afe_notify_spdif_fmt_update(void *payload)
|
||||
struct afe_port_mod_evt_rsp_hdr *evt_pl;
|
||||
|
||||
evt_pl = (struct afe_port_mod_evt_rsp_hdr *)payload;
|
||||
if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) {
|
||||
memcpy(&this_afe.pri_spdif_evt_pl, payload,
|
||||
sizeof(struct afe_port_mod_evt_rsp_hdr) +
|
||||
sizeof(struct afe_event_fmt_update));
|
||||
schedule_work(&this_afe.afe_pri_spdif_work);
|
||||
} else {
|
||||
memcpy(&this_afe.sec_spdif_evt_pl, payload,
|
||||
sizeof(struct afe_port_mod_evt_rsp_hdr) +
|
||||
sizeof(struct afe_event_fmt_update));
|
||||
schedule_work(&this_afe.afe_sec_spdif_work);
|
||||
}
|
||||
if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX)
|
||||
this_afe.pri_spdif_config_change = 1;
|
||||
else
|
||||
this_afe.sec_spdif_config_change = 1;
|
||||
|
||||
schedule_work(&this_afe.afe_spdif_work);
|
||||
}
|
||||
|
||||
static int32_t afe_callback(struct apr_client_data *data, void *priv)
|
||||
@@ -8163,10 +8074,8 @@ int __init afe_init(void)
|
||||
q6core_init_uevent_data(this_afe.uevent_data, "q6afe_uevent");
|
||||
|
||||
INIT_WORK(&this_afe.afe_dc_work, afe_notify_dc_presence_work_fn);
|
||||
INIT_WORK(&this_afe.afe_pri_spdif_work,
|
||||
afe_notify_pri_spdif_fmt_update_work_fn);
|
||||
INIT_WORK(&this_afe.afe_sec_spdif_work,
|
||||
afe_notify_sec_spdif_fmt_update_work_fn);
|
||||
INIT_WORK(&this_afe.afe_spdif_work,
|
||||
afe_notify_spdif_fmt_update_work_fn);
|
||||
|
||||
this_afe.event_notifier.notifier_call = afe_aud_event_notify;
|
||||
msm_aud_evt_blocking_register_client(&this_afe.event_notifier);
|
||||
|
472
dsp/q6asm.c
472
dsp/q6asm.c
@@ -40,6 +40,7 @@
|
||||
#include <dsp/q6asm-v2.h>
|
||||
#include <dsp/q6audio-v2.h>
|
||||
#include <dsp/q6common.h>
|
||||
#include <dsp/q6core.h>
|
||||
#include "adsp_err.h"
|
||||
|
||||
#define TRUE 0x01
|
||||
@@ -228,6 +229,9 @@ static inline uint32_t q6asm_get_pcm_format_id(uint32_t media_format_block_ver)
|
||||
uint32_t pcm_format_id;
|
||||
|
||||
switch (media_format_block_ver) {
|
||||
case PCM_MEDIA_FORMAT_V5:
|
||||
pcm_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V5;
|
||||
break;
|
||||
case PCM_MEDIA_FORMAT_V4:
|
||||
pcm_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4;
|
||||
break;
|
||||
@@ -3144,6 +3148,25 @@ int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_open_read_v4);
|
||||
|
||||
|
||||
/*
|
||||
* asm_open_read_v5 - Opens audio capture session
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @format: encoder format
|
||||
* @bits_per_sample: bit width of capture session
|
||||
* @ts_mode: timestamp mode
|
||||
*/
|
||||
int q6asm_open_read_v5(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, bool ts_mode, uint32_t enc_cfg_id)
|
||||
{
|
||||
return __q6asm_open_read(ac, format, bits_per_sample,
|
||||
PCM_MEDIA_FORMAT_V5 /*media fmt block ver*/,
|
||||
ts_mode, enc_cfg_id);
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_open_read_v5);
|
||||
|
||||
|
||||
/**
|
||||
* q6asm_open_write_compressed -
|
||||
* command to open ASM in compressed write mode
|
||||
@@ -3491,6 +3514,23 @@ int q6asm_stream_open_write_v3(struct audio_client *ac, uint32_t format,
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_stream_open_write_v3);
|
||||
|
||||
/*
|
||||
* q6asm_open_write_v5 - Opens audio playback session
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @format: decoder format
|
||||
* @bits_per_sample: bit width of playback session
|
||||
*/
|
||||
int q6asm_open_write_v5(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample)
|
||||
{
|
||||
return __q6asm_open_write(ac, format, bits_per_sample,
|
||||
ac->stream_id, false /*gapless*/,
|
||||
PCM_MEDIA_FORMAT_V5 /*pcm_format_block_ver*/);
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_open_write_v5);
|
||||
|
||||
|
||||
/*
|
||||
* q6asm_stream_open_write_v4 - Creates audio stream for playback
|
||||
*
|
||||
@@ -3510,6 +3550,26 @@ int q6asm_stream_open_write_v4(struct audio_client *ac, uint32_t format,
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_stream_open_write_v4);
|
||||
|
||||
/*
|
||||
* q6asm_stream_open_write_v5 - Creates audio stream for playback
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @format: asm playback format
|
||||
* @bits_per_sample: bit width of requested stream
|
||||
* @stream_id: stream id of stream to be associated with this session
|
||||
* @is_gapless_mode: true if gapless mode needs to be enabled
|
||||
*/
|
||||
int q6asm_stream_open_write_v5(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, int32_t stream_id,
|
||||
bool is_gapless_mode)
|
||||
{
|
||||
return __q6asm_open_write(ac, format, bits_per_sample,
|
||||
stream_id, is_gapless_mode,
|
||||
PCM_MEDIA_FORMAT_V5 /*pcm_format_block_ver*/);
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_stream_open_write_v5);
|
||||
|
||||
|
||||
static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format,
|
||||
uint32_t wr_format, bool is_meta_data_mode,
|
||||
uint32_t bits_per_sample,
|
||||
@@ -4747,6 +4807,108 @@ fail_cmd:
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_set_encdec_chan_map);
|
||||
|
||||
/*
|
||||
* q6asm_enc_cfg_blk_pcm_v5 - sends encoder configuration parameters
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @rate: sample rate
|
||||
* @channels: number of channels
|
||||
* @bits_per_sample: bit width of encoder session
|
||||
* @use_default_chmap: true if default channel map to be used
|
||||
* @use_back_flavor: to configure back left and right channel
|
||||
* @channel_map: input channel map
|
||||
* @sample_word_size: Size in bits of the word that holds a sample of a channel
|
||||
* @endianness: endianness of the pcm data
|
||||
* @mode: Mode to provide additional info about the pcm input data
|
||||
*/
|
||||
static int q6asm_enc_cfg_blk_pcm_v5(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample, bool use_default_chmap,
|
||||
bool use_back_flavor, u8 *channel_map,
|
||||
uint16_t sample_word_size, uint16_t endianness,
|
||||
uint16_t mode)
|
||||
{
|
||||
struct asm_multi_channel_pcm_enc_cfg_v5 enc_cfg;
|
||||
struct asm_enc_cfg_blk_param_v2 enc_fg_blk;
|
||||
u8 *channel_mapping;
|
||||
u32 frames_per_buf = 0;
|
||||
int rc;
|
||||
|
||||
if (!use_default_chmap && (channel_map == NULL)) {
|
||||
pr_err("%s: No valid chan map and can't use default\n",
|
||||
__func__);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd;
|
||||
}
|
||||
|
||||
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
|
||||
ac->session, rate, channels,
|
||||
bits_per_sample, sample_word_size);
|
||||
|
||||
memset(&enc_cfg, 0, sizeof(enc_cfg));
|
||||
q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
|
||||
atomic_set(&ac->cmd_state, -1);
|
||||
enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
|
||||
enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2;
|
||||
enc_cfg.encdec.param_size = sizeof(enc_cfg) - sizeof(enc_cfg.hdr) -
|
||||
sizeof(enc_cfg.encdec);
|
||||
enc_cfg.encblk.frames_per_buf = frames_per_buf;
|
||||
enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size -
|
||||
sizeof(enc_fg_blk);
|
||||
enc_cfg.num_channels = channels;
|
||||
enc_cfg.bits_per_sample = bits_per_sample;
|
||||
enc_cfg.sample_rate = rate;
|
||||
enc_cfg.is_signed = 1;
|
||||
enc_cfg.sample_word_size = sample_word_size;
|
||||
enc_cfg.endianness = endianness;
|
||||
enc_cfg.mode = mode;
|
||||
channel_mapping = enc_cfg.channel_mapping;
|
||||
|
||||
memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8);
|
||||
|
||||
if (use_default_chmap) {
|
||||
pr_debug("%s: setting default channel map for %d channels",
|
||||
__func__, channels);
|
||||
if (q6asm_map_channels(channel_mapping, channels,
|
||||
use_back_flavor)) {
|
||||
pr_err("%s: map channels failed %d\n",
|
||||
__func__, channels);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd;
|
||||
}
|
||||
} else {
|
||||
pr_debug("%s: Using pre-defined channel map", __func__);
|
||||
memcpy(channel_mapping, channel_map,
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL_V8);
|
||||
}
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: Command open failed %d\n", __func__, rc);
|
||||
goto fail_cmd;
|
||||
}
|
||||
rc = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state) >= 0), 5*HZ);
|
||||
if (!rc) {
|
||||
pr_err("%s: timeout opcode[0x%x]\n",
|
||||
__func__, enc_cfg.hdr.opcode);
|
||||
rc = -ETIMEDOUT;
|
||||
goto fail_cmd;
|
||||
}
|
||||
if (atomic_read(&ac->cmd_state) > 0) {
|
||||
pr_err("%s: DSP returned error[%s]\n",
|
||||
__func__, adsp_err_get_err_str(
|
||||
atomic_read(&ac->cmd_state)));
|
||||
rc = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&ac->cmd_state));
|
||||
goto fail_cmd;
|
||||
}
|
||||
return 0;
|
||||
fail_cmd:
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_v5);
|
||||
|
||||
/*
|
||||
* q6asm_enc_cfg_blk_pcm_v4 - sends encoder configuration parameters
|
||||
*
|
||||
@@ -5040,6 +5202,18 @@ fail_cmd:
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_v2);
|
||||
|
||||
static int __q6asm_enc_cfg_blk_pcm_v5(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size,
|
||||
uint16_t endianness,
|
||||
uint16_t mode)
|
||||
{
|
||||
return q6asm_enc_cfg_blk_pcm_v5(ac, rate, channels,
|
||||
bits_per_sample, true, false, NULL,
|
||||
sample_word_size, endianness, mode);
|
||||
}
|
||||
|
||||
static int __q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
@@ -5137,6 +5311,31 @@ int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac,
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_format_support_v4);
|
||||
|
||||
/*
|
||||
* q6asm_enc_cfg_blk_pcm_format_support_v5 - sends encoder configuration
|
||||
* parameters
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @rate: sample rate
|
||||
* @channels: number of channels
|
||||
* @bits_per_sample: bit width of encoder session
|
||||
* @sample_word_size: Size in bits of the word that holds a sample of a channel
|
||||
* @endianness: endianness of the pcm data
|
||||
* @mode: Mode to provide additional info about the pcm input data
|
||||
*/
|
||||
int q6asm_enc_cfg_blk_pcm_format_support_v5(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size,
|
||||
uint16_t endianness,
|
||||
uint16_t mode)
|
||||
{
|
||||
return __q6asm_enc_cfg_blk_pcm_v5(ac, rate, channels,
|
||||
bits_per_sample, sample_word_size,
|
||||
endianness, mode);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_format_support_v5);
|
||||
/**
|
||||
* q6asm_enc_cfg_blk_pcm_native -
|
||||
* command to set encode config block for pcm_native
|
||||
@@ -5274,6 +5473,44 @@ static int q6asm_map_channels(u8 *channel_mapping, uint32_t channels,
|
||||
lchannel_mapping[5] = PCM_CHANNEL_RB;
|
||||
lchannel_mapping[6] = PCM_CHANNEL_LS;
|
||||
lchannel_mapping[7] = PCM_CHANNEL_RS;
|
||||
} else if (channels == 12) {
|
||||
/*
|
||||
* Configured for 7.1.4 channel mapping
|
||||
* Todo: Needs to be checked
|
||||
*/
|
||||
lchannel_mapping[0] = PCM_CHANNEL_FL;
|
||||
lchannel_mapping[1] = PCM_CHANNEL_FR;
|
||||
lchannel_mapping[2] = PCM_CHANNEL_FC;
|
||||
lchannel_mapping[3] = PCM_CHANNEL_LFE;
|
||||
lchannel_mapping[4] = PCM_CHANNEL_LB;
|
||||
lchannel_mapping[5] = PCM_CHANNEL_RB;
|
||||
lchannel_mapping[6] = PCM_CHANNEL_LS;
|
||||
lchannel_mapping[7] = PCM_CHANNEL_RS;
|
||||
lchannel_mapping[8] = PCM_CHANNEL_TFL;
|
||||
lchannel_mapping[9] = PCM_CHANNEL_TFR;
|
||||
lchannel_mapping[10] = PCM_CHANNEL_TSL;
|
||||
lchannel_mapping[11] = PCM_CHANNEL_TSR;
|
||||
} else if (channels == 16) {
|
||||
/*
|
||||
* Configured for 7.1.8 channel mapping
|
||||
* Todo: Needs to be checked
|
||||
*/
|
||||
lchannel_mapping[0] = PCM_CHANNEL_FL;
|
||||
lchannel_mapping[1] = PCM_CHANNEL_FR;
|
||||
lchannel_mapping[2] = PCM_CHANNEL_FC;
|
||||
lchannel_mapping[3] = PCM_CHANNEL_LFE;
|
||||
lchannel_mapping[4] = PCM_CHANNEL_LB;
|
||||
lchannel_mapping[5] = PCM_CHANNEL_RB;
|
||||
lchannel_mapping[6] = PCM_CHANNEL_LS;
|
||||
lchannel_mapping[7] = PCM_CHANNEL_RS;
|
||||
lchannel_mapping[8] = PCM_CHANNEL_TFL;
|
||||
lchannel_mapping[9] = PCM_CHANNEL_TFR;
|
||||
lchannel_mapping[10] = PCM_CHANNEL_TSL;
|
||||
lchannel_mapping[11] = PCM_CHANNEL_TSR;
|
||||
lchannel_mapping[12] = PCM_CHANNEL_FLC;
|
||||
lchannel_mapping[13] = PCM_CHANNEL_FRC;
|
||||
lchannel_mapping[14] = PCM_CHANNEL_RLC;
|
||||
lchannel_mapping[15] = PCM_CHANNEL_RRC;
|
||||
} else {
|
||||
pr_err("%s: ERROR.unsupported num_ch = %u\n",
|
||||
__func__, channels);
|
||||
@@ -5953,6 +6190,92 @@ fail_cmd:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int __q6asm_media_format_block_pcm_v5(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
int stream_id,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t sample_word_size,
|
||||
uint16_t endianness,
|
||||
uint16_t mode)
|
||||
{
|
||||
struct asm_multi_channel_pcm_fmt_blk_param_v5 fmt;
|
||||
u8 *channel_mapping;
|
||||
int rc;
|
||||
|
||||
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
|
||||
ac->session, rate, channels,
|
||||
bits_per_sample, sample_word_size);
|
||||
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id);
|
||||
atomic_set(&ac->cmd_state, -1);
|
||||
/*
|
||||
* Updated the token field with stream/session for compressed playback
|
||||
* Platform driver must know the the stream with which the command is
|
||||
* associated
|
||||
*/
|
||||
if (ac->io_mode & COMPRESSED_STREAM_IO)
|
||||
fmt.hdr.token = ((ac->session << 8) & 0xFFFF00) |
|
||||
(stream_id & 0xFF);
|
||||
|
||||
pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n",
|
||||
__func__, fmt.hdr.token, stream_id, ac->session);
|
||||
|
||||
fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
|
||||
fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
|
||||
sizeof(fmt.fmt_blk);
|
||||
fmt.param.num_channels = (uint16_t) channels & 0xFFFF;
|
||||
fmt.param.bits_per_sample = bits_per_sample;
|
||||
fmt.param.sample_rate = rate;
|
||||
fmt.param.is_signed = 1;
|
||||
fmt.param.sample_word_size = sample_word_size;
|
||||
fmt.param.endianness = endianness;
|
||||
fmt.param.mode = mode;
|
||||
channel_mapping = fmt.param.channel_mapping;
|
||||
|
||||
memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8);
|
||||
|
||||
if (use_default_chmap) {
|
||||
if (q6asm_map_channels(channel_mapping, fmt.param.num_channels, false)) {
|
||||
pr_err("%s: map channels failed %d\n",
|
||||
__func__, channels);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd;
|
||||
}
|
||||
} else {
|
||||
memcpy(channel_mapping, channel_map,
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL_V8);
|
||||
}
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: Comamnd open failed %d\n", __func__, rc);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd;
|
||||
}
|
||||
rc = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state) >= 0), 5*HZ);
|
||||
if (!rc) {
|
||||
pr_err("%s: timeout. waited for format update\n", __func__);
|
||||
rc = -ETIMEDOUT;
|
||||
goto fail_cmd;
|
||||
}
|
||||
if (atomic_read(&ac->cmd_state) > 0) {
|
||||
pr_err("%s: DSP returned error[%s]\n",
|
||||
__func__, adsp_err_get_err_str(
|
||||
atomic_read(&ac->cmd_state)));
|
||||
rc = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&ac->cmd_state));
|
||||
goto fail_cmd;
|
||||
}
|
||||
return 0;
|
||||
fail_cmd:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* q6asm_media_format_block_pcm -
|
||||
* command to set mediafmt block for PCM on ASM stream
|
||||
@@ -6084,6 +6407,47 @@ int q6asm_media_format_block_pcm_format_support_v4(struct audio_client *ac,
|
||||
EXPORT_SYMBOL(q6asm_media_format_block_pcm_format_support_v4);
|
||||
|
||||
|
||||
/*
|
||||
* q6asm_media_format_block_pcm_format_support_v5- sends pcm decoder
|
||||
* configuration parameters
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @rate: sample rate
|
||||
* @channels: number of channels
|
||||
* @bits_per_sample: bit width of encoder session
|
||||
* @stream_id: stream id of stream to be associated with this session
|
||||
* @use_default_chmap: true if default channel map to be used
|
||||
* @channel_map: input channel map
|
||||
* @sample_word_size: Size in bits of the word that holds a sample of a channel
|
||||
* @endianness: endianness of the pcm data
|
||||
* @mode: Mode to provide additional info about the pcm input data
|
||||
*/
|
||||
int q6asm_media_format_block_pcm_format_support_v5(struct audio_client *ac,
|
||||
uint32_t rate,
|
||||
uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
int stream_id,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t sample_word_size,
|
||||
uint16_t endianness,
|
||||
uint16_t mode)
|
||||
{
|
||||
if (!use_default_chmap && (channel_map == NULL)) {
|
||||
pr_err("%s: No valid chan map and can't use default\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return __q6asm_media_format_block_pcm_v5(ac, rate,
|
||||
channels, bits_per_sample, stream_id,
|
||||
use_default_chmap, channel_map,
|
||||
sample_word_size, endianness,
|
||||
mode);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_media_format_block_pcm_format_support_v5);
|
||||
|
||||
|
||||
static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
bool use_default_chmap, char *channel_map,
|
||||
@@ -6290,6 +6654,79 @@ fail_cmd:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __q6asm_media_format_block_multi_ch_pcm_v5(struct audio_client *ac,
|
||||
uint32_t rate,
|
||||
uint32_t channels,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size,
|
||||
uint16_t endianness,
|
||||
uint16_t mode)
|
||||
{
|
||||
struct asm_multi_channel_pcm_fmt_blk_param_v5 fmt;
|
||||
u8 *channel_mapping;
|
||||
int rc;
|
||||
|
||||
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
|
||||
ac->session, rate, channels,
|
||||
bits_per_sample, sample_word_size);
|
||||
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
|
||||
atomic_set(&ac->cmd_state, -1);
|
||||
|
||||
fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
|
||||
fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
|
||||
sizeof(fmt.fmt_blk);
|
||||
fmt.param.num_channels = channels;
|
||||
fmt.param.bits_per_sample = bits_per_sample;
|
||||
fmt.param.sample_rate = rate;
|
||||
fmt.param.is_signed = 1;
|
||||
fmt.param.sample_word_size = sample_word_size;
|
||||
fmt.param.endianness = endianness;
|
||||
fmt.param.mode = mode;
|
||||
channel_mapping = fmt.param.channel_mapping;
|
||||
|
||||
memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8);
|
||||
|
||||
if (use_default_chmap) {
|
||||
if (q6asm_map_channels(channel_mapping, channels, false)) {
|
||||
pr_err("%s: map channels failed %d\n",
|
||||
__func__, channels);
|
||||
rc = -EINVAL;
|
||||
goto fail_cmd;
|
||||
}
|
||||
} else {
|
||||
memcpy(channel_mapping, channel_map,
|
||||
PCM_FORMAT_MAX_NUM_CHANNEL_V8);
|
||||
}
|
||||
|
||||
rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: Comamnd open failed %d\n", __func__, rc);
|
||||
goto fail_cmd;
|
||||
}
|
||||
rc = wait_event_timeout(ac->cmd_wait,
|
||||
(atomic_read(&ac->cmd_state) >= 0), 5*HZ);
|
||||
if (!rc) {
|
||||
pr_err("%s: timeout. waited for format update\n", __func__);
|
||||
rc = -ETIMEDOUT;
|
||||
goto fail_cmd;
|
||||
}
|
||||
if (atomic_read(&ac->cmd_state) > 0) {
|
||||
pr_err("%s: DSP returned error[%s]\n",
|
||||
__func__, adsp_err_get_err_str(
|
||||
atomic_read(&ac->cmd_state)));
|
||||
rc = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&ac->cmd_state));
|
||||
goto fail_cmd;
|
||||
}
|
||||
return 0;
|
||||
fail_cmd:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
bool use_default_chmap, char *channel_map)
|
||||
@@ -6369,6 +6806,41 @@ int q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac,
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_media_format_block_multi_ch_pcm_v4);
|
||||
|
||||
|
||||
/*
|
||||
* q6asm_media_format_block_multi_ch_pcm_v5 - sends pcm decoder configuration
|
||||
* parameters
|
||||
*
|
||||
* @ac: Client session handle
|
||||
* @rate: sample rate
|
||||
* @channels: number of channels
|
||||
* @bits_per_sample: bit width of encoder session
|
||||
* @use_default_chmap: true if default channel map to be used
|
||||
* @channel_map: input channel map
|
||||
* @sample_word_size: Size in bits of the word that holds a sample of a channel
|
||||
* @endianness: endianness of the pcm data
|
||||
* @mode: Mode to provide additional info about the pcm input data
|
||||
*/
|
||||
int q6asm_media_format_block_multi_ch_pcm_v5(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size,
|
||||
uint16_t endianness,
|
||||
uint16_t mode)
|
||||
{
|
||||
return __q6asm_media_format_block_multi_ch_pcm_v5(ac, rate, channels,
|
||||
use_default_chmap,
|
||||
channel_map,
|
||||
bits_per_sample,
|
||||
sample_word_size,
|
||||
endianness,
|
||||
mode);
|
||||
}
|
||||
EXPORT_SYMBOL(q6asm_media_format_block_multi_ch_pcm_v5);
|
||||
|
||||
|
||||
/*
|
||||
* q6asm_media_format_block_gen_compr - set up generic compress format params
|
||||
*
|
||||
|
17
dsp/q6core.c
17
dsp/q6core.c
@@ -193,23 +193,6 @@ int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *event)
|
||||
}
|
||||
EXPORT_SYMBOL(q6core_send_uevent);
|
||||
|
||||
/**
|
||||
* q6core_send_uevent_env - send uevent with list of keys to userspace.
|
||||
*
|
||||
* @uevent_data: uevent data.
|
||||
* @event: array of event keys to send.
|
||||
*
|
||||
* Returns 0 on success or error otherwise.
|
||||
*/
|
||||
int q6core_send_uevent_env(struct audio_uevent_data *uevent_data, char *env[])
|
||||
{
|
||||
if (!env || !uevent_data)
|
||||
return -EINVAL;
|
||||
|
||||
return kobject_uevent_env(&uevent_data->kobj, KOBJ_CHANGE, env);
|
||||
}
|
||||
EXPORT_SYMBOL(q6core_send_uevent_env);
|
||||
|
||||
static int parse_fwk_version_info(uint32_t *payload)
|
||||
{
|
||||
size_t ver_size;
|
||||
|
@@ -57,7 +57,9 @@ enum {
|
||||
};
|
||||
|
||||
#define MAX_COPPS_PER_PORT 0x8
|
||||
#define ADM_MAX_CHANNELS 8
|
||||
#define ADM_MAX_CHANNELS 32
|
||||
|
||||
#define ADSP_ADM_API_VERSION_V3 3
|
||||
|
||||
/* multiple copp per stream. */
|
||||
struct route_payload {
|
||||
@@ -208,4 +210,5 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id,
|
||||
int channel_index);
|
||||
void msm_dts_srs_acquire_lock(void);
|
||||
void msm_dts_srs_release_lock(void);
|
||||
void adm_set_native_mode(int mode);
|
||||
#endif /* __Q6_ADM_V2_H__ */
|
||||
|
@@ -112,11 +112,14 @@
|
||||
#define ASM_LITTLE_ENDIAN 0
|
||||
#define ASM_BIG_ENDIAN 1
|
||||
|
||||
#define ADSP_ASM_API_VERSION_V2 2
|
||||
|
||||
/* PCM_MEDIA_FORMAT_Version */
|
||||
enum {
|
||||
PCM_MEDIA_FORMAT_V2 = 0,
|
||||
PCM_MEDIA_FORMAT_V3,
|
||||
PCM_MEDIA_FORMAT_V4,
|
||||
PCM_MEDIA_FORMAT_V5,
|
||||
};
|
||||
|
||||
/* PCM format modes in DSP */
|
||||
@@ -296,6 +299,10 @@ int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, bool ts_mode,
|
||||
uint32_t enc_cfg_id);
|
||||
|
||||
int q6asm_open_read_v5(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, bool ts_mode,
|
||||
uint32_t enc_cfg_id);
|
||||
|
||||
int q6asm_open_write(struct audio_client *ac, uint32_t format
|
||||
/*, uint16_t bits_per_sample*/);
|
||||
|
||||
@@ -312,6 +319,9 @@ int q6asm_open_write_v3(struct audio_client *ac, uint32_t format,
|
||||
int q6asm_open_write_v4(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample);
|
||||
|
||||
int q6asm_open_write_v5(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample);
|
||||
|
||||
int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, int32_t stream_id,
|
||||
bool is_gapless_mode);
|
||||
@@ -324,6 +334,10 @@ int q6asm_stream_open_write_v4(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, int32_t stream_id,
|
||||
bool is_gapless_mode);
|
||||
|
||||
int q6asm_stream_open_write_v5(struct audio_client *ac, uint32_t format,
|
||||
uint16_t bits_per_sample, int32_t stream_id,
|
||||
bool is_gapless_mode);
|
||||
|
||||
int q6asm_open_read_compressed(struct audio_client *ac, uint32_t format,
|
||||
uint32_t passthrough_flag);
|
||||
|
||||
@@ -462,6 +476,13 @@ int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac,
|
||||
uint16_t endianness,
|
||||
uint16_t mode);
|
||||
|
||||
int q6asm_enc_cfg_blk_pcm_format_support_v5(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size,
|
||||
uint16_t endianness,
|
||||
uint16_t mode);
|
||||
|
||||
int q6asm_enc_cfg_blk_custom(struct audio_client *ac,
|
||||
uint32_t sample_rate, uint32_t channels,
|
||||
uint32_t format, void *cfg);
|
||||
@@ -526,6 +547,17 @@ int q6asm_media_format_block_pcm_format_support_v4(struct audio_client *ac,
|
||||
uint16_t endianness,
|
||||
uint16_t mode);
|
||||
|
||||
int q6asm_media_format_block_pcm_format_support_v5(struct audio_client *ac,
|
||||
uint32_t rate,
|
||||
uint32_t channels,
|
||||
uint16_t bits_per_sample,
|
||||
int stream_id,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t sample_word_size,
|
||||
uint16_t endianness,
|
||||
uint16_t mode);
|
||||
|
||||
int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
bool use_default_chmap, char *channel_map);
|
||||
@@ -561,6 +593,15 @@ int q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac,
|
||||
uint16_t endianness,
|
||||
uint16_t mode);
|
||||
|
||||
int q6asm_media_format_block_multi_ch_pcm_v5(struct audio_client *ac,
|
||||
uint32_t rate, uint32_t channels,
|
||||
bool use_default_chmap,
|
||||
char *channel_map,
|
||||
uint16_t bits_per_sample,
|
||||
uint16_t sample_word_size,
|
||||
uint16_t endianness,
|
||||
uint16_t mode);
|
||||
|
||||
int q6asm_media_format_block_aac(struct audio_client *ac,
|
||||
struct asm_aac_cfg *cfg);
|
||||
|
||||
|
@@ -35,7 +35,6 @@ struct audio_uevent_data {
|
||||
int q6core_init_uevent_data(struct audio_uevent_data *uevent_data, char *name);
|
||||
void q6core_destroy_uevent_data(struct audio_uevent_data *uevent_data);
|
||||
int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *name);
|
||||
int q6core_send_uevent_env(struct audio_uevent_data *uevent_data, char *env[]);
|
||||
int q6core_get_avcs_api_version_per_service(uint32_t service_id);
|
||||
|
||||
#define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919
|
||||
|
مرجع در شماره جدید
Block a user