From 808b3c9e30989b03e7757567bebd8f8dadb0602a Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 13 Apr 2009 20:45:42 +0200 Subject: [PATCH] --- yaml --- r: 143359 b: refs/heads/master c: 920e4ae31cb113328e617f4a0663fb17d7b09124 h: refs/heads/master i: 143357: 91085a3f40268310fdcc3a33637c7c07acd1006b 143355: 903020c302567363f0fb19c8d979e25c68c40101 143351: faef0de18d858a7d09f501735afbfed61c1183ce 143343: 0b2023ae85340dc04c89e54907312ad47143887b 143327: be3d45740204678069b1c2db8050ce26f7c32f3f 143295: 9531f4c779edf326f2ffbe7a46b73fec9b41bd3e 143231: 6f8a5fd88abf5270b3da7c6c91ffe248a0049bdb 143103: 407516816a571f20e363eb02b9e9f457bee74af8 142847: 492db4f97ea062c4805aaebb467280bb30cd9d1b 142335: 789ce096dc543e5a7f3020891c5edde3eed89ecc 141311: b9f0a2a9a55e27e85fa43af27ba7b2eba7599985 139263: 78d0ae86fae40371c332f42aaab3a939df3e8856 v: v3 --- [refs] | 2 +- trunk/sound/pci/intel8x0.c | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/[refs] b/[refs] index 91f4b8139ba1..0dd71de39331 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bbf6ad1399e9516b0a95de3ad58ffbaed670e4cc +refs/heads/master: 920e4ae31cb113328e617f4a0663fb17d7b09124 diff --git a/trunk/sound/pci/intel8x0.c b/trunk/sound/pci/intel8x0.c index 57648810eaf1..c86ff499460b 100644 --- a/trunk/sound/pci/intel8x0.c +++ b/trunk/sound/pci/intel8x0.c @@ -2661,8 +2661,9 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) struct snd_pcm_substream *subs; struct ichdev *ichdev; unsigned long port; - unsigned long pos, t; - struct timeval start_time, stop_time; + unsigned long pos, pos1, t; + int civ, timeout = 1000; + struct timespec start_time, stop_time; if (chip->ac97_bus->clock != 48000) return; /* specified in module option */ @@ -2693,16 +2694,27 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE); iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot); } - do_gettimeofday(&start_time); + do_posix_clock_monotonic_gettime(&start_time); spin_unlock_irq(&chip->reg_lock); msleep(50); spin_lock_irq(&chip->reg_lock); /* check the position */ + do { + civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV); + pos1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb); + if (pos1 == 0) { + udelay(10); + continue; + } + if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) && + pos1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) + break; + } while (timeout--); pos = ichdev->fragsize1; - pos -= igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << ichdev->pos_shift; + pos -= pos1 << ichdev->pos_shift; pos += ichdev->position; chip->in_measurement = 0; - do_gettimeofday(&stop_time); + do_posix_clock_monotonic_gettime(&stop_time); /* stop */ if (chip->device_type == DEVICE_ALI) { iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16)); @@ -2717,19 +2729,26 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); spin_unlock_irq(&chip->reg_lock); + pos /= 4; t = stop_time.tv_sec - start_time.tv_sec; t *= 1000000; - t += stop_time.tv_usec - start_time.tv_usec; - printk(KERN_INFO "%s: measured %lu usecs\n", __func__, t); + t += (stop_time.tv_nsec - start_time.tv_nsec) / 1000; + printk(KERN_INFO "%s: measured %lu usecs (%lu samples)\n", __func__, t, pos); if (t == 0) { - snd_printk(KERN_ERR "?? calculation error..\n"); + snd_printk(KERN_ERR "intel8x0: ?? calculation error..\n"); return; } - pos = (pos / 4) * 1000; + pos *= 1000; pos = (pos / t) * 1000 + ((pos % t) * 1000) / t; if (pos < 40000 || pos >= 60000) /* abnormal value. hw problem? */ printk(KERN_INFO "intel8x0: measured clock %ld rejected\n", pos); + else if (pos > 40500 || pos < 41500) + /* first exception - 41000Hz reference clock */ + chip->ac97_bus->clock = 41000; + else if (pos > 43600 || pos < 44600) + /* second exception - 44100HZ reference clock */ + chip->ac97_bus->clock = 44100; else if (pos < 47500 || pos > 48500) /* not 48000Hz, tuning the clock.. */ chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos;