diff options
Diffstat (limited to 'sound/pci/ac97/ac97_codec.c')
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index a4b72cd2eea0..6983eea226da 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -367,6 +367,7 @@ int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value) | |||
367 | ac97->regs[reg] = value; | 367 | ac97->regs[reg] = value; |
368 | ac97->bus->ops->write(ac97, reg, value); | 368 | ac97->bus->ops->write(ac97, reg, value); |
369 | } | 369 | } |
370 | set_bit(reg, ac97->reg_accessed); | ||
370 | up(&ac97->reg_mutex); | 371 | up(&ac97->reg_mutex); |
371 | return change; | 372 | return change; |
372 | } | 373 | } |
@@ -410,6 +411,7 @@ int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg, | |||
410 | ac97->regs[reg] = new; | 411 | ac97->regs[reg] = new; |
411 | ac97->bus->ops->write(ac97, reg, new); | 412 | ac97->bus->ops->write(ac97, reg, new); |
412 | } | 413 | } |
414 | set_bit(reg, ac97->reg_accessed); | ||
413 | return change; | 415 | return change; |
414 | } | 416 | } |
415 | 417 | ||
@@ -1076,6 +1078,11 @@ static void check_volume_resolution(ac97_t *ac97, int reg, unsigned char *lo_max | |||
1076 | for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { | 1078 | for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { |
1077 | unsigned short val; | 1079 | unsigned short val; |
1078 | snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8)); | 1080 | snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8)); |
1081 | /* Do the read twice due to buffers on some ac97 codecs. | ||
1082 | * e.g. The STAC9704 returns exactly what you wrote the the register | ||
1083 | * if you read it immediately. This causes the detect routine to fail. | ||
1084 | */ | ||
1085 | val = snd_ac97_read(ac97, reg); | ||
1079 | val = snd_ac97_read(ac97, reg); | 1086 | val = snd_ac97_read(ac97, reg); |
1080 | if (! *lo_max && (val & 0x7f) == cbit[i]) | 1087 | if (! *lo_max && (val & 0x7f) == cbit[i]) |
1081 | *lo_max = max[i]; | 1088 | *lo_max = max[i]; |
@@ -2224,7 +2231,7 @@ void snd_ac97_restore_iec958(ac97_t *ac97) | |||
2224 | */ | 2231 | */ |
2225 | void snd_ac97_resume(ac97_t *ac97) | 2232 | void snd_ac97_resume(ac97_t *ac97) |
2226 | { | 2233 | { |
2227 | int i; | 2234 | unsigned long end_time; |
2228 | 2235 | ||
2229 | if (ac97->bus->ops->reset) { | 2236 | if (ac97->bus->ops->reset) { |
2230 | ac97->bus->ops->reset(ac97); | 2237 | ac97->bus->ops->reset(ac97); |
@@ -2242,26 +2249,26 @@ void snd_ac97_resume(ac97_t *ac97) | |||
2242 | snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]); | 2249 | snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]); |
2243 | if (ac97_is_audio(ac97)) { | 2250 | if (ac97_is_audio(ac97)) { |
2244 | ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101); | 2251 | ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101); |
2245 | for (i = HZ/10; i >= 0; i--) { | 2252 | end_time = jiffies + msecs_to_jiffies(100); |
2253 | do { | ||
2246 | if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101) | 2254 | if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101) |
2247 | break; | 2255 | break; |
2248 | set_current_state(TASK_UNINTERRUPTIBLE); | 2256 | set_current_state(TASK_UNINTERRUPTIBLE); |
2249 | schedule_timeout(1); | 2257 | schedule_timeout(1); |
2250 | } | 2258 | } while (time_after_eq(end_time, jiffies)); |
2251 | /* FIXME: extra delay */ | 2259 | /* FIXME: extra delay */ |
2252 | ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); | 2260 | ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); |
2253 | if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) { | 2261 | if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) |
2254 | set_current_state(TASK_UNINTERRUPTIBLE); | 2262 | msleep(250); |
2255 | schedule_timeout(HZ/4); | ||
2256 | } | ||
2257 | } else { | 2263 | } else { |
2258 | for (i = HZ/10; i >= 0; i--) { | 2264 | end_time = jiffies + msecs_to_jiffies(100); |
2265 | do { | ||
2259 | unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID); | 2266 | unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID); |
2260 | if (val != 0xffff && (val & 1) != 0) | 2267 | if (val != 0xffff && (val & 1) != 0) |
2261 | break; | 2268 | break; |
2262 | set_current_state(TASK_UNINTERRUPTIBLE); | 2269 | set_current_state(TASK_UNINTERRUPTIBLE); |
2263 | schedule_timeout(1); | 2270 | schedule_timeout(1); |
2264 | } | 2271 | } while (time_after_eq(end_time, jiffies)); |
2265 | } | 2272 | } |
2266 | __reset_ready: | 2273 | __reset_ready: |
2267 | 2274 | ||