aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/s3c24xx
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/s3c24xx')
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c16
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c91
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c2
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c157
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h6
5 files changed, 195 insertions, 77 deletions
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 289fadf60b10..906709e6dd5f 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -345,9 +345,11 @@ static void lm4857_write_regs(void)
345static int lm4857_get_reg(struct snd_kcontrol *kcontrol, 345static int lm4857_get_reg(struct snd_kcontrol *kcontrol,
346 struct snd_ctl_elem_value *ucontrol) 346 struct snd_ctl_elem_value *ucontrol)
347{ 347{
348 int reg = kcontrol->private_value & 0xFF; 348 struct soc_mixer_control *mc =
349 int shift = (kcontrol->private_value >> 8) & 0x0F; 349 (struct soc_mixer_control *)kcontrol->private_value;
350 int mask = (kcontrol->private_value >> 16) & 0xFF; 350 int reg = mc->reg;
351 int shift = mc->shift;
352 int mask = mc->max;
351 353
352 pr_debug("Entered %s\n", __func__); 354 pr_debug("Entered %s\n", __func__);
353 355
@@ -358,9 +360,11 @@ static int lm4857_get_reg(struct snd_kcontrol *kcontrol,
358static int lm4857_set_reg(struct snd_kcontrol *kcontrol, 360static int lm4857_set_reg(struct snd_kcontrol *kcontrol,
359 struct snd_ctl_elem_value *ucontrol) 361 struct snd_ctl_elem_value *ucontrol)
360{ 362{
361 int reg = kcontrol->private_value & 0xFF; 363 struct soc_mixer_control *mc =
362 int shift = (kcontrol->private_value >> 8) & 0x0F; 364 (struct soc_mixer_control *)kcontrol->private_value;
363 int mask = (kcontrol->private_value >> 16) & 0xFF; 365 int reg = mc->reg;
366 int shift = mc->shift;
367 int mask = mc->max;
364 368
365 if (((lm4857_regs[reg] >> shift) & mask) == 369 if (((lm4857_regs[reg] >> shift) & mask) ==
366 ucontrol->value.integer.value[0]) 370 ucontrol->value.integer.value[0])
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index ab680aac3fcb..1a283170ca92 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -37,6 +37,20 @@
37 37
38#include "s3c-i2s-v2.h" 38#include "s3c-i2s-v2.h"
39 39
40#undef S3C_IIS_V2_SUPPORTED
41
42#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
43#define S3C_IIS_V2_SUPPORTED
44#endif
45
46#ifdef CONFIG_PLAT_S3C64XX
47#define S3C_IIS_V2_SUPPORTED
48#endif
49
50#ifndef S3C_IIS_V2_SUPPORTED
51#error Unsupported CPU model
52#endif
53
40#define S3C2412_I2S_DEBUG_CON 0 54#define S3C2412_I2S_DEBUG_CON 0
41 55
42static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) 56static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
@@ -75,7 +89,7 @@ static inline void dbg_showcon(const char *fn, u32 con)
75 89
76 90
77/* Turn on or off the transmission path. */ 91/* Turn on or off the transmission path. */
78void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) 92static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
79{ 93{
80 void __iomem *regs = i2s->regs; 94 void __iomem *regs = i2s->regs;
81 u32 fic, con, mod; 95 u32 fic, con, mod;
@@ -105,7 +119,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
105 break; 119 break;
106 120
107 default: 121 default:
108 dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n"); 122 dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n",
123 mod & S3C2412_IISMOD_MODE_MASK);
124 break;
109 } 125 }
110 126
111 writel(con, regs + S3C2412_IISCON); 127 writel(con, regs + S3C2412_IISCON);
@@ -132,7 +148,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
132 break; 148 break;
133 149
134 default: 150 default:
135 dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n"); 151 dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n",
152 mod & S3C2412_IISMOD_MODE_MASK);
153 break;
136 } 154 }
137 155
138 writel(mod, regs + S3C2412_IISMOD); 156 writel(mod, regs + S3C2412_IISMOD);
@@ -143,9 +161,8 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
143 dbg_showcon(__func__, con); 161 dbg_showcon(__func__, con);
144 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); 162 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
145} 163}
146EXPORT_SYMBOL_GPL(s3c2412_snd_txctrl);
147 164
148void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) 165static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
149{ 166{
150 void __iomem *regs = i2s->regs; 167 void __iomem *regs = i2s->regs;
151 u32 fic, con, mod; 168 u32 fic, con, mod;
@@ -175,7 +192,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
175 break; 192 break;
176 193
177 default: 194 default:
178 dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); 195 dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n",
196 mod & S3C2412_IISMOD_MODE_MASK);
179 } 197 }
180 198
181 writel(mod, regs + S3C2412_IISMOD); 199 writel(mod, regs + S3C2412_IISMOD);
@@ -199,7 +217,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
199 break; 217 break;
200 218
201 default: 219 default:
202 dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); 220 dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n",
221 mod & S3C2412_IISMOD_MODE_MASK);
203 } 222 }
204 223
205 writel(con, regs + S3C2412_IISCON); 224 writel(con, regs + S3C2412_IISCON);
@@ -209,7 +228,6 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
209 fic = readl(regs + S3C2412_IISFIC); 228 fic = readl(regs + S3C2412_IISFIC);
210 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); 229 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
211} 230}
212EXPORT_SYMBOL_GPL(s3c2412_snd_rxctrl);
213 231
214/* 232/*
215 * Wait for the LR signal to allow synchronisation to the L/R clock 233 * Wait for the LR signal to allow synchronisation to the L/R clock
@@ -266,7 +284,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
266 */ 284 */
267#define IISMOD_MASTER_MASK (1 << 11) 285#define IISMOD_MASTER_MASK (1 << 11)
268#define IISMOD_SLAVE (1 << 11) 286#define IISMOD_SLAVE (1 << 11)
269#define IISMOD_MASTER (0x0) 287#define IISMOD_MASTER (0 << 11)
270#endif 288#endif
271 289
272 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 290 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -281,7 +299,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
281 iismod |= IISMOD_MASTER; 299 iismod |= IISMOD_MASTER;
282 break; 300 break;
283 default: 301 default:
284 pr_debug("unknwon master/slave format\n"); 302 pr_err("unknwon master/slave format\n");
285 return -EINVAL; 303 return -EINVAL;
286 } 304 }
287 305
@@ -298,7 +316,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
298 iismod |= S3C2412_IISMOD_SDF_IIS; 316 iismod |= S3C2412_IISMOD_SDF_IIS;
299 break; 317 break;
300 default: 318 default:
301 pr_debug("Unknown data format\n"); 319 pr_err("Unknown data format\n");
302 return -EINVAL; 320 return -EINVAL;
303 } 321 }
304 322
@@ -327,6 +345,7 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
327 iismod = readl(i2s->regs + S3C2412_IISMOD); 345 iismod = readl(i2s->regs + S3C2412_IISMOD);
328 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); 346 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
329 347
348#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
330 switch (params_format(params)) { 349 switch (params_format(params)) {
331 case SNDRV_PCM_FORMAT_S8: 350 case SNDRV_PCM_FORMAT_S8:
332 iismod |= S3C2412_IISMOD_8BIT; 351 iismod |= S3C2412_IISMOD_8BIT;
@@ -335,6 +354,25 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
335 iismod &= ~S3C2412_IISMOD_8BIT; 354 iismod &= ~S3C2412_IISMOD_8BIT;
336 break; 355 break;
337 } 356 }
357#endif
358
359#ifdef CONFIG_PLAT_S3C64XX
360 iismod &= ~0x606;
361 /* Sample size */
362 switch (params_format(params)) {
363 case SNDRV_PCM_FORMAT_S8:
364 /* 8 bit sample, 16fs BCLK */
365 iismod |= 0x2004;
366 break;
367 case SNDRV_PCM_FORMAT_S16_LE:
368 /* 16 bit sample, 32fs BCLK */
369 break;
370 case SNDRV_PCM_FORMAT_S24_LE:
371 /* 24 bit sample, 48fs BCLK */
372 iismod |= 0x4002;
373 break;
374 }
375#endif
338 376
339 writel(iismod, i2s->regs + S3C2412_IISMOD); 377 writel(iismod, i2s->regs + S3C2412_IISMOD);
340 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); 378 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
@@ -489,6 +527,8 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
489 unsigned int best_rate = 0; 527 unsigned int best_rate = 0;
490 unsigned int best_deviation = INT_MAX; 528 unsigned int best_deviation = INT_MAX;
491 529
530 pr_debug("Input clock rate %ldHz\n", clkrate);
531
492 if (fstab == NULL) 532 if (fstab == NULL)
493 fstab = iis_fs_tab; 533 fstab = iis_fs_tab;
494 534
@@ -507,7 +547,7 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
507 actual = clkrate / (fsdiv * div); 547 actual = clkrate / (fsdiv * div);
508 deviation = actual - rate; 548 deviation = actual - rate;
509 549
510 printk(KERN_DEBUG "%dfs: div %d => result %d, deviation %d\n", 550 printk(KERN_DEBUG "%ufs: div %u => result %u, deviation %d\n",
511 fsdiv, div, actual, deviation); 551 fsdiv, div, actual, deviation);
512 552
513 deviation = abs(deviation); 553 deviation = abs(deviation);
@@ -523,7 +563,7 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
523 break; 563 break;
524 } 564 }
525 565
526 printk(KERN_DEBUG "best: fs=%d, div=%d, rate=%d\n", 566 printk(KERN_DEBUG "best: fs=%u, div=%u, rate=%u\n",
527 best_fs, best_div, best_rate); 567 best_fs, best_div, best_rate);
528 568
529 info->fs_div = best_fs; 569 info->fs_div = best_fs;
@@ -539,12 +579,31 @@ int s3c_i2sv2_probe(struct platform_device *pdev,
539 unsigned long base) 579 unsigned long base)
540{ 580{
541 struct device *dev = &pdev->dev; 581 struct device *dev = &pdev->dev;
582 unsigned int iismod;
542 583
543 i2s->dev = dev; 584 i2s->dev = dev;
544 585
545 /* record our i2s structure for later use in the callbacks */ 586 /* record our i2s structure for later use in the callbacks */
546 dai->private_data = i2s; 587 dai->private_data = i2s;
547 588
589 if (!base) {
590 struct resource *res = platform_get_resource(pdev,
591 IORESOURCE_MEM,
592 0);
593 if (!res) {
594 dev_err(dev, "Unable to get register resource\n");
595 return -ENXIO;
596 }
597
598 if (!request_mem_region(res->start, resource_size(res),
599 "s3c64xx-i2s-v4")) {
600 dev_err(dev, "Unable to request register region\n");
601 return -EBUSY;
602 }
603
604 base = res->start;
605 }
606
548 i2s->regs = ioremap(base, 0x100); 607 i2s->regs = ioremap(base, 0x100);
549 if (i2s->regs == NULL) { 608 if (i2s->regs == NULL) {
550 dev_err(dev, "cannot ioremap registers\n"); 609 dev_err(dev, "cannot ioremap registers\n");
@@ -560,12 +619,16 @@ int s3c_i2sv2_probe(struct platform_device *pdev,
560 619
561 clk_enable(i2s->iis_pclk); 620 clk_enable(i2s->iis_pclk);
562 621
622 /* Mark ourselves as in TXRX mode so we can run through our cleanup
623 * process without warnings. */
624 iismod = readl(i2s->regs + S3C2412_IISMOD);
625 iismod |= S3C2412_IISMOD_MODE_TXRX;
626 writel(iismod, i2s->regs + S3C2412_IISMOD);
563 s3c2412_snd_txctrl(i2s, 0); 627 s3c2412_snd_txctrl(i2s, 0);
564 s3c2412_snd_rxctrl(i2s, 0); 628 s3c2412_snd_rxctrl(i2s, 0);
565 629
566 return 0; 630 return 0;
567} 631}
568
569EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); 632EXPORT_SYMBOL_GPL(s3c_i2sv2_probe);
570 633
571#ifdef CONFIG_PM 634#ifdef CONFIG_PM
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index b7e0b3f0bfc8..168a088ba761 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -120,7 +120,7 @@ static int s3c2412_i2s_probe(struct platform_device *pdev,
120 120
121 s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk"); 121 s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk");
122 if (s3c2412_i2s.iis_cclk == NULL) { 122 if (s3c2412_i2s.iis_cclk == NULL) {
123 pr_debug("failed to get i2sclk clock\n"); 123 pr_err("failed to get i2sclk clock\n");
124 iounmap(s3c2412_i2s.regs); 124 iounmap(s3c2412_i2s.regs);
125 return -ENODEV; 125 return -ENODEV;
126 } 126 }
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index 33c5de7e255f..3c06c401d0fb 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -108,48 +108,19 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
108 return 0; 108 return 0;
109} 109}
110 110
111 111struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
112unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *dai)
113{ 112{
114 struct s3c_i2sv2_info *i2s = to_info(dai); 113 struct s3c_i2sv2_info *i2s = to_info(dai);
115 114
116 return clk_get_rate(i2s->iis_cclk); 115 return i2s->iis_cclk;
117} 116}
118EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate); 117EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
119 118
120static int s3c64xx_i2s_probe(struct platform_device *pdev, 119static int s3c64xx_i2s_probe(struct platform_device *pdev,
121 struct snd_soc_dai *dai) 120 struct snd_soc_dai *dai)
122{ 121{
123 struct device *dev = &pdev->dev;
124 struct s3c_i2sv2_info *i2s;
125 int ret;
126
127 dev_dbg(dev, "%s: probing dai %d\n", __func__, pdev->id);
128
129 if (pdev->id < 0 || pdev->id > ARRAY_SIZE(s3c64xx_i2s)) {
130 dev_err(dev, "id %d out of range\n", pdev->id);
131 return -EINVAL;
132 }
133
134 i2s = &s3c64xx_i2s[pdev->id];
135
136 ret = s3c_i2sv2_probe(pdev, dai, i2s,
137 pdev->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0);
138 if (ret)
139 return ret;
140
141 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
142 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
143
144 i2s->iis_cclk = clk_get(dev, "audio-bus");
145 if (IS_ERR(i2s->iis_cclk)) {
146 dev_err(dev, "failed to get audio-bus");
147 iounmap(i2s->regs);
148 return -ENODEV;
149 }
150
151 /* configure GPIO for i2s port */ 122 /* configure GPIO for i2s port */
152 switch (pdev->id) { 123 switch (dai->id) {
153 case 0: 124 case 0:
154 s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); 125 s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK);
155 s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK); 126 s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK);
@@ -175,41 +146,122 @@ static int s3c64xx_i2s_probe(struct platform_device *pdev,
175 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 146 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
176 147
177#define S3C64XX_I2S_FMTS \ 148#define S3C64XX_I2S_FMTS \
178 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE) 149 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
150 SNDRV_PCM_FMTBIT_S24_LE)
179 151
180static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { 152static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = {
181 .set_sysclk = s3c64xx_i2s_set_sysclk, 153 .set_sysclk = s3c64xx_i2s_set_sysclk,
182}; 154};
183 155
184struct snd_soc_dai s3c64xx_i2s_dai = { 156struct snd_soc_dai s3c64xx_i2s_dai[] = {
185 .name = "s3c64xx-i2s", 157 {
186 .id = 0, 158 .name = "s3c64xx-i2s",
187 .probe = s3c64xx_i2s_probe, 159 .id = 0,
188 .playback = { 160 .probe = s3c64xx_i2s_probe,
189 .channels_min = 2, 161 .playback = {
190 .channels_max = 2, 162 .channels_min = 2,
191 .rates = S3C64XX_I2S_RATES, 163 .channels_max = 2,
192 .formats = S3C64XX_I2S_FMTS, 164 .rates = S3C64XX_I2S_RATES,
165 .formats = S3C64XX_I2S_FMTS,
166 },
167 .capture = {
168 .channels_min = 2,
169 .channels_max = 2,
170 .rates = S3C64XX_I2S_RATES,
171 .formats = S3C64XX_I2S_FMTS,
172 },
173 .ops = &s3c64xx_i2s_dai_ops,
174 .symmetric_rates = 1,
193 }, 175 },
194 .capture = { 176 {
195 .channels_min = 2, 177 .name = "s3c64xx-i2s",
196 .channels_max = 2, 178 .id = 1,
197 .rates = S3C64XX_I2S_RATES, 179 .probe = s3c64xx_i2s_probe,
198 .formats = S3C64XX_I2S_FMTS, 180 .playback = {
181 .channels_min = 2,
182 .channels_max = 2,
183 .rates = S3C64XX_I2S_RATES,
184 .formats = S3C64XX_I2S_FMTS,
185 },
186 .capture = {
187 .channels_min = 2,
188 .channels_max = 2,
189 .rates = S3C64XX_I2S_RATES,
190 .formats = S3C64XX_I2S_FMTS,
191 },
192 .ops = &s3c64xx_i2s_dai_ops,
193 .symmetric_rates = 1,
199 }, 194 },
200 .ops = &s3c64xx_i2s_dai_ops,
201}; 195};
202EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); 196EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
203 197
198static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
199{
200 struct s3c_i2sv2_info *i2s;
201 struct snd_soc_dai *dai;
202 int ret;
203
204 if (pdev->id >= ARRAY_SIZE(s3c64xx_i2s)) {
205 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
206 return -EINVAL;
207 }
208
209 i2s = &s3c64xx_i2s[pdev->id];
210 dai = &s3c64xx_i2s_dai[pdev->id];
211 dai->dev = &pdev->dev;
212
213 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
214 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
215
216 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
217 if (IS_ERR(i2s->iis_cclk)) {
218 dev_err(&pdev->dev, "failed to get audio-bus\n");
219 ret = PTR_ERR(i2s->iis_cclk);
220 goto err;
221 }
222
223 ret = s3c_i2sv2_probe(pdev, dai, i2s, 0);
224 if (ret)
225 goto err_clk;
226
227 ret = s3c_i2sv2_register_dai(dai);
228 if (ret != 0)
229 goto err_i2sv2;
230
231 return 0;
232
233err_i2sv2:
234 /* Not implemented for I2Sv2 core yet */
235err_clk:
236 clk_put(i2s->iis_cclk);
237err:
238 return ret;
239}
240
241static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev)
242{
243 dev_err(&pdev->dev, "Device removal not yet supported\n");
244 return 0;
245}
246
247static struct platform_driver s3c64xx_iis_driver = {
248 .probe = s3c64xx_iis_dev_probe,
249 .remove = s3c64xx_iis_dev_remove,
250 .driver = {
251 .name = "s3c64xx-iis",
252 .owner = THIS_MODULE,
253 },
254};
255
204static int __init s3c64xx_i2s_init(void) 256static int __init s3c64xx_i2s_init(void)
205{ 257{
206 return s3c_i2sv2_register_dai(&s3c64xx_i2s_dai); 258 return platform_driver_register(&s3c64xx_iis_driver);
207} 259}
208module_init(s3c64xx_i2s_init); 260module_init(s3c64xx_i2s_init);
209 261
210static void __exit s3c64xx_i2s_exit(void) 262static void __exit s3c64xx_i2s_exit(void)
211{ 263{
212 snd_soc_unregister_dai(&s3c64xx_i2s_dai); 264 platform_driver_unregister(&s3c64xx_iis_driver);
213} 265}
214module_exit(s3c64xx_i2s_exit); 266module_exit(s3c64xx_i2s_exit);
215 267
@@ -217,6 +269,3 @@ module_exit(s3c64xx_i2s_exit);
217MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 269MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
218MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); 270MODULE_DESCRIPTION("S3C64XX I2S SoC Interface");
219MODULE_LICENSE("GPL"); 271MODULE_LICENSE("GPL");
220
221
222
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
index b7ffe3c38b66..02148cee2613 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.h
@@ -15,6 +15,8 @@
15#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H 15#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H
16#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__ 16#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__
17 17
18struct clk;
19
18#include "s3c-i2s-v2.h" 20#include "s3c-i2s-v2.h"
19 21
20#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK 22#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK
@@ -24,8 +26,8 @@
24#define S3C64XX_CLKSRC_PCLK (0) 26#define S3C64XX_CLKSRC_PCLK (0)
25#define S3C64XX_CLKSRC_MUX (1) 27#define S3C64XX_CLKSRC_MUX (1)
26 28
27extern struct snd_soc_dai s3c64xx_i2s_dai; 29extern struct snd_soc_dai s3c64xx_i2s_dai[];
28 30
29extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai); 31extern struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai);
30 32
31#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ 33#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */