diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c index c6f61e4937ea..2578f5d84123 100644 --- a/asoc/msm-dai-q6-v2.c +++ b/asoc/msm-dai-q6-v2.c @@ -261,6 +261,17 @@ struct msm_dai_q6_mi2s_dai_data { 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 { DECLARE_BITMAP(status_mask, STATUS_MAX); DECLARE_BITMAP(hwfree_status, STATUS_MAX); @@ -6096,6 +6107,42 @@ error_invalid_data: 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( 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; } +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 = { .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) { int rc, id; @@ -12175,6 +12891,13 @@ int __init msm_dai_q6_init(void) 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); if (rc) { pr_err("%s: fail to register dai MI2S\n", __func__); @@ -12224,6 +12947,8 @@ dai_q6_tdm_drv_fail: dai_spdif_q6_fail: platform_driver_unregister(&msm_dai_mi2s_q6); 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); dai_q6_mi2s_drv_fail: 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_spdif_driver); 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_dev); platform_driver_unregister(&msm_dai_q6); diff --git a/asoc/msm-dai-q6-v2.h b/asoc/msm-dai-q6-v2.h index b65e4e11d8be..a4aafc55aaf1 100644 --- a/asoc/msm-dai-q6-v2.h +++ b/asoc/msm-dai-q6-v2.h @@ -38,6 +38,11 @@ #define MSM_DISPLAY_PORT 0 #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 { u16 mode; u16 sync; @@ -60,6 +65,13 @@ struct msm_mi2s_pdata { 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 { u32 capability; /* RX or TX */ u16 sd_lines; diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c index f9bd2daceac5..b7be26d9b4d9 100644 --- a/asoc/msm-pcm-routing-v2.c +++ b/asoc/msm-pcm-routing-v2.c @@ -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_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_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 @@ -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_6", "RX_CDC_DMA_RX_7", "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, @@ -7143,6 +7148,189 @@ static const struct snd_kcontrol_new int4_mi2s_rx_mixer_controls[] = { 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[] = { SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM, MSM_BACKEND_DAI_HDMI_RX, @@ -23169,6 +23357,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SEN_TDM_TX_7", "Senary TDM7 Capture", 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", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("WSA_CDC_DMA_TX_0", "WSA CDC DMA0 Capture", @@ -23479,6 +23671,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, 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, wsa_cdc_dma_rx_0_mixer_controls, ARRAY_SIZE(wsa_cdc_dma_rx_0_mixer_controls)), @@ -24702,6 +24900,44 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEN_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, {"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", "MultiMedia2", "MM_DL2"}, {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"}, diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h index c9544cb316d6..aca00bbfccfd 100644 --- a/asoc/msm-pcm-routing-v2.h +++ b/asoc/msm-pcm-routing-v2.h @@ -81,6 +81,9 @@ #define LPASS_BE_SENARY_MI2S_TX "SENARY_MI2S_TX" #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_TX_0 "PRI_TDM_TX_0" #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_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, }; diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index d2da56e94423..89386c49807e 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -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[] = { - SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, 0, 47, - 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_mixer, + SOC_SINGLE_MULTI_EXT("Playback Device Channel Map", SND_SOC_NOPM, + 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), }; 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, - 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, msm_qti_pp_get_channel_map_capture, + SOC_SINGLE_MULTI_EXT("Capture Device Channel Map", SND_SOC_NOPM, + 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), };