Update of /cvsroot/alsa/alsa-kernel/pci
In directory sc8-pr-cvs1:/tmp/cvs-serv24608

Modified Files:
        intel8x0.c 
Log Message:
fixed ali5455 support.

the sample rate is fixed to 48k atm, since my test environment seems
accepting only this although the chip supports VRA.

spdif i/o and multi-channel are not tested.



Index: intel8x0.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/intel8x0.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -r1.81 -r1.82
--- intel8x0.c  18 Jun 2003 11:08:07 -0000      1.81
+++ intel8x0.c  27 Jun 2003 17:52:59 -0000      1.82
@@ -254,8 +254,13 @@
 DEFINE_REGSET(AL_PO, 0x50);    /* Ali PCM out */
 DEFINE_REGSET(AL_MC, 0x60);    /* Ali Mic in */
 DEFINE_REGSET(AL_CDC_SPO, 0x70);       /* Ali Codec SPDIF out */
+DEFINE_REGSET(AL_CENTER, 0x80);                /* Ali center out */
+DEFINE_REGSET(AL_LFE, 0x90);           /* Ali center out */
 DEFINE_REGSET(AL_CLR_SPI, 0xa0);       /* Ali Controller SPDIF in */
 DEFINE_REGSET(AL_CLR_SPO, 0xb0);       /* Ali Controller SPDIF out */
+DEFINE_REGSET(AL_I2S, 0xc0);   /* Ali I2S in */
+DEFINE_REGSET(AL_PI2, 0xd0);   /* Ali PCM2 in */
+DEFINE_REGSET(AL_MC2, 0xe0);   /* Ali Mic2 in */
 
 enum {
        ICH_REG_ALI_SCR = 0x00,         /* System Control Register */
@@ -275,32 +280,61 @@
        ICH_REG_ALI_RTSR = 0x34,        /* Receive Tag Slot  Register */
        ICH_REG_ALI_CSPSR = 0x38,       /* Command/Status Port Status Register */
        ICH_REG_ALI_CAS = 0x3c,         /* Codec Write Semaphore Register */
+       ICH_REG_ALI_HWVOL = 0xf0,       /* hardware volume control/status */
+       ICH_REG_ALI_I2SCR = 0xf4,       /* I2S control/status */
        ICH_REG_ALI_SPDIFCSR = 0xf8,    /* spdif channel status register  */
-       ICH_REG_ALI_SPDIFICS = 0xfc     /* spdif interface control/status  */
+       ICH_REG_ALI_SPDIFICS = 0xfc,    /* spdif interface control/status  */
 };
 
 #define ALI_CAS_SEM_BUSY       0x80000000
-#define ALI_CSPSR_CODEC_READY  0x08
+#define ALI_CPR_ADDR_SECONDARY 0x100
 #define ALI_CPR_ADDR_READ      0x80
+#define ALI_CSPSR_CODEC_READY  0x08
 #define ALI_CSPSR_READ_OK      0x02
 #define ALI_CSPSR_WRITE_OK     0x01
 
 /* interrupts for the whole chip by interrupt status register finish */
  
+#define ALI_INT_MICIN2         (1<<26)
+#define ALI_INT_PCMIN2         (1<<25)
+#define ALI_INT_I2SIN          (1<<24)
 #define ALI_INT_SPDIFOUT       (1<<23) /* controller spdif out INTERRUPT */
 #define ALI_INT_SPDIFIN                (1<<22)
+#define ALI_INT_LFEOUT         (1<<21)
+#define ALI_INT_CENTEROUT      (1<<20)
 #define ALI_INT_CODECSPDIFOUT  (1<<19)
 #define ALI_INT_MICIN          (1<<18)
 #define ALI_INT_PCMOUT         (1<<17)
 #define ALI_INT_PCMIN          (1<<16)
-#define ALI_INT_CPRAIS         (1<<7)
-#define ALI_INT_SPRAIS         (1<<5)
+#define ALI_INT_CPRAIS         (1<<7)  /* command port available */
+#define ALI_INT_SPRAIS         (1<<5)  /* status port available */
 #define ALI_INT_GPIO           (1<<1)
 #define ALI_INT_MASK           
(ALI_INT_SPDIFOUT|ALI_INT_CODECSPDIFOUT|ALI_INT_MICIN|ALI_INT_PCMOUT|ALI_INT_PCMIN)
 
-#define ALI_PCM_CH4            0x100
-#define ALI_PCM_CH6            0x200
-#define ALI_PCM_MASK           (ALI_PCM_CH4 | ALI_PCM_CH6)
+#define ICH_ALI_SC_RESET       (1<<31) /* master reset */
+#define ICH_ALI_SC_AC97_DBL    (1<<30)
+#define ICH_ALI_SC_CODEC_SPDF  (3<<20) /* 1=7/8, 2=6/9, 3=10/11 */
+#define ICH_ALI_SC_IN_BITS     (3<<18)
+#define ICH_ALI_SC_OUT_BITS    (3<<16)
+#define ICH_ALI_SC_6CH_CFG     (3<<14)
+#define ICH_ALI_SC_PCM_4       (1<<8)
+#define ICH_ALI_SC_PCM_6       (2<<8)
+#define ICH_ALI_SC_PCM_246_MASK        (3<<8)
+
+#define ICH_ALI_SS_SEC_ID      (3<<5)
+#define ICH_ALI_SS_PRI_ID      (3<<3)
+
+#define ICH_ALI_IF_AC97SP      (1<<21)
+#define ICH_ALI_IF_MC          (1<<20)
+#define ICH_ALI_IF_PI          (1<<19)
+#define ICH_ALI_IF_MC2         (1<<18)
+#define ICH_ALI_IF_PI2         (1<<17)
+#define ICH_ALI_IF_LINE_SRC    (1<<15) /* 0/1 = slot 3/6 */
+#define ICH_ALI_IF_MIC_SRC     (1<<14) /* 0/1 = slot 3/6 */
+#define ICH_ALI_IF_SPDF_SRC    (3<<12) /* 00 = PCM, 01 = AC97-in, 10 = spdif-in, 11 = 
i2s */
+#define ICH_ALI_IF_AC97_OUT    (3<<8)  /* 00 = PCM, 10 = spdif-in, 11 = i2s */
+#define ICH_ALI_IF_PO_SPDF     (1<<3)
+#define ICH_ALI_IF_PO          (1<<1)
 
 /*
  *  
@@ -336,11 +370,6 @@
        ac97_t *ac97;
        unsigned short ac97_rate_regs[3];
        int ac97_rates_idx;
-#ifdef CONFIG_PM
-       unsigned char civ_saved;
-       unsigned char piv_saved;
-       unsigned short picb_saved;
-#endif
 } ichdev_t;
 
 typedef struct _snd_intel8x0 intel8x0_t;
@@ -603,31 +632,29 @@
        int time = 100;
        while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
                udelay(1);
+       if (! time)
+               snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n");
        return snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_CODEC_READY);
 }
 
 static unsigned short snd_intel8x0_ali_codec_read(ac97_t *ac97, unsigned short reg)
 {
        intel8x0_t *chip = snd_magic_cast(intel8x0_t, ac97->private_data, return ~0);
-       unsigned short data, reg2;
+       unsigned short data = 0xffff;
 
        spin_lock(&chip->ac97_lock);
        if (snd_intel8x0_ali_codec_semaphore(chip))
                goto __err;
-       iputword(chip, ICHREG(ALI_CPR_ADDR), reg | ALI_CPR_ADDR_READ);
+       reg |= ALI_CPR_ADDR_READ;
+       if (ac97->num)
+               reg |= ALI_CPR_ADDR_SECONDARY;
+       iputword(chip, ICHREG(ALI_CPR_ADDR), reg);
        if (snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_READ_OK))
                goto __err;
        data = igetword(chip, ICHREG(ALI_SPR));
-       reg2 = igetword(chip, ICHREG(ALI_SPR_ADDR));
-       if (reg != reg2) {
-               snd_printd(KERN_WARNING "intel8x0: AC97 read not completed? 0x%x != 
0x%x\n", reg, reg2);
-               // goto __err;
-       }
-       spin_unlock(&chip->ac97_lock);
-       return data;
  __err:
        spin_unlock(&chip->ac97_lock);
-       return 0xffff;
+       return data;
 }
 
 static void snd_intel8x0_ali_codec_write(ac97_t *ac97, unsigned short reg, unsigned 
short val)
@@ -640,7 +667,9 @@
                return;
        }
        iputword(chip, ICHREG(ALI_CPR), val);
-       iputbyte(chip, ICHREG(ALI_CPR_ADDR), reg);
+       if (ac97->num)
+               reg |= ALI_CPR_ADDR_SECONDARY;
+       iputword(chip, ICHREG(ALI_CPR_ADDR), reg);
        snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_WRITE_OK);
        spin_unlock(&chip->ac97_lock);
 }
@@ -680,6 +709,7 @@
                ichdev->frags = ichdev->size / ichdev->fragsize;
        }
        iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi = ICH_REG_LVI_MASK);
+       iputbyte(chip, port + ICH_REG_OFF_CIV, 0);
        ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags;
        ichdev->position = 0;
 #if 0
@@ -728,6 +758,8 @@
        spin_lock(&chip->reg_lock);
        status = igetdword(chip, chip->int_sta_reg);
        if ((status & chip->int_sta_mask) == 0) {
+               if (status)
+                       iputdword(chip, chip->int_sta_reg, status);
                spin_unlock(&chip->reg_lock);
                return IRQ_NONE;
        }
@@ -776,8 +808,9 @@
        }
        iputbyte(chip, port + ICH_REG_OFF_CR, val);
        if (cmd == SNDRV_PCM_TRIGGER_STOP) {
-               /* reset whole DMA things */
+               /* wait until DMA stopped */
                while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) ;
+               /* reset whole DMA things */
                iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
        }
        return 0;
@@ -788,31 +821,40 @@
        intel8x0_t *chip = snd_pcm_substream_chip(substream);
        ichdev_t *ichdev = get_ichdev(substream);
        unsigned long port = ichdev->reg_offset;
+       static int fiforeg[] = { ICHREG(ALI_FIFOCR1), ICHREG(ALI_FIFOCR2), 
ICHREG(ALI_FIFOCR3) };
+       unsigned int val, fifo;
 
+       val = igetdword(chip, ICHREG(ALI_DMACR));
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
        case SNDRV_PCM_TRIGGER_RESUME:
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+                       /* clear FIFO for synchronization of channels */
+                       fifo = igetdword(chip, fiforeg[ichdev->ali_slot / 4]);
+                       fifo &= ~(0xff << (ichdev->ali_slot % 4));  
+                       fifo |= 0x83 << (ichdev->ali_slot % 4); 
+                       iputdword(chip, fiforeg[ichdev->ali_slot / 4], fifo);
+               }
                iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
-               iputbyte(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot);
+               val &= ~(1 << (ichdev->ali_slot + 16)); /* clear PAUSE flag */
+               iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot)); /* 
start DMA */
                break;
        case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
        case SNDRV_PCM_TRIGGER_SUSPEND:
-               iputbyte(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8));
+               iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 
16))); /* pause */
                iputbyte(chip, port + ICH_REG_OFF_CR, 0);
-               /* reset whole DMA things */
-               while (!(igetbyte(chip, port + ICH_REG_OFF_CR)))
+               while (igetbyte(chip, port + ICH_REG_OFF_CR))
                        ;
+               if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
+                       break;
+               /* reset whole DMA things */
                iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
                /* clear interrupts */
                iputbyte(chip, port + ICH_REG_OFF_SR, igetbyte(chip, port + 
ICH_REG_OFF_SR) | 0x1e);
                iputdword(chip, ICHREG(ALI_INTERRUPTSR),
-                         igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & (1 << 
(ichdev->ali_slot + 8)));
-               break;
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               iputbyte(chip, port + ICH_REG_OFF_CR, 0);
-               break;
-       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               iputbyte(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot);
+                         igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & 
ichdev->int_sta_mask);
                break;
        default:
                return -EINVAL;
@@ -833,21 +875,36 @@
 
 static void snd_intel8x0_setup_multi_channels(intel8x0_t *chip, int channels)
 {
-       unsigned int cnt = igetdword(chip, ICHREG(GLOB_CNT));
-       if (chip->device_type == DEVICE_SIS) {
+       unsigned int cnt;
+       switch (chip->device_type) {
+       case DEVICE_ALI:
+               cnt = igetdword(chip, ICHREG(ALI_SCR));
+               cnt &= ~ICH_ALI_SC_PCM_246_MASK;
+               if (chip->multi4 && channels == 4)
+                       cnt |= ICH_ALI_SC_PCM_4;
+               else if (chip->multi6 && channels == 6)
+                       cnt |= ICH_ALI_SC_PCM_6;
+               iputdword(chip, ICHREG(ALI_SCR), cnt);
+               break;
+       case DEVICE_SIS:
+               cnt = igetdword(chip, ICHREG(GLOB_CNT));
                cnt &= ~ICH_SIS_PCM_246_MASK;
                if (chip->multi4 && channels == 4)
                        cnt |= ICH_SIS_PCM_4;
                else if (chip->multi6 && channels == 6)
                        cnt |= ICH_SIS_PCM_6;
-       } else {
+               iputdword(chip, ICHREG(GLOB_CNT), cnt);
+               break;
+       default:
+               cnt = igetdword(chip, ICHREG(GLOB_CNT));
                cnt &= ~ICH_PCM_246_MASK;
                if (chip->multi4 && channels == 4)
                        cnt |= ICH_PCM_4;
                else if (chip->multi6 && channels == 6)
                        cnt |= ICH_PCM_6;
+               iputdword(chip, ICHREG(GLOB_CNT), cnt);
+               break;
        }
-       iputdword(chip, ICHREG(GLOB_CNT), cnt);
 }
 
 static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream)
@@ -860,7 +917,7 @@
        ichdev->physbuf = runtime->dma_addr;
        ichdev->size = snd_pcm_lib_buffer_bytes(substream);
        ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
-       if (ichdev->ichd == ICHD_PCMOUT && chip->device_type != DEVICE_ALI) {
+       if (ichdev->ichd == ICHD_PCMOUT) {
                spin_lock(&chip->reg_lock);
                snd_intel8x0_setup_multi_channels(chip, runtime->channels);
                spin_unlock(&chip->reg_lock);
@@ -881,10 +938,13 @@
 {
        intel8x0_t *chip = snd_pcm_substream_chip(substream);
        ichdev_t *ichdev = get_ichdev(substream);
-       size_t ptr;
+       size_t ptr1, ptr;
 
-       ptr = ichdev->fragsize1;
-       ptr -= igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << 
chip->pcm_pos_shift;
+       ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << 
chip->pcm_pos_shift;
+       if (ptr1 != 0)
+               ptr = ichdev->fragsize1 - ptr1;
+       else
+               ptr = 0;
        ptr += ichdev->position;
        if (ptr >= ichdev->size)
                return 0;
@@ -900,7 +960,7 @@
                                 SNDRV_PCM_INFO_RESUME),
        .formats =              SNDRV_PCM_FMTBIT_S16_LE,
        .rates =                SNDRV_PCM_RATE_48000,
-       .rate_min =             8000,
+       .rate_min =             48000,
        .rate_max =             48000,
        .channels_min =         2,
        .channels_max =         2,
@@ -940,14 +1000,23 @@
 {
        intel8x0_t *chip = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
+       static unsigned int i, rates[] = {
+               /* ATTENTION: these values depend on the definition in pcm.h! */
+               5512, 8000, 11025, 16000, 22050, 32000, 44100, 480000
+       };
        int err;
 
        ichdev->substream = substream;
        runtime->hw = snd_intel8x0_stream;
-       if (ichdev->ac97 && ichdev->ac97_rates_idx >= 0)
+       if (ichdev->ac97 && ichdev->ac97_rates_idx >= 0) {
                runtime->hw.rates = ichdev->ac97->rates[ichdev->ac97_rates_idx];
-       if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
-               runtime->hw.rate_min = 48000;
+               for (i = 0; i < ARRAY_SIZE(rates); i++) {
+                       if (runtime->hw.rates & (1 << i)) {
+                               runtime->hw.rate_min = rates[i];
+                               break;
+                       }
+               }
+       }
        if (chip->device_type == DEVICE_SIS) {
                runtime->hw.buffer_bytes_max = 64*1024;
                runtime->hw.period_bytes_max = 64*1024;
@@ -1063,6 +1132,14 @@
 static int snd_intel8x0_ali_ac97spdifout_open(snd_pcm_substream_t * substream)
 {
        intel8x0_t *chip = snd_pcm_substream_chip(substream);
+       unsigned long flags;
+       unsigned int val;
+
+       spin_lock_irqsave(&chip->reg_lock, flags);
+       val = igetdword(chip, ICHREG(ALI_INTERFACECR));
+       val |= ICH_ALI_IF_AC97SP;
+       /* also needs to set ALI_SC_CODEC_SPDF correctly */
+       spin_unlock_irqrestore(&chip->reg_lock, flags);
 
        return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_AC97SPDIFOUT]);
 }
@@ -1070,8 +1147,15 @@
 static int snd_intel8x0_ali_ac97spdifout_close(snd_pcm_substream_t * substream)
 {
        intel8x0_t *chip = snd_pcm_substream_chip(substream);
+       unsigned long flags;
+       unsigned int val;
 
        chip->ichd[ALID_AC97SPDIFOUT].substream = NULL;
+       spin_lock_irqsave(&chip->reg_lock, flags);
+       val = igetdword(chip, ICHREG(ALI_INTERFACECR));
+       val &= ~ICH_ALI_IF_AC97SP;
+       spin_unlock_irqrestore(&chip->reg_lock, flags);
+
        return 0;
 }
 
@@ -1090,6 +1174,7 @@
        return 0;
 }
 
+#if 0 // NYI
 static int snd_intel8x0_ali_spdifout_open(snd_pcm_substream_t * substream)
 {
        intel8x0_t *chip = snd_pcm_substream_chip(substream);
@@ -1104,6 +1189,7 @@
        chip->ichd[ALID_SPDIFOUT].substream = NULL;
        return 0;
 }
+#endif
 
 static snd_pcm_ops_t snd_intel8x0_playback_ops = {
        .open =         snd_intel8x0_playback_open,
@@ -1226,6 +1312,7 @@
        .pointer =      snd_intel8x0_pcm_pointer,
 };
 
+#if 0 // NYI
 static snd_pcm_ops_t snd_intel8x0_ali_spdifout_ops = {
        .open =         snd_intel8x0_ali_spdifout_open,
        .close =        snd_intel8x0_ali_spdifout_close,
@@ -1236,6 +1323,7 @@
        .trigger =      snd_intel8x0_pcm_trigger,
        .pointer =      snd_intel8x0_pcm_pointer,
 };
+#endif // NYI
 
 struct ich_pcm_table {
        char *suffix;
@@ -1357,18 +1445,20 @@
        },
        {
                .suffix = "IEC958",
-               .playback_ops = &snd_intel8x0_ali_spdifout_ops,
+               .playback_ops = &snd_intel8x0_ali_ac97spdifout_ops,
                .capture_ops = &snd_intel8x0_ali_spdifin_ops,
                .prealloc_size = 64 * 1024,
                .prealloc_max_size = 128 * 1024,
+               .ac97_idx = ALID_AC97SPDIFOUT,
        },
+#if 0 // NYI
        {
-               .suffix = "AC97 IEC958",
-               .playback_ops = &snd_intel8x0_ali_ac97spdifout_ops,
+               .suffix = "HW IEC958",
+               .playback_ops = &snd_intel8x0_ali_spdifout_ops,
                .prealloc_size = 64 * 1024,
                .prealloc_max_size = 128 * 1024,
-               .ac97_idx = ALID_AC97SPDIFOUT,
        },
+#endif
 };
 
 static int __devinit snd_intel8x0_pcm(intel8x0_t *chip)
@@ -1447,12 +1537,21 @@
 };
 
 static struct _ac97_rate_regs ali_ac97_rate_regs[] __devinitdata = {
+#if 0 /* FIXME: my test board doens't work well with VRA... */
        { ALID_PCMOUT, { AC97_PCM_FRONT_DAC_RATE, AC97_PCM_SURR_DAC_RATE, 
AC97_PCM_LFE_DAC_RATE }, AC97_RATES_FRONT_DAC },
        { ALID_PCMIN, { AC97_PCM_LR_ADC_RATE, 0, 0 }, AC97_RATES_ADC },
        { ALID_MIC, { AC97_PCM_MIC_ADC_RATE, 0, 0 }, AC97_RATES_MIC_ADC },
        { ALID_AC97SPDIFOUT, { AC97_SPDIF, 0, 0 }, AC97_RATES_SPDIF },
        { ALID_SPDIFOUT, { 0, 0, 0 }, -1 },
        { ALID_SPDIFIN, { 0, 0, 0 }, -1 },
+#else
+       { ALID_PCMOUT, { AC97_PCM_FRONT_DAC_RATE }, -1 },
+       { ALID_PCMIN, { AC97_PCM_LR_ADC_RATE }, -1 },
+       { ALID_MIC, { AC97_PCM_MIC_ADC_RATE }, -1 },
+       { ALID_AC97SPDIFOUT, { AC97_SPDIF }, -1 },
+       { ALID_SPDIFOUT, { }, -1 },
+       { ALID_SPDIFIN, { }, -1 },
+#endif
 };
 
 static struct ac97_quirk ac97_quirks[] __devinitdata = {
@@ -1470,19 +1569,24 @@
        ac97_t ac97, *x97;
        ichdev_t *ichdev;
        int err;
-       unsigned int i, num, channels = 2, codecs, _codecs;
+       unsigned int i, num, codecs, _codecs;
        unsigned int glob_sta = 0;
        struct _ac97_rate_regs *tbl;
+       int spdif_idx = -1; /* disabled */
 
        switch (chip->device_type) {
        case DEVICE_NFORCE:
                tbl = nforce_ac97_rate_regs;
+               spdif_idx = NVD_SPBAR;
                break;
        case DEVICE_ALI:
                tbl = ali_ac97_rate_regs;
+               spdif_idx = ALID_AC97SPDIFOUT;
                break;
        default:
                tbl = intel_ac97_rate_regs;
+               if (chip->device_type == DEVICE_INTEL_ICH4)
+                       spdif_idx = ICHD_SPBAR;
                break;
        };
        for (i = 0; i < chip->bdbars_count; i++) {
@@ -1506,10 +1610,6 @@
                glob_sta = igetdword(chip, ICHREG(GLOB_STA));
                ac97.write = snd_intel8x0_codec_write;
                ac97.read = snd_intel8x0_codec_read;
-               if (glob_sta & ICH_PCM_6)
-                       channels = 6;
-               else if (glob_sta & ICH_PCM_4)
-                       channels = 4;
                if (chip->device_type == DEVICE_INTEL_ICH4) {
                        codecs = 0;
                        if (glob_sta & ICH_PCR)
@@ -1532,7 +1632,6 @@
        } else {
                ac97.write = snd_intel8x0_ali_codec_write;
                ac97.read = snd_intel8x0_ali_codec_read;
-               channels = 6;
                codecs = 1;
                /* detect the secondary codec */
                for (i = 0; i < 100; i++) {
@@ -1556,19 +1655,8 @@
        if (x97->ext_id & AC97_EI_VRM)
                chip->ichd[ICHD_MIC].ac97 = x97;
        /* spdif */
-       if (x97->ext_id & AC97_EI_SPDIF) {
-               switch (chip->device_type) {
-               case DEVICE_INTEL_ICH4:
-                       chip->ichd[ICHD_SPBAR].ac97 = x97;
-                       break;
-               case DEVICE_NFORCE:
-                       chip->ichd[NVD_SPBAR].ac97 = x97;
-                       break;
-               case DEVICE_ALI:
-                       chip->ichd[ALID_AC97SPDIFOUT].ac97 = x97;
-                       break;
-               }
-       }
+       if ((x97->ext_id & AC97_EI_SPDIF) && spdif_idx >= 0)
+               chip->ichd[spdif_idx].ac97 = x97;
        /* make sure, that we have DACs at right slot for rev2.2 */
        if (ac97_is_rev22(x97))
                snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 0);
@@ -1599,23 +1687,18 @@
                                         chip->ichd[ICHD_PCM2IN].ac97 == x97)
                                        chip->ichd[ICHD_MIC2].ac97 = x97;
                        }
-                       if (x97->ext_id & AC97_EI_SPDIF) {
-                               if (chip->ichd[ICHD_SPBAR].ac97 == NULL)
-                                       chip->ichd[ICHD_SPBAR].ac97 = x97;
-                       }
                        break;
                default:
                        if (x97->ext_id & AC97_EI_VRM) {
                                if (chip->ichd[ICHD_MIC].ac97 == NULL)
                                        chip->ichd[ICHD_MIC].ac97 = x97;
                        }
-                       if ((x97->ext_id & AC97_EI_SPDIF) &&
-                           chip->device_type == DEVICE_NFORCE) {
-                               if (chip->ichd[NVD_SPBAR].ac97 == NULL)
-                                       chip->ichd[NVD_SPBAR].ac97 = x97;
-                       }
                        break;
                }
+               if ((x97->ext_id & AC97_EI_SPDIF) && spdif_idx >= 0) {
+                       if (chip->ichd[spdif_idx].ac97 == NULL)
+                               chip->ichd[spdif_idx].ac97 = x97;
+               }
        }
        
       __skip_secondary:
@@ -1645,22 +1728,24 @@
                if (x97->scaps & AC97_SCAP_CENTER_LFE_DAC)
                        chip->multi6 = 1;
        }
-       if (codecs > 1) {
+       if (chip->device_type == DEVICE_ALI && chip->ac97[1]) {
+               /* set secondary codec id */
+               iputdword(chip, ICHREG(ALI_SSR),
+                         (igetdword(chip, ICHREG(ALI_SSR)) & ~ICH_ALI_SS_SEC_ID) |
+                         (chip->ac97[1]->addr << 5));
+       }
+       if (codecs > 1 && !chip->multi6) {
                /* assign right slots for rev2.2 codecs */
                i = 1;
-               if (chip->multi4)
-                       goto __6ch;
-               for ( ; i < codecs; i++) {
+               for ( ; i < codecs && !chip->multi4; i++) {
                        x97 = chip->ac97[i];
                        if (!ac97_is_audio(x97))
                                continue;
                        if (ac97_is_rev22(x97)) {
                                snd_ac97_update_bits(x97, AC97_EXTENDED_ID, 
AC97_EI_DACS_SLOT_MASK, 1);
                                chip->multi4 = 1;
-                               break;
                        }
                }
-             __6ch:
                for ( ; i < codecs && chip->multi4; i++) {
                        x97 = chip->ac97[i];
                        if (!ac97_is_audio(x97))
@@ -1673,27 +1758,20 @@
                }
                /* ok, some older codecs might support only AMAP */
                if (!chip->multi4) {
+                       int cnums = 0;
                        for (i = 1; i < codecs; i++) {
                                x97 = chip->ac97[i];
                                if (!ac97_is_audio(x97))
                                        continue;
                                if (ac97_can_amap(x97)) {
-                                       if (x97->addr == 1) {
-                                               chip->multi4 = 1;
-                                               break;
-                                       }
-                               }
-                       }
-                       for ( ; i < codecs && chip->multi4; i++) {
-                               if (!ac97_is_audio(x97))
-                                       continue;
-                               if (ac97_can_amap(x97)) {
-                                       if (x97->addr == 2) {
-                                               chip->multi6 = 1;
-                                               break;
-                                       }
+                                       if (x97->addr > 0)
+                                               cnums++;
                                }
                        }
+                       if (cnums >= 2)
+                               chip->multi6 = 1;
+                       if (cnums >= 1)
+                               chip->multi4 = 1;
                }
        }
        chip->in_ac97_init = 0;
@@ -1707,10 +1785,12 @@
 
 static void do_ali_reset(intel8x0_t *chip)
 {
-       iputdword(chip, ICHREG(ALI_SCR), 0x8000000);
+       iputdword(chip, ICHREG(ALI_SCR), ICH_ALI_SC_RESET);
        iputdword(chip, ICHREG(ALI_FIFOCR1), 0x83838383);
        iputdword(chip, ICHREG(ALI_FIFOCR2), 0x83838383);
-       iputdword(chip, ICHREG(ALI_INTERFACECR), 0x04080002); /* no spdif? */
+       iputdword(chip, ICHREG(ALI_FIFOCR3), 0x83838383);
+       iputdword(chip, ICHREG(ALI_INTERFACECR),
+                 ICH_ALI_IF_MC|ICH_ALI_IF_PI|ICH_ALI_IF_PO);
        iputdword(chip, ICHREG(ALI_INTERRUPTCR), 0x00000000);
        iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000);
 }
@@ -1845,14 +1925,14 @@
        unsigned int i;
        int err;
        
-       if (chip->device_type != DEVICE_ALI)
-               err = snd_intel8x0_ich_chip_init(chip);
-       else
-               err = snd_intel8x0_ali_chip_init(chip);
-       if (err < 0)
-               return err;
-
-       iagetword(chip, 0);     /* clear semaphore flag */
+       if (chip->device_type != DEVICE_ALI) {
+               if ((err = snd_intel8x0_ich_chip_init(chip)) < 0)
+                       return err;
+               iagetword(chip, 0);     /* clear semaphore flag */
+       } else {
+               if ((err = snd_intel8x0_ali_chip_init(chip)) < 0)
+                       return err;
+       }
 
        /* disable interrupts */
        for (i = 0; i < chip->bdbars_count; i++)
@@ -2019,7 +2099,7 @@
                iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE | ICH_STARTBM);
        else {
                iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
-               iputbyte(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot);
+               iputdword(chip, ICHREG(ALI_DMACR), 1 << ichdev->ali_slot);
        }
        do_gettimeofday(&start_time);
        spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -2037,12 +2117,16 @@
        pos += ichdev->position;
        do_gettimeofday(&stop_time);
        /* stop */
-       if (chip->device_type == DEVICE_ALI)
-               iputbyte(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8));
-       iputbyte(chip, port + ICH_REG_OFF_CR, 0);
-       /* reset whole DMA things */
-       while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH))
-               ;
+       if (chip->device_type == DEVICE_ALI) {
+               iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8));
+               iputbyte(chip, port + ICH_REG_OFF_CR, 0);
+               while (igetbyte(chip, port + ICH_REG_OFF_CR))
+                       ;
+       } else {
+               iputbyte(chip, port + ICH_REG_OFF_CR, 0);
+               while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH))
+                       ;
+       }
        iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
        spin_unlock_irqrestore(&chip->reg_lock, flags);
 
@@ -2267,7 +2351,8 @@
                        ichdev->roff_sr = ICH_REG_OFF_SR;
                        ichdev->roff_picb = ICH_REG_OFF_PICB;
                }
-               ichdev->ali_slot = i + 1;       /* is this right for last three 
devices? --jk */
+               if (device_type == DEVICE_ALI)
+                       ichdev->ali_slot = (ichdev->reg_offset - 0x40) / 0x10;
        }
        /* SIS7012 handles the pcm data in bytes, others are in words */
        chip->pcm_pos_shift = (device_type == DEVICE_SIS) ? 0 : 1;



-------------------------------------------------------
This SF.Net email sponsored by: Free pre-built ASP.NET sites including
Data Reports, E-commerce, Portals, and Forums are available now.
Download today and enter to win an XBOX or Visual Studio .NET.
http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to