Update of /cvsroot/alsa/alsa-kernel/pci/cs46xx In directory sc8-pr-cvs1:/tmp/cvs-serv3954/pci/cs46xx
Modified Files: cs46xx.c cs46xx_lib.c cs46xx_lib.h dsp_spos.c dsp_spos.h dsp_spos_scb_lib.c Log Message: Update by Benny Sjostrand <[EMAIL PROTECTED]>: The main new feuture is a new PCM channel: - Cards with a dual CODEC configuration (2 x cs4294 || 1 x cs4297A + 1 x cs4294), like (Hercules GTXP, Santa Cruz, Terratec SixPack 5.1): PCM 0 - slot 3 and 4 (Primary CODEC) main channel PCM 1 - slot 7 and 8 (Seconadry CODEC) rear channel PCM 2 - IEC958, SPDIF output from the DSP PCM 3 - slot 6 and 9 (Seconadry CODEC) left channel is Center and right is LFE Theoretically it should also possible to support yet another analog output on slot 11 and 5 on primary CODEC, to support surround 7.1, (Hercules GTXP has done something here, but dont exaclty how stuff are wired ...) - Cards with a single CODEC configuration (1 x cs4294), like Terratec XFire 1024: (This configuration is untested) PCM 0 - slot 3 and 4 (Primary CODEC) main channel PCM 1 - slot 11 and 5 (Primary CODEC) rear channel PCM 2 - IEC958, SPDIF output from the DSP - Some changes to the IEC958 input, should be functional by now, but still far from being perfect. - There is another theoretical problem which will prevent the cs46xx work on Big Endian architectures. I've started to work on this issue, but not finished yet. What's left on this point is to initialize all DSP structs with the C99 style (.member = value, ...) a lot of painful work (anyone like to help me ? -;) ) Known problems (for the moment): - The Terratec SixPack 5.1 card wont initialize correctly on a cold/warm boot. A reload of the ALSA driver fixes the problem. - The IEC958 input port sometimes just stop working, the only thing that seems to fix it is a cold boot. (a warm reboot does not seems to be enough) - The analog output's on the SiXPack 5.1 are very distorcionated when PCM volumes is over ~ 65 %. The only amplified output on this cards seems to be the Headphone output. Index: cs46xx.c =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/pci/cs46xx/cs46xx.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- cs46xx.c 4 Nov 2002 09:56:20 -0000 1.19 +++ cs46xx.c 2 Apr 2003 14:42:38 -0000 1.20 @@ -124,6 +124,14 @@ snd_card_free(card); return err; } +#ifdef CONFIG_SND_CS46XX_NEW_DSP + if (chip->nr_ac97_codecs ==2) { + if ((err = snd_cs46xx_pcm_center_lfe(chip,3,NULL)) < 0) { + snd_card_free(card); + return err; + } + } +#endif if ((err = snd_cs46xx_midi(chip, 0, NULL)) < 0) { snd_card_free(card); return err; Index: cs46xx_lib.c =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/pci/cs46xx/cs46xx_lib.c,v retrieving revision 1.56 retrieving revision 1.57 diff -u -r1.56 -r1.57 --- cs46xx_lib.c 28 Mar 2003 09:49:10 -0000 1.56 +++ cs46xx_lib.c 2 Apr 2003 14:42:39 -0000 1.57 @@ -1014,6 +1014,8 @@ substream->ops = &snd_cs46xx_playback_ops; } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { substream->ops = &snd_cs46xx_playback_rear_ops; + } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { + substream->ops = &snd_cs46xx_playback_clfe_ops; } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { substream->ops = &snd_cs46xx_playback_iec958_ops; } else { @@ -1041,6 +1043,8 @@ substream->ops = &snd_cs46xx_playback_indirect_ops; } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { substream->ops = &snd_cs46xx_playback_indirect_rear_ops; + } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { + substream->ops = &snd_cs46xx_playback_indirect_clfe_ops; } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { substream->ops = &snd_cs46xx_playback_indirect_iec958_ops; } else { @@ -1423,6 +1427,13 @@ return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL); } +static int snd_cs46xx_playback_open_clfe(snd_pcm_substream_t * substream) +{ + snd_printdd("open center - LFE channel\n"); + + return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL); +} + static int snd_cs46xx_playback_open_iec958(snd_pcm_substream_t * substream) { cs46xx_t *chip = snd_pcm_substream_chip(substream); @@ -1541,6 +1552,29 @@ .ack = snd_cs46xx_playback_transfer, }; +snd_pcm_ops_t snd_cs46xx_playback_clfe_ops = { + .open = snd_cs46xx_playback_open_clfe, + .close = snd_cs46xx_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_cs46xx_playback_hw_params, + .hw_free = snd_cs46xx_playback_hw_free, + .prepare = snd_cs46xx_playback_prepare, + .trigger = snd_cs46xx_playback_trigger, + .pointer = snd_cs46xx_playback_direct_pointer, +}; + +snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops = { + .open = snd_cs46xx_playback_open_clfe, + .close = snd_cs46xx_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_cs46xx_playback_hw_params, + .hw_free = snd_cs46xx_playback_hw_free, + .prepare = snd_cs46xx_playback_prepare, + .trigger = snd_cs46xx_playback_trigger, + .pointer = snd_cs46xx_playback_indirect_pointer, + .ack = snd_cs46xx_playback_transfer, +}; + snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = { .open = snd_cs46xx_playback_open_iec958, .close = snd_cs46xx_playback_close_iec958, @@ -1627,6 +1661,13 @@ snd_pcm_lib_preallocate_free_for_all(pcm); } +static void snd_cs46xx_pcm_center_lfe_free(snd_pcm_t *pcm) +{ + cs46xx_t *chip = snd_magic_cast(cs46xx_t, pcm->private_data, return); + chip->pcm_center_lfe = NULL; + snd_pcm_lib_preallocate_free_for_all(pcm); +} + static void snd_cs46xx_pcm_iec958_free(snd_pcm_t *pcm) { cs46xx_t *chip = snd_magic_cast(cs46xx_t, pcm->private_data, return); @@ -1699,6 +1740,35 @@ return 0; } +int __devinit snd_cs46xx_pcm_center_lfe(cs46xx_t *chip, int device, snd_pcm_t ** rpcm) +{ + snd_pcm_t *pcm; + int err; + + if (rpcm) + *rpcm = NULL; + + if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) + return err; + + pcm->private_data = chip; + pcm->private_free = snd_cs46xx_pcm_center_lfe_free; + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops); + + /* global setup */ + pcm->info_flags = 0; + strcpy(pcm->name, "CS46xx - Center LFE"); + chip->pcm_center_lfe = pcm; + + snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 256*1024); + + if (rpcm) + *rpcm = pcm; + + return 0; +} + int __devinit snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t ** rpcm) { snd_pcm_t *pcm; @@ -1812,6 +1882,7 @@ return change; } +#if 0 static int snd_cs46xx_vol_iec958_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { cs46xx_t *chip = snd_kcontrol_chip(kcontrol); @@ -1836,6 +1907,7 @@ return change; } +#endif static int snd_mixer_boolean_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) @@ -2234,6 +2306,8 @@ .put = snd_cs46xx_iec958_put, .private_value = CS46XX_MIXER_SPDIF_INPUT_ELEMENT, }, +#if 0 +/* Input IEC958 volume does not work for the moment. (Benny) */ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "IEC958 Input Volume", @@ -2242,6 +2316,7 @@ .put = snd_cs46xx_vol_iec958_put, .private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2, }, +#endif { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -2314,16 +2389,25 @@ }; -static void snd_cs46xx_sec_codec_reset (ac97_t * ac97) +static void snd_cs46xx_codec_reset (ac97_t * ac97) { unsigned long end_time; int err; + cs46xx_t * chip = snd_magic_cast(cs46xx_t,ac97->private_data,return /* -ENXIO */); /* reset to defaults */ snd_ac97_write(ac97, AC97_RESET, 0); - /* set codec in extended mode */ - snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3); + /* set the desired CODEC mode */ + if (chip->nr_ac97_codecs == 0) { + snd_printdd("cs46xx: CODOEC1 mode %04x\n",0x0); + snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x0); + } else if (chip->nr_ac97_codecs == 1) { + snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3); + snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3); + } else { + snd_assert(0); /* should never happen ... */ + } udelay(50); @@ -2372,7 +2456,9 @@ ac97.read = snd_cs46xx_ac97_read; ac97.private_data = chip; ac97.private_free = snd_cs46xx_mixer_free_ac97; - +#ifdef CONFIG_SND_CS46XX_NEW_DSP + ac97.reset = snd_cs46xx_codec_reset; +#endif chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = &ac97; snd_cs46xx_ac97_write(&ac97, AC97_MASTER, 0x8000); @@ -2432,7 +2518,7 @@ /* use custom reset to set secondary codec in extended mode */ - ac97.reset = snd_cs46xx_sec_codec_reset; + ac97.reset = snd_cs46xx_codec_reset; if ((err = snd_ac97_mixer(card, &ac97, &chip->ac97[CS46XX_SECONDARY_CODEC_INDEX])) < 0) return err; @@ -2870,6 +2956,7 @@ kfree(chip->gameport); } #endif + if (chip->amplifier_ctrl) chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */ @@ -2892,10 +2979,14 @@ if (chip->active_ctrl) chip->active_ctrl(chip, -chip->amplifier); - + #ifdef CONFIG_SND_CS46XX_NEW_DSP - cs46xx_dsp_spos_destroy(chip); + if (chip->dsp_spos_instance) { + cs46xx_dsp_spos_destroy(chip); + chip->dsp_spos_instance = NULL; + } #endif + snd_magic_kfree(chip); return 0; } @@ -3104,8 +3195,21 @@ } } +#ifndef CONFIG_SND_CS46XX_NEW_DSP snd_printk("create - never read ISV3 & ISV4 from AC'97\n"); return -EIO; +#else + /* This may happen on a cold boot with a Terratec SiXPack 5.1. + Reloading the driver may help, if there's other soundcards + with the same problem I would like to know. (Benny) */ + + snd_printk("ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n"); + snd_printk(" Try reloading the ALSA driver, if you find something\n"); + snd_printk(" broken or not working on your soundcard upon\n"); + snd_printk(" this message please report to [EMAIL PROTECTED]"); + + return -EIO; +#endif ok2: /* @@ -3113,8 +3217,7 @@ * commense the transfer of digital audio data to the AC97 codec. */ - snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4 | - ACOSV_SLV7 | ACOSV_SLV8); + snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); /* @@ -3224,21 +3327,7 @@ tmp |= 0x00000001; snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ -#ifdef CONFIG_SND_CS46XX_NEW_DSP - /* set the attenuation to 0dB */ - /* snd_cs46xx_poke(chip, (MASTERMIX_SCB_ADDR + 0xE) << 2, 0x80008000); - snd_cs46xx_poke(chip, (VARIDECIMATE_SCB_ADDR + 0xE) << 2, 0x80008000); */ - - /* - * Initialize cs46xx SPDIF controller - */ - - /* time countdown enable */ - cs46xx_poke_via_dsp (chip,SP_ASER_COUNTDOWN, 0x80000000); - - /* SPDIF input MASTER ENABLE */ - cs46xx_poke_via_dsp (chip,SP_SPDIN_CONTROL, 0x800003ff); -#else +#ifndef CONFIG_SND_CS46XX_NEW_DSP /* set the attenuation to 0dB */ snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000); snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000); @@ -3312,7 +3401,8 @@ logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY, CS46XX_SECONDARY_CODEC_INDEX); - logic_type &=0x27F; + logic_type &=0x27F; + snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type, CS46XX_SECONDARY_CODEC_INDEX); @@ -3592,55 +3682,62 @@ .id = 0x3357, .name = "Voyetra", .amp = amp_voyetra, - .mixer_init = voyetra_mixer_init + .mixer_init = voyetra_mixer_init, }, { .vendor = 0x1071, .id = 0x6003, .name = "Mitac MI6020/21", - .amp = amp_voyetra + .amp = amp_voyetra, }, { .vendor = 0x14AF, .id = 0x0050, .name = "Hercules Game Theatre XP", .amp = amp_hercules, - .mixer_init = hercules_mixer_init + .mixer_init = hercules_mixer_init, }, { .vendor = 0x1681, .id = 0x0050, .name = "Hercules Game Theatre XP", .amp = amp_hercules, - .mixer_init = hercules_mixer_init + .mixer_init = hercules_mixer_init, }, { .vendor = 0x1681, .id = 0x0051, .name = "Hercules Game Theatre XP", .amp = amp_hercules, - .mixer_init = hercules_mixer_init + .mixer_init = hercules_mixer_init, + }, { .vendor = 0x1681, .id = 0x0052, .name = "Hercules Game Theatre XP", .amp = amp_hercules, - .mixer_init = hercules_mixer_init + .mixer_init = hercules_mixer_init, }, { .vendor = 0x1681, .id = 0x0053, .name = "Hercules Game Theatre XP", .amp = amp_hercules, - .mixer_init = hercules_mixer_init + .mixer_init = hercules_mixer_init, }, { .vendor = 0x1681, .id = 0x0054, .name = "Hercules Game Theatre XP", .amp = amp_hercules, - .mixer_init = hercules_mixer_init + .mixer_init = hercules_mixer_init, + }, + /* Teratec */ + { + .vendor = 0x153b, + .id = 0x1136, + .name = "Terratec SiXPack 5.1", }, /* Not sure if the 570 needs the clkrun hack */ { @@ -3648,19 +3745,19 @@ .id = 0x0132, .name = "Thinkpad 570", .init = clkrun_init, - .active = clkrun_hack + .active = clkrun_hack, }, { .vendor = PCI_VENDOR_ID_IBM, .id = 0x0153, .name = "Thinkpad 600X/A20/T20", .init = clkrun_init, - .active = clkrun_hack + .active = clkrun_hack, }, { .vendor = PCI_VENDOR_ID_IBM, .id = 0x1010, - .name = "Thinkpad 600E (unsupported)" + .name = "Thinkpad 600E (unsupported)", }, {} /* terminator */ }; @@ -3823,10 +3920,12 @@ for (cp = &cards[0]; cp->name; cp++) { if (cp->vendor == ss_vendor && cp->id == ss_card) { - snd_printd ("hack for %s enabled\n", cp->name); + snd_printdd ("hack for %s enabled\n", cp->name); + chip->amplifier_ctrl = cp->amp; chip->active_ctrl = cp->active; chip->mixer_init = cp->mixer_init; + if (cp->init) cp->init(chip); break; @@ -3867,6 +3966,7 @@ return -ENOMEM; } } + if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS46XX", (void *) chip)) { snd_printk("unable to grab IRQ %d\n", pci->irq); snd_cs46xx_free(chip); Index: cs46xx_lib.h =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/pci/cs46xx/cs46xx_lib.h,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- cs46xx_lib.h 3 Mar 2003 11:33:01 -0000 1.11 +++ cs46xx_lib.h 2 Apr 2003 14:42:39 -0000 1.12 @@ -63,6 +63,8 @@ extern snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops; extern snd_pcm_ops_t snd_cs46xx_playback_iec958_ops; extern snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops; +extern snd_pcm_ops_t snd_cs46xx_playback_clfe_ops; +extern snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops; /* Index: dsp_spos.c =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/pci/cs46xx/dsp_spos.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- dsp_spos.c 3 Mar 2003 11:33:01 -0000 1.19 +++ dsp_spos.c 2 Apr 2003 14:42:39 -0000 1.20 @@ -291,11 +291,14 @@ if (ins->code.data) kfree(ins->code.data); + if (ins->symbol_table.symbols) vfree(ins->symbol_table.symbols); + if (ins->modules) kfree(ins->modules); - kfree(ins); + + kfree(ins); up(&chip->spos_mutex); } @@ -630,7 +633,7 @@ snd_iprintf(buffer,"\nSRC_TASK_SCB1:\n"); col = 0; - for (i = 0x2580 ; i < 0x2580 + 0x40 ; i += sizeof(u32),col ++) { + for (i = 0x2480 ; i < 0x2480 + 0x40 ; i += sizeof(u32),col ++) { if (col == 4) { snd_iprintf(buffer,"\n"); col = 0; @@ -1030,7 +1033,6 @@ return desc; } - int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip) { dsp_spos_instance_t * ins = chip->dsp_spos_instance; @@ -1049,8 +1051,11 @@ dsp_scb_descriptor_t * record_mix_scb; dsp_scb_descriptor_t * write_back_scb; dsp_scb_descriptor_t * vari_decimate_scb; - dsp_scb_descriptor_t * sec_codec_out_scb; + dsp_scb_descriptor_t * rear_codec_out_scb; + dsp_scb_descriptor_t * clfe_codec_out_scb; dsp_scb_descriptor_t * magic_snoop_scb; + + int fifo_addr,fifo_span,valid_slots; spos_control_block_t sposcb = { /* 0 */ HFG_TREE_SCB,HFG_STACK, @@ -1335,28 +1340,78 @@ if (!record_mix_scb) goto _fail_end; - /* create secondary CODEC output */ - sec_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_II",0x0010,0x0040, - REAR_MIXER_SCB_ADDR, - SEC_CODECOUT_SCB_ADDR,codec_in_scb, - SCB_ON_PARENT_NEXT_SCB); - if (!sec_codec_out_scb) goto _fail_end; + valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV); + + snd_assert (chip->nr_ac97_codecs == 1 || chip->nr_ac97_codecs == 2); + if (chip->nr_ac97_codecs == 1) { + /* output on slot 5 and 11 + on primary CODEC */ + fifo_addr = 0x20; + fifo_span = 0x60; + /* enable slot 5 and 11 */ + valid_slots |= ACOSV_SLV5 | ACOSV_SLV11; + } else { + /* output on slot 7 and 8 + on secondary CODEC */ + fifo_addr = 0x40; + fifo_span = 0x10; + + /* enable slot 7 and 8 */ + valid_slots |= ACOSV_SLV7 | ACOSV_SLV8; + } + /* create CODEC tasklet for rear speakers output*/ + rear_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_Rear",fifo_span,fifo_addr, + REAR_MIXER_SCB_ADDR, + REAR_CODECOUT_SCB_ADDR,codec_in_scb, + SCB_ON_PARENT_NEXT_SCB); + if (!rear_codec_out_scb) goto _fail_end; + + /* create the rear PCM channel mixer SCB */ rear_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"RearMixerSCB", MIX_SAMPLE_BUF3, REAR_MIXER_SCB_ADDR, - sec_codec_out_scb, + rear_codec_out_scb, SCB_ON_PARENT_SUBLIST_SCB); ins->rear_mix_scb = rear_mix_scb; if (!rear_mix_scb) goto _fail_end; + + if (chip->nr_ac97_codecs == 2) { + /* create CODEC tasklet for rear Center/LFE output + slot 6 and 9 on seconadry CODEC */ + clfe_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_CLFE",0x0030,0x0030, + CLFE_MIXER_SCB_ADDR, + CLFE_CODEC_SCB_ADDR, + rear_codec_out_scb, + SCB_ON_PARENT_NEXT_SCB); + if (!clfe_codec_out_scb) goto _fail_end; + + + /* create the rear PCM channel mixer SCB */ + ins->center_lfe_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"CLFEMixerSCB", + MIX_SAMPLE_BUF4, + CLFE_MIXER_SCB_ADDR, + clfe_codec_out_scb, + SCB_ON_PARENT_SUBLIST_SCB); + if (!ins->center_lfe_mix_scb) goto _fail_end; + + /* enable slot 6 and 9 */ + valid_slots |= ACOSV_SLV6 | ACOSV_SLV9; + } else { + clfe_codec_out_scb = rear_codec_out_scb; + ins->center_lfe_mix_scb = rear_mix_scb; + } + + /* enable slots depending on CODEC configuration */ + snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots); /* the magic snooper */ magic_snoop_scb = cs46xx_dsp_create_magic_snoop_scb (chip,"MagicSnoopSCB_I",OUTPUTSNOOP_SCB_ADDR, OUTPUT_SNOOP_BUFFER, codec_out_scb, - sec_codec_out_scb, + clfe_codec_out_scb, SCB_ON_PARENT_NEXT_SCB); @@ -1375,10 +1430,9 @@ SRC_OUTPUT_BUF1, SRC_DELAY_BUF1,SRCTASK_SCB_ADDR, master_mix_scb, - SCB_ON_PARENT_SUBLIST_SCB,0); + SCB_ON_PARENT_SUBLIST_SCB,1); if (!src_task_scb) goto _fail_end; - cs46xx_src_unlink(chip,src_task_scb); /* NOTE: when we now how to detect the SPDIF input @@ -1453,12 +1507,12 @@ /* 0 */ DSP_SPOS_UULO,DSP_SPOS_UUHI, /* 1 */ 0, /* 2 */ 0, - /* 3 */ 1,4000, - /* 4 */ DSP_SPOS_UUUU, - /* 5 */ DSP_SPOS_UULO,DSP_SPOS_UUHI, - /* 6 */ DSP_SPOS_UUUU, - /* 7 */ DSP_SPOS_UU,DSP_SPOS_DC, - /* 8 */ DSP_SPOS_UUUU, + /* 3 */ 1,4000, /* SPDIFICountLimit SPDIFICount */ + /* 4 */ DSP_SPOS_UUUU, /* SPDIFIStatusData */ + /* 5 */ 0,DSP_SPOS_UUHI, /* StatusData, Free4 */ + /* 6 */ DSP_SPOS_UUUU, /* Free3 */ + /* 7 */ DSP_SPOS_UU,DSP_SPOS_DC, /* Free2 BitCount*/ + /* 8 */ DSP_SPOS_UUUU, /* TempStatus */ /* 9 */ SPDIFO_SCB_INST, NULL_SCB_ADDR, /* A */ spdifi_task->address, SPDIFI_SCB_INST + SPDIFIFIFOPointer, @@ -1470,7 +1524,7 @@ /* C */ (SPDIFI_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC, /* D */ 0x8048,0, /* E */ 0x01f0,0x0001, - /* F */ DSP_SPOS_UUUU + /* F */ DSP_SPOS_UUUU /* SPDIN_STATUS monitor */ }; /* 0xBA0 */ @@ -1579,6 +1633,9 @@ /*cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_default);*/ cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x0); + /* clear fifo pointer */ + cs46xx_poke_via_dsp (chip,SP_SPDIN_FIFOPTR, 0x0); + /* monitor state */ ins->spdif_status_out &= ~DSP_SPDIF_STATUS_HW_ENABLED; } @@ -1618,6 +1675,20 @@ snd_assert (ins->spdif_in_src != NULL,return -EINVAL); down(&chip->spos_mutex); + + if ( ! (ins->spdif_status_out & DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED) ) { + /* time countdown enable */ + cs46xx_poke_via_dsp (chip,SP_ASER_COUNTDOWN, 0x80000005); + /* NOTE: 80000005 value is just magic. With all values + that I've tested this one seem to give the best result. + Got no explication why. (Benny) */ + + /* SPDIF input MASTER ENABLE */ + cs46xx_poke_via_dsp (chip,SP_SPDIN_CONTROL, 0x800003ff); + + ins->spdif_status_out |= DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED; + } + /* create and start the asynchronous receiver SCB */ ins->asynch_rx_scb = cs46xx_dsp_create_asynch_fg_rx_scb(chip,"AsynchFGRxSCB", ASYNCRX_SCB_ADDR, @@ -1629,11 +1700,11 @@ spin_lock_irq(&chip->reg_lock); /* reset SPDIF input sample buffer pointer */ - snd_cs46xx_poke (chip, (SPDIFI_SCB_INST + 0x0c) << 2, - (SPDIFI_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC); + /*snd_cs46xx_poke (chip, (SPDIFI_SCB_INST + 0x0c) << 2, + (SPDIFI_IP_OUTPUT_BUFFER1 << 0x10) | 0xFFFC);*/ /* reset FIFO ptr */ - cs46xx_poke_via_dsp (chip,SP_SPDIN_FIFOPTR, 0x0); + /*cs46xx_poke_via_dsp (chip,SP_SPDIN_FIFOPTR, 0x0);*/ cs46xx_src_link(chip,ins->spdif_in_src); /* unmute SRC volume */ @@ -1657,9 +1728,10 @@ dsp_spos_instance_t * ins = chip->dsp_spos_instance; snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL); - snd_assert (ins->spdif_in_src != NULL,return -EINVAL); + snd_assert (ins->spdif_in_src != NULL,return -EINVAL); down(&chip->spos_mutex); + /* Remove the asynchronous receiver SCB */ cs46xx_dsp_remove_scb (chip,ins->asynch_rx_scb); ins->asynch_rx_scb = NULL; @@ -1727,10 +1799,10 @@ snd_assert (ins->adc_input != NULL,return -EINVAL); - down(&chip->spos_mutex); + down(&chip->spos_mutex); cs46xx_dsp_remove_scb (chip,ins->adc_input); ins->adc_input = NULL; - up(&chip->spos_mutex); + up(&chip->spos_mutex); return 0; } Index: dsp_spos.h =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/pci/cs46xx/dsp_spos.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- dsp_spos.h 20 Mar 2003 16:45:59 -0000 1.10 +++ dsp_spos.h 2 Apr 2003 14:42:39 -0000 1.11 @@ -73,9 +73,9 @@ #define SPDIFI_IP_OUTPUT_BUFFER1 0x0E00 #define SPDIFO_IP_OUTPUT_BUFFER1 0x1000 #define MIX_SAMPLE_BUF1 0x1400 -#define MIX_SAMPLE_BUF2 0x2D00 -#define MIX_SAMPLE_BUF3 0x2E00 -#define MIX_SAMPLE_BUF4 0x2F00 +#define MIX_SAMPLE_BUF2 0x2E80 +#define MIX_SAMPLE_BUF3 0x2F00 +#define MIX_SAMPLE_BUF4 0x2F80 #define MIX_SAMPLE_BUF5 0x3000 /* Task stack address */ @@ -103,12 +103,13 @@ #define OUTPUTSNOOP_SCB_ADDR 0x110 #define PCMSERIALINII_SCB_ADDR 0x120 #define SPIOWRITE_SCB_ADDR 0x130 -#define SEC_CODECOUT_SCB_ADDR 0x140 +#define REAR_CODECOUT_SCB_ADDR 0x140 #define OUTPUTSNOOPII_SCB_ADDR 0x150 #define PCMSERIALIN_PCM_SCB_ADDR 0x160 #define RECORD_MIXER_SCB_ADDR 0x170 #define REAR_MIXER_SCB_ADDR 0x180 -#define SPDIF_MIXER_SCB_ADDR 0x190 +#define CLFE_MIXER_SCB_ADDR 0x190 +#define CLFE_CODEC_SCB_ADDR 0x1A0 /* hyperforground SCB's*/ #define HFG_TREE_SCB 0xBA0 Index: dsp_spos_scb_lib.c =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- dsp_spos_scb_lib.c 3 Mar 2003 11:33:01 -0000 1.20 +++ dsp_spos_scb_lib.c 2 Apr 2003 14:42:39 -0000 1.21 @@ -681,6 +681,54 @@ return scb; } +dsp_scb_descriptor_t * +cs46xx_dsp_create_filter_scb(cs46xx_t * chip,char * scb_name, + u16 buffer_addr,u32 dest, + dsp_scb_descriptor_t * parent_scb, + int scb_child_type) { + dsp_scb_descriptor_t * scb; + + filter_scb_t filter_scb = { + .a0_right = 0x41a9, + .a0_left = 0x41a9, + .a1_right = 0xb8e4, + .a1_left = 0xb8e4, + .a2_right = 0x3e55, + .a2_left = 0x3e55, + + .filter_unused3 = 0x0000, + .filter_unused2 = 0x0000, + + .output_buf_ptr = buffer_addr, + .init = 0x000, + + .prev_sample_output1 = 0x00000000, + .prev_sample_output2 = 0x00000000, + + .prev_sample_input1 = 0x00000000, + .prev_sample_input2 = 0x00000000, + + .next_scb_ptr = 0x0000, + .sub_list_ptr = 0x0000, + + .entry_point = 0x0000, + .spb_ptr = 0x0000, + + .b0_right = 0x0e38, + .b0_left = 0x0e38, + .b1_right = 0x1c71, + .b1_left = 0x1c71, + .b2_right = 0x0e38, + .b2_left = 0x0e38, + }; + + + scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&filter_scb, + dest,"FILTERTASK",parent_scb, + scb_child_type); + + return scb; +} dsp_scb_descriptor_t * cs46xx_dsp_create_mix_only_scb(cs46xx_t * chip,char * scb_name, @@ -705,8 +753,8 @@ }, /* 9 */ 0,0, /* A */ 0,0, - /* B */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64, - /* C */ (mix_buffer_addr + (32 * 4)) << 0x10, + /* B */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_32, + /* C */ (mix_buffer_addr + (16 * 4)) << 0x10, /* D */ 0, { /* E */ 0x8000,0x8000, @@ -768,7 +816,8 @@ scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&mix2_ostream_scb, - dest,"S16_MIX_TO_OSTREAM",parent_scb, + + dest,"S16_MIX_TO_OSTREAM",parent_scb, scb_child_type); return scb; @@ -1120,24 +1169,39 @@ }; static u32 src_output_buffer_addr[DSP_MAX_SRC_NR] = { - 0x2580, - 0x2680, - 0x2780, - 0x2980, - 0x2A80, - 0x2B80, + 0x2B80, + 0x2BA0, + 0x2BC0, + 0x2BE0, + 0x2D00, + 0x2D20, + 0x2D40, + 0x2D60, + 0x2D80, + 0x2DA0, + 0x2DC0, + 0x2DE0, + 0x2E00, + 0x2E20 }; static u32 src_delay_buffer_addr[DSP_MAX_SRC_NR] = { + 0x2480, + 0x2500, + 0x2580, 0x2600, + 0x2680, 0x2700, + 0x2780, 0x2800, + 0x2880, 0x2900, + 0x2980, 0x2A00, - 0x2B00, + 0x2A80, + 0x2B00 }; - pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip, u32 sample_rate, void * private_data, u32 hw_dma_addr, @@ -1159,11 +1223,10 @@ case DSP_PCM_REAR_CHANNEL: mixer_scb = ins->rear_mix_scb; break; - case DSP_PCM_CENTER_CHANNEL: - /* TODO */ - snd_assert(0); + case DSP_PCM_CENTER_LFE_CHANNEL: + mixer_scb = ins->center_lfe_mix_scb; break; - case DSP_PCM_LFE_CHANNEL: + case DSP_PCM_S71_CHANNEL: /* TODO */ snd_assert(0); break; ------------------------------------------------------- This SF.net email is sponsored by: ValueWeb: Dedicated Hosting for just $79/mo with 500 GB of bandwidth! No other company gives more support or power for your dedicated server http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ _______________________________________________ Alsa-cvslog mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-cvslog