Commit c7e076de authored by Mark Brown's avatar Mark Brown

ASoC: mt8188: add new board support

Merge series from Trevor Wu <trevor.wu@mediatek.com>:

In the series, we extend the capability of mt8188-mt6359 driver.

The following changes are included.
1. Divide ADDA BE dai into two dais for SOF.
2. Register hdmi/dp jack pins.
3. dai_fmt can be configured from device tree.
4. Add some I2S codecs support.

In addition, new compatible string "mediatek,mt8188-nau8825" is
included for a new board support.
parents 1499febc ee02b869
...@@ -11,7 +11,9 @@ maintainers: ...@@ -11,7 +11,9 @@ maintainers:
properties: properties:
compatible: compatible:
const: mediatek,mt8188-mt6359-evb enum:
- mediatek,mt8188-mt6359-evb
- mediatek,mt8188-nau8825
model: model:
$ref: /schemas/types.yaml#/definitions/string $ref: /schemas/types.yaml#/definitions/string
...@@ -42,7 +44,6 @@ patternProperties: ...@@ -42,7 +44,6 @@ patternProperties:
we are going to update parameters in this node. we are going to update parameters in this node.
items: items:
enum: enum:
- ADDA_BE
- DPTX_BE - DPTX_BE
- ETDM1_IN_BE - ETDM1_IN_BE
- ETDM2_IN_BE - ETDM2_IN_BE
...@@ -62,11 +63,28 @@ patternProperties: ...@@ -62,11 +63,28 @@ patternProperties:
required: required:
- sound-dai - sound-dai
dai-format:
description: audio format.
items:
enum:
- i2s
- right_j
- left_j
- dsp_a
- dsp_b
mediatek,clk-provider:
$ref: /schemas/types.yaml#/definitions/string
description: Indicates dai-link clock master.
items:
enum:
- cpu
- codec
additionalProperties: false additionalProperties: false
required: required:
- link-name - link-name
- codec
additionalProperties: false additionalProperties: false
...@@ -87,7 +105,8 @@ examples: ...@@ -87,7 +105,8 @@ examples:
"AIN1", "Headset Mic"; "AIN1", "Headset Mic";
dai-link-0 { dai-link-0 {
link-name = "ETDM3_OUT_BE"; link-name = "ETDM3_OUT_BE";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec { codec {
sound-dai = <&hdmi0>; sound-dai = <&hdmi0>;
}; };
......
...@@ -225,6 +225,10 @@ config SND_SOC_MT8188_MT6359 ...@@ -225,6 +225,10 @@ config SND_SOC_MT8188_MT6359
depends on SND_SOC_MT8188 && MTK_PMIC_WRAP depends on SND_SOC_MT8188 && MTK_PMIC_WRAP
select SND_SOC_MT6359 select SND_SOC_MT6359
select SND_SOC_HDMI_CODEC select SND_SOC_HDMI_CODEC
select SND_SOC_DMIC
select SND_SOC_MAX98390
select SND_SOC_NAU8315
select SND_SOC_NAU8825
help help
This adds support for ASoC machine driver for MediaTek MT8188 This adds support for ASoC machine driver for MediaTek MT8188
boards with the MT6359 and other I2S audio codecs. boards with the MT6359 and other I2S audio codecs.
......
...@@ -21,8 +21,10 @@ static int set_card_codec_info(struct snd_soc_card *card, ...@@ -21,8 +21,10 @@ static int set_card_codec_info(struct snd_soc_card *card,
int ret; int ret;
codec_node = of_get_child_by_name(sub_node, "codec"); codec_node = of_get_child_by_name(sub_node, "codec");
if (!codec_node) if (!codec_node) {
return -EINVAL; dev_dbg(dev, "%s no specified codec\n", dai_link->name);
return 0;
}
/* set card codec info */ /* set card codec info */
ret = snd_soc_of_get_dai_link_codecs(dev, codec_node, dai_link); ret = snd_soc_of_get_dai_link_codecs(dev, codec_node, dai_link);
...@@ -36,6 +38,47 @@ static int set_card_codec_info(struct snd_soc_card *card, ...@@ -36,6 +38,47 @@ static int set_card_codec_info(struct snd_soc_card *card,
return 0; return 0;
} }
static int set_dailink_daifmt(struct snd_soc_card *card,
struct device_node *sub_node,
struct snd_soc_dai_link *dai_link)
{
unsigned int daifmt;
const char *str;
int ret;
struct {
char *name;
unsigned int val;
} of_clk_table[] = {
{ "cpu", SND_SOC_DAIFMT_CBC_CFC },
{ "codec", SND_SOC_DAIFMT_CBP_CFP },
};
daifmt = snd_soc_daifmt_parse_format(sub_node, NULL);
if (daifmt) {
dai_link->dai_fmt &= SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
dai_link->dai_fmt |= daifmt;
}
/*
* check "mediatek,clk-provider = xxx"
* SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK area
*/
ret = of_property_read_string(sub_node, "mediatek,clk-provider", &str);
if (ret == 0) {
int i;
for (i = 0; i < ARRAY_SIZE(of_clk_table); i++) {
if (strcmp(str, of_clk_table[i].name) == 0) {
dai_link->dai_fmt &= ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
dai_link->dai_fmt |= of_clk_table[i].val;
break;
}
}
}
return 0;
}
int parse_dai_link_info(struct snd_soc_card *card) int parse_dai_link_info(struct snd_soc_card *card)
{ {
struct device *dev = card->dev; struct device *dev = card->dev;
...@@ -67,6 +110,12 @@ int parse_dai_link_info(struct snd_soc_card *card) ...@@ -67,6 +110,12 @@ int parse_dai_link_info(struct snd_soc_card *card)
of_node_put(sub_node); of_node_put(sub_node);
return ret; return ret;
} }
ret = set_dailink_daifmt(card, sub_node, dai_link);
if (ret < 0) {
of_node_put(sub_node);
return ret;
}
} }
return 0; return 0;
......
...@@ -39,7 +39,7 @@ enum { ...@@ -39,7 +39,7 @@ enum {
MT8188_AFE_MEMIF_END, MT8188_AFE_MEMIF_END,
MT8188_AFE_MEMIF_NUM = (MT8188_AFE_MEMIF_END - MT8188_AFE_MEMIF_START), MT8188_AFE_MEMIF_NUM = (MT8188_AFE_MEMIF_END - MT8188_AFE_MEMIF_START),
MT8188_AFE_IO_START = MT8188_AFE_MEMIF_END, MT8188_AFE_IO_START = MT8188_AFE_MEMIF_END,
MT8188_AFE_IO_ADDA = MT8188_AFE_IO_START, MT8188_AFE_IO_DL_SRC = MT8188_AFE_IO_START,
MT8188_AFE_IO_DMIC_IN, MT8188_AFE_IO_DMIC_IN,
MT8188_AFE_IO_DPTX, MT8188_AFE_IO_DPTX,
MT8188_AFE_IO_ETDM_START, MT8188_AFE_IO_ETDM_START,
...@@ -52,6 +52,7 @@ enum { ...@@ -52,6 +52,7 @@ enum {
MT8188_AFE_IO_ETDM_NUM = MT8188_AFE_IO_ETDM_NUM =
(MT8188_AFE_IO_ETDM_END - MT8188_AFE_IO_ETDM_START), (MT8188_AFE_IO_ETDM_END - MT8188_AFE_IO_ETDM_START),
MT8188_AFE_IO_PCM = MT8188_AFE_IO_ETDM_END, MT8188_AFE_IO_PCM = MT8188_AFE_IO_ETDM_END,
MT8188_AFE_IO_UL_SRC,
MT8188_AFE_IO_END, MT8188_AFE_IO_END,
MT8188_AFE_IO_NUM = (MT8188_AFE_IO_END - MT8188_AFE_IO_START), MT8188_AFE_IO_NUM = (MT8188_AFE_IO_END - MT8188_AFE_IO_START),
MT8188_DAI_END = MT8188_AFE_IO_END, MT8188_DAI_END = MT8188_AFE_IO_END,
......
...@@ -53,8 +53,7 @@ enum { ...@@ -53,8 +53,7 @@ enum {
}; };
struct mtk_dai_adda_priv { struct mtk_dai_adda_priv {
unsigned int dl_rate; bool hires_required;
unsigned int ul_rate;
}; };
static unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe, static unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe,
...@@ -241,42 +240,35 @@ static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w, ...@@ -241,42 +240,35 @@ static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
return 0; return 0;
} }
static int mtk_afe_adc_hires_connect(struct snd_soc_dapm_widget *source, static struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe,
struct snd_soc_dapm_widget *sink) const char *name)
{ {
struct snd_soc_dapm_widget *w = source;
struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
struct mt8188_afe_private *afe_priv = afe->platform_priv; struct mt8188_afe_private *afe_priv = afe->platform_priv;
struct mtk_dai_adda_priv *adda_priv;
adda_priv = afe_priv->dai_priv[MT8188_AFE_IO_ADDA];
if (!adda_priv) { if (strstr(name, "aud_adc_hires"))
dev_err(afe->dev, "%s adda_priv == NULL", __func__); return afe_priv->dai_priv[MT8188_AFE_IO_UL_SRC];
return 0; else if (strstr(name, "aud_dac_hires"))
} return afe_priv->dai_priv[MT8188_AFE_IO_DL_SRC];
else
return !!(adda_priv->ul_rate > ADDA_HIRES_THRES); return NULL;
} }
static int mtk_afe_dac_hires_connect(struct snd_soc_dapm_widget *source, static int mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink) struct snd_soc_dapm_widget *sink)
{ {
struct snd_soc_dapm_widget *w = source; struct snd_soc_dapm_widget *w = source;
struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
struct mt8188_afe_private *afe_priv = afe->platform_priv;
struct mtk_dai_adda_priv *adda_priv; struct mtk_dai_adda_priv *adda_priv;
adda_priv = afe_priv->dai_priv[MT8188_AFE_IO_ADDA]; adda_priv = get_adda_priv_by_name(afe, w->name);
if (!adda_priv) { if (!adda_priv) {
dev_err(afe->dev, "%s adda_priv == NULL", __func__); dev_dbg(afe->dev, "adda_priv == NULL");
return 0; return 0;
} }
return !!(adda_priv->dl_rate > ADDA_HIRES_THRES); return (adda_priv->hires_required) ? 1 : 0;
} }
static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = { static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {
...@@ -361,7 +353,7 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { ...@@ -361,7 +353,7 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
{"ADDA Capture", NULL, "ADDA Capture Enable"}, {"ADDA Capture", NULL, "ADDA Capture Enable"},
{"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"}, {"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
{"ADDA Capture", NULL, "aud_adc"}, {"ADDA Capture", NULL, "aud_adc"},
{"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adc_hires_connect}, {"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adda_hires_connect},
{"I168", NULL, "ADDA Capture"}, {"I168", NULL, "ADDA Capture"},
{"I169", NULL, "ADDA Capture"}, {"I169", NULL, "ADDA Capture"},
...@@ -369,7 +361,7 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { ...@@ -369,7 +361,7 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
{"ADDA Playback", NULL, "ADDA Enable"}, {"ADDA Playback", NULL, "ADDA Enable"},
{"ADDA Playback", NULL, "ADDA Playback Enable"}, {"ADDA Playback", NULL, "ADDA Playback Enable"},
{"ADDA Playback", NULL, "aud_dac"}, {"ADDA Playback", NULL, "aud_dac"},
{"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_dac_hires_connect}, {"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_adda_hires_connect},
{"DL_GAIN", NULL, "O176"}, {"DL_GAIN", NULL, "O176"},
{"DL_GAIN", NULL, "O177"}, {"DL_GAIN", NULL, "O177"},
...@@ -503,13 +495,12 @@ static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream, ...@@ -503,13 +495,12 @@ static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %u\n", dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %u\n",
__func__, id, substream->stream, rate); __func__, id, substream->stream, rate);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { adda_priv->hires_required = (rate > ADDA_HIRES_THRES);
adda_priv->dl_rate = rate;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = mtk_dai_da_configure(afe, rate, id); ret = mtk_dai_da_configure(afe, rate, id);
} else { else
adda_priv->ul_rate = rate;
ret = mtk_dai_ad_configure(afe, rate, id); ret = mtk_dai_ad_configure(afe, rate, id);
}
return ret; return ret;
} }
...@@ -536,8 +527,8 @@ static const struct snd_soc_dai_ops mtk_dai_adda_ops = { ...@@ -536,8 +527,8 @@ static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
{ {
.name = "ADDA", .name = "DL_SRC",
.id = MT8188_AFE_IO_ADDA, .id = MT8188_AFE_IO_DL_SRC,
.playback = { .playback = {
.stream_name = "ADDA Playback", .stream_name = "ADDA Playback",
.channels_min = 1, .channels_min = 1,
...@@ -545,6 +536,11 @@ static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { ...@@ -545,6 +536,11 @@ static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
.rates = MTK_ADDA_PLAYBACK_RATES, .rates = MTK_ADDA_PLAYBACK_RATES,
.formats = MTK_ADDA_FORMATS, .formats = MTK_ADDA_FORMATS,
}, },
.ops = &mtk_dai_adda_ops,
},
{
.name = "UL_SRC",
.id = MT8188_AFE_IO_UL_SRC,
.capture = { .capture = {
.stream_name = "ADDA Capture", .stream_name = "ADDA Capture",
.channels_min = 1, .channels_min = 1,
...@@ -560,13 +556,18 @@ static int init_adda_priv_data(struct mtk_base_afe *afe) ...@@ -560,13 +556,18 @@ static int init_adda_priv_data(struct mtk_base_afe *afe)
{ {
struct mt8188_afe_private *afe_priv = afe->platform_priv; struct mt8188_afe_private *afe_priv = afe->platform_priv;
struct mtk_dai_adda_priv *adda_priv; struct mtk_dai_adda_priv *adda_priv;
int adda_dai_list[] = {MT8188_AFE_IO_DL_SRC, MT8188_AFE_IO_UL_SRC};
int i;
adda_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_adda_priv), for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) {
GFP_KERNEL); adda_priv = devm_kzalloc(afe->dev,
if (!adda_priv) sizeof(struct mtk_dai_adda_priv),
return -ENOMEM; GFP_KERNEL);
if (!adda_priv)
return -ENOMEM;
afe_priv->dai_priv[MT8188_AFE_IO_ADDA] = adda_priv; afe_priv->dai_priv[adda_dai_list[i]] = adda_priv;
}
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -2216,6 +2216,16 @@ static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w) ...@@ -2216,6 +2216,16 @@ static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
&dapm_widget_power_fops); &dapm_widget_power_fops);
} }
static void dapm_debugfs_free_widget(struct snd_soc_dapm_widget *w)
{
struct snd_soc_dapm_context *dapm = w->dapm;
if (!dapm->debugfs_dapm || !w->name)
return;
debugfs_lookup_and_remove(w->name, dapm->debugfs_dapm);
}
static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm) static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
{ {
debugfs_remove_recursive(dapm->debugfs_dapm); debugfs_remove_recursive(dapm->debugfs_dapm);
...@@ -2232,6 +2242,10 @@ static inline void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w) ...@@ -2232,6 +2242,10 @@ static inline void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
{ {
} }
static inline void dapm_debugfs_free_widget(struct snd_soc_dapm_widget *w)
{
}
static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm) static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
{ {
} }
...@@ -2495,6 +2509,8 @@ void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w) ...@@ -2495,6 +2509,8 @@ void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w)
dapm_free_path(p); dapm_free_path(p);
} }
dapm_debugfs_free_widget(w);
kfree(w->kcontrols); kfree(w->kcontrols);
kfree_const(w->name); kfree_const(w->name);
kfree_const(w->sname); kfree_const(w->sname);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment