aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/s3c24xx
diff options
context:
space:
mode:
authorBen Dooks <ben@simtec.co.uk>2009-08-20 17:50:40 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-21 05:52:42 -0400
commit14412acde5b57450b8afb3d4b03132419b6abebf (patch)
treec9b0e3c5897c842e74fd8f9fc6474ffec007f622 /sound/soc/s3c24xx
parenta0a499c5792b8656cd51e11d5e0db9fb21640f58 (diff)
ASoC: S3C24XX: Add audio core and tlv320aic23 for Simtec boards
Add core support for the range of S3C24XX Simtec boards with TLV320AIC23 CODECs on them. Since there are also boards with similar IIS routing the AMP and the configuration code is placed in a core file for re-use with other CODEC bindings. Signed-off-by: Ben Dooks <ben@simtec.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/s3c24xx')
-rw-r--r--sound/soc/s3c24xx/Kconfig12
-rw-r--r--sound/soc/s3c24xx/Makefile4
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec.c394
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec.h22
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c137
5 files changed, 569 insertions, 0 deletions
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index 2987239f1383..78cfd8d08e56 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -79,3 +79,15 @@ config SND_S3C24XX_SOC_S3C24XX_UDA134X
79 select SND_S3C24XX_SOC_I2S 79 select SND_S3C24XX_SOC_I2S
80 select SND_SOC_L3 80 select SND_SOC_L3
81 select SND_SOC_UDA134X 81 select SND_SOC_UDA134X
82
83config SND_S3C24XX_SOC_SIMTEC
84 tristate
85 help
86 Internal node for common S3C24XX/Simtec suppor
87
88config SND_S3C24XX_SOC_SIMTEC_TLV320AIC23
89 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
90 depends on SND_S3C24XX_SOC
91 select SND_S3C24XX_SOC_I2S
92 select SND_SOC_TLV320AIC23
93 select SND_S3C24XX_SOC_SIMTEC
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index eb219b016499..1ccbb877df3c 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -20,6 +20,8 @@ snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
20snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o 20snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
21snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o 21snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
22snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o 22snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
23snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
24snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
23 25
24obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o 26obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
25obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 27obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -27,3 +29,5 @@ obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm87
27obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o 29obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
28obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o 30obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
29obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o 31obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
32obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o
33obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c
new file mode 100644
index 000000000000..1966e0d5652d
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx_simtec.c
@@ -0,0 +1,394 @@
1/* sound/soc/s3c24xx/s3c24xx_simtec.c
2 *
3 * Copyright 2009 Simtec Electronics
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8*/
9
10#include <linux/module.h>
11#include <linux/moduleparam.h>
12#include <linux/platform_device.h>
13#include <linux/gpio.h>
14#include <linux/clk.h>
15#include <linux/i2c.h>
16
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21
22#include <plat/audio-simtec.h>
23
24#include "s3c24xx-pcm.h"
25#include "s3c24xx-i2s.h"
26#include "s3c24xx_simtec.h"
27
28static struct s3c24xx_audio_simtec_pdata *pdata;
29static struct clk *xtal_clk;
30
31static int spk_gain;
32static int spk_unmute;
33
34/**
35 * speaker_gain_get - read the speaker gain setting.
36 * @kcontrol: The control for the speaker gain.
37 * @ucontrol: The value that needs to be updated.
38 *
39 * Read the value for the AMP gain control.
40 */
41static int speaker_gain_get(struct snd_kcontrol *kcontrol,
42 struct snd_ctl_elem_value *ucontrol)
43{
44 ucontrol->value.integer.value[0] = spk_gain;
45 return 0;
46}
47
48/**
49 * speaker_gain_set - set the value of the speaker amp gain
50 * @value: The value to write.
51 */
52static void speaker_gain_set(int value)
53{
54 gpio_set_value_cansleep(pdata->amp_gain[0], value & 1);
55 gpio_set_value_cansleep(pdata->amp_gain[1], value >> 1);
56}
57
58/**
59 * speaker_gain_put - set the speaker gain setting.
60 * @kcontrol: The control for the speaker gain.
61 * @ucontrol: The value that needs to be set.
62 *
63 * Set the value of the speaker gain from the specified
64 * @ucontrol setting.
65 *
66 * Note, if the speaker amp is muted, then we do not set a gain value
67 * as at-least one of the ICs that is fitted will try and power up even
68 * if the main control is set to off.
69 */
70static int speaker_gain_put(struct snd_kcontrol *kcontrol,
71 struct snd_ctl_elem_value *ucontrol)
72{
73 int value = ucontrol->value.integer.value[0];
74
75 spk_gain = value;
76
77 if (!spk_unmute)
78 speaker_gain_set(value);
79
80 return 0;
81}
82
83static const struct snd_kcontrol_new amp_gain_controls[] = {
84 SOC_SINGLE_EXT("Speaker Gain", 0, 0, 3, 0,
85 speaker_gain_get, speaker_gain_put),
86};
87
88/**
89 * spk_unmute_state - set the unmute state of the speaker
90 * @to: zero to unmute, non-zero to ununmute.
91 */
92static void spk_unmute_state(int to)
93{
94 pr_debug("%s: to=%d\n", __func__, to);
95
96 spk_unmute = to;
97 gpio_set_value(pdata->amp_gpio, to);
98
99 /* if we're umuting, also re-set the gain */
100 if (to && pdata->amp_gain[0] > 0)
101 speaker_gain_set(spk_gain);
102}
103
104/**
105 * speaker_unmute_get - read the speaker unmute setting.
106 * @kcontrol: The control for the speaker gain.
107 * @ucontrol: The value that needs to be updated.
108 *
109 * Read the value for the AMP gain control.
110 */
111static int speaker_unmute_get(struct snd_kcontrol *kcontrol,
112 struct snd_ctl_elem_value *ucontrol)
113{
114 ucontrol->value.integer.value[0] = spk_unmute;
115 return 0;
116}
117
118/**
119 * speaker_unmute_put - set the speaker unmute setting.
120 * @kcontrol: The control for the speaker gain.
121 * @ucontrol: The value that needs to be set.
122 *
123 * Set the value of the speaker gain from the specified
124 * @ucontrol setting.
125 */
126static int speaker_unmute_put(struct snd_kcontrol *kcontrol,
127 struct snd_ctl_elem_value *ucontrol)
128{
129 spk_unmute_state(ucontrol->value.integer.value[0]);
130 return 0;
131}
132
133/* This is added as a manual control as the speaker amps create clicks
134 * when their power state is changed, which are far more noticeable than
135 * anything produced by the CODEC itself.
136 */
137static const struct snd_kcontrol_new amp_unmute_controls[] = {
138 SOC_SINGLE_EXT("Speaker Switch", 0, 0, 1, 0,
139 speaker_unmute_get, speaker_unmute_put),
140};
141
142void simtec_audio_init(struct snd_soc_codec *codec)
143{
144 if (pdata->amp_gpio > 0) {
145 pr_debug("%s: adding amp routes\n", __func__);
146
147 snd_soc_add_controls(codec, amp_unmute_controls,
148 ARRAY_SIZE(amp_unmute_controls));
149 }
150
151 if (pdata->amp_gain[0] > 0) {
152 pr_debug("%s: adding amp controls\n", __func__);
153 snd_soc_add_controls(codec, amp_gain_controls,
154 ARRAY_SIZE(amp_gain_controls));
155 }
156}
157EXPORT_SYMBOL_GPL(simtec_audio_init);
158
159#define CODEC_CLOCK 12000000
160
161/**
162 * simtec_hw_params - update hardware parameters
163 * @substream: The audio substream instance.
164 * @params: The parameters requested.
165 *
166 * Update the codec data routing and configuration settings
167 * from the supplied data.
168 */
169static int simtec_hw_params(struct snd_pcm_substream *substream,
170 struct snd_pcm_hw_params *params)
171{
172 struct snd_soc_pcm_runtime *rtd = substream->private_data;
173 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
174 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
175 int ret;
176
177 /* Set the CODEC as the bus clock master, I2S */
178 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
179 SND_SOC_DAIFMT_NB_NF |
180 SND_SOC_DAIFMT_CBM_CFM);
181 if (ret) {
182 pr_err("%s: failed set cpu dai format\n", __func__);
183 return ret;
184 }
185
186 /* Set the CODEC as the bus clock master */
187 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
188 SND_SOC_DAIFMT_NB_NF |
189 SND_SOC_DAIFMT_CBM_CFM);
190 if (ret) {
191 pr_err("%s: failed set codec dai format\n", __func__);
192 return ret;
193 }
194
195 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
196 CODEC_CLOCK, SND_SOC_CLOCK_IN);
197 if (ret) {
198 pr_err( "%s: failed setting codec sysclk\n", __func__);
199 return ret;
200 }
201
202 if (pdata->use_mpllin) {
203 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_MPLL,
204 0, SND_SOC_CLOCK_OUT);
205
206 if (ret) {
207 pr_err("%s: failed to set MPLLin as clksrc\n",
208 __func__);
209 return ret;
210 }
211 }
212
213 if (pdata->output_cdclk) {
214 int cdclk_scale;
215
216 cdclk_scale = clk_get_rate(xtal_clk) / CODEC_CLOCK;
217 cdclk_scale--;
218
219 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
220 cdclk_scale);
221 }
222
223 return 0;
224}
225
226static int simtec_call_startup(struct s3c24xx_audio_simtec_pdata *pd)
227{
228 /* call any board supplied startup code, this currently only
229 * covers the bast/vr1000 which have a CPLD in the way of the
230 * LRCLK */
231 if (pd->startup)
232 pd->startup();
233
234 return 0;
235}
236
237static struct snd_soc_ops simtec_snd_ops = {
238 .hw_params = simtec_hw_params,
239};
240
241/**
242 * attach_gpio_amp - get and configure the necessary gpios
243 * @dev: The device we're probing.
244 * @pd: The platform data supplied by the board.
245 *
246 * If there is a GPIO based amplifier attached to the board, claim
247 * the necessary GPIO lines for it, and set default values.
248 */
249static int attach_gpio_amp(struct device *dev,
250 struct s3c24xx_audio_simtec_pdata *pd)
251{
252 int ret;
253
254 /* attach gpio amp gain (if any) */
255 if (pdata->amp_gain[0] > 0) {
256 ret = gpio_request(pd->amp_gain[0], "gpio-amp-gain0");
257 if (ret) {
258 dev_err(dev, "cannot get amp gpio gain0\n");
259 return ret;
260 }
261
262 ret = gpio_request(pd->amp_gain[1], "gpio-amp-gain1");
263 if (ret) {
264 dev_err(dev, "cannot get amp gpio gain1\n");
265 gpio_free(pdata->amp_gain[0]);
266 return ret;
267 }
268
269 gpio_direction_output(pd->amp_gain[0], 0);
270 gpio_direction_output(pd->amp_gain[1], 0);
271 }
272
273 /* note, curently we assume GPA0 isn't valid amp */
274 if (pdata->amp_gpio > 0) {
275 ret = gpio_request(pd->amp_gpio, "gpio-amp");
276 if (ret) {
277 dev_err(dev, "cannot get amp gpio %d (%d)\n",
278 pd->amp_gpio, ret);
279 goto err_amp;
280 }
281
282 /* set the amp off at startup */
283 spk_unmute_state(0);
284 }
285
286 return 0;
287
288err_amp:
289 if (pd->amp_gain[0] > 0) {
290 gpio_free(pd->amp_gain[0]);
291 gpio_free(pd->amp_gain[1]);
292 }
293
294 return ret;
295}
296
297static void detach_gpio_amp(struct s3c24xx_audio_simtec_pdata *pd)
298{
299 if (pd->amp_gain[0] > 0) {
300 gpio_free(pd->amp_gain[0]);
301 gpio_free(pd->amp_gain[1]);
302 }
303
304 if (pd->amp_gpio > 0)
305 gpio_free(pd->amp_gpio);
306}
307
308#ifdef CONFIG_PM
309int simtec_audio_resume(struct device *dev)
310{
311 simtec_call_startup(pdata);
312 return 0;
313}
314
315struct dev_pm_ops simtec_audio_pmops = {
316 .resume = simtec_audio_resume,
317};
318EXPORT_SYMBOL_GPL(simtec_audio_pmops);
319#endif
320
321int __devinit simtec_audio_core_probe(struct platform_device *pdev,
322 struct snd_soc_device *socdev)
323{
324 struct platform_device *snd_dev;
325 int ret;
326
327 socdev->card->dai_link->ops = &simtec_snd_ops;
328
329 pdata = pdev->dev.platform_data;
330 if (!pdata) {
331 dev_err(&pdev->dev, "no platform data supplied\n");
332 return -EINVAL;
333 }
334
335 simtec_call_startup(pdata);
336
337 xtal_clk = clk_get(&pdev->dev, "xtal");
338 if (IS_ERR(xtal_clk)) {
339 dev_err(&pdev->dev, "could not get clkout0\n");
340 return -EINVAL;
341 }
342
343 dev_info(&pdev->dev, "xtal rate is %ld\n", clk_get_rate(xtal_clk));
344
345 ret = attach_gpio_amp(&pdev->dev, pdata);
346 if (ret)
347 goto err_clk;
348
349 snd_dev = platform_device_alloc("soc-audio", -1);
350 if (!snd_dev) {
351 dev_err(&pdev->dev, "failed to alloc soc-audio devicec\n");
352 ret = -ENOMEM;
353 goto err_gpio;
354 }
355
356 platform_set_drvdata(snd_dev, socdev);
357 socdev->dev = &snd_dev->dev;
358
359 ret = platform_device_add(snd_dev);
360 if (ret) {
361 dev_err(&pdev->dev, "failed to add soc-audio dev\n");
362 goto err_pdev;
363 }
364
365 platform_set_drvdata(pdev, snd_dev);
366 return 0;
367
368err_pdev:
369 platform_device_put(snd_dev);
370
371err_gpio:
372 detach_gpio_amp(pdata);
373
374err_clk:
375 clk_put(xtal_clk);
376 return ret;
377}
378EXPORT_SYMBOL_GPL(simtec_audio_core_probe);
379
380int __devexit simtec_audio_remove(struct platform_device *pdev)
381{
382 struct platform_device *snd_dev = platform_get_drvdata(pdev);
383
384 platform_device_unregister(snd_dev);
385
386 detach_gpio_amp(pdata);
387 clk_put(xtal_clk);
388 return 0;
389}
390EXPORT_SYMBOL_GPL(simtec_audio_remove);
391
392MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
393MODULE_DESCRIPTION("ALSA SoC Simtec Audio common support");
394MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/s3c24xx/s3c24xx_simtec.h
new file mode 100644
index 000000000000..2714203af161
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx_simtec.h
@@ -0,0 +1,22 @@
1/* sound/soc/s3c24xx/s3c24xx_simtec.h
2 *
3 * Copyright 2009 Simtec Electronics
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8*/
9
10extern void simtec_audio_init(struct snd_soc_codec *codec);
11
12extern int simtec_audio_core_probe(struct platform_device *pdev,
13 struct snd_soc_device *socdev);
14
15extern int simtec_audio_remove(struct platform_device *pdev);
16
17#ifdef CONFIG_PM
18extern struct dev_pm_ops simtec_audio_pmops;
19#define simtec_audio_pm &simtec_audio_pmops
20#else
21#define simtec_audio_pm NULL
22#endif
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
new file mode 100644
index 000000000000..25797e096175
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
@@ -0,0 +1,137 @@
1/* sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
2 *
3 * Copyright 2009 Simtec Electronics
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8*/
9
10#include <linux/module.h>
11#include <linux/clk.h>
12#include <linux/platform_device.h>
13
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/soc.h>
17#include <sound/soc-dapm.h>
18
19#include <plat/audio-simtec.h>
20
21#include "s3c24xx-pcm.h"
22#include "s3c24xx-i2s.h"
23#include "s3c24xx_simtec.h"
24
25#include "../codecs/tlv320aic23.h"
26
27/* supported machines:
28 *
29 * Machine Connections AMP
30 * ------- ----------- ---
31 * BAST MIC, HPOUT, LOUT, LIN TPA2001D1 (HPOUTL,R) (gain hardwired)
32 * VR1000 HPOUT, LIN None
33 * VR2000 LIN, LOUT, MIC, HP LM4871 (HPOUTL,R)
34 * DePicture LIN, LOUT, MIC, HP LM4871 (HPOUTL,R)
35 * Anubis LIN, LOUT, MIC, HP TPA2001D1 (HPOUTL,R)
36 */
37
38static const struct snd_soc_dapm_widget dapm_widgets[] = {
39 SND_SOC_DAPM_HP("Headphone Jack", NULL),
40 SND_SOC_DAPM_LINE("Line In", NULL),
41 SND_SOC_DAPM_LINE("Line Out", NULL),
42 SND_SOC_DAPM_MIC("Mic Jack", NULL),
43};
44
45static const struct snd_soc_dapm_route base_map[] = {
46 { "Headphone Jack", NULL, "LHPOUT"},
47 { "Headphone Jack", NULL, "RHPOUT"},
48
49 { "Line Out", NULL, "LOUT" },
50 { "Line Out", NULL, "ROUT" },
51
52 { "LLINEIN", NULL, "Line In"},
53 { "RLINEIN", NULL, "Line In"},
54
55 { "MICIN", NULL, "Mic Jack"},
56};
57
58/**
59 * simtec_tlv320aic23_init - initialise and add controls
60 * @codec; The codec instance to attach to.
61 *
62 * Attach our controls and configure the necessary codec
63 * mappings for our sound card instance.
64*/
65static int simtec_tlv320aic23_init(struct snd_soc_codec *codec)
66{
67 snd_soc_dapm_new_controls(codec, dapm_widgets,
68 ARRAY_SIZE(dapm_widgets));
69
70 snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map));
71
72 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
73 snd_soc_dapm_enable_pin(codec, "Line In");
74 snd_soc_dapm_enable_pin(codec, "Line Out");
75 snd_soc_dapm_enable_pin(codec, "Mic Jack");
76
77 simtec_audio_init(codec);
78 snd_soc_dapm_sync(codec);
79
80 return 0;
81}
82
83static struct snd_soc_dai_link simtec_dai_aic23 = {
84 .name = "tlv320aic23",
85 .stream_name = "TLV320AIC23",
86 .cpu_dai = &s3c24xx_i2s_dai,
87 .codec_dai = &tlv320aic23_dai,
88 .init = simtec_tlv320aic23_init,
89};
90
91/* simtec audio machine driver */
92static struct snd_soc_card snd_soc_machine_simtec_aic23 = {
93 .name = "Simtec",
94 .platform = &s3c24xx_soc_platform,
95 .dai_link = &simtec_dai_aic23,
96 .num_links = 1,
97};
98
99/* simtec audio subsystem */
100static struct snd_soc_device simtec_snd_devdata_aic23 = {
101 .card = &snd_soc_machine_simtec_aic23,
102 .codec_dev = &soc_codec_dev_tlv320aic23,
103};
104
105static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd)
106{
107 return simtec_audio_core_probe(pd, &simtec_snd_devdata_aic23);
108}
109
110static struct platform_driver simtec_audio_tlv320aic23_platdrv = {
111 .driver = {
112 .owner = THIS_MODULE,
113 .name = "s3c24xx-simtec-tlv320aic23",
114 .pm = simtec_audio_pm,
115 },
116 .probe = simtec_audio_tlv320aic23_probe,
117 .remove = __devexit_p(simtec_audio_remove),
118};
119
120MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23");
121
122static int __init simtec_tlv320aic23_modinit(void)
123{
124 return platform_driver_register(&simtec_audio_tlv320aic23_platdrv);
125}
126
127static void __exit simtec_tlv320aic23_modexit(void)
128{
129 platform_driver_unregister(&simtec_audio_tlv320aic23_platdrv);
130}
131
132module_init(simtec_tlv320aic23_modinit);
133module_exit(simtec_tlv320aic23_modexit);
134
135MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
136MODULE_DESCRIPTION("ALSA SoC Simtec Audio support");
137MODULE_LICENSE("GPL");