diff -ruN alsa-driver-0.9.1.old/README.xbox alsa-driver-0.9.1/README.xbox --- alsa-driver-0.9.1.old/README.xbox 1970-01-01 01:00:00.000000000 +0100 +++ alsa-driver-0.9.1/README.xbox 2004-03-26 11:45:48.334192088 +0000 @@ -0,0 +1,33 @@ +Alsa patches for Xbox + +The original information for working with Alsa is provided by Georg Lukas +Other S/PDIF stuff by andy@warmcat.com + +In order to cook ALSA you need the kernel sources for your version of the Xbox Linux kernel +installed and happy. + +If you can't get the courses or recompile your own kernel, then you are out of luck using +Alsa until someone issues a version suitable for your kernel or an updated distro is made +with lateast ALSA stuff already included. Sorry. + + + +Step 1: First catch your ALSA +$ wget ftp://ftp.alsa-project.org/pub/driver/alsa-driver-0.9.1.tar.bz2 + +Step 2: Untar +$ tar xjf alsa-driver-0.9.1.tar.bz2 + +Step 3: Copy over the patched files included with this README.xbox +$ cp -rf alsaxbox/* alsa-driver-0.9.1 + +Step 4: Configure ALSA suitably +$ cd alsa-driver-0.9.1 +$ ./configure --with-cards=intel8x0 + +Step 5: Cook Alsa with the mods +$ make && make install && rmmod snd-intel8x0 && modprobe snd-intel8x0 + +Step 6: Play some music! +$ mpg123 myfile.mp3 + diff -ruN alsa-driver-0.9.1.old/alsa-kernel/pci/ac97/ac97_codec.c alsa-driver-0.9.1/alsa-kernel/pci/ac97/ac97_codec.c --- alsa-driver-0.9.1.old/alsa-kernel/pci/ac97/ac97_codec.c 2003-02-28 19:22:18.000000000 +0000 +++ alsa-driver-0.9.1/alsa-kernel/pci/ac97/ac97_codec.c 2004-03-26 11:45:48.383184640 +0000 @@ -1958,8 +1958,8 @@ if (ac97_reset_wait(ac97, HZ/2, 0) < 0 && ac97_reset_wait(ac97, HZ/2, 1) < 0) { snd_printk("AC'97 %d:%d does not respond - RESET\n", ac97->num, ac97->addr); - snd_ac97_free(ac97); - return -ENXIO; + /*snd_ac97_free(ac97); + return -ENXIO;*/ } } __access_ok: diff -ruN alsa-driver-0.9.1.old/alsa-kernel/pci/intel8x0.c alsa-driver-0.9.1/alsa-kernel/pci/intel8x0.c --- alsa-driver-0.9.1.old/alsa-kernel/pci/intel8x0.c 2003-03-10 16:08:16.000000000 +0000 +++ alsa-driver-0.9.1/alsa-kernel/pci/intel8x0.c 2004-03-26 11:45:48.392183272 +0000 @@ -26,6 +26,15 @@ * */ +// andy@warmcat.com 2003-03-19 added support for Xbox S/PDIF to echo PCM OUT +// currently there is some lowlevel snap crackle and pop +// its to do with moving between descriptor buffers but +// I can't track it down any further at the moment +// +// define XBOX to get the mods + +#define XBOX + #include #include #include @@ -139,7 +148,7 @@ #define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da #endif -enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_SIS, DEVICE_ALI }; +enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE }; #define ICHREG(x) ICH_REG_##x @@ -159,12 +168,14 @@ DEFINE_REGSET(PI, 0x00); /* PCM in */ DEFINE_REGSET(PO, 0x10); /* PCM out */ DEFINE_REGSET(MC, 0x20); /* Mic in */ - +#ifndef XBOX /* ICH4 busmaster blocks */ DEFINE_REGSET(MC2, 0x40); /* Mic in 2 */ DEFINE_REGSET(PI2, 0x50); /* PCM in 2 */ DEFINE_REGSET(SP, 0x60); /* SPDIF out */ - +#else +DEFINE_REGSET(SP, 0x70); /* SPDIF out */ +#endif /* values for each busmaster block */ /* LVI */ @@ -296,7 +307,11 @@ * */ +#ifdef XBOX +enum { ICHD_PCMIN, ICHD_PCMOUT, ICHD_MIC, ICHD_SPBAR, ICHD_LAST = ICHD_SPBAR }; +#else enum { ICHD_PCMIN, ICHD_PCMOUT, ICHD_MIC, ICHD_MIC2, ICHD_PCM2IN, ICHD_SPBAR, ICHD_LAST = ICHD_SPBAR }; +#endif enum { ALID_PCMIN, ALID_PCMOUT, ALID_MIC, ALID_AC97SPDIFOUT, ALID_SPDIFIN, ALID_SPDIFOUT, ALID_LAST = ALID_SPDIFOUT }; #define get_ichdev(substream) (ichdev_t *)(substream->runtime->private_data) @@ -325,6 +340,9 @@ ac97_t *ac97; unsigned short ac97_rate_regs[3]; int ac97_rates_idx; +#ifdef XBOX + unsigned int m_uiLastRetiredDescriptorIndex; +#endif #ifdef CONFIG_PM unsigned char civ_saved; unsigned char piv_saved; @@ -396,9 +414,9 @@ { 0x8086, 0x24d5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH5 */ { 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_INTEL }, /* NFORCE */ - { 0x10de, 0x006a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* NFORCE2 */ - { 0x10de, 0x00da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* NFORCE3 */ + { 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE */ + { 0x10de, 0x006a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE2 */ + { 0x10de, 0x00da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE3 */ { 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 */ @@ -653,89 +671,148 @@ unsigned long port = ichdev->reg_offset; int shiftlen = (chip->device_type == DEVICE_SIS) ? 0 : 1; - iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr); + iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr); // tell DMA where to find descriptor table for this channel if (ichdev->size == ichdev->fragsize) { + printk("snd_intel8x0_setup_periods ichdev->size=%d, ichdev->fragsize=%d\n", ichdev->size, ichdev->fragsize); ichdev->ack_reload = ichdev->ack = 2; ichdev->fragsize1 = ichdev->fragsize >> 1; for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 4) { bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf); - bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */ + bdbar[idx + 1] = (0x80000000 | /* interrupt on completion */ ichdev->fragsize1 >> shiftlen); bdbar[idx + 2] = cpu_to_le32(ichdev->physbuf + (ichdev->size >> 1)); - bdbar[idx + 3] = cpu_to_le32(0x80000000 | /* interrupt on completion */ - ichdev->fragsize1 >> shiftlen); + bdbar[idx + 3] = (0x80000000 | /* interrupt on completion */ + (ichdev->fragsize1 >> shiftlen)); } ichdev->frags = 2; } else { + printk("snd_intel8x0_setup_periods ichdev->size=%d, ichdev->fragsize=%d\n", ichdev->size, ichdev->fragsize); ichdev->ack_reload = ichdev->ack = 1; ichdev->fragsize1 = ichdev->fragsize; for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 2) { bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf + (((idx >> 1) * ichdev->fragsize) % ichdev->size)); - bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */ - ichdev->fragsize >> shiftlen); + bdbar[idx + 1] = (0x80000000 | /* interrupt on completion */ + ((ichdev->fragsize >> shiftlen))); // count of sample-pairs // printk("bdbar[%i] = 0x%x [0x%x]\n", idx + 0, bdbar[idx + 0], bdbar[idx + 1]); } ichdev->frags = ichdev->size / ichdev->fragsize; } - iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi = ICH_REG_LVI_MASK); + + ichdev->lvi = ICH_REG_LVI_MASK; + iputbyte(chip, port + ICH_REG_OFF_LVI, ICH_REG_LVI_MASK); + ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags; ichdev->position = 0; + ichdev->m_uiLastRetiredDescriptorIndex=0xffffffff; // stands for no lat retired descriptor index + #if 0 printk("lvi_frag = %i, frags = %i, period_size = 0x%x, period_size1 = 0x%x\n", ichdev->lvi_frag, ichdev->frags, ichdev->fragsize, ichdev->fragsize1); #endif - /* clear interrupts */ + /* clear interrupts in local SR */ +#ifdef XBOX + iputbyte(chip, port + 0x06, 0xff); +#else iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); +#endif } /* * Interrupt handler + * + * Its job it to update the descriptor list with a new buffer, since we just finished one of the old ones */ static inline void snd_intel8x0_update(intel8x0_t *chip, ichdev_t *ichdev) { unsigned long port = ichdev->reg_offset; int ack = 0; + +// printk("Running snd_intel8x0_update on BMDMA %u\n", ichdev->ichd ); spin_lock(&chip->reg_lock); - ichdev->position += ichdev->fragsize1; - ichdev->position %= ichdev->size; - ichdev->lvi++; - ichdev->lvi &= ICH_REG_LVI_MASK; - iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi); - ichdev->lvi_frag++; - ichdev->lvi_frag %= ichdev->frags; - ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf + ichdev->lvi_frag * ichdev->fragsize1); - // printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n", ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2], ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port), inl(port + 4), inb(port + ICH_REG_OFF_CR)); - if ((ack = (--ichdev->ack == 0)) != 0) - ichdev->ack = ichdev->ack_reload; - spin_unlock(&chip->reg_lock); - if (ack && ichdev->substream) - snd_pcm_period_elapsed(ichdev->substream); + + ichdev->m_uiLastRetiredDescriptorIndex++; // track last used up buffer + if(ichdev->m_uiLastRetiredDescriptorIndex==0x7fffffff) ichdev->m_uiLastRetiredDescriptorIndex=2; + + iputbyte(chip, ichdev->reg_offset + ICH_REG_OFF_LVI, (chip->ichd[ICHD_PCMOUT].lvi+1)& ICH_REG_LVI_MASK); + + if(ichdev->m_uiLastRetiredDescriptorIndex>1) { + if(chip->ichd[ICHD_PCMOUT].m_uiLastRetiredDescriptorIndex == chip->ichd[ICHD_SPBAR].m_uiLastRetiredDescriptorIndex) { + + chip->ichd[ICHD_PCMOUT].position += chip->ichd[ICHD_PCMOUT].fragsize1; + chip->ichd[ICHD_PCMOUT].position %= chip->ichd[ICHD_PCMOUT].size; + chip->ichd[ICHD_PCMOUT].lvi++; + chip->ichd[ICHD_PCMOUT].lvi &= ICH_REG_LVI_MASK; + + chip->ichd[ICHD_PCMOUT].lvi_frag++; + chip->ichd[ICHD_PCMOUT].lvi_frag %= chip->ichd[ICHD_PCMOUT].frags; + + ichdev->bdbar[chip->ichd[ICHD_PCMOUT].lvi * 2] = cpu_to_le32( + chip->ichd[ICHD_PCMOUT].physbuf + + chip->ichd[ICHD_PCMOUT].lvi_frag * chip->ichd[ICHD_PCMOUT].fragsize1 + ); + + // printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n", ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2], ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port), inl(port + 4), inb(port + ICH_REG_OFF_CR)); + if ((ack = (--chip->ichd[ICHD_PCMOUT].ack == 0))) { + chip->ichd[ICHD_PCMOUT].ack = chip->ichd[ICHD_PCMOUT].ack_reload; + } + if (ack && chip->ichd[ICHD_PCMOUT].substream) { + snd_pcm_period_elapsed(chip->ichd[ICHD_PCMOUT].substream); + } + } + } + + // clear interrupt from this DMA channel iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); + spin_unlock(&chip->reg_lock); + } + static void snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs) { intel8x0_t *chip = snd_magic_cast(intel8x0_t, dev_id, return); ichdev_t *ichdev; unsigned int status; unsigned int i; + unsigned char ucaStatuses[10]; spin_lock(&chip->reg_lock); status = igetdword(chip, chip->int_sta_reg); - if ((status & chip->int_sta_mask) == 0) { +#ifndef XBOX + if ((status & (chip->int_sta_mask)) == 0) { // (Xbox S/PDIF IRQ not in normal SR, defeat check for Xbox) spin_unlock(&chip->reg_lock); return; } - /* ack first */ - iputdword(chip, chip->int_sta_reg, status & ~chip->int_sta_mask); +#endif +// printk("Audio int 0x%x/0x%x/0x%x\n", status, igetbyte(chip, chip->ichd[ICHD_PCMOUT].reg_offset + 0x06), igetbyte(chip, chip->ichd[ICHD_SPBAR].reg_offset + 0x06)); + + + for (i = 0; i < chip->bdbars_count; i++) { + ichdev = &chip->ichd[i]; + ucaStatuses[i]=igetbyte(chip, ichdev->reg_offset + 0x06); + } + + /* ack GLOBAL STATUS first */ + iputdword(chip, chip->int_sta_reg, status & ~(chip->int_sta_mask)); + spin_unlock(&chip->reg_lock); + for (i = 0; i < chip->bdbars_count; i++) { ichdev = &chip->ichd[i]; - if (status & ichdev->int_sta_mask) - snd_intel8x0_update(chip, ichdev); + +#ifdef XBOX + if(ucaStatuses[i] & 0x10) { + printk("FIFO underrun ch %d\n", i); + } + if(ucaStatuses[i] & 8 ) { +#else + if (status & ichdev->int_sta_mask) { +#endif + snd_intel8x0_update(chip, ichdev); // only if interrupt source + } } } @@ -750,6 +827,7 @@ unsigned char val = 0; unsigned long port = ichdev->reg_offset; + switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: @@ -768,12 +846,34 @@ default: return -EINVAL; } + iputbyte(chip, port + ICH_REG_OFF_CR, val); + +#ifdef XBOX + + if (ichdev->ichd == ICHD_PCMOUT) { // SPDIF in lockstep + iputbyte(chip, chip->ichd[ICHD_SPBAR].reg_offset + ICH_REG_OFF_CR, val); + } + +#endif + + if (cmd == SNDRV_PCM_TRIGGER_STOP) { /* reset whole DMA things */ while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) ; iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS); } + +#ifdef XBOX + + if (cmd == SNDRV_PCM_TRIGGER_STOP) { + // reset whole DMA things + // caused hard freeze +// while (!(igetbyte(chip, port + chip->ichd[ICHD_SPBAR].roff_sr) & ICH_DCH)) ; + iputbyte(chip, chip->ichd[ICHD_SPBAR].reg_offset + ICH_REG_OFF_CR, ICH_RESETREGS); + } +#endif + return 0; } @@ -851,6 +951,7 @@ ichdev_t *ichdev = get_ichdev(substream); int i; + printk("snd_intel8x0_pcm_prepare %d\n", ichdev->ichd); ichdev->physbuf = runtime->dma_addr; ichdev->size = snd_pcm_lib_buffer_bytes(substream); ichdev->fragsize = snd_pcm_lib_period_bytes(substream); @@ -863,6 +964,15 @@ if (ichdev->ac97_rate_regs[i]) snd_ac97_set_rate(ichdev->ac97, ichdev->ac97_rate_regs[i], runtime->rate); snd_intel8x0_setup_periods(chip, ichdev); +#ifdef XBOX + if (ichdev->ichd == ICHD_PCMOUT) { // SPDIF in lockstep + printk("snd_intel8x0_pcm_prepare doing S/PDIF lockstep\n"); + chip->ichd[ICHD_SPBAR].physbuf = runtime->dma_addr; + chip->ichd[ICHD_SPBAR].size = snd_pcm_lib_buffer_bytes(substream); + chip->ichd[ICHD_SPBAR].fragsize = snd_pcm_lib_period_bytes(substream); + snd_intel8x0_setup_periods(chip, &chip->ichd[ICHD_SPBAR]); + } +#endif return 0; } @@ -1002,36 +1112,48 @@ chip->ichd[ICHD_MIC].substream = NULL; return 0; } - +#ifndef XBOX static int snd_intel8x0_mic2_open(snd_pcm_substream_t * substream) { +#ifndef XBOX intel8x0_t *chip = snd_pcm_substream_chip(substream); - return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_MIC2]); +#else + return 0; +#endif } + static int snd_intel8x0_mic2_close(snd_pcm_substream_t * substream) { +#ifndef XBOX intel8x0_t *chip = snd_pcm_substream_chip(substream); chip->ichd[ICHD_MIC2].substream = NULL; +#endif return 0; } + static int snd_intel8x0_capture2_open(snd_pcm_substream_t * substream) { +#ifndef XBOX intel8x0_t *chip = snd_pcm_substream_chip(substream); - return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCM2IN]); +#else + return 0; +#endif } static int snd_intel8x0_capture2_close(snd_pcm_substream_t * substream) { +#ifndef XBOX intel8x0_t *chip = snd_pcm_substream_chip(substream); - chip->ichd[ICHD_PCM2IN].substream = NULL; +#endif return 0; } +#endif static int snd_intel8x0_spdif_open(snd_pcm_substream_t * substream) { @@ -1125,6 +1247,7 @@ .trigger = snd_intel8x0_pcm_trigger, .pointer = snd_intel8x0_pcm_pointer, }; +#ifndef XBOX static snd_pcm_ops_t snd_intel8x0_capture_mic2_ops = { .open = snd_intel8x0_mic2_open, @@ -1147,7 +1270,7 @@ .trigger = snd_intel8x0_pcm_trigger, .pointer = snd_intel8x0_pcm_pointer, }; - +#endif static snd_pcm_ops_t snd_intel8x0_spdif_ops = { .open = snd_intel8x0_spdif_open, .close = snd_intel8x0_spdif_close, @@ -1307,7 +1430,7 @@ /* * PCM code - MIC2 */ - +#ifndef XBOX static void snd_intel8x0_pcm_mic2_free(snd_pcm_t *pcm) { intel8x0_t *chip = snd_magic_cast(intel8x0_t, pcm->private_data, return); @@ -1341,6 +1464,8 @@ return 0; } + + /* * PCM code - capture2 */ @@ -1351,6 +1476,8 @@ chip->pcm2 = NULL; } + + static int __devinit snd_intel8x0_pcm_capture2(intel8x0_t *chip, int device, snd_pcm_t ** rpcm) { snd_pcm_t *pcm; @@ -1378,6 +1505,8 @@ return 0; } +#endif + /* * PCM code - S/PDIF */ @@ -1508,8 +1637,10 @@ { ICHD_PCMOUT, { AC97_PCM_FRONT_DAC_RATE, AC97_PCM_SURR_DAC_RATE, AC97_PCM_LFE_DAC_RATE }, AC97_RATES_FRONT_DAC }, { ICHD_PCMIN, { AC97_PCM_LR_ADC_RATE, 0, 0 }, AC97_RATES_ADC }, { ICHD_MIC, { AC97_PCM_MIC_ADC_RATE, 0, 0 }, AC97_RATES_MIC_ADC }, +#ifndef XBOX { ICHD_MIC2, { AC97_PCM_MIC_ADC_RATE, 0, 0 }, AC97_RATES_MIC_ADC }, { ICHD_PCM2IN, { AC97_PCM_LR_ADC_RATE, 0, 0 }, AC97_RATES_ADC }, +#endif { ICHD_SPBAR, { AC97_SPDIF, 0, 0 }, AC97_RATES_SPDIF }, }; @@ -1644,6 +1775,7 @@ continue; switch (chip->device_type) { case DEVICE_INTEL_ICH4: +#ifndef XBOX if (chip->ichd[ICHD_PCM2IN].ac97 == NULL) chip->ichd[ICHD_PCM2IN].ac97 = x97; if (x97->ext_id & AC97_EI_VRM) { @@ -1653,6 +1785,7 @@ chip->ichd[ICHD_PCM2IN].ac97 == x97) chip->ichd[ICHD_MIC2].ac97 = x97; } +#endif if (x97->ext_id & AC97_EI_SPDIF) { if (chip->ichd[ICHD_SPBAR].ac97 == NULL) chip->ichd[ICHD_SPBAR].ac97 = x97; @@ -1668,6 +1801,7 @@ } __skip_secondary: +#ifndef XBOX if (chip->device_type == DEVICE_INTEL_ICH4) { u8 tmp = igetbyte(chip, ICHREG(SDM)); tmp &= ~(ICH_DI2L_MASK|ICH_DI1L_MASK); @@ -1680,6 +1814,7 @@ } iputbyte(chip, ICHREG(SDM), tmp); } +#endif for (i = 0; i < codecs; i++) { x97 = chip->ac97[i]; if (!ac97_is_audio(x97)) @@ -2118,6 +2253,10 @@ else if (pos < 47500 || pos > 48500) /* not 48000Hz, tuning the clock.. */ chip->ac97[0]->clock = (chip->ac97[0]->clock * 48000) / pos; +#ifdef XBOX + printk(KERN_INFO "intel8x0: measured 48000 clock as %d\n", chip->ac97[0]->clock); + chip->ac97[0]->clock = 48000; +#endif printk(KERN_INFO "intel8x0: clocking to %d\n", chip->ac97[0]->clock); } @@ -2175,7 +2314,11 @@ .dev_free = snd_intel8x0_dev_free, }; static u32 intel_int_sta_masks[6] = { +#ifdef XBOX + ICH_PIINT, ICH_POINT, ICH_MCINT, ICH_POINT // <--- last one is S/PDIF +#else ICH_PIINT, ICH_POINT, ICH_MCINT, ICH_M2INT, ICH_P2INT, ICH_SPINT +#endif }; static u32 ali_int_sta_masks[6] = { ALI_INT_PCMIN, ALI_INT_PCMOUT, ALI_INT_MICIN, @@ -2259,7 +2402,15 @@ for (i = 0; i <= ICHD_LAST; i++) { ichdev = &chip->ichd[i]; ichdev->ichd = i; +#ifdef XBOX + if(i==ICHD_SPBAR) { + ichdev->reg_offset = 0x70; + } else { + ichdev->reg_offset = i * 0x10 + (i >= 0x30 ? 0x10 : 0); + } +#else ichdev->reg_offset = i * 0x10 + (i >= 0x30 ? 0x10 : 0); +#endif ichdev->roff_sr = ICH_REG_OFF_SR; ichdev->roff_picb = ICH_REG_OFF_PICB; ichdev->int_sta_mask = device_type == DEVICE_ALI ? ali_int_sta_masks[i] : intel_int_sta_masks[i]; @@ -2283,6 +2434,9 @@ /* allocate buffer descriptor lists */ /* the start of each lists must be aligned to 8 bytes */ chip->bdbars_count = 3; +#ifdef XBOX + if(device_type == DEVICE_NFORCE) chip->bdbars_count = 4; // ag: added one for S/PDIF in this case +#endif if (device_type == DEVICE_INTEL_ICH4 || device_type == DEVICE_ALI) chip->bdbars_count = 6; chip->bdbars = (u32 *)snd_malloc_pci_pages(pci, chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2, &chip->bdbars_addr); @@ -2308,7 +2462,7 @@ int_sta_masks |= ichdev->int_sta_mask; } chip->int_sta_reg = device_type == DEVICE_ALI ? ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA; - chip->int_sta_mask = int_sta_masks; + chip->int_sta_mask = int_sta_masks; // mask for all interrupts that belong to us in global status reg if ((err = snd_intel8x0_chip_init(chip)) < 0) { snd_intel8x0_free(chip); @@ -2411,7 +2565,7 @@ if (chip->device_type == DEVICE_ALI) { if (chip->ichd[ALID_AC97SPDIFOUT].ac97) err = snd_intel8x0_ali_ac97spdif(chip, pcm_dev++, NULL); - } else { + } else { // ag: looks very good, on an Xbox we have separate PCM-style DMA for SPDIF if (chip->ichd[ICHD_SPBAR].ac97) err = snd_intel8x0_pcm_spdif(chip, pcm_dev++, NULL); } @@ -2419,20 +2573,24 @@ snd_card_free(card); return err; } - if (chip->device_type != DEVICE_ALI) { - /* activate MIC2 only when associated AC'97 codec */ - if (chip->ichd[ICHD_MIC2].ac97) - if ((err = snd_intel8x0_pcm_mic2(chip, pcm_dev++, NULL)) < 0) { - snd_card_free(card); - return err; - } - /* activate PCM2IN only when associated AC'97 codec */ - if (chip->ichd[ICHD_PCM2IN].ac97) - if ((err = snd_intel8x0_pcm_capture2(chip, pcm_dev++, NULL)) < 0) { - snd_card_free(card); - return err; - } +#ifndef XBOX + { + if (chip->device_type != DEVICE_ALI) { + /* activate MIC2 only when associated AC'97 codec */ + if (chip->ichd[ICHD_MIC2].ac97) + if ((err = snd_intel8x0_pcm_mic2(chip, pcm_dev++, NULL)) < 0) { + snd_card_free(card); + return err; + } + /* activate PCM2IN only when associated AC'97 codec */ + if (chip->ichd[ICHD_PCM2IN].ac97) + if ((err = snd_intel8x0_pcm_capture2(chip, pcm_dev++, NULL)) < 0) { + snd_card_free(card); + return err; + } + } } +#endif } @@ -2561,7 +2719,15 @@ have_joystick = 1; } #endif - return 0; + +#ifdef MODULE +#ifdef XBOX + printk(KERN_INFO "Compiled for XBOX NFORCE Usage\n"); +#endif +#endif + + + return 0; } diff -ruN alsa-driver-0.9.1.old/include/adriver.h alsa-driver-0.9.1/include/adriver.h --- alsa-driver-0.9.1.old/include/adriver.h 2003-03-08 13:38:29.000000000 +0000 +++ alsa-driver-0.9.1/include/adriver.h 2004-03-26 12:33:08.136476520 +0000 @@ -107,10 +107,10 @@ #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 4) #include -static inline struct proc_dir_entry *PDE(const struct inode *inode) -{ - return (struct proc_dir_entry *) inode->u.generic_ip; -} +//static inline struct proc_dir_entry *PDE(const struct inode *inode) +//{ +// return (struct proc_dir_entry *) inode->u.generic_ip; +//} #endif #include #if !defined(isa_virt_to_bus)