aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/isa/ad1848/ad1848_lib.c57
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
204static void snd_ad1848_mce_down(struct snd_ad1848 *chip) 204static 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)));