diff options
author | Bernhard Urban <lewurm@gmail.com> | 2010-03-22 23:12:38 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-03-23 12:34:23 -0400 |
commit | ae76148114aa2457baa0d340fc506bb7d114cb12 (patch) | |
tree | 4c2db08dde721d0565aaa16e0d32b4ed2cb7438c /sound/pci | |
parent | 6da7a2aa899f75116e1a62cef78c358ada9878b7 (diff) |
ALSA: aureon - Patch for suspend/resume for Terratec Aureon cards.
Add proper suspend/resume code for Terratec Aureon cards.
Based on ice1724 suspend/resume work of Igor Chernyshev.
Fixes bug https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4944
Tested on linux-2.6.32.9
Signed-off-by: Bernhard Urban <lewurm@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/ice1712/aureon.c | 89 |
1 files changed, 64 insertions, 25 deletions
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 9e66f6d306f8..2f6252266a02 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c | |||
@@ -1956,11 +1956,10 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) | |||
1956 | return 0; | 1956 | return 0; |
1957 | } | 1957 | } |
1958 | 1958 | ||
1959 | |||
1960 | /* | 1959 | /* |
1961 | * initialize the chip | 1960 | * reset the chip |
1962 | */ | 1961 | */ |
1963 | static int __devinit aureon_init(struct snd_ice1712 *ice) | 1962 | static int aureon_reset(struct snd_ice1712 *ice) |
1964 | { | 1963 | { |
1965 | static const unsigned short wm_inits_aureon[] = { | 1964 | static const unsigned short wm_inits_aureon[] = { |
1966 | /* These come first to reduce init pop noise */ | 1965 | /* These come first to reduce init pop noise */ |
@@ -2047,30 +2046,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) | |||
2047 | 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */ | 2046 | 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */ |
2048 | (unsigned short)-1 | 2047 | (unsigned short)-1 |
2049 | }; | 2048 | }; |
2050 | struct aureon_spec *spec; | ||
2051 | unsigned int tmp; | 2049 | unsigned int tmp; |
2052 | const unsigned short *p; | 2050 | const unsigned short *p; |
2053 | int err, i; | 2051 | int err; |
2054 | 2052 | struct aureon_spec *spec = ice->spec; | |
2055 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
2056 | if (!spec) | ||
2057 | return -ENOMEM; | ||
2058 | ice->spec = spec; | ||
2059 | |||
2060 | if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) { | ||
2061 | ice->num_total_dacs = 6; | ||
2062 | ice->num_total_adcs = 2; | ||
2063 | } else { | ||
2064 | /* aureon 7.1 and prodigy 7.1 */ | ||
2065 | ice->num_total_dacs = 8; | ||
2066 | ice->num_total_adcs = 2; | ||
2067 | } | ||
2068 | |||
2069 | /* to remeber the register values of CS8415 */ | ||
2070 | ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); | ||
2071 | if (!ice->akm) | ||
2072 | return -ENOMEM; | ||
2073 | ice->akm_codecs = 1; | ||
2074 | 2053 | ||
2075 | err = aureon_ac97_init(ice); | 2054 | err = aureon_ac97_init(ice); |
2076 | if (err != 0) | 2055 | if (err != 0) |
@@ -2118,6 +2097,61 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) | |||
2118 | /* initialize PCA9554 pin directions & set default input */ | 2097 | /* initialize PCA9554 pin directions & set default input */ |
2119 | aureon_pca9554_write(ice, PCA9554_DIR, 0x00); | 2098 | aureon_pca9554_write(ice, PCA9554_DIR, 0x00); |
2120 | aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ | 2099 | aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ |
2100 | return 0; | ||
2101 | } | ||
2102 | |||
2103 | /* | ||
2104 | * suspend/resume | ||
2105 | */ | ||
2106 | #ifdef CONFIG_PM | ||
2107 | static int aureon_resume(struct snd_ice1712 *ice) | ||
2108 | { | ||
2109 | struct aureon_spec *spec = ice->spec; | ||
2110 | int err, i; | ||
2111 | |||
2112 | err = aureon_reset(ice); | ||
2113 | if (err != 0) | ||
2114 | return err; | ||
2115 | |||
2116 | /* workaround for poking volume with alsamixer after resume: | ||
2117 | * just set stored volume again */ | ||
2118 | for (i = 0; i < ice->num_total_dacs; i++) | ||
2119 | wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]); | ||
2120 | return 0; | ||
2121 | } | ||
2122 | #endif | ||
2123 | |||
2124 | /* | ||
2125 | * initialize the chip | ||
2126 | */ | ||
2127 | static int __devinit aureon_init(struct snd_ice1712 *ice) | ||
2128 | { | ||
2129 | struct aureon_spec *spec; | ||
2130 | int i, err; | ||
2131 | |||
2132 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
2133 | if (!spec) | ||
2134 | return -ENOMEM; | ||
2135 | ice->spec = spec; | ||
2136 | |||
2137 | if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) { | ||
2138 | ice->num_total_dacs = 6; | ||
2139 | ice->num_total_adcs = 2; | ||
2140 | } else { | ||
2141 | /* aureon 7.1 and prodigy 7.1 */ | ||
2142 | ice->num_total_dacs = 8; | ||
2143 | ice->num_total_adcs = 2; | ||
2144 | } | ||
2145 | |||
2146 | /* to remeber the register values of CS8415 */ | ||
2147 | ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); | ||
2148 | if (!ice->akm) | ||
2149 | return -ENOMEM; | ||
2150 | ice->akm_codecs = 1; | ||
2151 | |||
2152 | err = aureon_reset(ice); | ||
2153 | if (err != 0) | ||
2154 | return err; | ||
2121 | 2155 | ||
2122 | spec->master[0] = WM_VOL_MUTE; | 2156 | spec->master[0] = WM_VOL_MUTE; |
2123 | spec->master[1] = WM_VOL_MUTE; | 2157 | spec->master[1] = WM_VOL_MUTE; |
@@ -2126,6 +2160,11 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) | |||
2126 | wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]); | 2160 | wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]); |
2127 | } | 2161 | } |
2128 | 2162 | ||
2163 | #ifdef CONFIG_PM | ||
2164 | ice->pm_resume = aureon_resume; | ||
2165 | ice->pm_suspend_enabled = 1; | ||
2166 | #endif | ||
2167 | |||
2129 | return 0; | 2168 | return 0; |
2130 | } | 2169 | } |
2131 | 2170 | ||