sound: use DEFINE_PCI_DEVICE_TABLE
[safe/jmp/linux-2.6] / sound / pci / intel8x0.c
index 10f8609..6433e65 100644 (file)
@@ -356,8 +356,6 @@ struct ichdev {
         unsigned int position;
        unsigned int pos_shift;
        unsigned int last_pos;
-       unsigned long last_pos_jiffies;
-       unsigned int jiffy_to_bytes;
         int frags;
         int lvi;
         int lvi_frag;
@@ -422,30 +420,30 @@ struct intel8x0 {
        u32 int_sta_mask;               /* interrupt status mask */
 };
 
-static struct pci_device_id snd_intel8x0_ids[] = {
-       { 0x8086, 0x2415, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */
-       { 0x8086, 0x2425, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */
-       { 0x8086, 0x2445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */
-       { 0x8086, 0x2485, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH3 */
-       { 0x8086, 0x24c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH4 */
-       { 0x8086, 0x24d5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH5 */
-       { 0x8086, 0x25a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ESB */
-       { 0x8086, 0x266e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH6 */
-       { 0x8086, 0x27de, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH7 */
-       { 0x8086, 0x2698, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ESB2 */
-       { 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */
-       { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS },   /* SI7012 */
-       { 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },        /* NFORCE */
-       { 0x10de, 0x003a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },        /* MCP04 */
-       { 0x10de, 0x006a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },        /* NFORCE2 */
-       { 0x10de, 0x0059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },        /* CK804 */
-       { 0x10de, 0x008a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },        /* CK8 */
-       { 0x10de, 0x00da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },        /* NFORCE3 */
-       { 0x10de, 0x00ea, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },        /* CK8S */
-       { 0x10de, 0x026b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE },        /* MCP51 */
-       { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
-       { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
-       { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI },   /* Ali5455 */
+static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0_ids) = {
+       { PCI_VDEVICE(INTEL, 0x2415), DEVICE_INTEL },   /* 82801AA */
+       { PCI_VDEVICE(INTEL, 0x2425), DEVICE_INTEL },   /* 82901AB */
+       { PCI_VDEVICE(INTEL, 0x2445), DEVICE_INTEL },   /* 82801BA */
+       { PCI_VDEVICE(INTEL, 0x2485), DEVICE_INTEL },   /* ICH3 */
+       { PCI_VDEVICE(INTEL, 0x24c5), DEVICE_INTEL_ICH4 }, /* ICH4 */
+       { PCI_VDEVICE(INTEL, 0x24d5), DEVICE_INTEL_ICH4 }, /* ICH5 */
+       { PCI_VDEVICE(INTEL, 0x25a6), DEVICE_INTEL_ICH4 }, /* ESB */
+       { PCI_VDEVICE(INTEL, 0x266e), DEVICE_INTEL_ICH4 }, /* ICH6 */
+       { PCI_VDEVICE(INTEL, 0x27de), DEVICE_INTEL_ICH4 }, /* ICH7 */
+       { PCI_VDEVICE(INTEL, 0x2698), DEVICE_INTEL_ICH4 }, /* ESB2 */
+       { PCI_VDEVICE(INTEL, 0x7195), DEVICE_INTEL },   /* 440MX */
+       { PCI_VDEVICE(SI, 0x7012), DEVICE_SIS },        /* SI7012 */
+       { PCI_VDEVICE(NVIDIA, 0x01b1), DEVICE_NFORCE }, /* NFORCE */
+       { PCI_VDEVICE(NVIDIA, 0x003a), DEVICE_NFORCE }, /* MCP04 */
+       { PCI_VDEVICE(NVIDIA, 0x006a), DEVICE_NFORCE }, /* NFORCE2 */
+       { PCI_VDEVICE(NVIDIA, 0x0059), DEVICE_NFORCE }, /* CK804 */
+       { PCI_VDEVICE(NVIDIA, 0x008a), DEVICE_NFORCE }, /* CK8 */
+       { PCI_VDEVICE(NVIDIA, 0x00da), DEVICE_NFORCE }, /* NFORCE3 */
+       { PCI_VDEVICE(NVIDIA, 0x00ea), DEVICE_NFORCE }, /* CK8S */
+       { PCI_VDEVICE(NVIDIA, 0x026b), DEVICE_NFORCE }, /* MCP51 */
+       { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL },     /* AMD8111 */
+       { PCI_VDEVICE(AMD, 0x7445), DEVICE_INTEL },     /* AMD768 */
+       { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI },   /* Ali5455 */
        { 0, }
 };
 
@@ -844,7 +842,6 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                val = ICH_IOCE | ICH_STARTBM;
                ichdev->last_pos = ichdev->position;
-               ichdev->last_pos_jiffies = jiffies;
                break;
        case SNDRV_PCM_TRIGGER_SUSPEND:
                ichdev->suspended = 1;
@@ -1048,7 +1045,6 @@ static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream)
                        ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1;
        }
        snd_intel8x0_setup_periods(chip, ichdev);
-       ichdev->jiffy_to_bytes = (runtime->rate * 4 * ichdev->pos_shift) / HZ;
        return 0;
 }
 
@@ -1073,19 +1069,23 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs
                    ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
                        break;
        } while (timeout--);
+       ptr = ichdev->last_pos;
        if (ptr1 != 0) {
                ptr1 <<= ichdev->pos_shift;
                ptr = ichdev->fragsize1 - ptr1;
                ptr += position;
-               ichdev->last_pos = ptr;
-               ichdev->last_pos_jiffies = jiffies;
-       } else {
-               ptr1 = jiffies - ichdev->last_pos_jiffies;
-               if (ptr1)
-                       ptr1 -= 1;
-               ptr = ichdev->last_pos + ptr1 * ichdev->jiffy_to_bytes;
-               ptr %= ichdev->size;
+               if (ptr < ichdev->last_pos) {
+                       unsigned int pos_base, last_base;
+                       pos_base = position / ichdev->fragsize1;
+                       last_base = ichdev->last_pos / ichdev->fragsize1;
+                       /* another sanity check; ptr1 can go back to full
+                        * before the base position is updated
+                        */
+                       if (pos_base == last_base)
+                               ptr = ichdev->last_pos;
+               }
        }
+       ichdev->last_pos = ptr;
        spin_unlock(&chip->reg_lock);
        if (ptr >= ichdev->size)
                return 0;
@@ -1854,6 +1854,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
        },
        {
                .subvendor = 0x1028,
+               .subdevice = 0x016a,
+               .name = "Dell Inspiron 8600",   /* STAC9750/51 */
+               .type = AC97_TUNE_HP_ONLY
+       },
+       {
+               .subvendor = 0x1028,
                .subdevice = 0x0186,
                .name = "Dell Latitude D810", /* cf. Malone #41015 */
                .type = AC97_TUNE_HP_MUTE_LED
@@ -1896,12 +1902,6 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
        },
        {
                .subvendor = 0x103c,
-               .subdevice = 0x0934,
-               .name = "HP nx8220",
-               .type = AC97_TUNE_MUTE_LED
-       },
-       {
-               .subvendor = 0x103c,
                .subdevice = 0x129d,
                .name = "HP xw8000",
                .type = AC97_TUNE_HP_ONLY
@@ -1950,10 +1950,28 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
        },
        {
                .subvendor = 0x104d,
+               .subdevice = 0x8144,
+               .name = "Sony",
+               .type = AC97_TUNE_INV_EAPD
+       },
+       {
+               .subvendor = 0x104d,
                .subdevice = 0x8197,
                .name = "Sony S1XP",
                .type = AC97_TUNE_INV_EAPD
        },
+       {
+               .subvendor = 0x104d,
+               .subdevice = 0x81c0,
+               .name = "Sony VAIO VGN-T350P", /*AD1981B*/
+               .type = AC97_TUNE_INV_EAPD
+       },
+       {
+               .subvendor = 0x104d,
+               .subdevice = 0x81c5,
+               .name = "Sony VAIO VGN-B1VP", /*AD1981B*/
+               .type = AC97_TUNE_INV_EAPD
+       },
        {
                .subvendor = 0x1043,
                .subdevice = 0x80f3,
@@ -2045,6 +2063,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
                .type = AC97_TUNE_HP_ONLY
        },
        {
+               .subvendor = 0x161f,
+               .subdevice = 0x203a,
+               .name = "Gateway 4525GZ",               /* AD1981B */
+               .type = AC97_TUNE_INV_EAPD
+       },
+       {
                .subvendor = 0x1734,
                .subdevice = 0x0088,
                .name = "Fujitsu-Siemens D1522",        /* AD1981 */
@@ -2676,12 +2700,13 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
        struct ichdev *ichdev;
        unsigned long port;
        unsigned long pos, pos1, t;
-       int civ, timeout = 1000;
+       int civ, timeout = 1000, attempt = 1;
        struct timespec start_time, stop_time;
 
        if (chip->ac97_bus->clock != 48000)
                return; /* specified in module option */
 
+      __again:
        subs = chip->pcm[0]->streams[0].substream;
        if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) {
                snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n");
@@ -2749,7 +2774,13 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
 
        if (pos == 0) {
                snd_printk(KERN_ERR "intel8x0: measure - unreliable DMA position..\n");
-               return;
+             __retry:
+               if (attempt < 3) {
+                       msleep(300);
+                       attempt++;
+                       goto __again;
+               }
+               goto __end;
        }
 
        pos /= 4;
@@ -2759,14 +2790,15 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
        printk(KERN_INFO "%s: measured %lu usecs (%lu samples)\n", __func__, t, pos);
        if (t == 0) {
                snd_printk(KERN_ERR "intel8x0: ?? calculation error..\n");
-               return;
+               goto __retry;
        }
        pos *= 1000;
        pos = (pos / t) * 1000 + ((pos % t) * 1000) / t;
-       if (pos < 40000 || pos >= 60000) 
+       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)
+               goto __retry;
+       } else if (pos > 40500 && pos < 41500)
                /* first exception - 41000Hz reference clock */
                chip->ac97_bus->clock = 41000;
        else if (pos > 43600 && pos < 44600)
@@ -2775,6 +2807,7 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
        else if (pos < 47500 || pos > 48500)
                /* not 48000Hz, tuning the clock.. */
                chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos;
+      __end:
        printk(KERN_INFO "intel8x0: clocking to %d\n", chip->ac97_bus->clock);
        snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0);
 }