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