diff options
Diffstat (limited to 'sound/soc/s3c24xx/s3c-i2s-v2.c')
-rw-r--r-- | sound/soc/s3c24xx/s3c-i2s-v2.c | 87 |
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 | |||
349 | static 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 | ||
565 | struct 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 | } | ||
575 | EXPORT_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 */ |
542 | static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 }; | 578 | static 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) |