diff options
author | Kurt J. Bosch <kjb-temp-2005@gmx.de> | 2005-11-16 12:41:21 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:16:18 -0500 |
commit | f31a31b9024f21b2ad8f5a7c30e265a652e2e211 (patch) | |
tree | c0e75c82a7cc38008d76242857d2f9b8b4687419 | |
parent | 26741b5512a99ee35f398ef018d23a38e8dc6e8a (diff) |
[ALSA] Fix missing suspend/resume-code for ens1371
Modules: ENS1370/1+ driver
This patch fixes missing suspend/resume-code for snd-ens1371
(but not for snd-ens1370)
Signed-off-by: Kurt J. Bosch <kjb-temp-2005@gmx.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/ens1370.c | 174 |
1 files changed, 123 insertions, 51 deletions
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 2daa575f43ff..fa619a959d8c 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -19,6 +19,13 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | /* Power-Management-Code ( CONFIG_PM ) | ||
23 | * for ens1371 only ( FIXME ) | ||
24 | * derived from cs4281.c, atiixp.c and via82xx.c | ||
25 | * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm | ||
26 | * by Kurt J. Bosch | ||
27 | */ | ||
28 | |||
22 | #include <sound/driver.h> | 29 | #include <sound/driver.h> |
23 | #include <asm/io.h> | 30 | #include <asm/io.h> |
24 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
@@ -1924,6 +1931,117 @@ static struct { | |||
1924 | }; | 1931 | }; |
1925 | #endif | 1932 | #endif |
1926 | 1933 | ||
1934 | static void snd_ensoniq_chip_init(ensoniq_t * ensoniq) | ||
1935 | { | ||
1936 | #ifdef CHIP1371 | ||
1937 | int idx; | ||
1938 | struct pci_dev *pci = ensoniq->pci; | ||
1939 | #endif | ||
1940 | // this code was part of snd_ensoniq_create before intruduction of suspend/resume | ||
1941 | #ifdef CHIP1370 | ||
1942 | outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); | ||
1943 | outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); | ||
1944 | outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); | ||
1945 | outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); | ||
1946 | outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); | ||
1947 | #else | ||
1948 | outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); | ||
1949 | outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); | ||
1950 | outl(0, ES_REG(ensoniq, 1371_LEGACY)); | ||
1951 | for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) | ||
1952 | if (pci->vendor == es1371_ac97_reset_hack[idx].vid && | ||
1953 | pci->device == es1371_ac97_reset_hack[idx].did && | ||
1954 | ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { | ||
1955 | outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); | ||
1956 | /* need to delay around 20ms(bleech) to give | ||
1957 | some CODECs enough time to wakeup */ | ||
1958 | msleep(20); | ||
1959 | break; | ||
1960 | } | ||
1961 | /* AC'97 warm reset to start the bitclk */ | ||
1962 | outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); | ||
1963 | inl(ES_REG(ensoniq, CONTROL)); | ||
1964 | udelay(20); | ||
1965 | outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); | ||
1966 | /* Init the sample rate converter */ | ||
1967 | snd_es1371_wait_src_ready(ensoniq); | ||
1968 | outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); | ||
1969 | for (idx = 0; idx < 0x80; idx++) | ||
1970 | snd_es1371_src_write(ensoniq, idx, 0); | ||
1971 | snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); | ||
1972 | snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); | ||
1973 | snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); | ||
1974 | snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); | ||
1975 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); | ||
1976 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); | ||
1977 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); | ||
1978 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); | ||
1979 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); | ||
1980 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); | ||
1981 | snd_es1371_adc_rate(ensoniq, 22050); | ||
1982 | snd_es1371_dac1_rate(ensoniq, 22050); | ||
1983 | snd_es1371_dac2_rate(ensoniq, 22050); | ||
1984 | /* WARNING: | ||
1985 | * enabling the sample rate converter without properly programming | ||
1986 | * its parameters causes the chip to lock up (the SRC busy bit will | ||
1987 | * be stuck high, and I've found no way to rectify this other than | ||
1988 | * power cycle) - Thomas Sailer | ||
1989 | */ | ||
1990 | snd_es1371_wait_src_ready(ensoniq); | ||
1991 | outl(0, ES_REG(ensoniq, 1371_SMPRATE)); | ||
1992 | /* try reset codec directly */ | ||
1993 | outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); | ||
1994 | #endif | ||
1995 | outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); | ||
1996 | outb(0x00, ES_REG(ensoniq, UART_RES)); | ||
1997 | outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); | ||
1998 | synchronize_irq(ensoniq->irq); | ||
1999 | } | ||
2000 | |||
2001 | #ifdef CONFIG_PM | ||
2002 | static int snd_ensoniq_suspend (snd_card_t * card, | ||
2003 | pm_message_t state) | ||
2004 | { | ||
2005 | ensoniq_t *ensoniq = card->pm_private_data; | ||
2006 | |||
2007 | snd_pcm_suspend_all(ensoniq->pcm1); | ||
2008 | snd_pcm_suspend_all(ensoniq->pcm2); | ||
2009 | |||
2010 | #ifdef CHIP1371 | ||
2011 | if (ensoniq->u.es1371.ac97) | ||
2012 | snd_ac97_suspend(ensoniq->u.es1371.ac97); | ||
2013 | #else | ||
2014 | /* FIXME */ | ||
2015 | #endif | ||
2016 | pci_set_power_state(ensoniq->pci, 3); | ||
2017 | pci_disable_device(ensoniq->pci); | ||
2018 | // snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); // only 2.6.10 | ||
2019 | return 0; | ||
2020 | } | ||
2021 | |||
2022 | static int snd_ensoniq_resume (snd_card_t * card | ||
2023 | ) | ||
2024 | { | ||
2025 | ensoniq_t *ensoniq = card->pm_private_data; | ||
2026 | |||
2027 | pci_enable_device(ensoniq->pci); | ||
2028 | pci_set_power_state(ensoniq->pci, 0); | ||
2029 | pci_set_master(ensoniq->pci); | ||
2030 | |||
2031 | snd_ensoniq_chip_init(ensoniq); | ||
2032 | |||
2033 | #ifdef CHIP1371 | ||
2034 | if (ensoniq->u.es1371.ac97) | ||
2035 | snd_ac97_resume(ensoniq->u.es1371.ac97); | ||
2036 | #else | ||
2037 | /* FIXME */ | ||
2038 | #endif | ||
2039 | // snd_power_change_state(card, SNDRV_CTL_POWER_D0); // only 2.6.10 | ||
2040 | return 0; | ||
2041 | } | ||
2042 | #endif /* CONFIG_PM */ | ||
2043 | |||
2044 | |||
1927 | static int __devinit snd_ensoniq_create(snd_card_t * card, | 2045 | static int __devinit snd_ensoniq_create(snd_card_t * card, |
1928 | struct pci_dev *pci, | 2046 | struct pci_dev *pci, |
1929 | ensoniq_t ** rensoniq) | 2047 | ensoniq_t ** rensoniq) |
@@ -1986,12 +2104,6 @@ static int __devinit snd_ensoniq_create(snd_card_t * card, | |||
1986 | ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000)); | 2104 | ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000)); |
1987 | #endif | 2105 | #endif |
1988 | ensoniq->sctrl = 0; | 2106 | ensoniq->sctrl = 0; |
1989 | /* initialize the chips */ | ||
1990 | outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); | ||
1991 | outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); | ||
1992 | outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE)); | ||
1993 | outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME)); | ||
1994 | outl(0, ES_REG(ensoniq, PHANTOM_COUNT)); | ||
1995 | #else | 2107 | #else |
1996 | ensoniq->ctrl = 0; | 2108 | ensoniq->ctrl = 0; |
1997 | ensoniq->sctrl = 0; | 2109 | ensoniq->sctrl = 0; |
@@ -2002,59 +2114,16 @@ static int __devinit snd_ensoniq_create(snd_card_t * card, | |||
2002 | ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ | 2114 | ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ |
2003 | break; | 2115 | break; |
2004 | } | 2116 | } |
2005 | /* initialize the chips */ | ||
2006 | outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); | ||
2007 | outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); | ||
2008 | outl(0, ES_REG(ensoniq, 1371_LEGACY)); | ||
2009 | for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) | 2117 | for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) |
2010 | if (pci->vendor == es1371_ac97_reset_hack[idx].vid && | 2118 | if (pci->vendor == es1371_ac97_reset_hack[idx].vid && |
2011 | pci->device == es1371_ac97_reset_hack[idx].did && | 2119 | pci->device == es1371_ac97_reset_hack[idx].did && |
2012 | ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { | 2120 | ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { |
2013 | ensoniq->cssr |= ES_1371_ST_AC97_RST; | 2121 | ensoniq->cssr |= ES_1371_ST_AC97_RST; |
2014 | outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); | ||
2015 | /* need to delay around 20ms(bleech) to give | ||
2016 | some CODECs enough time to wakeup */ | ||
2017 | msleep(20); | ||
2018 | break; | 2122 | break; |
2019 | } | 2123 | } |
2020 | /* AC'97 warm reset to start the bitclk */ | ||
2021 | outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); | ||
2022 | inl(ES_REG(ensoniq, CONTROL)); | ||
2023 | udelay(20); | ||
2024 | outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); | ||
2025 | /* Init the sample rate converter */ | ||
2026 | snd_es1371_wait_src_ready(ensoniq); | ||
2027 | outl(ES_1371_SRC_DISABLE, ES_REG(ensoniq, 1371_SMPRATE)); | ||
2028 | for (idx = 0; idx < 0x80; idx++) | ||
2029 | snd_es1371_src_write(ensoniq, idx, 0); | ||
2030 | snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); | ||
2031 | snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); | ||
2032 | snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); | ||
2033 | snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); | ||
2034 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, 1 << 12); | ||
2035 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, 1 << 12); | ||
2036 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1, 1 << 12); | ||
2037 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); | ||
2038 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2, 1 << 12); | ||
2039 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); | ||
2040 | snd_es1371_adc_rate(ensoniq, 22050); | ||
2041 | snd_es1371_dac1_rate(ensoniq, 22050); | ||
2042 | snd_es1371_dac2_rate(ensoniq, 22050); | ||
2043 | /* WARNING: | ||
2044 | * enabling the sample rate converter without properly programming | ||
2045 | * its parameters causes the chip to lock up (the SRC busy bit will | ||
2046 | * be stuck high, and I've found no way to rectify this other than | ||
2047 | * power cycle) - Thomas Sailer | ||
2048 | */ | ||
2049 | snd_es1371_wait_src_ready(ensoniq); | ||
2050 | outl(0, ES_REG(ensoniq, 1371_SMPRATE)); | ||
2051 | /* try reset codec directly */ | ||
2052 | outl(ES_1371_CODEC_WRITE(0, 0), ES_REG(ensoniq, 1371_CODEC)); | ||
2053 | #endif | 2124 | #endif |
2054 | outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); | 2125 | |
2055 | outb(0x00, ES_REG(ensoniq, UART_RES)); | 2126 | snd_ensoniq_chip_init(ensoniq); |
2056 | outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); | ||
2057 | synchronize_irq(ensoniq->irq); | ||
2058 | 2127 | ||
2059 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) { | 2128 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) { |
2060 | snd_ensoniq_free(ensoniq); | 2129 | snd_ensoniq_free(ensoniq); |
@@ -2063,6 +2132,8 @@ static int __devinit snd_ensoniq_create(snd_card_t * card, | |||
2063 | 2132 | ||
2064 | snd_ensoniq_proc_init(ensoniq); | 2133 | snd_ensoniq_proc_init(ensoniq); |
2065 | 2134 | ||
2135 | snd_card_set_pm_callback(card, snd_ensoniq_suspend, snd_ensoniq_resume, ensoniq); | ||
2136 | |||
2066 | snd_card_set_dev(card, &pci->dev); | 2137 | snd_card_set_dev(card, &pci->dev); |
2067 | 2138 | ||
2068 | *rensoniq = ensoniq; | 2139 | *rensoniq = ensoniq; |
@@ -2389,6 +2460,7 @@ static struct pci_driver driver = { | |||
2389 | .id_table = snd_audiopci_ids, | 2460 | .id_table = snd_audiopci_ids, |
2390 | .probe = snd_audiopci_probe, | 2461 | .probe = snd_audiopci_probe, |
2391 | .remove = __devexit_p(snd_audiopci_remove), | 2462 | .remove = __devexit_p(snd_audiopci_remove), |
2463 | SND_PCI_PM_CALLBACKS | ||
2392 | }; | 2464 | }; |
2393 | 2465 | ||
2394 | static int __init alsa_card_ens137x_init(void) | 2466 | static int __init alsa_card_ens137x_init(void) |