ALSA: hda - Fix SSYNC register value for non-Intel controllers
authorTakashi Iwai <tiwai@suse.de>
Fri, 10 Jun 2011 12:56:26 +0000 (14:56 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 10 Jun 2011 13:00:07 +0000 (15:00 +0200)
SSYNC register was once defined as 0x34-37 in the old Intel datasheet,
but corrected later to 0x38-3b.  For fixing the register usage, a new
bit-flag is introduced for indicating the old ICH SSYNC register, and
ICH* PCI entries are added explicitly to enable this quirk.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_intel.c

index 5f2d05a8d0eb0257ed6cdd4a88797c42b31c046b..81bd3b33a15f9fa30e543d234fb882c9882dfc8f 100644 (file)
@@ -177,7 +177,8 @@ MODULE_DESCRIPTION("Intel HDA driver");
 #define ICH6_REG_INTCTL                        0x20
 #define ICH6_REG_INTSTS                        0x24
 #define ICH6_REG_WALLCLK               0x30    /* 24Mhz source */
-#define ICH6_REG_SYNC                  0x34    
+#define ICH6_REG_OLD_SSYNC             0x34    /* SSYNC for old ICH */
+#define ICH6_REG_SSYNC                 0x38
 #define ICH6_REG_CORBLBASE             0x40
 #define ICH6_REG_CORBUBASE             0x44
 #define ICH6_REG_CORBWP                        0x48
@@ -479,6 +480,7 @@ enum {
 #define AZX_DCAPS_POSFIX_VIA   (1 << 17)       /* Use VIACOMBO as default */
 #define AZX_DCAPS_NO_64BIT     (1 << 18)       /* No 64bit address */
 #define AZX_DCAPS_SYNC_WRITE   (1 << 19)       /* sync each cmd write */
+#define AZX_DCAPS_OLD_SSYNC    (1 << 20)       /* Old SSYNC reg for ICH */
 
 /* quirks for ATI SB / AMD Hudson */
 #define AZX_DCAPS_PRESET_ATI_SB \
@@ -1795,7 +1797,11 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        spin_lock(&chip->reg_lock);
        if (nsync > 1) {
                /* first, set SYNC bits of corresponding streams */
-               azx_writel(chip, SYNC, azx_readl(chip, SYNC) | sbits);
+               if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
+                       azx_writel(chip, OLD_SSYNC,
+                                  azx_readl(chip, OLD_SSYNC) | sbits);
+               else
+                       azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits);
        }
        snd_pcm_group_for_each_entry(s, substream) {
                if (s->pcm->card != substream->pcm->card)
@@ -1851,7 +1857,11 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        if (nsync > 1) {
                spin_lock(&chip->reg_lock);
                /* reset SYNC bits */
-               azx_writel(chip, SYNC, azx_readl(chip, SYNC) & ~sbits);
+               if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
+                       azx_writel(chip, OLD_SSYNC,
+                                  azx_readl(chip, OLD_SSYNC) & ~sbits);
+               else
+                       azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
                spin_unlock(&chip->reg_lock);
        }
        return 0;
@@ -2819,6 +2829,22 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
        /* SCH */
        { PCI_DEVICE(0x8086, 0x811b),
          .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP },
+       { PCI_DEVICE(0x8086, 0x2668),
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH6 */
+       { PCI_DEVICE(0x8086, 0x27d8),
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH7 */
+       { PCI_DEVICE(0x8086, 0x269a),
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ESB2 */
+       { PCI_DEVICE(0x8086, 0x284b),
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH8 */
+       { PCI_DEVICE(0x8086, 0x293e),
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH9 */
+       { PCI_DEVICE(0x8086, 0x293f),
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH9 */
+       { PCI_DEVICE(0x8086, 0x3a3e),
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH10 */
+       { PCI_DEVICE(0x8086, 0x3a6e),
+         .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH10 */
        /* Generic Intel */
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
          .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,