aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/s3c24xx
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/s3c24xx')
-rw-r--r--sound/soc/s3c24xx/Kconfig5
-rw-r--r--sound/soc/s3c24xx/Makefile2
-rw-r--r--sound/soc/s3c24xx/ln2440sbc_alc650.c8
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c9
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c38
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c30
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c35
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c12
-rw-r--r--sound/soc/s3c24xx/s3c24xx_uda134x.c373
-rw-r--r--sound/soc/s3c24xx/smdk2443_wm9710.c8
10 files changed, 478 insertions, 42 deletions
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index b9f2353effeb..fcd03acf10f6 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -44,3 +44,8 @@ config SND_S3C24XX_SOC_LN2440SBC_ALC650
44 Say Y if you want to add support for SoC audio on ln2440sbc 44 Say Y if you want to add support for SoC audio on ln2440sbc
45 with the ALC650. 45 with the ALC650.
46 46
47config SND_S3C24XX_SOC_S3C24XX_UDA134X
48 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
49 depends on SND_S3C24XX_SOC
50 select SND_S3C24XX_SOC_I2S
51 select SND_SOC_UDA134X
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index 0aa5fb0b9700..96b3f3f617d4 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -13,7 +13,9 @@ obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
13snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o 13snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
14snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o 14snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
15snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o 15snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
16snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
16 17
17obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 18obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
18obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o 19obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
19obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o 20obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
21obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c
index 4eab2c19c454..12c71482d258 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c
@@ -27,7 +27,7 @@
27#include "s3c24xx-pcm.h" 27#include "s3c24xx-pcm.h"
28#include "s3c24xx-ac97.h" 28#include "s3c24xx-ac97.h"
29 29
30static struct snd_soc_machine ln2440sbc; 30static struct snd_soc_card ln2440sbc;
31 31
32static struct snd_soc_dai_link ln2440sbc_dai[] = { 32static struct snd_soc_dai_link ln2440sbc_dai[] = {
33{ 33{
@@ -38,15 +38,15 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
38}, 38},
39}; 39};
40 40
41static struct snd_soc_machine ln2440sbc = { 41static struct snd_soc_card ln2440sbc = {
42 .name = "LN2440SBC", 42 .name = "LN2440SBC",
43 .platform = &s3c24xx_soc_platform,
43 .dai_link = ln2440sbc_dai, 44 .dai_link = ln2440sbc_dai,
44 .num_links = ARRAY_SIZE(ln2440sbc_dai), 45 .num_links = ARRAY_SIZE(ln2440sbc_dai),
45}; 46};
46 47
47static struct snd_soc_device ln2440sbc_snd_ac97_devdata = { 48static struct snd_soc_device ln2440sbc_snd_ac97_devdata = {
48 .machine = &ln2440sbc, 49 .card = &ln2440sbc,
49 .platform = &s3c24xx_soc_platform,
50 .codec_dev = &soc_codec_dev_ac97, 50 .codec_dev = &soc_codec_dev_ac97,
51}; 51};
52 52
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 87ddfefcc2fb..45bb12e8ea44 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -59,7 +59,7 @@
59#define NEO_CAPTURE_HEADSET 7 59#define NEO_CAPTURE_HEADSET 7
60#define NEO_CAPTURE_BLUETOOTH 8 60#define NEO_CAPTURE_BLUETOOTH 8
61 61
62static struct snd_soc_machine neo1973; 62static struct snd_soc_card neo1973;
63static struct i2c_client *i2c; 63static struct i2c_client *i2c;
64 64
65static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, 65static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
@@ -548,7 +548,6 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
548static struct snd_soc_dai bt_dai = { 548static struct snd_soc_dai bt_dai = {
549 .name = "Bluetooth", 549 .name = "Bluetooth",
550 .id = 0, 550 .id = 0,
551 .type = SND_SOC_DAI_PCM,
552 .playback = { 551 .playback = {
553 .channels_min = 1, 552 .channels_min = 1,
554 .channels_max = 1, 553 .channels_max = 1,
@@ -579,8 +578,9 @@ static struct snd_soc_dai_link neo1973_dai[] = {
579}, 578},
580}; 579};
581 580
582static struct snd_soc_machine neo1973 = { 581static struct snd_soc_card neo1973 = {
583 .name = "neo1973", 582 .name = "neo1973",
583 .platform = &s3c24xx_soc_platform,
584 .dai_link = neo1973_dai, 584 .dai_link = neo1973_dai,
585 .num_links = ARRAY_SIZE(neo1973_dai), 585 .num_links = ARRAY_SIZE(neo1973_dai),
586}; 586};
@@ -591,8 +591,7 @@ static struct wm8753_setup_data neo1973_wm8753_setup = {
591}; 591};
592 592
593static struct snd_soc_device neo1973_snd_devdata = { 593static struct snd_soc_device neo1973_snd_devdata = {
594 .machine = &neo1973, 594 .card = &neo1973,
595 .platform = &s3c24xx_soc_platform,
596 .codec_dev = &soc_codec_dev_wm8753, 595 .codec_dev = &soc_codec_dev_wm8753,
597 .codec_data = &neo1973_wm8753_setup, 596 .codec_data = &neo1973_wm8753_setup,
598}; 597};
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index ded7d995a922..f3fc0aba0aaf 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -343,7 +343,8 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
343} 343}
344 344
345static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, 345static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
346 struct snd_pcm_hw_params *params) 346 struct snd_pcm_hw_params *params,
347 struct snd_soc_dai *dai)
347{ 348{
348 struct snd_soc_pcm_runtime *rtd = substream->private_data; 349 struct snd_soc_pcm_runtime *rtd = substream->private_data;
349 u32 iismod; 350 u32 iismod;
@@ -373,7 +374,8 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
373 return 0; 374 return 0;
374} 375}
375 376
376static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 377static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
378 struct snd_soc_dai *dai)
377{ 379{
378 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 380 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
379 unsigned long irqs; 381 unsigned long irqs;
@@ -647,8 +649,7 @@ static int s3c2412_i2s_probe(struct platform_device *pdev,
647} 649}
648 650
649#ifdef CONFIG_PM 651#ifdef CONFIG_PM
650static int s3c2412_i2s_suspend(struct platform_device *dev, 652static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
651 struct snd_soc_dai *dai)
652{ 653{
653 struct s3c2412_i2s_info *i2s = &s3c2412_i2s; 654 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
654 u32 iismod; 655 u32 iismod;
@@ -663,25 +664,24 @@ static int s3c2412_i2s_suspend(struct platform_device *dev,
663 iismod = readl(i2s->regs + S3C2412_IISMOD); 664 iismod = readl(i2s->regs + S3C2412_IISMOD);
664 665
665 if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) 666 if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
666 dev_warn(&dev->dev, "%s: RXDMA active?\n", __func__); 667 pr_warning("%s: RXDMA active?\n", __func__);
667 668
668 if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) 669 if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
669 dev_warn(&dev->dev, "%s: TXDMA active?\n", __func__); 670 pr_warning("%s: TXDMA active?\n", __func__);
670 671
671 if (iismod & S3C2412_IISCON_IIS_ACTIVE) 672 if (iismod & S3C2412_IISCON_IIS_ACTIVE)
672 dev_warn(&dev->dev, "%s: IIS active\n", __func__); 673 pr_warning("%s: IIS active\n", __func__);
673 } 674 }
674 675
675 return 0; 676 return 0;
676} 677}
677 678
678static int s3c2412_i2s_resume(struct platform_device *pdev, 679static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
679 struct snd_soc_dai *dai)
680{ 680{
681 struct s3c2412_i2s_info *i2s = &s3c2412_i2s; 681 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
682 682
683 dev_info(&pdev->dev, "dai_active %d, IISMOD %08x, IISCON %08x\n", 683 pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
684 dai->active, i2s->suspend_iismod, i2s->suspend_iiscon); 684 dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
685 685
686 if (dai->active) { 686 if (dai->active) {
687 writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); 687 writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
@@ -711,7 +711,6 @@ static int s3c2412_i2s_resume(struct platform_device *pdev,
711struct snd_soc_dai s3c2412_i2s_dai = { 711struct snd_soc_dai s3c2412_i2s_dai = {
712 .name = "s3c2412-i2s", 712 .name = "s3c2412-i2s",
713 .id = 0, 713 .id = 0,
714 .type = SND_SOC_DAI_I2S,
715 .probe = s3c2412_i2s_probe, 714 .probe = s3c2412_i2s_probe,
716 .suspend = s3c2412_i2s_suspend, 715 .suspend = s3c2412_i2s_suspend,
717 .resume = s3c2412_i2s_resume, 716 .resume = s3c2412_i2s_resume,
@@ -730,8 +729,6 @@ struct snd_soc_dai s3c2412_i2s_dai = {
730 .ops = { 729 .ops = {
731 .trigger = s3c2412_i2s_trigger, 730 .trigger = s3c2412_i2s_trigger,
732 .hw_params = s3c2412_i2s_hw_params, 731 .hw_params = s3c2412_i2s_hw_params,
733 },
734 .dai_ops = {
735 .set_fmt = s3c2412_i2s_set_fmt, 732 .set_fmt = s3c2412_i2s_set_fmt,
736 .set_clkdiv = s3c2412_i2s_set_clkdiv, 733 .set_clkdiv = s3c2412_i2s_set_clkdiv,
737 .set_sysclk = s3c2412_i2s_set_sysclk, 734 .set_sysclk = s3c2412_i2s_set_sysclk,
@@ -739,6 +736,19 @@ struct snd_soc_dai s3c2412_i2s_dai = {
739}; 736};
740EXPORT_SYMBOL_GPL(s3c2412_i2s_dai); 737EXPORT_SYMBOL_GPL(s3c2412_i2s_dai);
741 738
739static int __init s3c2412_i2s_init(void)
740{
741 return snd_soc_register_dai(&s3c2412_i2s_dai);
742}
743module_init(s3c2412_i2s_init);
744
745static void __exit s3c2412_i2s_exit(void)
746{
747 snd_soc_unregister_dai(&s3c2412_i2s_dai);
748}
749module_exit(s3c2412_i2s_exit);
750
751
742/* Module information */ 752/* Module information */
743MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 753MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
744MODULE_DESCRIPTION("S3C2412 I2S SoC Interface"); 754MODULE_DESCRIPTION("S3C2412 I2S SoC Interface");
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
index 19c5c3cf5d8c..1bfce40bb2e4 100644
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c
@@ -271,7 +271,8 @@ static void s3c2443_ac97_remove(struct platform_device *pdev,
271} 271}
272 272
273static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream, 273static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params) 274 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai)
275{ 276{
276 struct snd_soc_pcm_runtime *rtd = substream->private_data; 277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
277 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 278 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -284,7 +285,8 @@ static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
284 return 0; 285 return 0;
285} 286}
286 287
287static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd) 288static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
289 struct snd_soc_dai *dai)
288{ 290{
289 u32 ac_glbctrl; 291 u32 ac_glbctrl;
290 292
@@ -313,7 +315,8 @@ static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd)
313} 315}
314 316
315static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream, 317static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
316 struct snd_pcm_hw_params *params) 318 struct snd_pcm_hw_params *params,
319 struct snd_soc_dai *dai)
317{ 320{
318 struct snd_soc_pcm_runtime *rtd = substream->private_data; 321 struct snd_soc_pcm_runtime *rtd = substream->private_data;
319 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 322 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -327,7 +330,7 @@ static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
327} 330}
328 331
329static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream, 332static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
330 int cmd) 333 int cmd, struct snd_soc_dai *dai)
331{ 334{
332 u32 ac_glbctrl; 335 u32 ac_glbctrl;
333 336
@@ -356,7 +359,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
356{ 359{
357 .name = "s3c2443-ac97", 360 .name = "s3c2443-ac97",
358 .id = 0, 361 .id = 0,
359 .type = SND_SOC_DAI_AC97, 362 .ac97_control = 1,
360 .probe = s3c2443_ac97_probe, 363 .probe = s3c2443_ac97_probe,
361 .remove = s3c2443_ac97_remove, 364 .remove = s3c2443_ac97_remove,
362 .playback = { 365 .playback = {
@@ -378,7 +381,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
378{ 381{
379 .name = "pxa2xx-ac97-mic", 382 .name = "pxa2xx-ac97-mic",
380 .id = 1, 383 .id = 1,
381 .type = SND_SOC_DAI_AC97, 384 .ac97_control = 1,
382 .capture = { 385 .capture = {
383 .stream_name = "AC97 Mic Capture", 386 .stream_name = "AC97 Mic Capture",
384 .channels_min = 1, 387 .channels_min = 1,
@@ -393,6 +396,21 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
393EXPORT_SYMBOL_GPL(s3c2443_ac97_dai); 396EXPORT_SYMBOL_GPL(s3c2443_ac97_dai);
394EXPORT_SYMBOL_GPL(soc_ac97_ops); 397EXPORT_SYMBOL_GPL(soc_ac97_ops);
395 398
399static int __init s3c2443_ac97_init(void)
400{
401 return snd_soc_register_dais(s3c2443_ac97_dai,
402 ARRAY_SIZE(s3c2443_ac97_dai));
403}
404module_init(s3c2443_ac97_init);
405
406static void __exit s3c2443_ac97_exit(void)
407{
408 snd_soc_unregister_dais(s3c2443_ac97_dai,
409 ARRAY_SIZE(s3c2443_ac97_dai));
410}
411module_exit(s3c2443_ac97_exit);
412
413
396MODULE_AUTHOR("Graeme Gregory"); 414MODULE_AUTHOR("Graeme Gregory");
397MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip"); 415MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip");
398MODULE_LICENSE("GPL"); 416MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index ba4476b55fbc..6f4d439b57aa 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -243,7 +243,8 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
243} 243}
244 244
245static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, 245static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
246 struct snd_pcm_hw_params *params) 246 struct snd_pcm_hw_params *params,
247 struct snd_soc_dai *dai)
247{ 248{
248 struct snd_soc_pcm_runtime *rtd = substream->private_data; 249 struct snd_soc_pcm_runtime *rtd = substream->private_data;
249 u32 iismod; 250 u32 iismod;
@@ -261,10 +262,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
261 262
262 switch (params_format(params)) { 263 switch (params_format(params)) {
263 case SNDRV_PCM_FORMAT_S8: 264 case SNDRV_PCM_FORMAT_S8:
265 iismod &= ~S3C2410_IISMOD_16BIT;
266 ((struct s3c24xx_pcm_dma_params *)
267 rtd->dai->cpu_dai->dma_data)->dma_size = 1;
264 break; 268 break;
265 case SNDRV_PCM_FORMAT_S16_LE: 269 case SNDRV_PCM_FORMAT_S16_LE:
266 iismod |= S3C2410_IISMOD_16BIT; 270 iismod |= S3C2410_IISMOD_16BIT;
271 ((struct s3c24xx_pcm_dma_params *)
272 rtd->dai->cpu_dai->dma_data)->dma_size = 2;
267 break; 273 break;
274 default:
275 return -EINVAL;
268 } 276 }
269 277
270 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); 278 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -272,7 +280,8 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
272 return 0; 280 return 0;
273} 281}
274 282
275static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 283static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
284 struct snd_soc_dai *dai)
276{ 285{
277 int ret = 0; 286 int ret = 0;
278 287
@@ -410,8 +419,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev,
410} 419}
411 420
412#ifdef CONFIG_PM 421#ifdef CONFIG_PM
413static int s3c24xx_i2s_suspend(struct platform_device *pdev, 422static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai)
414 struct snd_soc_dai *cpu_dai)
415{ 423{
416 DBG("Entered %s\n", __func__); 424 DBG("Entered %s\n", __func__);
417 425
@@ -425,8 +433,7 @@ static int s3c24xx_i2s_suspend(struct platform_device *pdev,
425 return 0; 433 return 0;
426} 434}
427 435
428static int s3c24xx_i2s_resume(struct platform_device *pdev, 436static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai)
429 struct snd_soc_dai *cpu_dai)
430{ 437{
431 DBG("Entered %s\n", __func__); 438 DBG("Entered %s\n", __func__);
432 clk_enable(s3c24xx_i2s.iis_clk); 439 clk_enable(s3c24xx_i2s.iis_clk);
@@ -452,7 +459,6 @@ static int s3c24xx_i2s_resume(struct platform_device *pdev,
452struct snd_soc_dai s3c24xx_i2s_dai = { 459struct snd_soc_dai s3c24xx_i2s_dai = {
453 .name = "s3c24xx-i2s", 460 .name = "s3c24xx-i2s",
454 .id = 0, 461 .id = 0,
455 .type = SND_SOC_DAI_I2S,
456 .probe = s3c24xx_i2s_probe, 462 .probe = s3c24xx_i2s_probe,
457 .suspend = s3c24xx_i2s_suspend, 463 .suspend = s3c24xx_i2s_suspend,
458 .resume = s3c24xx_i2s_resume, 464 .resume = s3c24xx_i2s_resume,
@@ -468,8 +474,7 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
468 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, 474 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
469 .ops = { 475 .ops = {
470 .trigger = s3c24xx_i2s_trigger, 476 .trigger = s3c24xx_i2s_trigger,
471 .hw_params = s3c24xx_i2s_hw_params,}, 477 .hw_params = s3c24xx_i2s_hw_params,
472 .dai_ops = {
473 .set_fmt = s3c24xx_i2s_set_fmt, 478 .set_fmt = s3c24xx_i2s_set_fmt,
474 .set_clkdiv = s3c24xx_i2s_set_clkdiv, 479 .set_clkdiv = s3c24xx_i2s_set_clkdiv,
475 .set_sysclk = s3c24xx_i2s_set_sysclk, 480 .set_sysclk = s3c24xx_i2s_set_sysclk,
@@ -477,6 +482,18 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
477}; 482};
478EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai); 483EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai);
479 484
485static int __init s3c24xx_i2s_init(void)
486{
487 return snd_soc_register_dai(&s3c24xx_i2s_dai);
488}
489module_init(s3c24xx_i2s_init);
490
491static void __exit s3c24xx_i2s_exit(void)
492{
493 snd_soc_unregister_dai(&s3c24xx_i2s_dai);
494}
495module_exit(s3c24xx_i2s_exit);
496
480/* Module information */ 497/* Module information */
481MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 498MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
482MODULE_DESCRIPTION("s3c24xx I2S SoC Interface"); 499MODULE_DESCRIPTION("s3c24xx I2S SoC Interface");
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index e13e614bada9..7c64d31d067e 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -465,6 +465,18 @@ struct snd_soc_platform s3c24xx_soc_platform = {
465}; 465};
466EXPORT_SYMBOL_GPL(s3c24xx_soc_platform); 466EXPORT_SYMBOL_GPL(s3c24xx_soc_platform);
467 467
468static int __init s3c24xx_soc_platform_init(void)
469{
470 return snd_soc_register_platform(&s3c24xx_soc_platform);
471}
472module_init(s3c24xx_soc_platform_init);
473
474static void __exit s3c24xx_soc_platform_exit(void)
475{
476 snd_soc_unregister_platform(&s3c24xx_soc_platform);
477}
478module_exit(s3c24xx_soc_platform_exit);
479
468MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 480MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
469MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module"); 481MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module");
470MODULE_LICENSE("GPL"); 482MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c
new file mode 100644
index 000000000000..a0a4d1832a14
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c
@@ -0,0 +1,373 @@
1/*
2 * Modifications by Christian Pellegrin <chripell@evolware.org>
3 *
4 * s3c24xx_uda134x.c -- S3C24XX_UDA134X ALSA SoC Audio board driver
5 *
6 * Copyright 2007 Dension Audio Systems Ltd.
7 * Author: Zoltan Devai
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/clk.h>
16#include <linux/mutex.h>
17#include <linux/gpio.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/s3c24xx_uda134x.h>
23#include <sound/uda134x.h>
24
25#include <asm/plat-s3c24xx/regs-iis.h>
26
27#include "s3c24xx-pcm.h"
28#include "s3c24xx-i2s.h"
29#include "../codecs/uda134x.h"
30
31
32/* #define ENFORCE_RATES 1 */
33/*
34 Unfortunately the S3C24XX in master mode has a limited capacity of
35 generating the clock for the codec. If you define this only rates
36 that are really available will be enforced. But be careful, most
37 user level application just want the usual sampling frequencies (8,
38 11.025, 22.050, 44.1 kHz) and anyway resampling is a costly
39 operation for embedded systems. So if you aren't very lucky or your
40 hardware engineer wasn't very forward-looking it's better to leave
41 this undefined. If you do so an approximate value for the requested
42 sampling rate in the range -/+ 5% will be chosen. If this in not
43 possible an error will be returned.
44*/
45
46static struct clk *xtal;
47static struct clk *pclk;
48/* this is need because we don't have a place where to keep the
49 * pointers to the clocks in each substream. We get the clocks only
50 * when we are actually using them so we don't block stuff like
51 * frequency change or oscillator power-off */
52static int clk_users;
53static DEFINE_MUTEX(clk_lock);
54
55static unsigned int rates[33 * 2];
56#ifdef ENFORCE_RATES
57static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
58 .count = ARRAY_SIZE(rates),
59 .list = rates,
60 .mask = 0,
61};
62#endif
63
64static struct platform_device *s3c24xx_uda134x_snd_device;
65
66static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
67{
68 int ret = 0;
69#ifdef ENFORCE_RATES
70 struct snd_pcm_runtime *runtime = substream->runtime;;
71#endif
72
73 mutex_lock(&clk_lock);
74 pr_debug("%s %d\n", __func__, clk_users);
75 if (clk_users == 0) {
76 xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
77 if (!xtal) {
78 printk(KERN_ERR "%s cannot get xtal\n", __func__);
79 ret = -EBUSY;
80 } else {
81 pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
82 "pclk");
83 if (!pclk) {
84 printk(KERN_ERR "%s cannot get pclk\n",
85 __func__);
86 clk_put(xtal);
87 ret = -EBUSY;
88 }
89 }
90 if (!ret) {
91 int i, j;
92
93 for (i = 0; i < 2; i++) {
94 int fs = i ? 256 : 384;
95
96 rates[i*33] = clk_get_rate(xtal) / fs;
97 for (j = 1; j < 33; j++)
98 rates[i*33 + j] = clk_get_rate(pclk) /
99 (j * fs);
100 }
101 }
102 }
103 clk_users += 1;
104 mutex_unlock(&clk_lock);
105 if (!ret) {
106#ifdef ENFORCE_RATES
107 ret = snd_pcm_hw_constraint_list(runtime, 0,
108 SNDRV_PCM_HW_PARAM_RATE,
109 &hw_constraints_rates);
110 if (ret < 0)
111 printk(KERN_ERR "%s cannot set constraints\n",
112 __func__);
113#endif
114 }
115 return ret;
116}
117
118static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
119{
120 mutex_lock(&clk_lock);
121 pr_debug("%s %d\n", __func__, clk_users);
122 clk_users -= 1;
123 if (clk_users == 0) {
124 clk_put(xtal);
125 xtal = NULL;
126 clk_put(pclk);
127 pclk = NULL;
128 }
129 mutex_unlock(&clk_lock);
130}
131
132static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
133 struct snd_pcm_hw_params *params)
134{
135 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
137 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
138 unsigned int clk = 0;
139 int ret = 0;
140 int clk_source, fs_mode;
141 unsigned long rate = params_rate(params);
142 long err, cerr;
143 unsigned int div;
144 int i, bi;
145
146 err = 999999;
147 bi = 0;
148 for (i = 0; i < 2*33; i++) {
149 cerr = rates[i] - rate;
150 if (cerr < 0)
151 cerr = -cerr;
152 if (cerr < err) {
153 err = cerr;
154 bi = i;
155 }
156 }
157 if (bi / 33 == 1)
158 fs_mode = S3C2410_IISMOD_256FS;
159 else
160 fs_mode = S3C2410_IISMOD_384FS;
161 if (bi % 33 == 0) {
162 clk_source = S3C24XX_CLKSRC_MPLL;
163 div = 1;
164 } else {
165 clk_source = S3C24XX_CLKSRC_PCLK;
166 div = bi % 33;
167 }
168 pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi);
169
170 clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate;
171 pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__,
172 fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
173 clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
174 div, clk, err);
175
176 if ((err * 100 / rate) > 5) {
177 printk(KERN_ERR "S3C24XX_UDA134X: effective frequency "
178 "too different from desired (%ld%%)\n",
179 err * 100 / rate);
180 return -EINVAL;
181 }
182
183 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
184 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
185 if (ret < 0)
186 return ret;
187
188 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
189 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
190 if (ret < 0)
191 return ret;
192
193 ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk,
194 SND_SOC_CLOCK_IN);
195 if (ret < 0)
196 return ret;
197
198 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, fs_mode);
199 if (ret < 0)
200 return ret;
201
202 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
203 S3C2410_IISMOD_32FS);
204 if (ret < 0)
205 return ret;
206
207 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
208 S3C24XX_PRESCALE(div, div));
209 if (ret < 0)
210 return ret;
211
212 /* set the codec system clock for DAC and ADC */
213 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
214 SND_SOC_CLOCK_OUT);
215 if (ret < 0)
216 return ret;
217
218 return 0;
219}
220
221static struct snd_soc_ops s3c24xx_uda134x_ops = {
222 .startup = s3c24xx_uda134x_startup,
223 .shutdown = s3c24xx_uda134x_shutdown,
224 .hw_params = s3c24xx_uda134x_hw_params,
225};
226
227static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
228 .name = "UDA134X",
229 .stream_name = "UDA134X",
230 .codec_dai = &uda134x_dai,
231 .cpu_dai = &s3c24xx_i2s_dai,
232 .ops = &s3c24xx_uda134x_ops,
233};
234
235static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
236 .name = "S3C24XX_UDA134X",
237 .platform = &s3c24xx_soc_platform,
238 .dai_link = &s3c24xx_uda134x_dai_link,
239 .num_links = 1,
240};
241
242static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins;
243
244static void setdat(int v)
245{
246 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0);
247}
248
249static void setclk(int v)
250{
251 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);
252}
253
254static void setmode(int v)
255{
256 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);
257}
258
259static struct uda134x_platform_data s3c24xx_uda134x = {
260 .l3 = {
261 .setdat = setdat,
262 .setclk = setclk,
263 .setmode = setmode,
264 .data_hold = 1,
265 .data_setup = 1,
266 .clock_high = 1,
267 .mode_hold = 1,
268 .mode = 1,
269 .mode_setup = 1,
270 },
271};
272
273static struct snd_soc_device s3c24xx_uda134x_snd_devdata = {
274 .card = &snd_soc_s3c24xx_uda134x,
275 .codec_dev = &soc_codec_dev_uda134x,
276 .codec_data = &s3c24xx_uda134x,
277};
278
279static int s3c24xx_uda134x_setup_pin(int pin, char *fun)
280{
281 if (gpio_request(pin, "s3c24xx_uda134x") < 0) {
282 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
283 "l3 %s pin already in use", fun);
284 return -EBUSY;
285 }
286 gpio_direction_output(pin, 0);
287 return 0;
288}
289
290static int s3c24xx_uda134x_probe(struct platform_device *pdev)
291{
292 int ret;
293
294 printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");
295
296 s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;
297 if (s3c24xx_uda134x_l3_pins == NULL) {
298 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
299 "unable to find platform data\n");
300 return -ENODEV;
301 }
302 s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;
303 s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;
304
305 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,
306 "data") < 0)
307 return -EBUSY;
308 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,
309 "clk") < 0) {
310 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
311 return -EBUSY;
312 }
313 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,
314 "mode") < 0) {
315 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
316 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
317 return -EBUSY;
318 }
319
320 s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);
321 if (!s3c24xx_uda134x_snd_device) {
322 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
323 "Unable to register\n");
324 return -ENOMEM;
325 }
326
327 platform_set_drvdata(s3c24xx_uda134x_snd_device,
328 &s3c24xx_uda134x_snd_devdata);
329 s3c24xx_uda134x_snd_devdata.dev = &s3c24xx_uda134x_snd_device->dev;
330 ret = platform_device_add(s3c24xx_uda134x_snd_device);
331 if (ret) {
332 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");
333 platform_device_put(s3c24xx_uda134x_snd_device);
334 }
335
336 return ret;
337}
338
339static int s3c24xx_uda134x_remove(struct platform_device *pdev)
340{
341 platform_device_unregister(s3c24xx_uda134x_snd_device);
342 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
343 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
344 gpio_free(s3c24xx_uda134x_l3_pins->l3_mode);
345 return 0;
346}
347
348static struct platform_driver s3c24xx_uda134x_driver = {
349 .probe = s3c24xx_uda134x_probe,
350 .remove = s3c24xx_uda134x_remove,
351 .driver = {
352 .name = "s3c24xx_uda134x",
353 .owner = THIS_MODULE,
354 },
355};
356
357static int __init s3c24xx_uda134x_init(void)
358{
359 return platform_driver_register(&s3c24xx_uda134x_driver);
360}
361
362static void __exit s3c24xx_uda134x_exit(void)
363{
364 platform_driver_unregister(&s3c24xx_uda134x_driver);
365}
366
367
368module_init(s3c24xx_uda134x_init);
369module_exit(s3c24xx_uda134x_exit);
370
371MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
372MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver");
373MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
index 8515d6ff03f2..a2a4f5323c17 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
@@ -23,7 +23,7 @@
23#include "s3c24xx-pcm.h" 23#include "s3c24xx-pcm.h"
24#include "s3c24xx-ac97.h" 24#include "s3c24xx-ac97.h"
25 25
26static struct snd_soc_machine smdk2443; 26static struct snd_soc_card smdk2443;
27 27
28static struct snd_soc_dai_link smdk2443_dai[] = { 28static struct snd_soc_dai_link smdk2443_dai[] = {
29{ 29{
@@ -34,15 +34,15 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
34}, 34},
35}; 35};
36 36
37static struct snd_soc_machine smdk2443 = { 37static struct snd_soc_card smdk2443 = {
38 .name = "SMDK2443", 38 .name = "SMDK2443",
39 .platform = &s3c24xx_soc_platform,
39 .dai_link = smdk2443_dai, 40 .dai_link = smdk2443_dai,
40 .num_links = ARRAY_SIZE(smdk2443_dai), 41 .num_links = ARRAY_SIZE(smdk2443_dai),
41}; 42};
42 43
43static struct snd_soc_device smdk2443_snd_ac97_devdata = { 44static struct snd_soc_device smdk2443_snd_ac97_devdata = {
44 .machine = &smdk2443, 45 .card = &smdk2443,
45 .platform = &s3c24xx_soc_platform,
46 .codec_dev = &soc_codec_dev_ac97, 46 .codec_dev = &soc_codec_dev_ac97,
47}; 47};
48 48