summaryrefslogtreecommitdiffstats
path: root/sound/soc/mediatek
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/mediatek')
-rw-r--r--sound/soc/mediatek/mt8173-max98090.c19
-rw-r--r--sound/soc/mediatek/mt8173-rt5650-rt5676.c21
-rw-r--r--sound/soc/mediatek/mtk-afe-common.h8
-rw-r--r--sound/soc/mediatek/mtk-afe-pcm.c91
4 files changed, 109 insertions, 30 deletions
diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173-max98090.c
index 4d44b58..684e8a7 100644
--- a/sound/soc/mediatek/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173-max98090.c
@@ -103,7 +103,6 @@ static struct snd_soc_dai_link mt8173_max98090_dais[] = {
.name = "MAX98090 Playback",
.stream_name = "MAX98090 Playback",
.cpu_dai_name = "DL1",
- .platform_name = "11220000.mt8173-afe-pcm",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
@@ -114,7 +113,6 @@ static struct snd_soc_dai_link mt8173_max98090_dais[] = {
.name = "MAX98090 Capture",
.stream_name = "MAX98090 Capture",
.cpu_dai_name = "VUL",
- .platform_name = "11220000.mt8173-afe-pcm",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
@@ -125,7 +123,6 @@ static struct snd_soc_dai_link mt8173_max98090_dais[] = {
{
.name = "Codec",
.cpu_dai_name = "I2S",
- .platform_name = "11220000.mt8173-afe-pcm",
.no_pcm = 1,
.codec_dai_name = "HiFi",
.init = mt8173_max98090_init,
@@ -139,6 +136,7 @@ static struct snd_soc_dai_link mt8173_max98090_dais[] = {
static struct snd_soc_card mt8173_max98090_card = {
.name = "mt8173-max98090",
+ .owner = THIS_MODULE,
.dai_link = mt8173_max98090_dais,
.num_links = ARRAY_SIZE(mt8173_max98090_dais),
.controls = mt8173_max98090_controls,
@@ -152,9 +150,21 @@ static struct snd_soc_card mt8173_max98090_card = {
static int mt8173_max98090_dev_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &mt8173_max98090_card;
- struct device_node *codec_node;
+ struct device_node *codec_node, *platform_node;
int ret, i;
+ platform_node = of_parse_phandle(pdev->dev.of_node,
+ "mediatek,platform", 0);
+ if (!platform_node) {
+ dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < card->num_links; i++) {
+ if (mt8173_max98090_dais[i].platform_name)
+ continue;
+ mt8173_max98090_dais[i].platform_of_node = platform_node;
+ }
+
codec_node = of_parse_phandle(pdev->dev.of_node,
"mediatek,audio-codec", 0);
if (!codec_node) {
@@ -193,7 +203,6 @@ MODULE_DEVICE_TABLE(of, mt8173_max98090_dt_match);
static struct platform_driver mt8173_max98090_driver = {
.driver = {
.name = "mt8173-max98090",
- .owner = THIS_MODULE,
.of_match_table = mt8173_max98090_dt_match,
#ifdef CONFIG_PM
.pm = &snd_soc_pm_ops,
diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
index 0940553..86cf975 100644
--- a/sound/soc/mediatek/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
@@ -138,7 +138,6 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
.name = "rt5650_rt5676 Playback",
.stream_name = "rt5650_rt5676 Playback",
.cpu_dai_name = "DL1",
- .platform_name = "11220000.mt8173-afe-pcm",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
@@ -149,7 +148,6 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
.name = "rt5650_rt5676 Capture",
.stream_name = "rt5650_rt5676 Capture",
.cpu_dai_name = "VUL",
- .platform_name = "11220000.mt8173-afe-pcm",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
@@ -161,7 +159,6 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
{
.name = "Codec",
.cpu_dai_name = "I2S",
- .platform_name = "11220000.mt8173-afe-pcm",
.no_pcm = 1,
.codecs = mt8173_rt5650_rt5676_codecs,
.num_codecs = 2,
@@ -194,6 +191,7 @@ static struct snd_soc_codec_conf mt8173_rt5650_rt5676_codec_conf[] = {
static struct snd_soc_card mt8173_rt5650_rt5676_card = {
.name = "mtk-rt5650-rt5676",
+ .owner = THIS_MODULE,
.dai_link = mt8173_rt5650_rt5676_dais,
.num_links = ARRAY_SIZE(mt8173_rt5650_rt5676_dais),
.codec_conf = mt8173_rt5650_rt5676_codec_conf,
@@ -209,7 +207,21 @@ static struct snd_soc_card mt8173_rt5650_rt5676_card = {
static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &mt8173_rt5650_rt5676_card;
- int ret;
+ struct device_node *platform_node;
+ int i, ret;
+
+ platform_node = of_parse_phandle(pdev->dev.of_node,
+ "mediatek,platform", 0);
+ if (!platform_node) {
+ dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < card->num_links; i++) {
+ if (mt8173_rt5650_rt5676_dais[i].platform_name)
+ continue;
+ mt8173_rt5650_rt5676_dais[i].platform_of_node = platform_node;
+ }
mt8173_rt5650_rt5676_codecs[0].of_node =
of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 0);
@@ -258,7 +270,6 @@ MODULE_DEVICE_TABLE(of, mt8173_rt5650_rt5676_dt_match);
static struct platform_driver mt8173_rt5650_rt5676_driver = {
.driver = {
.name = "mtk-rt5650-rt5676",
- .owner = THIS_MODULE,
.of_match_table = mt8173_rt5650_rt5676_dt_match,
#ifdef CONFIG_PM
.pm = &snd_soc_pm_ops,
diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h
index a88b175..cc4393c 100644
--- a/sound/soc/mediatek/mtk-afe-common.h
+++ b/sound/soc/mediatek/mtk-afe-common.h
@@ -98,12 +98,4 @@ struct mtk_afe_memif {
const struct mtk_afe_irq_data *irqdata;
};
-struct mtk_afe {
- /* address for ioremap audio hardware register */
- void __iomem *base_addr;
- struct device *dev;
- struct regmap *regmap;
- struct mtk_afe_memif memif[MTK_AFE_MEMIF_NUM];
- struct clk *clocks[MTK_CLK_NUM];
-};
#endif
diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c
index cc228db..d190fe0 100644
--- a/sound/soc/mediatek/mtk-afe-pcm.c
+++ b/sound/soc/mediatek/mtk-afe-pcm.c
@@ -45,18 +45,21 @@
/* Memory interface */
#define AFE_DL1_BASE 0x0040
#define AFE_DL1_CUR 0x0044
+#define AFE_DL1_END 0x0048
#define AFE_DL2_BASE 0x0050
#define AFE_DL2_CUR 0x0054
#define AFE_AWB_BASE 0x0070
#define AFE_AWB_CUR 0x007c
#define AFE_VUL_BASE 0x0080
#define AFE_VUL_CUR 0x008c
+#define AFE_VUL_END 0x0088
#define AFE_DAI_BASE 0x0090
#define AFE_DAI_CUR 0x009c
#define AFE_MOD_PCM_BASE 0x0330
#define AFE_MOD_PCM_CUR 0x033c
#define AFE_HDMI_OUT_BASE 0x0374
#define AFE_HDMI_OUT_CUR 0x0378
+#define AFE_HDMI_OUT_END 0x037c
#define AFE_ADDA2_TOP_CON0 0x0600
@@ -127,6 +130,34 @@ enum afe_tdm_ch_start {
AFE_TDM_CH_ZERO,
};
+static const unsigned int mtk_afe_backup_list[] = {
+ AUDIO_TOP_CON0,
+ AFE_CONN1,
+ AFE_CONN2,
+ AFE_CONN7,
+ AFE_CONN8,
+ AFE_DAC_CON1,
+ AFE_DL1_BASE,
+ AFE_DL1_END,
+ AFE_VUL_BASE,
+ AFE_VUL_END,
+ AFE_HDMI_OUT_BASE,
+ AFE_HDMI_OUT_END,
+ AFE_HDMI_CONN0,
+ AFE_DAC_CON0,
+};
+
+struct mtk_afe {
+ /* address for ioremap audio hardware register */
+ void __iomem *base_addr;
+ struct device *dev;
+ struct regmap *regmap;
+ struct mtk_afe_memif memif[MTK_AFE_MEMIF_NUM];
+ struct clk *clocks[MTK_CLK_NUM];
+ unsigned int backup_regs[ARRAY_SIZE(mtk_afe_backup_list)];
+ bool suspended;
+};
+
static const struct snd_pcm_hardware mtk_afe_hardware = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -722,11 +753,53 @@ static const struct snd_soc_dai_ops mtk_afe_hdmi_ops = {
};
+static int mtk_afe_runtime_suspend(struct device *dev);
+static int mtk_afe_runtime_resume(struct device *dev);
+
+static int mtk_afe_dai_suspend(struct snd_soc_dai *dai)
+{
+ struct mtk_afe *afe = snd_soc_dai_get_drvdata(dai);
+ int i;
+
+ dev_dbg(afe->dev, "%s\n", __func__);
+ if (pm_runtime_status_suspended(afe->dev) || afe->suspended)
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(mtk_afe_backup_list); i++)
+ regmap_read(afe->regmap, mtk_afe_backup_list[i],
+ &afe->backup_regs[i]);
+
+ afe->suspended = true;
+ mtk_afe_runtime_suspend(afe->dev);
+ return 0;
+}
+
+static int mtk_afe_dai_resume(struct snd_soc_dai *dai)
+{
+ struct mtk_afe *afe = snd_soc_dai_get_drvdata(dai);
+ int i = 0;
+
+ dev_dbg(afe->dev, "%s\n", __func__);
+ if (pm_runtime_status_suspended(afe->dev) || !afe->suspended)
+ return 0;
+
+ mtk_afe_runtime_resume(afe->dev);
+
+ for (i = 0; i < ARRAY_SIZE(mtk_afe_backup_list); i++)
+ regmap_write(afe->regmap, mtk_afe_backup_list[i],
+ afe->backup_regs[i]);
+
+ afe->suspended = false;
+ return 0;
+}
+
static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = {
/* FE DAIs: memory intefaces to CPU */
{
.name = "DL1", /* downlink 1 */
.id = MTK_AFE_MEMIF_DL1,
+ .suspend = mtk_afe_dai_suspend,
+ .resume = mtk_afe_dai_resume,
.playback = {
.stream_name = "DL1",
.channels_min = 1,
@@ -738,6 +811,8 @@ static struct snd_soc_dai_driver mtk_afe_pcm_dais[] = {
}, {
.name = "VUL", /* voice uplink */
.id = MTK_AFE_MEMIF_VUL,
+ .suspend = mtk_afe_dai_suspend,
+ .resume = mtk_afe_dai_resume,
.capture = {
.stream_name = "VUL",
.channels_min = 1,
@@ -774,6 +849,8 @@ static struct snd_soc_dai_driver mtk_afe_hdmi_dais[] = {
{
.name = "HDMI",
.id = MTK_AFE_MEMIF_HDMI,
+ .suspend = mtk_afe_dai_suspend,
+ .resume = mtk_afe_dai_resume,
.playback = {
.stream_name = "HDMI",
.channels_min = 2,
@@ -820,10 +897,6 @@ static const struct snd_kcontrol_new mtk_afe_o10_mix[] = {
};
static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = {
- /* Backend DAIs */
- SND_SOC_DAPM_AIF_IN("I2S Capture", NULL, 0, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_AIF_OUT("I2S Playback", NULL, 0, SND_SOC_NOPM, 0, 0),
-
/* inter-connections */
SND_SOC_DAPM_MIXER("I05", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("I06", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -855,11 +928,6 @@ static const struct snd_soc_dapm_route mtk_afe_pcm_routes[] = {
{ "O10", "I18 Switch", "I18" },
};
-static const struct snd_soc_dapm_widget mtk_afe_hdmi_widgets[] = {
- /* Backend DAIs */
- SND_SOC_DAPM_AIF_OUT("HDMIO Playback", NULL, 0, SND_SOC_NOPM, 0, 0),
-};
-
static const struct snd_soc_dapm_route mtk_afe_hdmi_routes[] = {
{"HDMIO Playback", NULL, "HDMI"},
};
@@ -874,8 +942,6 @@ static const struct snd_soc_component_driver mtk_afe_pcm_dai_component = {
static const struct snd_soc_component_driver mtk_afe_hdmi_dai_component = {
.name = "mtk-afe-hdmi-dai",
- .dapm_widgets = mtk_afe_hdmi_widgets,
- .num_dapm_widgets = ARRAY_SIZE(mtk_afe_hdmi_widgets),
.dapm_routes = mtk_afe_hdmi_routes,
.num_dapm_routes = ARRAY_SIZE(mtk_afe_hdmi_routes),
};
@@ -1199,6 +1265,8 @@ err_pm_disable:
static int mtk_afe_pcm_dev_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
+ if (!pm_runtime_status_suspended(&pdev->dev))
+ mtk_afe_runtime_suspend(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
snd_soc_unregister_platform(&pdev->dev);
return 0;
@@ -1218,7 +1286,6 @@ static const struct dev_pm_ops mtk_afe_pm_ops = {
static struct platform_driver mtk_afe_pcm_driver = {
.driver = {
.name = "mtk-afe-pcm",
- .owner = THIS_MODULE,
.of_match_table = mtk_afe_pcm_dt_match,
.pm = &mtk_afe_pm_ops,
},
OpenPOWER on IntegriCloud