Commit | Line | Data |
---|---|---|
05ae3231 ML |
1 | /* |
2 | * DB1200 ASoC audio fabric support code. | |
3 | * | |
adbc7a5a | 4 | * (c) 2008-2011 Manuel Lauss <manuel.lauss@googlemail.com> |
05ae3231 ML |
5 | * |
6 | */ | |
7 | ||
8 | #include <linux/module.h> | |
9 | #include <linux/moduleparam.h> | |
10 | #include <linux/timer.h> | |
11 | #include <linux/interrupt.h> | |
12 | #include <linux/platform_device.h> | |
13 | #include <sound/core.h> | |
14 | #include <sound/pcm.h> | |
15 | #include <sound/soc.h> | |
05ae3231 ML |
16 | #include <asm/mach-au1x00/au1000.h> |
17 | #include <asm/mach-au1x00/au1xxx_psc.h> | |
18 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | |
19 | #include <asm/mach-db1x00/bcsr.h> | |
20 | ||
05ae3231 ML |
21 | #include "../codecs/wm8731.h" |
22 | #include "psc.h" | |
23 | ||
adbc7a5a ML |
24 | static struct platform_device_id db1200_pids[] = { |
25 | { | |
26 | .name = "db1200-ac97", | |
27 | .driver_data = 0, | |
28 | }, { | |
29 | .name = "db1200-i2s", | |
30 | .driver_data = 1, | |
31 | }, | |
32 | {}, | |
33 | }; | |
34 | ||
05ae3231 ML |
35 | /*------------------------- AC97 PART ---------------------------*/ |
36 | ||
37 | static struct snd_soc_dai_link db1200_ac97_dai = { | |
38 | .name = "AC97", | |
39 | .stream_name = "AC97 HiFi", | |
f0fba2ad | 40 | .codec_dai_name = "ac97-hifi", |
ffc4fdbb ML |
41 | .cpu_dai_name = "au1xpsc_ac97.1", |
42 | .platform_name = "au1xpsc-pcm.1", | |
43 | .codec_name = "ac97-codec.1", | |
05ae3231 ML |
44 | }; |
45 | ||
46 | static struct snd_soc_card db1200_ac97_machine = { | |
47 | .name = "DB1200_AC97", | |
48 | .dai_link = &db1200_ac97_dai, | |
49 | .num_links = 1, | |
05ae3231 ML |
50 | }; |
51 | ||
52 | /*------------------------- I2S PART ---------------------------*/ | |
53 | ||
54 | static int db1200_i2s_startup(struct snd_pcm_substream *substream) | |
55 | { | |
56 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
f0fba2ad LG |
57 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
58 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | |
05ae3231 ML |
59 | int ret; |
60 | ||
61 | /* WM8731 has its own 12MHz crystal */ | |
9745e824 | 62 | snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, |
05ae3231 ML |
63 | 12000000, SND_SOC_CLOCK_IN); |
64 | ||
65 | /* codec is bitclock and lrclk master */ | |
66 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | | |
67 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | |
68 | if (ret < 0) | |
69 | goto out; | |
70 | ||
71 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_LEFT_J | | |
72 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | |
73 | if (ret < 0) | |
74 | goto out; | |
75 | ||
76 | ret = 0; | |
77 | out: | |
78 | return ret; | |
79 | } | |
80 | ||
81 | static struct snd_soc_ops db1200_i2s_wm8731_ops = { | |
82 | .startup = db1200_i2s_startup, | |
83 | }; | |
84 | ||
85 | static struct snd_soc_dai_link db1200_i2s_dai = { | |
86 | .name = "WM8731", | |
87 | .stream_name = "WM8731 PCM", | |
ffc4fdbb ML |
88 | .codec_dai_name = "wm8731-hifi", |
89 | .cpu_dai_name = "au1xpsc_i2s.1", | |
90 | .platform_name = "au1xpsc-pcm.1", | |
99b59f3c | 91 | .codec_name = "wm8731.0-001b", |
05ae3231 ML |
92 | .ops = &db1200_i2s_wm8731_ops, |
93 | }; | |
94 | ||
95 | static struct snd_soc_card db1200_i2s_machine = { | |
96 | .name = "DB1200_I2S", | |
97 | .dai_link = &db1200_i2s_dai, | |
98 | .num_links = 1, | |
05ae3231 ML |
99 | }; |
100 | ||
101 | /*------------------------- COMMON PART ---------------------------*/ | |
102 | ||
adbc7a5a ML |
103 | static struct snd_soc_card *db1200_cards[] __devinitdata = { |
104 | &db1200_ac97_machine, | |
105 | &db1200_i2s_machine, | |
106 | }; | |
05ae3231 | 107 | |
adbc7a5a | 108 | static int __devinit db1200_audio_probe(struct platform_device *pdev) |
05ae3231 | 109 | { |
adbc7a5a ML |
110 | const struct platform_device_id *pid = platform_get_device_id(pdev); |
111 | struct snd_soc_card *card; | |
05ae3231 | 112 | |
adbc7a5a ML |
113 | card = db1200_cards[pid->driver_data]; |
114 | card->dev = &pdev->dev; | |
115 | return snd_soc_register_card(card); | |
116 | } | |
05ae3231 | 117 | |
adbc7a5a ML |
118 | static int __devexit db1200_audio_remove(struct platform_device *pdev) |
119 | { | |
120 | struct snd_soc_card *card = platform_get_drvdata(pdev); | |
121 | snd_soc_unregister_card(card); | |
122 | return 0; | |
123 | } | |
05ae3231 | 124 | |
adbc7a5a ML |
125 | static struct platform_driver db1200_audio_driver = { |
126 | .driver = { | |
127 | .name = "db1200-ac97", | |
128 | .owner = THIS_MODULE, | |
129 | .pm = &snd_soc_pm_ops, | |
130 | }, | |
131 | .id_table = db1200_pids, | |
132 | .probe = db1200_audio_probe, | |
133 | .remove = __devexit_p(db1200_audio_remove), | |
134 | }; | |
05ae3231 | 135 | |
adbc7a5a ML |
136 | static int __init db1200_audio_load(void) |
137 | { | |
138 | return platform_driver_register(&db1200_audio_driver); | |
05ae3231 ML |
139 | } |
140 | ||
141 | static void __exit db1200_audio_unload(void) | |
142 | { | |
adbc7a5a | 143 | platform_driver_unregister(&db1200_audio_driver); |
05ae3231 ML |
144 | } |
145 | ||
146 | module_init(db1200_audio_load); | |
147 | module_exit(db1200_audio_unload); | |
148 | ||
149 | MODULE_LICENSE("GPL"); | |
150 | MODULE_DESCRIPTION("DB1200 ASoC audio support"); | |
151 | MODULE_AUTHOR("Manuel Lauss"); |