Merge "asoc: qcs405: Add support for META MI2S ports"

这个提交包含在:
qctecmdr
2019-09-04 03:40:09 -07:00
提交者 Gerrit - the friendly Code Review server
当前提交 bfa4bebe53

查看文件

@@ -105,6 +105,12 @@ enum {
MI2S_MAX, MI2S_MAX,
}; };
enum {
PRIM_META_MI2S = 0,
SEC_META_MI2S,
META_MI2S_MAX,
};
enum { enum {
PRIM_AUX_PCM = 0, PRIM_AUX_PCM = 0,
SEC_AUX_PCM, SEC_AUX_PCM,
@@ -157,6 +163,12 @@ static u32 mi2s_ebit_clk[MI2S_MAX] = {
Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT
}; };
struct meta_mi2s_conf {
u32 num_member_ports;
u32 member_port[MAX_NUM_I2S_META_PORT_MEMBER_PORTS];
bool clk_enable[MAX_NUM_I2S_META_PORT_MEMBER_PORTS];
};
struct dev_config { struct dev_config {
u32 sample_rate; u32 sample_rate;
u32 bit_format; u32 bit_format;
@@ -402,6 +414,11 @@ static struct dev_config mi2s_rx_cfg[] = {
[SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
}; };
static struct dev_config meta_mi2s_rx_cfg[] = {
[PRIM_META_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
[SEC_META_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
};
/* Default configuration of SPDIF channels */ /* Default configuration of SPDIF channels */
static struct dev_config spdif_rx_cfg[] = { static struct dev_config spdif_rx_cfg[] = {
[PRIM_SPDIF_RX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, [PRIM_SPDIF_RX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
@@ -487,6 +504,14 @@ static const char *const mi2s_ch_text[] = {
"Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen",
"Fourteen", "Fifteen", "Sixteen" "Fourteen", "Fifteen", "Sixteen"
}; };
static const char *const meta_mi2s_ch_text[] = {
"One", "Two", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen",
"Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen",
"Nineteen", "Twenty", "TwentyOne", "TwentyTwo", "TwentyThree",
"TwentyFour", "TwentyFive", "TwentySix", "TwentySeven",
"TwentyEight", "TwentyNine", "Thirty", "ThirtyOne", "ThirtyTwo"
};
static const char *const qos_text[] = {"Disable", "Enable"}; static const char *const qos_text[] = {"Disable", "Enable"};
static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"}; static const char *const cdc_dma_rx_ch_text[] = {"One", "Two"};
@@ -576,6 +601,12 @@ 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(mi2s_tx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(prim_meta_mi2s_rx_sample_rate, mi2s_rate_text);
static SOC_ENUM_SINGLE_EXT_DECL(sec_meta_mi2s_rx_sample_rate, mi2s_rate_text);
static SOC_ENUM_SINGLE_EXT_DECL(prim_meta_mi2s_rx_chs, meta_mi2s_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(sec_meta_mi2s_rx_chs, meta_mi2s_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(prim_meta_mi2s_rx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(sec_meta_mi2s_rx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_chs, cdc_dma_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_0_chs, cdc_dma_rx_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_chs, cdc_dma_rx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_rx_1_chs, cdc_dma_rx_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_cdc_dma_tx_0_chs, cdc_dma_tx_ch_text);
@@ -689,6 +720,8 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; static struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
static struct meta_mi2s_conf meta_mi2s_intf_conf[META_MI2S_MAX];
static int msm_island_vad_get_portid_from_beid(int32_t be_id, int *port_id) static int msm_island_vad_get_portid_from_beid(int32_t be_id, int *port_id)
{ {
*port_id = 0xFFFF; *port_id = 0xFFFF;
@@ -3070,6 +3103,143 @@ static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol,
return 0; return 0;
} }
static int msm_meta_mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
{
int idx = 0;
if (strnstr(kcontrol->id.name, "PRIM_META_MI2S_RX",
sizeof("PRIM_META_MI2S_RX"))) {
idx = PRIM_META_MI2S;
} else if (strnstr(kcontrol->id.name, "SEC_META_MI2S_RX",
sizeof("SEC_META_MI2S_RX"))) {
idx = SEC_META_MI2S;
} else {
pr_err("%s: unsupported port: %s",
__func__, kcontrol->id.name);
idx = -EINVAL;
}
return idx;
}
static int msm_meta_mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int idx = msm_meta_mi2s_get_port_idx(kcontrol);
if (idx < 0)
return idx;
ucontrol->value.enumerated.item[0] =
mi2s_get_sample_rate_val(meta_mi2s_rx_cfg[idx].sample_rate);
pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
idx, meta_mi2s_rx_cfg[idx].sample_rate,
ucontrol->value.enumerated.item[0]);
return 0;
}
static int msm_meta_mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int idx = msm_meta_mi2s_get_port_idx(kcontrol);
if (idx < 0)
return idx;
meta_mi2s_rx_cfg[idx].sample_rate =
mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
idx, meta_mi2s_rx_cfg[idx].sample_rate,
ucontrol->value.enumerated.item[0]);
return 0;
}
static int msm_meta_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int idx = msm_meta_mi2s_get_port_idx(kcontrol);
if (idx < 0)
return idx;
ucontrol->value.enumerated.item[0] = meta_mi2s_rx_cfg[idx].channels - 1;
pr_debug("%s: meta_mi2s_[%d]_rx_ch = %d\n", __func__,
idx, meta_mi2s_rx_cfg[idx].channels);
return 0;
}
static int msm_meta_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int idx = msm_meta_mi2s_get_port_idx(kcontrol);
if (idx < 0)
return idx;
meta_mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
pr_debug("%s: meta_mi2s_[%d]_rx_ch = %d\n", __func__,
idx, meta_mi2s_rx_cfg[idx].channels);
return 1;
}
static int msm_meta_mi2s_rx_format_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int idx = msm_meta_mi2s_get_port_idx(kcontrol);
if (idx < 0)
return idx;
ucontrol->value.enumerated.item[0] =
mi2s_auxpcm_get_format_value(meta_mi2s_rx_cfg[idx].bit_format);
pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
idx, meta_mi2s_rx_cfg[idx].bit_format,
ucontrol->value.enumerated.item[0]);
return 0;
}
static int msm_meta_mi2s_rx_format_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct msm_asoc_mach_data *pdata = NULL;
struct snd_soc_card *card = NULL;
int idx = msm_meta_mi2s_get_port_idx(kcontrol);
card = kcontrol->private_data;
pdata = snd_soc_card_get_drvdata(card);
if (idx < 0)
return idx;
/* check for PRIM_META_MI2S and CSRAx to allow 24bit BE config only */
if ((idx == PRIM_META_MI2S) && pdata->codec_is_csra) {
meta_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, meta_mi2s_rx_cfg[idx].bit_format,
ucontrol->value.enumerated.item[0]);
} else {
meta_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, meta_mi2s_rx_cfg[idx].bit_format,
ucontrol->value.enumerated.item[0]);
}
return 0;
}
static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol, static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
@@ -3979,6 +4149,26 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
msm_mi2s_rx_format_get, msm_mi2s_rx_format_put), msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
SOC_ENUM_EXT("SEN_MI2S_TX Format", mi2s_tx_format, SOC_ENUM_EXT("SEN_MI2S_TX Format", mi2s_tx_format,
msm_mi2s_tx_format_get, msm_mi2s_tx_format_put), msm_mi2s_tx_format_get, msm_mi2s_tx_format_put),
SOC_ENUM_EXT("PRIM_META_MI2S_RX SampleRate",
prim_meta_mi2s_rx_sample_rate,
msm_meta_mi2s_rx_sample_rate_get,
msm_meta_mi2s_rx_sample_rate_put),
SOC_ENUM_EXT("SEC_META_MI2S_RX SampleRate",
sec_meta_mi2s_rx_sample_rate,
msm_meta_mi2s_rx_sample_rate_get,
msm_meta_mi2s_rx_sample_rate_put),
SOC_ENUM_EXT("PRIM_META_MI2S_RX Channels", prim_meta_mi2s_rx_chs,
msm_meta_mi2s_rx_ch_get,
msm_meta_mi2s_rx_ch_put),
SOC_ENUM_EXT("SEC_META_MI2S_RX Channels", sec_meta_mi2s_rx_chs,
msm_meta_mi2s_rx_ch_get,
msm_meta_mi2s_rx_ch_put),
SOC_ENUM_EXT("PRIM_META_MI2S_RX Format", mi2s_rx_format,
msm_meta_mi2s_rx_format_get,
msm_meta_mi2s_rx_format_put),
SOC_ENUM_EXT("SEC_META_MI2S_RX Format", mi2s_rx_format,
msm_meta_mi2s_rx_format_get,
msm_meta_mi2s_rx_format_put),
SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format, SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format,
msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put), msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format, SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format,
@@ -4761,6 +4951,25 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
channels->min = channels->max = channels->min = channels->max =
mi2s_tx_cfg[SEN_MI2S].channels; mi2s_tx_cfg[SEN_MI2S].channels;
break; break;
case MSM_BACKEND_DAI_PRI_META_MI2S_RX:
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
meta_mi2s_rx_cfg[PRIM_META_MI2S].bit_format);
rate->min = rate->max =
meta_mi2s_rx_cfg[PRIM_META_MI2S].sample_rate;
channels->min = channels->max =
meta_mi2s_rx_cfg[PRIM_META_MI2S].channels;
break;
case MSM_BACKEND_DAI_SEC_META_MI2S_RX:
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
meta_mi2s_rx_cfg[SEC_META_MI2S].bit_format);
rate->min = rate->max =
meta_mi2s_rx_cfg[SEC_META_MI2S].sample_rate;
channels->min = channels->max =
meta_mi2s_rx_cfg[SEC_META_MI2S].channels;
break;
case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0: case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0:
case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1: case MSM_BACKEND_DAI_WSA_CDC_DMA_RX_1:
idx = msm_cdc_dma_get_idx_from_beid(dai_link->id); idx = msm_cdc_dma_get_idx_from_beid(dai_link->id);
@@ -5996,6 +6205,172 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
mutex_unlock(&mi2s_intf_conf[index].lock); mutex_unlock(&mi2s_intf_conf[index].lock);
} }
static int msm_meta_mi2s_set_sclk(struct snd_pcm_substream *substream,
int member_id, bool enable)
{
int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int be_id = 0;
int port_id = 0;
int index = cpu_dai->id;
u32 bit_per_sample = 0;
switch (member_id) {
case PRIM_MI2S:
be_id = MSM_BACKEND_DAI_PRI_MI2S_RX;
break;
case SEC_MI2S:
be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX;
break;
case TERT_MI2S:
be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX;
break;
case QUAT_MI2S:
be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX;
break;
default:
dev_err(rtd->card->dev, "%s: Invalid member_id\n", __func__);
ret = -EINVAL;
goto err;
}
port_id = msm_get_port_id(be_id);
if (port_id < 0) {
dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__);
ret = port_id;
goto err;
}
if (enable) {
bit_per_sample =
get_mi2s_bits_per_sample(
meta_mi2s_rx_cfg[index].bit_format);
mi2s_clk[member_id].clk_freq_in_hz =
meta_mi2s_rx_cfg[index].sample_rate * 2 *
bit_per_sample;
dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__,
mi2s_clk[member_id].clk_freq_in_hz);
}
mi2s_clk[member_id].enable = enable;
ret = afe_set_lpass_clock_v2(port_id, &mi2s_clk[member_id]);
if (ret < 0) {
dev_err(rtd->card->dev,
"%s: afe lpass clock failed for port 0x%x , err:%d\n",
__func__, port_id, ret);
goto err;
}
err:
return ret;
}
static int msm_meta_mi2s_snd_startup(struct snd_pcm_substream *substream)
{
int ret = 0;
int i = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int index = cpu_dai->id;
int member_port = 0;
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
struct snd_soc_card *card = rtd->card;
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
dev_dbg(rtd->card->dev,
"%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
__func__, substream->name, substream->stream,
cpu_dai->name, cpu_dai->id);
if (index < PRIM_META_MI2S || index >= META_MI2S_MAX) {
ret = -EINVAL;
dev_err(rtd->card->dev,
"%s: CPU DAI id (%d) out of range\n",
__func__, cpu_dai->id);
goto err;
}
for (i = 0; i < meta_mi2s_intf_conf[index].num_member_ports; i++) {
member_port = meta_mi2s_intf_conf[index].member_port[i];
if (!mi2s_intf_conf[member_port].msm_is_mi2s_master) {
mi2s_clk[member_port].clk_id =
mi2s_ebit_clk[member_port];
fmt = SND_SOC_DAIFMT_CBM_CFM;
}
ret = msm_meta_mi2s_set_sclk(substream, member_port, true);
if (ret < 0) {
dev_err(rtd->card->dev,
"%s: afe lpass clock failed to enable MI2S clock, err:%d\n",
__func__, ret);
goto clk_off;
}
meta_mi2s_intf_conf[index].clk_enable[i] = true;
if (i == 0) {
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
pr_err("%s: set fmt cpu dai failed for META_MI2S (%d), err:%d\n",
__func__, index, ret);
goto clk_off;
}
}
if (pdata->mi2s_gpio_p[member_port])
msm_cdc_pinctrl_select_active_state(
pdata->mi2s_gpio_p[member_port]);
}
return 0;
clk_off:
for (i = 0; i < meta_mi2s_intf_conf[index].num_member_ports; i++) {
member_port = meta_mi2s_intf_conf[index].member_port[i];
if (pdata->mi2s_gpio_p[member_port])
msm_cdc_pinctrl_select_sleep_state(
pdata->mi2s_gpio_p[member_port]);
if (meta_mi2s_intf_conf[index].clk_enable[i]) {
msm_meta_mi2s_set_sclk(substream, member_port, false);
meta_mi2s_intf_conf[index].clk_enable[i] = false;
}
}
err:
return ret;
}
static void msm_meta_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
{
int ret = 0;
int i = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
int index = rtd->cpu_dai->id;
int member_port = 0;
struct snd_soc_card *card = rtd->card;
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
pr_debug("%s(): substream = %s stream = %d\n", __func__,
substream->name, substream->stream);
if (index < PRIM_MI2S || index >= MI2S_MAX) {
pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index);
return;
}
for (i = 0; i < meta_mi2s_intf_conf[index].num_member_ports; i++) {
member_port = meta_mi2s_intf_conf[index].member_port[i];
if (pdata->mi2s_gpio_p[member_port])
msm_cdc_pinctrl_select_sleep_state(
pdata->mi2s_gpio_p[member_port]);
ret = msm_meta_mi2s_set_sclk(substream, member_port, false);
if (ret < 0)
pr_err("%s:clock disable failed for META MI2S (%d); ret=%d\n",
__func__, index, ret);
}
}
static int msm_spdif_set_clk(struct snd_pcm_substream *substream, bool enable) static int msm_spdif_set_clk(struct snd_pcm_substream *substream, bool enable)
{ {
int ret = 0; int ret = 0;
@@ -6131,6 +6506,11 @@ static struct snd_soc_ops msm_mi2s_be_ops = {
.shutdown = msm_mi2s_snd_shutdown, .shutdown = msm_mi2s_snd_shutdown,
}; };
static struct snd_soc_ops msm_meta_mi2s_be_ops = {
.startup = msm_meta_mi2s_snd_startup,
.shutdown = msm_meta_mi2s_snd_shutdown,
};
static struct snd_soc_ops msm_auxpcm_be_ops = { static struct snd_soc_ops msm_auxpcm_be_ops = {
.startup = msm_snd_auxpcm_startup, .startup = msm_snd_auxpcm_startup,
}; };
@@ -7567,6 +7947,39 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = {
}; };
static struct snd_soc_dai_link msm_meta_mi2s_be_dai_links[] = {
{
.name = LPASS_BE_PRI_META_MI2S_RX,
.stream_name = "Primary META MI2S Playback",
.cpu_dai_name = "msm-dai-q6-meta-mi2s.4864",
.platform_name = "msm-pcm-routing",
.codec_name = "msm-stub-codec.1",
.codec_dai_name = "msm-stub-rx",
.no_pcm = 1,
.dpcm_playback = 1,
.id = MSM_BACKEND_DAI_PRI_META_MI2S_RX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
.ops = &msm_meta_mi2s_be_ops,
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
},
{
.name = LPASS_BE_SEC_META_MI2S_RX,
.stream_name = "Secondary META MI2S Playback",
.cpu_dai_name = "msm-dai-q6-meta-mi2s.4866",
.platform_name = "msm-pcm-routing",
.codec_name = "msm-stub-codec.1",
.codec_dai_name = "msm-stub-rx",
.no_pcm = 1,
.dpcm_playback = 1,
.id = MSM_BACKEND_DAI_SEC_META_MI2S_RX,
.be_hw_params_fixup = msm_be_hw_params_fixup,
.ops = &msm_meta_mi2s_be_ops,
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
},
};
static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = {
/* Primary AUX PCM Backend DAI Links */ /* Primary AUX PCM Backend DAI Links */
{ {
@@ -7885,6 +8298,7 @@ static struct snd_soc_dai_link msm_qcs405_dai_links[
ARRAY_SIZE(msm_tasha_be_dai_links) + ARRAY_SIZE(msm_tasha_be_dai_links) +
ARRAY_SIZE(msm_wcn_be_dai_links) + ARRAY_SIZE(msm_wcn_be_dai_links) +
ARRAY_SIZE(msm_mi2s_be_dai_links) + ARRAY_SIZE(msm_mi2s_be_dai_links) +
ARRAY_SIZE(msm_meta_mi2s_be_dai_links) +
ARRAY_SIZE(msm_auxpcm_be_dai_links) + ARRAY_SIZE(msm_auxpcm_be_dai_links) +
ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) + ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) +
ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) + ARRAY_SIZE(msm_wsa_cdc_dma_be_dai_links) +
@@ -8140,7 +8554,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
uint32_t tasha_codec = 0, auxpcm_audio_intf = 0; uint32_t tasha_codec = 0, auxpcm_audio_intf = 0;
uint32_t va_bolero_codec = 0, wsa_bolero_codec = 0, mi2s_audio_intf = 0; uint32_t va_bolero_codec = 0, wsa_bolero_codec = 0, mi2s_audio_intf = 0;
uint32_t spdif_audio_intf = 0, wcn_audio_intf = 0; uint32_t spdif_audio_intf = 0, wcn_audio_intf = 0;
uint32_t afe_loopback_intf = 0; uint32_t afe_loopback_intf = 0, meta_mi2s_intf = 0;
const struct of_device_id *match; const struct of_device_id *match;
char __iomem *spdif_cfg, *spdif_pin_ctl; char __iomem *spdif_cfg, *spdif_pin_ctl;
int rc = 0; int rc = 0;
@@ -8248,6 +8662,22 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
ARRAY_SIZE(msm_mi2s_be_dai_links); ARRAY_SIZE(msm_mi2s_be_dai_links);
} }
} }
rc = of_property_read_u32(dev->of_node, "qcom,meta-mi2s-intf",
&meta_mi2s_intf);
if (rc) {
dev_dbg(dev, "%s: No DT match META-MI2S interface\n",
__func__);
} else {
if (meta_mi2s_intf) {
memcpy(msm_qcs405_dai_links + total_links,
msm_meta_mi2s_be_dai_links,
sizeof(msm_meta_mi2s_be_dai_links));
total_links +=
ARRAY_SIZE(msm_meta_mi2s_be_dai_links);
}
}
rc = of_property_read_u32(dev->of_node, rc = of_property_read_u32(dev->of_node,
"qcom,auxpcm-audio-intf", "qcom,auxpcm-audio-intf",
&auxpcm_audio_intf); &auxpcm_audio_intf);
@@ -8807,6 +9237,81 @@ static void msm_i2s_auxpcm_deinit(void)
} }
} }
static void msm_meta_mi2s_init(struct platform_device *pdev)
{
int rc = 0;
int i = 0;
int index = 0;
bool parse_of = false;
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct snd_soc_dai_link *dai_link = card->dai_link;
dev_dbg(&pdev->dev, "%s: read from DT\n", __func__);
for (index = 0; index < META_MI2S_MAX; index++) {
meta_mi2s_intf_conf[index].num_member_ports = 0;
meta_mi2s_intf_conf[index].member_port[0] = 0;
meta_mi2s_intf_conf[index].member_port[1] = 0;
meta_mi2s_intf_conf[index].member_port[2] = 0;
meta_mi2s_intf_conf[index].member_port[3] = 0;
meta_mi2s_intf_conf[index].clk_enable[0] = false;
meta_mi2s_intf_conf[index].clk_enable[1] = false;
meta_mi2s_intf_conf[index].clk_enable[2] = false;
meta_mi2s_intf_conf[index].clk_enable[3] = false;
}
/* get member port info to set matching clocks for involved ports */
for (i = 0; i < card->num_links; i++) {
if (dai_link[i].id == MSM_BACKEND_DAI_PRI_META_MI2S_RX) {
parse_of = true;
index = PRIM_META_MI2S;
} else if (dai_link[i].id == MSM_BACKEND_DAI_SEC_META_MI2S_RX) {
parse_of = true;
index = SEC_META_MI2S;
} else {
parse_of = false;
}
if (parse_of && dai_link[i].cpu_of_node) {
rc = of_property_read_u32(dai_link[i].cpu_of_node,
"qcom,msm-mi2s-num-members",
&meta_mi2s_intf_conf[index].num_member_ports);
if (rc) {
dev_err(&pdev->dev, "%s: invalid num from DT file %s\n",
__func__, "qcom,msm-mi2s-num-members");
}
if (meta_mi2s_intf_conf[index].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_intf_conf[index].num_member_ports);
}
if (meta_mi2s_intf_conf[index].num_member_ports > 0) {
rc = of_property_read_u32_array(
dai_link[i].cpu_of_node,
"qcom,msm-mi2s-member-id",
meta_mi2s_intf_conf[index].member_port,
meta_mi2s_intf_conf[index].num_member_ports);
if (rc) {
dev_err(&pdev->dev, "%s: member-id from DT file %s\n",
__func__,
"qcom,msm-mi2s-member-id");
}
}
dev_dbg(&pdev->dev, "dev name %s num-members=%d\n",
dev_name(&pdev->dev),
meta_mi2s_intf_conf[index].num_member_ports);
dev_dbg(&pdev->dev, "member array (%d, %d, %d, %d)\n",
meta_mi2s_intf_conf[index].member_port[0],
meta_mi2s_intf_conf[index].member_port[1],
meta_mi2s_intf_conf[index].member_port[2],
meta_mi2s_intf_conf[index].member_port[3]);
}
}
}
static int msm_scan_i2c_addr(struct platform_device *pdev, static int msm_scan_i2c_addr(struct platform_device *pdev,
uint32_t busnum, uint32_t addr) uint32_t busnum, uint32_t addr)
{ {
@@ -8984,6 +9489,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
if (val) { if (val) {
pdata->codec_is_csra = true; pdata->codec_is_csra = true;
mi2s_rx_cfg[PRIM_MI2S].bit_format = SNDRV_PCM_FORMAT_S24_LE; mi2s_rx_cfg[PRIM_MI2S].bit_format = SNDRV_PCM_FORMAT_S24_LE;
meta_mi2s_rx_cfg[PRIM_META_MI2S].bit_format =
SNDRV_PCM_FORMAT_S24_LE;
ret = msm_init_csra_dev(pdev, card); ret = msm_init_csra_dev(pdev, card);
if (ret) if (ret)
goto err; goto err;
@@ -9065,6 +9572,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
msm_i2s_auxpcm_init(pdev); msm_i2s_auxpcm_init(pdev);
msm_meta_mi2s_init(pdev);
is_initial_boot = true; is_initial_boot = true;
return 0; return 0;
err: err: