diff options
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/s3c24xx/s3c2412-i2s.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c index b10f7ffa9424..c4a46dd589b3 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.c +++ b/sound/soc/s3c24xx/s3c2412-i2s.c | |||
@@ -79,6 +79,10 @@ struct s3c2412_i2s_info { | |||
79 | struct clk *iis_clk; | 79 | struct clk *iis_clk; |
80 | struct clk *iis_pclk; | 80 | struct clk *iis_pclk; |
81 | struct clk *iis_cclk; | 81 | struct clk *iis_cclk; |
82 | |||
83 | u32 suspend_iismod; | ||
84 | u32 suspend_iiscon; | ||
85 | u32 suspend_iispsr; | ||
82 | }; | 86 | }; |
83 | 87 | ||
84 | static struct s3c2412_i2s_info s3c2412_i2s; | 88 | static struct s3c2412_i2s_info s3c2412_i2s; |
@@ -641,6 +645,63 @@ static int s3c2412_i2s_probe(struct platform_device *pdev) | |||
641 | return 0; | 645 | return 0; |
642 | } | 646 | } |
643 | 647 | ||
648 | #ifdef CONFIG_PM | ||
649 | static int s3c2412_i2s_suspend(struct platform_device *dev, | ||
650 | struct snd_soc_cpu_dai *dai) | ||
651 | { | ||
652 | struct s3c2412_i2s_info *i2s = &s3c2412_i2s; | ||
653 | u32 iismod; | ||
654 | |||
655 | if (dai->active) { | ||
656 | i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD); | ||
657 | i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON); | ||
658 | i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR); | ||
659 | |||
660 | /* some basic suspend checks */ | ||
661 | |||
662 | iismod = readl(i2s->regs + S3C2412_IISMOD); | ||
663 | |||
664 | if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) | ||
665 | dev_warn(&dev->dev, "%s: RXDMA active?\n", __func__); | ||
666 | |||
667 | if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) | ||
668 | dev_warn(&dev->dev, "%s: TXDMA active?\n", __func__); | ||
669 | |||
670 | if (iismod & S3C2412_IISCON_IIS_ACTIVE) | ||
671 | dev_warn(&dev->dev, "%s: IIS active\n", __func__); | ||
672 | } | ||
673 | |||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | static int s3c2412_i2s_resume(struct platform_device *pdev, | ||
678 | struct snd_soc_cpu_dai *dai) | ||
679 | { | ||
680 | struct s3c2412_i2s_info *i2s = &s3c2412_i2s; | ||
681 | |||
682 | dev_info(&pdev->dev, "dai_active %d, IISMOD %08x, IISCON %08x\n", | ||
683 | dai->active, i2s->suspend_iismod, i2s->suspend_iiscon); | ||
684 | |||
685 | if (dai->active) { | ||
686 | writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); | ||
687 | writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD); | ||
688 | writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR); | ||
689 | |||
690 | writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH, | ||
691 | i2s->regs + S3C2412_IISFIC); | ||
692 | |||
693 | ndelay(250); | ||
694 | writel(0x0, i2s->regs + S3C2412_IISFIC); | ||
695 | |||
696 | } | ||
697 | |||
698 | return 0; | ||
699 | } | ||
700 | #else | ||
701 | #define s3c2412_i2s_suspend NULL | ||
702 | #define s3c2412_i2s_resume NULL | ||
703 | #endif /* CONFIG_PM */ | ||
704 | |||
644 | #define S3C2412_I2S_RATES \ | 705 | #define S3C2412_I2S_RATES \ |
645 | (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ | 706 | (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ |
646 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ | 707 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ |
@@ -651,6 +712,8 @@ struct snd_soc_cpu_dai s3c2412_i2s_dai = { | |||
651 | .id = 0, | 712 | .id = 0, |
652 | .type = SND_SOC_DAI_I2S, | 713 | .type = SND_SOC_DAI_I2S, |
653 | .probe = s3c2412_i2s_probe, | 714 | .probe = s3c2412_i2s_probe, |
715 | .suspend = s3c2412_i2s_suspend, | ||
716 | .resume = s3c2412_i2s_resume, | ||
654 | .playback = { | 717 | .playback = { |
655 | .channels_min = 2, | 718 | .channels_min = 2, |
656 | .channels_max = 2, | 719 | .channels_max = 2, |