1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun // phycore-ac97.c -- SoC audio for imx_phycore in AC97 mode
4*4882a593Smuzhiyun //
5*4882a593Smuzhiyun // Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <linux/module.h>
8*4882a593Smuzhiyun #include <linux/moduleparam.h>
9*4882a593Smuzhiyun #include <linux/device.h>
10*4882a593Smuzhiyun #include <linux/i2c.h>
11*4882a593Smuzhiyun #include <sound/core.h>
12*4882a593Smuzhiyun #include <sound/pcm.h>
13*4882a593Smuzhiyun #include <sound/soc.h>
14*4882a593Smuzhiyun #include <asm/mach-types.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include "imx-audmux.h"
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun static struct snd_soc_card imx_phycore;
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun static const struct snd_soc_ops imx_phycore_hifi_ops = {
21*4882a593Smuzhiyun };
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun SND_SOC_DAILINK_DEFS(hifi,
24*4882a593Smuzhiyun DAILINK_COMP_ARRAY(COMP_CPU("imx-ssi.0")),
25*4882a593Smuzhiyun DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")),
26*4882a593Smuzhiyun DAILINK_COMP_ARRAY(COMP_PLATFORM("imx-ssi.0")));
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun .name = "HiFi",
31*4882a593Smuzhiyun .stream_name = "HiFi",
32*4882a593Smuzhiyun .ops = &imx_phycore_hifi_ops,
33*4882a593Smuzhiyun SND_SOC_DAILINK_REG(hifi),
34*4882a593Smuzhiyun },
35*4882a593Smuzhiyun };
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun static struct snd_soc_card imx_phycore = {
38*4882a593Smuzhiyun .name = "PhyCORE-ac97-audio",
39*4882a593Smuzhiyun .owner = THIS_MODULE,
40*4882a593Smuzhiyun .dai_link = imx_phycore_dai_ac97,
41*4882a593Smuzhiyun .num_links = ARRAY_SIZE(imx_phycore_dai_ac97),
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun static struct platform_device *imx_phycore_snd_ac97_device;
45*4882a593Smuzhiyun static struct platform_device *imx_phycore_snd_device;
46*4882a593Smuzhiyun
imx_phycore_init(void)47*4882a593Smuzhiyun static int __init imx_phycore_init(void)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun int ret;
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun if (machine_is_pca100()) {
52*4882a593Smuzhiyun imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
53*4882a593Smuzhiyun IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
54*4882a593Smuzhiyun IMX_AUDMUX_V1_PCR_TFCSEL(3) |
55*4882a593Smuzhiyun IMX_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
56*4882a593Smuzhiyun IMX_AUDMUX_V1_PCR_RXDSEL(3));
57*4882a593Smuzhiyun imx_audmux_v1_configure_port(3,
58*4882a593Smuzhiyun IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */
59*4882a593Smuzhiyun IMX_AUDMUX_V1_PCR_TFCSEL(0) |
60*4882a593Smuzhiyun IMX_AUDMUX_V1_PCR_TFSDIR |
61*4882a593Smuzhiyun IMX_AUDMUX_V1_PCR_RXDSEL(0));
62*4882a593Smuzhiyun } else if (machine_is_pcm043()) {
63*4882a593Smuzhiyun imx_audmux_v2_configure_port(3,
64*4882a593Smuzhiyun IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
65*4882a593Smuzhiyun IMX_AUDMUX_V2_PTCR_TFSEL(0) |
66*4882a593Smuzhiyun IMX_AUDMUX_V2_PTCR_TFSDIR,
67*4882a593Smuzhiyun IMX_AUDMUX_V2_PDCR_RXDSEL(0));
68*4882a593Smuzhiyun imx_audmux_v2_configure_port(0,
69*4882a593Smuzhiyun IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
70*4882a593Smuzhiyun IMX_AUDMUX_V2_PTCR_TCSEL(3) |
71*4882a593Smuzhiyun IMX_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
72*4882a593Smuzhiyun IMX_AUDMUX_V2_PDCR_RXDSEL(3));
73*4882a593Smuzhiyun } else {
74*4882a593Smuzhiyun /* return happy. We might run on a totally different machine */
75*4882a593Smuzhiyun return 0;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1);
79*4882a593Smuzhiyun if (!imx_phycore_snd_ac97_device)
80*4882a593Smuzhiyun return -ENOMEM;
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun platform_set_drvdata(imx_phycore_snd_ac97_device, &imx_phycore);
83*4882a593Smuzhiyun ret = platform_device_add(imx_phycore_snd_ac97_device);
84*4882a593Smuzhiyun if (ret)
85*4882a593Smuzhiyun goto fail1;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun imx_phycore_snd_device = platform_device_alloc("wm9712-codec", -1);
88*4882a593Smuzhiyun if (!imx_phycore_snd_device) {
89*4882a593Smuzhiyun ret = -ENOMEM;
90*4882a593Smuzhiyun goto fail2;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun ret = platform_device_add(imx_phycore_snd_device);
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun if (ret) {
95*4882a593Smuzhiyun printk(KERN_ERR "ASoC: Platform device allocation failed\n");
96*4882a593Smuzhiyun goto fail3;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun return 0;
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun fail3:
102*4882a593Smuzhiyun platform_device_put(imx_phycore_snd_device);
103*4882a593Smuzhiyun fail2:
104*4882a593Smuzhiyun platform_device_del(imx_phycore_snd_ac97_device);
105*4882a593Smuzhiyun fail1:
106*4882a593Smuzhiyun platform_device_put(imx_phycore_snd_ac97_device);
107*4882a593Smuzhiyun return ret;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun
imx_phycore_exit(void)110*4882a593Smuzhiyun static void __exit imx_phycore_exit(void)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun platform_device_unregister(imx_phycore_snd_device);
113*4882a593Smuzhiyun platform_device_unregister(imx_phycore_snd_ac97_device);
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun late_initcall(imx_phycore_init);
117*4882a593Smuzhiyun module_exit(imx_phycore_exit);
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
120*4882a593Smuzhiyun MODULE_DESCRIPTION("PhyCORE ALSA SoC driver");
121*4882a593Smuzhiyun MODULE_LICENSE("GPL");
122