asoc: Add support for META MI2S ports

QCS405 can group data lines of several MI2S interfaces.
Add backend dai links for new META MI2S ports.

Change-Id: I9fc5ff06b61ffc2e085c5f05a75111b63ceeeb68
Signed-off-by: Ralf Herz <rherz@codeaurora.org>
This commit is contained in:
Ralf Herz
2019-07-26 15:15:21 +02:00
parent 43c0abd0c0
commit 29e071318d
5 changed files with 986 additions and 5 deletions

View File

@@ -261,6 +261,17 @@ struct msm_dai_q6_mi2s_dai_data {
struct msm_dai_q6_mi2s_dai_config rx_dai; struct msm_dai_q6_mi2s_dai_config rx_dai;
}; };
struct msm_dai_q6_meta_mi2s_dai_data {
DECLARE_BITMAP(status_mask, STATUS_MAX);
u16 num_member_ports;
u16 member_port_id[MAX_NUM_I2S_META_PORT_MEMBER_PORTS];
u16 channel_mode[MAX_NUM_I2S_META_PORT_MEMBER_PORTS];
u32 rate;
u32 channels;
u32 bitwidth;
union afe_port_config port_config;
};
struct msm_dai_q6_cdc_dma_dai_data { struct msm_dai_q6_cdc_dma_dai_data {
DECLARE_BITMAP(status_mask, STATUS_MAX); DECLARE_BITMAP(status_mask, STATUS_MAX);
DECLARE_BITMAP(hwfree_status, STATUS_MAX); DECLARE_BITMAP(hwfree_status, STATUS_MAX);
@@ -6096,6 +6107,42 @@ error_invalid_data:
return -EINVAL; return -EINVAL;
} }
static u16 msm_dai_q6_mi2s_get_num_channels(u16 config)
{
switch (config) {
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:
return 2;
case AFE_PORT_I2S_QUAD01:
case AFE_PORT_I2S_QUAD23:
case AFE_PORT_I2S_QUAD45:
case AFE_PORT_I2S_QUAD67:
return 4;
case AFE_PORT_I2S_6CHS:
return 6;
case AFE_PORT_I2S_8CHS:
case AFE_PORT_I2S_8CHS_2:
return 8;
case AFE_PORT_I2S_10CHS:
return 10;
case AFE_PORT_I2S_12CHS:
return 12;
case AFE_PORT_I2S_14CHS:
return 14;
case AFE_PORT_I2S_16CHS:
return 16;
default:
pr_err("%s: invalid config\n", __func__);
return 0;
}
}
static int msm_dai_q6_mi2s_platform_data_validation( static int msm_dai_q6_mi2s_platform_data_validation(
struct platform_device *pdev, struct snd_soc_dai_driver *dai_driver) struct platform_device *pdev, struct snd_soc_dai_driver *dai_driver)
{ {
@@ -6261,6 +6308,657 @@ static int msm_dai_q6_mi2s_dev_remove(struct platform_device *pdev)
return 0; return 0;
} }
static int msm_dai_q6_dai_meta_mi2s_probe(struct snd_soc_dai *dai)
{
struct msm_meta_mi2s_pdata *meta_mi2s_pdata =
(struct msm_meta_mi2s_pdata *) dai->dev->platform_data;
int rc = 0;
dai->id = meta_mi2s_pdata->intf_id;
rc = msm_dai_q6_dai_add_route(dai);
return rc;
}
static int msm_dai_q6_dai_meta_mi2s_remove(struct snd_soc_dai *dai)
{
return 0;
}
static int msm_dai_q6_meta_mi2s_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
return 0;
}
static int msm_meta_mi2s_get_port_id(u32 mi2s_id, int stream, u16 *port_id)
{
int ret = 0;
switch (stream) {
case SNDRV_PCM_STREAM_PLAYBACK:
switch (mi2s_id) {
case MSM_PRIM_META_MI2S:
*port_id = AFE_PORT_ID_PRIMARY_META_MI2S_RX;
break;
case MSM_SEC_META_MI2S:
*port_id = AFE_PORT_ID_SECONDARY_META_MI2S_RX;
break;
default:
pr_err("%s: playback err id 0x%x\n",
__func__, mi2s_id);
ret = -1;
break;
}
break;
case SNDRV_PCM_STREAM_CAPTURE:
switch (mi2s_id) {
default:
pr_err("%s: capture err id 0x%x\n", __func__, mi2s_id);
ret = -1;
break;
}
break;
default:
pr_err("%s: default err %d\n", __func__, stream);
ret = -1;
break;
}
pr_debug("%s: port_id = 0x%x\n", __func__, *port_id);
return ret;
}
static int msm_dai_q6_meta_mi2s_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct msm_dai_q6_meta_mi2s_dai_data *dai_data =
dev_get_drvdata(dai->dev);
u16 port_id = 0;
int rc = 0;
if (msm_meta_mi2s_get_port_id(dai->id, substream->stream,
&port_id) != 0) {
dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n",
__func__, port_id);
return -EINVAL;
}
dev_dbg(dai->dev, "%s: dai id %d, afe port id = 0x%x\n"
"dai_data->channels = %u sample_rate = %u\n", __func__,
dai->id, port_id, dai_data->channels, dai_data->rate);
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
/* PORT START should be set if prepare called
* in active state.
*/
rc = afe_port_start(port_id, &dai_data->port_config,
dai_data->rate);
if (rc < 0)
dev_err(dai->dev, "fail to open AFE port 0x%x\n",
dai->id);
else
set_bit(STATUS_PORT_STARTED,
dai_data->status_mask);
}
return rc;
}
static int msm_dai_q6_meta_mi2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct msm_dai_q6_meta_mi2s_dai_data *dai_data =
dev_get_drvdata(dai->dev);
struct afe_param_id_meta_i2s_cfg *port_cfg =
&dai_data->port_config.meta_i2s;
int idx = 0;
u16 port_channels = 0;
u16 channels_left = 0;
dai_data->channels = params_channels(params);
channels_left = dai_data->channels;
/* map requested channels to channels that member ports provide */
for (idx = 0; idx < dai_data->num_member_ports; idx++) {
port_channels = msm_dai_q6_mi2s_get_num_channels(
dai_data->channel_mode[idx]);
if (channels_left >= port_channels) {
port_cfg->member_port_id[idx] =
dai_data->member_port_id[idx];
port_cfg->member_port_channel_mode[idx] =
dai_data->channel_mode[idx];
channels_left -= port_channels;
} else {
switch (channels_left) {
case 15:
case 16:
switch (dai_data->channel_mode[idx]) {
case AFE_PORT_I2S_16CHS:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_16CHS;
break;
default:
goto error_invalid_data;
};
break;
case 13:
case 14:
switch (dai_data->channel_mode[idx]) {
case AFE_PORT_I2S_14CHS:
case AFE_PORT_I2S_16CHS:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_14CHS;
break;
default:
goto error_invalid_data;
};
break;
case 11:
case 12:
switch (dai_data->channel_mode[idx]) {
case AFE_PORT_I2S_12CHS:
case AFE_PORT_I2S_14CHS:
case AFE_PORT_I2S_16CHS:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_12CHS;
break;
default:
goto error_invalid_data;
};
break;
case 9:
case 10:
switch (dai_data->channel_mode[idx]) {
case AFE_PORT_I2S_10CHS:
case AFE_PORT_I2S_12CHS:
case AFE_PORT_I2S_14CHS:
case AFE_PORT_I2S_16CHS:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_10CHS;
break;
default:
goto error_invalid_data;
};
break;
case 8:
case 7:
switch (dai_data->channel_mode[idx]) {
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:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_8CHS;
break;
case AFE_PORT_I2S_8CHS_2:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_8CHS_2;
break;
default:
goto error_invalid_data;
};
break;
case 6:
case 5:
switch (dai_data->channel_mode[idx]) {
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:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_6CHS;
break;
default:
goto error_invalid_data;
};
break;
case 4:
case 3:
switch (dai_data->channel_mode[idx]) {
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;
case AFE_PORT_I2S_QUAD01:
case AFE_PORT_I2S_QUAD23:
case AFE_PORT_I2S_QUAD45:
case AFE_PORT_I2S_QUAD67:
port_cfg->member_port_channel_mode[idx]
= dai_data->channel_mode[idx];
break;
case AFE_PORT_I2S_8CHS_2:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_QUAD45;
break;
default:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_QUAD01;
};
break;
case 2:
case 1:
if (dai_data->channel_mode[idx] <
AFE_PORT_I2S_SD0)
goto error_invalid_data;
switch (dai_data->channel_mode[idx]) {
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:
port_cfg->member_port_channel_mode[idx]
= dai_data->channel_mode[idx];
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:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_SD0;
break;
case AFE_PORT_I2S_QUAD23:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_SD2;
break;
case AFE_PORT_I2S_QUAD45:
case AFE_PORT_I2S_8CHS_2:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_SD4;
break;
case AFE_PORT_I2S_QUAD67:
port_cfg->member_port_channel_mode[idx]
= AFE_PORT_I2S_SD6;
break;
}
break;
case 0:
port_cfg->member_port_channel_mode[idx] = 0;
}
if (port_cfg->member_port_channel_mode[idx] == 0) {
port_cfg->member_port_id[idx] =
AFE_PORT_ID_INVALID;
} else {
port_cfg->member_port_id[idx] =
dai_data->member_port_id[idx];
channels_left -=
msm_dai_q6_mi2s_get_num_channels(
port_cfg->member_port_channel_mode[idx]);
}
}
}
if (channels_left > 0) {
pr_err("%s: too many channels %d\n",
__func__, dai_data->channels);
return -EINVAL;
}
dai_data->rate = params_rate(params);
port_cfg->sample_rate = dai_data->rate;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
case SNDRV_PCM_FORMAT_SPECIAL:
port_cfg->bit_width = 16;
dai_data->bitwidth = 16;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S24_3LE:
port_cfg->bit_width = 24;
dai_data->bitwidth = 24;
break;
default:
pr_err("%s: format %d\n",
__func__, params_format(params));
return -EINVAL;
}
port_cfg->minor_version = AFE_API_VERSION_META_I2S_CONFIG;
port_cfg->data_format = AFE_LINEAR_PCM_DATA;
dev_dbg(dai->dev, "%s: dai id %d dai_data->channels = %d\n"
"bit_width = %hu ws_src = 0x%x sample_rate = %u\n"
"member_ports 0x%x 0x%x 0x%x 0x%x\n"
"sd_lines 0x%x 0x%x 0x%x 0x%x\n",
__func__, dai->id, dai_data->channels,
port_cfg->bit_width, port_cfg->ws_src, port_cfg->sample_rate,
port_cfg->member_port_id[0],
port_cfg->member_port_id[1],
port_cfg->member_port_id[2],
port_cfg->member_port_id[3],
port_cfg->member_port_channel_mode[0],
port_cfg->member_port_channel_mode[1],
port_cfg->member_port_channel_mode[2],
port_cfg->member_port_channel_mode[3]);
return 0;
error_invalid_data:
pr_err("%s: error when assigning member port %d channels (channels_left %d)\n",
__func__, idx, channels_left);
return -EINVAL;
}
static int msm_dai_q6_meta_mi2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt)
{
struct msm_dai_q6_meta_mi2s_dai_data *dai_data =
dev_get_drvdata(dai->dev);
if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
dev_err(dai->dev, "%s: err chg meta i2s mode while dai running",
__func__);
return -EPERM;
}
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
dai_data->port_config.meta_i2s.ws_src = 1;
break;
case SND_SOC_DAIFMT_CBM_CFM:
dai_data->port_config.meta_i2s.ws_src = 0;
break;
default:
pr_err("%s: fmt %d\n",
__func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
return -EINVAL;
}
return 0;
}
static void msm_dai_q6_meta_mi2s_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct msm_dai_q6_meta_mi2s_dai_data *dai_data =
dev_get_drvdata(dai->dev);
u16 port_id = 0;
int rc = 0;
if (msm_meta_mi2s_get_port_id(dai->id, substream->stream,
&port_id) != 0) {
dev_err(dai->dev, "%s: Invalid Port ID 0x%x\n",
__func__, port_id);
}
dev_dbg(dai->dev, "%s: closing afe port id = 0x%x\n",
__func__, port_id);
if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
rc = afe_close(port_id);
if (rc < 0)
dev_err(dai->dev, "fail to close AFE port\n");
clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
}
}
static struct snd_soc_dai_ops msm_dai_q6_meta_mi2s_ops = {
.startup = msm_dai_q6_meta_mi2s_startup,
.prepare = msm_dai_q6_meta_mi2s_prepare,
.hw_params = msm_dai_q6_meta_mi2s_hw_params,
.set_fmt = msm_dai_q6_meta_mi2s_set_fmt,
.shutdown = msm_dai_q6_meta_mi2s_shutdown,
};
/* Channel min and max are initialized base on platform data */
static struct snd_soc_dai_driver msm_dai_q6_meta_mi2s_dai[] = {
{
.playback = {
.stream_name = "Primary META MI2S Playback",
.aif_name = "PRI_META_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_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 = 384000,
},
.ops = &msm_dai_q6_meta_mi2s_ops,
.name = "Primary META MI2S",
.id = AFE_PORT_ID_PRIMARY_META_MI2S_RX,
.probe = msm_dai_q6_dai_meta_mi2s_probe,
.remove = msm_dai_q6_dai_meta_mi2s_remove,
},
{
.playback = {
.stream_name = "Secondary META MI2S Playback",
.aif_name = "SEC_META_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,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_min = 8000,
.rate_max = 192000,
},
.ops = &msm_dai_q6_meta_mi2s_ops,
.name = "Secondary META MI2S",
.id = AFE_PORT_ID_SECONDARY_META_MI2S_RX,
.probe = msm_dai_q6_dai_meta_mi2s_probe,
.remove = msm_dai_q6_dai_meta_mi2s_remove,
},
};
static int msm_dai_q6_meta_mi2s_platform_data_validation(
struct platform_device *pdev, struct snd_soc_dai_driver *dai_driver)
{
struct msm_dai_q6_meta_mi2s_dai_data *dai_data =
dev_get_drvdata(&pdev->dev);
struct msm_meta_mi2s_pdata *meta_mi2s_pdata =
(struct msm_meta_mi2s_pdata *) pdev->dev.platform_data;
int rc = 0;
int idx = 0;
u16 channel_mode = 0;
unsigned int ch_cnt = 0;
unsigned int ch_cnt_sum = 0;
struct afe_param_id_meta_i2s_cfg *port_cfg =
&dai_data->port_config.meta_i2s;
if (meta_mi2s_pdata == NULL) {
pr_err("%s: meta_mi2s_pdata NULL", __func__);
return -EINVAL;
}
dai_data->num_member_ports = meta_mi2s_pdata->num_member_ports;
for (idx = 0; idx < meta_mi2s_pdata->num_member_ports; idx++) {
rc = msm_dai_q6_mi2s_get_lineconfig(
meta_mi2s_pdata->sd_lines[idx],
&channel_mode,
&ch_cnt);
if (rc < 0) {
dev_err(&pdev->dev, "invalid META MI2S RX sd line config\n");
goto rtn;
}
if (ch_cnt) {
msm_mi2s_get_port_id(meta_mi2s_pdata->member_port[idx],
SNDRV_PCM_STREAM_PLAYBACK,
&dai_data->member_port_id[idx]);
dai_data->channel_mode[idx] = channel_mode;
port_cfg->member_port_id[idx] =
dai_data->member_port_id[idx];
port_cfg->member_port_channel_mode[idx] = channel_mode;
}
ch_cnt_sum += ch_cnt;
}
if (ch_cnt_sum) {
dai_driver->playback.channels_min = 1;
dai_driver->playback.channels_max = ch_cnt_sum << 1;
} else {
dai_driver->playback.channels_min = 0;
dai_driver->playback.channels_max = 0;
}
dev_dbg(&pdev->dev, "%s: sdline 0x%x 0x%x 0x%x 0x%x\n", __func__,
dai_data->channel_mode[0], dai_data->channel_mode[1],
dai_data->channel_mode[2], dai_data->channel_mode[3]);
dev_dbg(&pdev->dev, "%s: playback ch_max %d\n",
__func__, dai_driver->playback.channels_max);
rtn:
return rc;
}
static const struct snd_soc_component_driver msm_q6_meta_mi2s_dai_component = {
.name = "msm-dai-q6-meta-mi2s",
};
static int msm_dai_q6_meta_mi2s_dev_probe(struct platform_device *pdev)
{
struct msm_dai_q6_meta_mi2s_dai_data *dai_data;
const char *q6_meta_mi2s_dev_id = "qcom,msm-dai-q6-meta-mi2s-dev-id";
u32 dev_id = 0;
u32 meta_mi2s_intf = 0;
struct msm_meta_mi2s_pdata *meta_mi2s_pdata;
int rc;
rc = of_property_read_u32(pdev->dev.of_node, q6_meta_mi2s_dev_id,
&dev_id);
if (rc) {
dev_err(&pdev->dev,
"%s: missing %s in dt node\n", __func__,
q6_meta_mi2s_dev_id);
goto rtn;
}
dev_dbg(&pdev->dev, "dev name %s dev id 0x%x\n", dev_name(&pdev->dev),
dev_id);
switch (dev_id) {
case AFE_PORT_ID_PRIMARY_META_MI2S_RX:
meta_mi2s_intf = 0;
break;
case AFE_PORT_ID_SECONDARY_META_MI2S_RX:
meta_mi2s_intf = 1;
break;
default:
dev_err(&pdev->dev,
"%s: Invalid META MI2S ID 0x%x from Device Tree\n",
__func__, dev_id);
rc = -ENXIO;
goto rtn;
}
pdev->id = dev_id;
meta_mi2s_pdata = kzalloc(sizeof(struct msm_meta_mi2s_pdata),
GFP_KERNEL);
if (!meta_mi2s_pdata) {
rc = -ENOMEM;
goto rtn;
}
rc = of_property_read_u32(pdev->dev.of_node,
"qcom,msm-mi2s-num-members",
&meta_mi2s_pdata->num_member_ports);
if (rc) {
dev_err(&pdev->dev, "%s: invalid num from DT file %s\n",
__func__, "qcom,msm-mi2s-num-members");
goto free_pdata;
}
if (meta_mi2s_pdata->num_member_ports >
MAX_NUM_I2S_META_PORT_MEMBER_PORTS) {
dev_err(&pdev->dev, "%s: num-members %d too large from DT file\n",
__func__, meta_mi2s_pdata->num_member_ports);
goto free_pdata;
}
rc = of_property_read_u32_array(pdev->dev.of_node,
"qcom,msm-mi2s-member-id",
meta_mi2s_pdata->member_port,
meta_mi2s_pdata->num_member_ports);
if (rc) {
dev_err(&pdev->dev, "%s: member-id from DT file %s\n",
__func__, "qcom,msm-mi2s-member-id");
goto free_pdata;
}
rc = of_property_read_u32_array(pdev->dev.of_node,
"qcom,msm-mi2s-rx-lines",
meta_mi2s_pdata->sd_lines,
meta_mi2s_pdata->num_member_ports);
if (rc) {
dev_err(&pdev->dev, "%s: Rx line from DT file %s\n",
__func__, "qcom,msm-mi2s-rx-lines");
goto free_pdata;
}
dev_dbg(&pdev->dev, "dev name %s num-members=%d\n",
dev_name(&pdev->dev), meta_mi2s_pdata->num_member_ports);
dev_dbg(&pdev->dev, "member array (%d, %d, %d, %d)\n",
meta_mi2s_pdata->member_port[0],
meta_mi2s_pdata->member_port[1],
meta_mi2s_pdata->member_port[2],
meta_mi2s_pdata->member_port[3]);
dev_dbg(&pdev->dev, "sd-lines array (0x%x, 0x%x, 0x%x, 0x%x)\n",
meta_mi2s_pdata->sd_lines[0],
meta_mi2s_pdata->sd_lines[1],
meta_mi2s_pdata->sd_lines[2],
meta_mi2s_pdata->sd_lines[3]);
meta_mi2s_pdata->intf_id = meta_mi2s_intf;
dai_data = kzalloc(sizeof(struct msm_dai_q6_meta_mi2s_dai_data),
GFP_KERNEL);
if (!dai_data) {
rc = -ENOMEM;
goto free_pdata;
} else
dev_set_drvdata(&pdev->dev, dai_data);
pdev->dev.platform_data = meta_mi2s_pdata;
rc = msm_dai_q6_meta_mi2s_platform_data_validation(pdev,
&msm_dai_q6_meta_mi2s_dai[meta_mi2s_intf]);
if (rc < 0)
goto free_dai_data;
rc = snd_soc_register_component(&pdev->dev,
&msm_q6_meta_mi2s_dai_component,
&msm_dai_q6_meta_mi2s_dai[meta_mi2s_intf], 1);
if (rc < 0)
goto err_register;
return 0;
err_register:
dev_err(&pdev->dev, "fail to %s\n", __func__);
free_dai_data:
kfree(dai_data);
free_pdata:
kfree(meta_mi2s_pdata);
rtn:
return rc;
}
static int msm_dai_q6_meta_mi2s_dev_remove(struct platform_device *pdev)
{
snd_soc_unregister_component(&pdev->dev);
return 0;
}
static const struct snd_soc_component_driver msm_dai_q6_component = { static const struct snd_soc_component_driver msm_dai_q6_component = {
.name = "msm-dai-q6-dev", .name = "msm-dai-q6-dev",
}; };
@@ -6627,6 +7325,24 @@ static struct platform_driver msm_dai_q6_mi2s_driver = {
}, },
}; };
static const struct of_device_id msm_dai_q6_meta_mi2s_dev_dt_match[] = {
{ .compatible = "qcom,msm-dai-q6-meta-mi2s", },
{ }
};
MODULE_DEVICE_TABLE(of, msm_dai_q6_meta_mi2s_dev_dt_match);
static struct platform_driver msm_dai_q6_meta_mi2s_driver = {
.probe = msm_dai_q6_meta_mi2s_dev_probe,
.remove = msm_dai_q6_meta_mi2s_dev_remove,
.driver = {
.name = "msm-dai-q6-meta-mi2s",
.owner = THIS_MODULE,
.of_match_table = msm_dai_q6_meta_mi2s_dev_dt_match,
.suppress_bind_attrs = true,
},
};
static int msm_dai_q6_spdif_dev_probe(struct platform_device *pdev) static int msm_dai_q6_spdif_dev_probe(struct platform_device *pdev)
{ {
int rc, id; int rc, id;
@@ -12175,6 +12891,13 @@ int __init msm_dai_q6_init(void)
goto dai_q6_mi2s_drv_fail; goto dai_q6_mi2s_drv_fail;
} }
rc = platform_driver_register(&msm_dai_q6_meta_mi2s_driver);
if (rc) {
pr_err("%s: fail to register dai META MI2S dev drv\n",
__func__);
goto dai_q6_meta_mi2s_drv_fail;
}
rc = platform_driver_register(&msm_dai_mi2s_q6); rc = platform_driver_register(&msm_dai_mi2s_q6);
if (rc) { if (rc) {
pr_err("%s: fail to register dai MI2S\n", __func__); pr_err("%s: fail to register dai MI2S\n", __func__);
@@ -12224,6 +12947,8 @@ dai_q6_tdm_drv_fail:
dai_spdif_q6_fail: dai_spdif_q6_fail:
platform_driver_unregister(&msm_dai_mi2s_q6); platform_driver_unregister(&msm_dai_mi2s_q6);
dai_mi2s_q6_fail: dai_mi2s_q6_fail:
platform_driver_unregister(&msm_dai_q6_meta_mi2s_driver);
dai_q6_meta_mi2s_drv_fail:
platform_driver_unregister(&msm_dai_q6_mi2s_driver); platform_driver_unregister(&msm_dai_q6_mi2s_driver);
dai_q6_mi2s_drv_fail: dai_q6_mi2s_drv_fail:
platform_driver_unregister(&msm_dai_q6_dev); platform_driver_unregister(&msm_dai_q6_dev);
@@ -12243,6 +12968,7 @@ void msm_dai_q6_exit(void)
platform_driver_unregister(&msm_dai_q6_tdm_driver); platform_driver_unregister(&msm_dai_q6_tdm_driver);
platform_driver_unregister(&msm_dai_q6_spdif_driver); platform_driver_unregister(&msm_dai_q6_spdif_driver);
platform_driver_unregister(&msm_dai_mi2s_q6); platform_driver_unregister(&msm_dai_mi2s_q6);
platform_driver_unregister(&msm_dai_q6_meta_mi2s_driver);
platform_driver_unregister(&msm_dai_q6_mi2s_driver); platform_driver_unregister(&msm_dai_q6_mi2s_driver);
platform_driver_unregister(&msm_dai_q6_dev); platform_driver_unregister(&msm_dai_q6_dev);
platform_driver_unregister(&msm_dai_q6); platform_driver_unregister(&msm_dai_q6);

View File

@@ -38,6 +38,11 @@
#define MSM_DISPLAY_PORT 0 #define MSM_DISPLAY_PORT 0
#define MSM_DISPLAY_PORT1 1 #define MSM_DISPLAY_PORT1 1
#define MSM_PRIM_META_MI2S 0
#define MSM_SEC_META_MI2S 1
#define MSM_META_MI2S_MIN MSM_PRIM_META_MI2S
#define MSM_META_MI2S_MAX MSM_SEC_META_MI2S
struct msm_dai_auxpcm_config { struct msm_dai_auxpcm_config {
u16 mode; u16 mode;
u16 sync; u16 sync;
@@ -60,6 +65,13 @@ struct msm_mi2s_pdata {
u16 intf_id; u16 intf_id;
}; };
struct msm_meta_mi2s_pdata {
u32 num_member_ports;
u32 member_port[MAX_NUM_I2S_META_PORT_MEMBER_PORTS];
u32 sd_lines[MAX_NUM_I2S_META_PORT_MEMBER_PORTS];
u16 intf_id;
};
struct msm_i2s_data { struct msm_i2s_data {
u32 capability; /* RX or TX */ u32 capability; /* RX or TX */
u16 sd_lines; u16 sd_lines;

View File

@@ -689,6 +689,10 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
{ SLIMBUS_9_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_9_RX}, { SLIMBUS_9_RX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_9_RX},
{ SLIMBUS_9_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_9_TX}, { SLIMBUS_9_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_SLIMBUS_9_TX},
{ AFE_LOOPBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_AFE_LOOPBACK_TX}, { AFE_LOOPBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, LPASS_BE_AFE_LOOPBACK_TX},
{ AFE_PORT_ID_PRIMARY_META_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_PRI_META_MI2S_RX},
{ AFE_PORT_ID_SECONDARY_META_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0,
LPASS_BE_SEC_META_MI2S_RX},
}; };
/* Track ASM playback & capture sessions of DAI /* Track ASM playback & capture sessions of DAI
@@ -3435,7 +3439,8 @@ static const char *const be_name[] = {
"RX_CDC_DMA_RX_4", "TX_CDC_DMA_TX_4", "RX_CDC_DMA_RX_5", "TX_CDC_DMA_TX_5", "RX_CDC_DMA_RX_4", "TX_CDC_DMA_TX_4", "RX_CDC_DMA_RX_5", "TX_CDC_DMA_TX_5",
"RX_CDC_DMA_RX_6", "RX_CDC_DMA_RX_7", "RX_CDC_DMA_RX_6", "RX_CDC_DMA_RX_7",
"PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX", "PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX",
"SLIM_9_RX", "SLIM_9_TX", "AFE_LOOPBACK_TX" "SLIM_9_RX", "SLIM_9_TX", "AFE_LOOPBACK_TX", "PRI_META_MI2S_RX",
"SEC_META_MI2S_RX"
}; };
static SOC_ENUM_SINGLE_DECL(mm1_channel_mux, static SOC_ENUM_SINGLE_DECL(mm1_channel_mux,
@@ -7138,6 +7143,189 @@ static const struct snd_kcontrol_new int4_mi2s_rx_mixer_controls[] = {
msm_routing_put_audio_mixer), msm_routing_put_audio_mixer),
}; };
static const struct snd_kcontrol_new pri_meta_mi2s_rx_mixer_controls[] = {
SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new sec_meta_mi2s_rx_mixer_controls[] = {
SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia26", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new hdmi_mixer_controls[] = { static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM,
MSM_BACKEND_DAI_HDMI_RX, MSM_BACKEND_DAI_HDMI_RX,
@@ -23164,6 +23352,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
0, 0, 0, 0), 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_7", "Senary TDM7 Capture", SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_7", "Senary TDM7 Capture",
0, 0, 0, 0), 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("PRI_META_MI2S_RX", "Primary META MI2S Playback",
0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("SEC_META_MI2S_RX", "Secondary META MI2S Playback",
0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("WSA_CDC_DMA_RX_0", "WSA CDC DMA0 Playback", SND_SOC_DAPM_AIF_OUT("WSA_CDC_DMA_RX_0", "WSA CDC DMA0 Playback",
0, 0, 0, 0), 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("WSA_CDC_DMA_TX_0", "WSA CDC DMA0 Capture", SND_SOC_DAPM_AIF_IN("WSA_CDC_DMA_TX_0", "WSA CDC DMA0 Capture",
@@ -23474,6 +23666,12 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_MIXER("SEN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MIXER("SEN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
sen_tdm_rx_3_mixer_controls, sen_tdm_rx_3_mixer_controls,
ARRAY_SIZE(sen_tdm_rx_3_mixer_controls)), ARRAY_SIZE(sen_tdm_rx_3_mixer_controls)),
SND_SOC_DAPM_MIXER("PRI_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
pri_meta_mi2s_rx_mixer_controls,
ARRAY_SIZE(pri_meta_mi2s_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("SEC_META_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
sec_meta_mi2s_rx_mixer_controls,
ARRAY_SIZE(sec_meta_mi2s_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
wsa_cdc_dma_rx_0_mixer_controls, wsa_cdc_dma_rx_0_mixer_controls,
ARRAY_SIZE(wsa_cdc_dma_rx_0_mixer_controls)), ARRAY_SIZE(wsa_cdc_dma_rx_0_mixer_controls)),
@@ -24697,6 +24895,44 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SEN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SEN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
{"SEN_MI2S_RX", NULL, "SEN_MI2S_RX Audio Mixer"}, {"SEN_MI2S_RX", NULL, "SEN_MI2S_RX Audio Mixer"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
{"PRI_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"},
{"PRI_META_MI2S_RX", NULL, "PRI_META_MI2S_RX Audio Mixer"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia13", "MM_DL13"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
{"SEC_META_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"},
{"SEC_META_MI2S_RX", NULL, "SEC_META_MI2S_RX Audio Mixer"},
{"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
{"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
{"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},

View File

@@ -81,6 +81,9 @@
#define LPASS_BE_SENARY_MI2S_TX "SENARY_MI2S_TX" #define LPASS_BE_SENARY_MI2S_TX "SENARY_MI2S_TX"
#define LPASS_BE_SENARY_MI2S_RX "SENARY_MI2S_RX" #define LPASS_BE_SENARY_MI2S_RX "SENARY_MI2S_RX"
#define LPASS_BE_PRI_META_MI2S_RX "PRI_META_MI2S_RX"
#define LPASS_BE_SEC_META_MI2S_RX "SEC_META_MI2S_RX"
#define LPASS_BE_PRI_TDM_RX_0 "PRI_TDM_RX_0" #define LPASS_BE_PRI_TDM_RX_0 "PRI_TDM_RX_0"
#define LPASS_BE_PRI_TDM_TX_0 "PRI_TDM_TX_0" #define LPASS_BE_PRI_TDM_TX_0 "PRI_TDM_TX_0"
#define LPASS_BE_PRI_TDM_RX_1 "PRI_TDM_RX_1" #define LPASS_BE_PRI_TDM_RX_1 "PRI_TDM_RX_1"
@@ -494,6 +497,8 @@ enum {
MSM_BACKEND_DAI_SLIMBUS_9_RX, MSM_BACKEND_DAI_SLIMBUS_9_RX,
MSM_BACKEND_DAI_SLIMBUS_9_TX, MSM_BACKEND_DAI_SLIMBUS_9_TX,
MSM_BACKEND_DAI_AFE_LOOPBACK_TX, MSM_BACKEND_DAI_AFE_LOOPBACK_TX,
MSM_BACKEND_DAI_PRI_META_MI2S_RX,
MSM_BACKEND_DAI_SEC_META_MI2S_RX,
MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_MAX,
}; };

View File

@@ -1484,14 +1484,16 @@ static const struct snd_kcontrol_new sec_auxpcm_lb_vol_mixer_controls[] = {
}; };
static const struct snd_kcontrol_new multi_ch_channel_map_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, 47, SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM,
0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_mixer, 0, PCM_MAX_CHMAP_ID, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8,
msm_qti_pp_get_channel_map_mixer,
msm_qti_pp_put_channel_map_mixer), msm_qti_pp_put_channel_map_mixer),
}; };
static const struct snd_kcontrol_new multi_ch_channel_map_capture_controls[] = { static const struct snd_kcontrol_new multi_ch_channel_map_capture_controls[] = {
SOC_SINGLE_MULTI_EXT("Capture Device Channel Map", SND_SOC_NOPM, 0, 47, SOC_SINGLE_MULTI_EXT("Capture Device Channel Map", SND_SOC_NOPM,
0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_capture, 0, PCM_MAX_CHMAP_ID, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8,
msm_qti_pp_get_channel_map_capture,
msm_qti_pp_put_channel_map_capture), msm_qti_pp_put_channel_map_capture),
}; };