diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/isa/ad1848/ad1848_lib.c | 57 |
1 files changed, 21 insertions, 36 deletions
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index 18355fd66cb5..21536b7de608 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c | |||
@@ -203,9 +203,8 @@ static void snd_ad1848_mce_up(struct snd_ad1848 *chip) | |||
203 | 203 | ||
204 | static void snd_ad1848_mce_down(struct snd_ad1848 *chip) | 204 | static void snd_ad1848_mce_down(struct snd_ad1848 *chip) |
205 | { | 205 | { |
206 | unsigned long flags; | 206 | unsigned long flags, timeout; |
207 | int timeout; | 207 | int reg; |
208 | unsigned long end_time; | ||
209 | 208 | ||
210 | spin_lock_irqsave(&chip->reg_lock, flags); | 209 | spin_lock_irqsave(&chip->reg_lock, flags); |
211 | for (timeout = 5; timeout > 0; timeout--) | 210 | for (timeout = 5; timeout > 0; timeout--) |
@@ -222,50 +221,36 @@ static void snd_ad1848_mce_down(struct snd_ad1848 *chip) | |||
222 | #endif | 221 | #endif |
223 | 222 | ||
224 | chip->mce_bit &= ~AD1848_MCE; | 223 | chip->mce_bit &= ~AD1848_MCE; |
225 | timeout = inb(AD1848P(chip, REGSEL)); | 224 | reg = inb(AD1848P(chip, REGSEL)); |
226 | outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL)); | 225 | outb(chip->mce_bit | (reg & 0x1f), AD1848P(chip, REGSEL)); |
227 | if (timeout == 0x80) | 226 | if (reg == 0x80) |
228 | snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); | 227 | snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); |
229 | if ((timeout & AD1848_MCE) == 0) { | 228 | if ((reg & AD1848_MCE) == 0) { |
230 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 229 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
231 | return; | 230 | return; |
232 | } | 231 | } |
233 | 232 | ||
234 | /* | 233 | /* |
235 | * Wait for (possible -- during init auto-calibration may not be set) | 234 | * Wait for auto-calibration (AC) process to finish, i.e. ACI to go low. |
236 | * calibration process to start. Needs upto 5 sample periods on AD1848 | 235 | * It may take up to 5 sample periods (at most 907 us @ 5.5125 kHz) for |
237 | * which at the slowest possible rate of 5.5125 kHz means 907 us. | 236 | * the process to _start_, so it is important to wait at least that long |
237 | * before checking. Otherwise we might think AC has finished when it | ||
238 | * has in fact not begun. It could take 128 (no AC) or 384 (AC) cycles | ||
239 | * for ACI to drop. This gives a wait of at most 70 ms with a more | ||
240 | * typical value of 3-9 ms. | ||
238 | */ | 241 | */ |
239 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 242 | timeout = jiffies + msecs_to_jiffies(250); |
240 | msleep(1); | 243 | do { |
241 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
242 | |||
243 | snd_printdd("(2) jiffies = %lu\n", jiffies); | ||
244 | |||
245 | end_time = jiffies + msecs_to_jiffies(250); | ||
246 | while (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) { | ||
247 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 244 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
248 | if (time_after(jiffies, end_time)) { | ||
249 | snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n"); | ||
250 | return; | ||
251 | } | ||
252 | msleep(1); | 245 | msleep(1); |
253 | spin_lock_irqsave(&chip->reg_lock, flags); | 246 | spin_lock_irqsave(&chip->reg_lock, flags); |
254 | } | 247 | reg = snd_ad1848_in(chip, AD1848_TEST_INIT) & |
255 | 248 | AD1848_CALIB_IN_PROGRESS; | |
256 | snd_printdd("(3) jiffies = %lu\n", jiffies); | 249 | } while (reg && time_before(jiffies, timeout)); |
257 | |||
258 | end_time = jiffies + msecs_to_jiffies(100); | ||
259 | while (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) { | ||
260 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
261 | if (time_after(jiffies, end_time)) { | ||
262 | snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); | ||
263 | return; | ||
264 | } | ||
265 | msleep(1); | ||
266 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
267 | } | ||
268 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 250 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
251 | if (reg) | ||
252 | snd_printk(KERN_ERR | ||
253 | "mce_down - auto calibration time out (2)\n"); | ||
269 | 254 | ||
270 | snd_printdd("(4) jiffies = %lu\n", jiffies); | 255 | snd_printdd("(4) jiffies = %lu\n", jiffies); |
271 | snd_printd("mce_down - exit = 0x%x\n", inb(AD1848P(chip, REGSEL))); | 256 | snd_printd("mce_down - exit = 0x%x\n", inb(AD1848P(chip, REGSEL))); |