aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/s3c24xx/s3c-i2s-v2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/s3c24xx/s3c-i2s-v2.c')
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c87
1 files changed, 62 insertions, 25 deletions
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index 865f93143bf..13311c8cf96 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -24,10 +24,9 @@
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26 26
27#include <plat/regs-s3c2412-iis.h>
28
29#include <mach/dma.h> 27#include <mach/dma.h>
30 28
29#include "regs-i2s-v2.h"
31#include "s3c-i2s-v2.h" 30#include "s3c-i2s-v2.h"
32#include "s3c-dma.h" 31#include "s3c-dma.h"
33 32
@@ -266,35 +265,14 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
266 iismod = readl(i2s->regs + S3C2412_IISMOD); 265 iismod = readl(i2s->regs + S3C2412_IISMOD);
267 pr_debug("hw_params r: IISMOD: %x \n", iismod); 266 pr_debug("hw_params r: IISMOD: %x \n", iismod);
268 267
269#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
270#define IISMOD_MASTER_MASK S3C2412_IISMOD_MASTER_MASK
271#define IISMOD_SLAVE S3C2412_IISMOD_SLAVE
272#define IISMOD_MASTER S3C2412_IISMOD_MASTER_INTERNAL
273#endif
274
275#if defined(CONFIG_PLAT_S3C64XX)
276/* From Rev1.1 datasheet, we have two master and two slave modes:
277 * IMS[11:10]:
278 * 00 = master mode, fed from PCLK
279 * 01 = master mode, fed from CLKAUDIO
280 * 10 = slave mode, using PCLK
281 * 11 = slave mode, using I2SCLK
282 */
283#define IISMOD_MASTER_MASK (1 << 11)
284#define IISMOD_SLAVE (1 << 11)
285#define IISMOD_MASTER (0 << 11)
286#endif
287
288 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 268 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
289 case SND_SOC_DAIFMT_CBM_CFM: 269 case SND_SOC_DAIFMT_CBM_CFM:
290 i2s->master = 0; 270 i2s->master = 0;
291 iismod &= ~IISMOD_MASTER_MASK; 271 iismod |= S3C2412_IISMOD_SLAVE;
292 iismod |= IISMOD_SLAVE;
293 break; 272 break;
294 case SND_SOC_DAIFMT_CBS_CFS: 273 case SND_SOC_DAIFMT_CBS_CFS:
295 i2s->master = 1; 274 i2s->master = 1;
296 iismod &= ~IISMOD_MASTER_MASK; 275 iismod &= ~S3C2412_IISMOD_SLAVE;
297 iismod |= IISMOD_MASTER;
298 break; 276 break;
299 default: 277 default:
300 pr_err("unknwon master/slave format\n"); 278 pr_err("unknwon master/slave format\n");
@@ -364,6 +342,52 @@ static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream,
364 342
365 writel(iismod, i2s->regs + S3C2412_IISMOD); 343 writel(iismod, i2s->regs + S3C2412_IISMOD);
366 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); 344 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
345
346 return 0;
347}
348
349static int s3c_i2sv2_set_sysclk(struct snd_soc_dai *cpu_dai,
350 int clk_id, unsigned int freq, int dir)
351{
352 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
353 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
354
355 pr_debug("Entered %s\n", __func__);
356 pr_debug("%s r: IISMOD: %x\n", __func__, iismod);
357
358 switch (clk_id) {
359 case S3C_I2SV2_CLKSRC_PCLK:
360 iismod &= ~S3C2412_IISMOD_IMS_SYSMUX;
361 break;
362
363 case S3C_I2SV2_CLKSRC_AUDIOBUS:
364 iismod |= S3C2412_IISMOD_IMS_SYSMUX;
365 break;
366
367 case S3C_I2SV2_CLKSRC_CDCLK:
368 /* Error if controller doesn't have the CDCLKCON bit */
369 if (!(i2s->feature & S3C_FEATURE_CDCLKCON))
370 return -EINVAL;
371
372 switch (dir) {
373 case SND_SOC_CLOCK_IN:
374 iismod |= S3C64XX_IISMOD_CDCLKCON;
375 break;
376 case SND_SOC_CLOCK_OUT:
377 iismod &= ~S3C64XX_IISMOD_CDCLKCON;
378 break;
379 default:
380 return -EINVAL;
381 }
382 break;
383
384 default:
385 return -EINVAL;
386 }
387
388 writel(iismod, i2s->regs + S3C2412_IISMOD);
389 pr_debug("%s w: IISMOD: %x\n", __func__, iismod);
390
367 return 0; 391 return 0;
368} 392}
369 393
@@ -538,6 +562,18 @@ static snd_pcm_sframes_t s3c2412_i2s_delay(struct snd_pcm_substream *substream,
538 return delay; 562 return delay;
539} 563}
540 564
565struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai)
566{
567 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
568 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
569
570 if (iismod & S3C2412_IISMOD_IMS_SYSMUX)
571 return i2s->iis_cclk;
572 else
573 return i2s->iis_pclk;
574}
575EXPORT_SYMBOL_GPL(s3c_i2sv2_get_clock);
576
541/* default table of all avaialable root fs divisors */ 577/* default table of all avaialable root fs divisors */
542static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 }; 578static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 };
543 579
@@ -724,6 +760,7 @@ int s3c_i2sv2_register_dai(struct snd_soc_dai *dai)
724 ops->hw_params = s3c_i2sv2_hw_params; 760 ops->hw_params = s3c_i2sv2_hw_params;
725 ops->set_fmt = s3c2412_i2s_set_fmt; 761 ops->set_fmt = s3c2412_i2s_set_fmt;
726 ops->set_clkdiv = s3c2412_i2s_set_clkdiv; 762 ops->set_clkdiv = s3c2412_i2s_set_clkdiv;
763 ops->set_sysclk = s3c_i2sv2_set_sysclk;
727 764
728 /* Allow overriding by (for example) IISv4 */ 765 /* Allow overriding by (for example) IISv4 */
729 if (!ops->delay) 766 if (!ops->delay)