1 // SPDX-License-Identifier: GPL-2.0
3 // Phytec pcm030 driver for the PSC of the Freescale MPC52xx
4 // configured as AC97 interface
6 // Copyright 2008 Jon Smirl, Digispeaker
7 // Author: Jon Smirl <jonsmirl@gmail.com>
9 #include <linux/init.h>
10 #include <linux/module.h>
11 #include <linux/device.h>
12 #include <linux/of_device.h>
13 #include <linux/of_platform.h>
15 #include <sound/soc.h>
17 #include "mpc5200_dma.h"
19 #define DRV_NAME "pcm030-audio-fabric"
21 struct pcm030_audio_data
{
22 struct snd_soc_card
*card
;
23 struct platform_device
*codec_device
;
26 SND_SOC_DAILINK_DEFS(analog
,
27 DAILINK_COMP_ARRAY(COMP_CPU("mpc5200-psc-ac97.0")),
28 DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")),
29 DAILINK_COMP_ARRAY(COMP_EMPTY()));
31 SND_SOC_DAILINK_DEFS(iec958
,
32 DAILINK_COMP_ARRAY(COMP_CPU("mpc5200-psc-ac97.1")),
33 DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")),
34 DAILINK_COMP_ARRAY(COMP_EMPTY()));
36 static struct snd_soc_dai_link pcm030_fabric_dai
[] = {
39 .stream_name
= "AC97 Analog",
40 SND_SOC_DAILINK_REG(analog
),
44 .stream_name
= "AC97 IEC958",
45 SND_SOC_DAILINK_REG(iec958
),
49 static struct snd_soc_card pcm030_card
= {
52 .dai_link
= pcm030_fabric_dai
,
53 .num_links
= ARRAY_SIZE(pcm030_fabric_dai
),
56 static int pcm030_fabric_probe(struct platform_device
*op
)
58 struct device_node
*np
= op
->dev
.of_node
;
59 struct device_node
*platform_np
;
60 struct snd_soc_card
*card
= &pcm030_card
;
61 struct pcm030_audio_data
*pdata
;
62 struct snd_soc_dai_link
*dai_link
;
66 if (!of_machine_is_compatible("phytec,pcm030"))
69 pdata
= devm_kzalloc(&op
->dev
, sizeof(struct pcm030_audio_data
),
78 platform_np
= of_parse_phandle(np
, "asoc-platform", 0);
80 dev_err(&op
->dev
, "ac97 not registered\n");
84 for_each_card_prelinks(card
, i
, dai_link
)
85 dai_link
->platforms
->of_node
= platform_np
;
87 ret
= request_module("snd-soc-wm9712");
89 dev_err(&op
->dev
, "request_module returned: %d\n", ret
);
91 pdata
->codec_device
= platform_device_alloc("wm9712-codec", -1);
92 if (!pdata
->codec_device
)
93 dev_err(&op
->dev
, "platform_device_alloc() failed\n");
95 ret
= platform_device_add(pdata
->codec_device
);
97 dev_err(&op
->dev
, "platform_device_add() failed: %d\n", ret
);
99 ret
= snd_soc_register_card(card
);
101 dev_err(&op
->dev
, "snd_soc_register_card() failed: %d\n", ret
);
103 platform_set_drvdata(op
, pdata
);
108 static int pcm030_fabric_remove(struct platform_device
*op
)
110 struct pcm030_audio_data
*pdata
= platform_get_drvdata(op
);
113 ret
= snd_soc_unregister_card(pdata
->card
);
114 platform_device_unregister(pdata
->codec_device
);
119 static const struct of_device_id pcm030_audio_match
[] = {
120 { .compatible
= "phytec,pcm030-audio-fabric", },
123 MODULE_DEVICE_TABLE(of
, pcm030_audio_match
);
125 static struct platform_driver pcm030_fabric_driver
= {
126 .probe
= pcm030_fabric_probe
,
127 .remove
= pcm030_fabric_remove
,
130 .of_match_table
= pcm030_audio_match
,
134 module_platform_driver(pcm030_fabric_driver
);
137 MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
138 MODULE_DESCRIPTION(DRV_NAME
": mpc5200 pcm030 fabric driver");
139 MODULE_LICENSE("GPL");