~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/cs5535audio/cs5535audio_pm.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Power management for audio on multifunction CS5535 companion device
  4  * Copyright (C) Jaya Kumar
  5  */
  6 
  7 #include <linux/init.h>
  8 #include <linux/pci.h>
  9 #include <linux/delay.h>
 10 #include <sound/core.h>
 11 #include <sound/control.h>
 12 #include <sound/initval.h>
 13 #include <sound/asoundef.h>
 14 #include <sound/pcm.h>
 15 #include <sound/ac97_codec.h>
 16 #include "cs5535audio.h"
 17 
 18 static void snd_cs5535audio_stop_hardware(struct cs5535audio *cs5535au)
 19 {
 20         /* 
 21         we depend on snd_ac97_suspend to tell the
 22         AC97 codec to shutdown. the amd spec suggests
 23         that the LNK_SHUTDOWN be done at the same time
 24         that the codec power-down is issued. instead,
 25         we do it just after rather than at the same 
 26         time. excluding codec specific build_ops->suspend
 27         ac97 powerdown hits:
 28         0x8000 EAPD 
 29         0x4000 Headphone amplifier 
 30         0x0300 ADC & DAC 
 31         0x0400 Analog Mixer powerdown (Vref on) 
 32         I am not sure if this is the best that we can do.
 33         The remainder to be investigated are:
 34         - analog mixer (vref off) 0x0800
 35         - AC-link powerdown 0x1000
 36         - codec internal clock 0x2000
 37         */
 38 
 39         /* set LNK_SHUTDOWN to shutdown AC link */
 40         cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_SHUTDOWN);
 41 
 42 }
 43 
 44 static int __maybe_unused snd_cs5535audio_suspend(struct device *dev)
 45 {
 46         struct snd_card *card = dev_get_drvdata(dev);
 47         struct cs5535audio *cs5535au = card->private_data;
 48         int i;
 49 
 50         snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 51         snd_ac97_suspend(cs5535au->ac97);
 52         for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
 53                 struct cs5535audio_dma *dma = &cs5535au->dmas[i];
 54                 if (dma && dma->substream)
 55                         dma->saved_prd = dma->ops->read_prd(cs5535au);
 56         }
 57         /* save important regs, then disable aclink in hw */
 58         snd_cs5535audio_stop_hardware(cs5535au);
 59         return 0;
 60 }
 61 
 62 static int __maybe_unused snd_cs5535audio_resume(struct device *dev)
 63 {
 64         struct snd_card *card = dev_get_drvdata(dev);
 65         struct cs5535audio *cs5535au = card->private_data;
 66         u32 tmp;
 67         int timeout;
 68         int i;
 69 
 70         /* set LNK_WRM_RST to reset AC link */
 71         cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_WRM_RST);
 72 
 73         timeout = 50;
 74         do {
 75                 tmp = cs_readl(cs5535au, ACC_CODEC_STATUS);
 76                 if (tmp & PRM_RDY_STS)
 77                         break;
 78                 udelay(1);
 79         } while (--timeout);
 80 
 81         if (!timeout)
 82                 dev_err(cs5535au->card->dev, "Failure getting AC Link ready\n");
 83 
 84         /* set up rate regs, dma. actual initiation is done in trig */
 85         for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
 86                 struct cs5535audio_dma *dma = &cs5535au->dmas[i];
 87                 if (dma && dma->substream) {
 88                         dma->substream->ops->prepare(dma->substream);
 89                         dma->ops->setup_prd(cs5535au, dma->saved_prd);
 90                 }
 91         }
 92 
 93         /* we depend on ac97 to perform the codec power up */
 94         snd_ac97_resume(cs5535au->ac97);
 95         snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 96 
 97         return 0;
 98 }
 99 
100 SIMPLE_DEV_PM_OPS(snd_cs5535audio_pm, snd_cs5535audio_suspend, snd_cs5535audio_resume);
101 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php