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