📄 dsp_spos_scb_lib.c
字号:
return scb;}struct dsp_scb_descriptor * cs46xx_dsp_create_codec_in_scb(struct snd_cs46xx * chip, char * codec_name, u16 channel_disp, u16 fifo_addr, u16 sample_buffer_addr, u32 dest, struct dsp_scb_descriptor * parent_scb, int scb_child_type){ struct dsp_scb_descriptor * scb; struct dsp_codec_input_scb codec_input_scb = { { 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, #if 0 /* cs4620 */ SyncIOSCB,NULL_SCB_ADDR#else 0 , 0,#endif 0,0, RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64, /* strmRsConfig */ sample_buffer_addr << 0x10, /* strmBufPtr; defined as a dword ptr, used as a byte ptr */ channel_disp,fifo_addr, /* (!AC97!) leftChanBaseINaddr=AC97primary link input slot 3 :rightChanINdisp=""slot 4 */ 0x0000,0x0000, /* (!AC97!) ????:scaleShiftCount; no shift needed because AC97 is already 20 bits */ 0x80008000 /* ??clw cwcgame.scb has 0 */ }; scb = cs46xx_dsp_create_generic_scb(chip,codec_name,(u32 *)&codec_input_scb, dest,"S16_CODECINPUTTASK",parent_scb, scb_child_type); return scb;}static struct dsp_scb_descriptor * cs46xx_dsp_create_pcm_reader_scb(struct snd_cs46xx * chip, char * scb_name, u16 sample_buffer_addr, u32 dest, int virtual_channel, u32 playback_hw_addr, struct dsp_scb_descriptor * parent_scb, int scb_child_type){ struct dsp_spos_instance * ins = chip->dsp_spos_instance; struct dsp_scb_descriptor * scb; struct dsp_generic_scb pcm_reader_scb = { /* Play DMA Task xfers data from host buffer to SP buffer init/runtime variables: PlayAC: Play Audio Data Conversion - SCB loc: 2nd dword, mask: 0x0000F000L DATA_FMT_16BIT_ST_LTLEND(0x00000000L) from 16-bit stereo, little-endian DATA_FMT_8_BIT_ST_SIGNED(0x00001000L) from 8-bit stereo, signed DATA_FMT_16BIT_MN_LTLEND(0x00002000L) from 16-bit mono, little-endian DATA_FMT_8_BIT_MN_SIGNED(0x00003000L) from 8-bit mono, signed DATA_FMT_16BIT_ST_BIGEND(0x00004000L) from 16-bit stereo, big-endian DATA_FMT_16BIT_MN_BIGEND(0x00006000L) from 16-bit mono, big-endian DATA_FMT_8_BIT_ST_UNSIGNED(0x00009000L) from 8-bit stereo, unsigned DATA_FMT_8_BIT_MN_UNSIGNED(0x0000b000L) from 8-bit mono, unsigned ? Other combinations possible from: DMA_RQ_C2_AUDIO_CONVERT_MASK 0x0000F000L DMA_RQ_C2_AC_NONE 0x00000000L DMA_RQ_C2_AC_8_TO_16_BIT 0x00001000L DMA_RQ_C2_AC_MONO_TO_STEREO 0x00002000L DMA_RQ_C2_AC_ENDIAN_CONVERT 0x00004000L DMA_RQ_C2_AC_SIGNED_CONVERT 0x00008000L HostBuffAddr: Host Buffer Physical Byte Address - SCB loc:3rd dword, Mask: 0xFFFFFFFFL aligned to dword boundary */ /* Basic (non scatter/gather) DMA requestor (4 ints) */ { DMA_RQ_C1_SOURCE_ON_HOST + /* source buffer is on the host */ DMA_RQ_C1_SOURCE_MOD1024 + /* source buffer is 1024 dwords (4096 bytes) */ DMA_RQ_C1_DEST_MOD32 + /* dest buffer(PCMreaderBuf) is 32 dwords*/ DMA_RQ_C1_WRITEBACK_SRC_FLAG + /* ?? */ DMA_RQ_C1_WRITEBACK_DEST_FLAG + /* ?? */ 15, /* DwordCount-1: picked 16 for DwordCount because Jim */ /* Barnette said that is what we should use since */ /* we are not running in optimized mode? */ DMA_RQ_C2_AC_NONE + DMA_RQ_C2_SIGNAL_SOURCE_PINGPONG + /* set play interrupt (bit0) in HISR when source */ /* buffer (on host) crosses half-way point */ virtual_channel, /* Play DMA channel arbitrarily set to 0 */ playback_hw_addr, /* HostBuffAddr (source) */ DMA_RQ_SD_SP_SAMPLE_ADDR + /* destination buffer is in SP Sample Memory */ sample_buffer_addr /* SP Buffer Address (destination) */ }, /* Scatter/gather DMA requestor extension (5 ints) */ { 0, 0, 0, 0, 0 }, /* Sublist pointer & next stream control block (SCB) link. */ NULL_SCB_ADDR,NULL_SCB_ADDR, /* Pointer to this tasks parameter block & stream function pointer */ 0,NULL_SCB_ADDR, /* rsConfig register for stream buffer (rsDMA reg. is loaded from basicReq.daw */ /* for incoming streams, or basicReq.saw, for outgoing streams) */ RSCONFIG_DMA_ENABLE + /* enable DMA */ (19 << RSCONFIG_MAX_DMA_SIZE_SHIFT) + /* MAX_DMA_SIZE picked to be 19 since SPUD */ /* uses it for some reason */ ((dest >> 4) << RSCONFIG_STREAM_NUM_SHIFT) + /* stream number = SCBaddr/16 */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_32, /* dest buffer(PCMreaderBuf) is 32 dwords (256 bytes) */ /* Stream sample pointer & MAC-unit mode for this stream */ (sample_buffer_addr << 0x10), /* Fractional increment per output sample in the input sample buffer */ 0, { /* Standard stereo volume control default muted */ 0xffff,0xffff, 0xffff,0xffff } }; if (ins->null_algorithm == NULL) { ins->null_algorithm = cs46xx_dsp_lookup_symbol (chip,"NULLALGORITHM", SYMBOL_CODE); if (ins->null_algorithm == NULL) { snd_printk (KERN_ERR "dsp_spos: symbol NULLALGORITHM not found\n"); return NULL; } } scb = _dsp_create_generic_scb(chip,scb_name,(u32 *)&pcm_reader_scb, dest,ins->null_algorithm,parent_scb, scb_child_type); return scb;}#define GOF_PER_SEC 200struct dsp_scb_descriptor * cs46xx_dsp_create_src_task_scb(struct snd_cs46xx * chip, char * scb_name, int rate, u16 src_buffer_addr, u16 src_delay_buffer_addr, u32 dest, struct dsp_scb_descriptor * parent_scb, int scb_child_type, int pass_through){ struct dsp_spos_instance * ins = chip->dsp_spos_instance; struct dsp_scb_descriptor * scb; unsigned int tmp1, tmp2; unsigned int phiIncr; unsigned int correctionPerGOF, correctionPerSec; snd_printdd( "dsp_spos: setting %s rate to %u\n",scb_name,rate); /* * Compute the values used to drive the actual sample rate conversion. * The following formulas are being computed, using inline assembly * since we need to use 64 bit arithmetic to compute the values: * * phiIncr = floor((Fs,in * 2^26) / Fs,out) * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) / * GOF_PER_SEC) * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M * GOF_PER_SEC * correctionPerGOF * * i.e. * * phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out) * correctionPerGOF:correctionPerSec = * dividend:remainder(ulOther / GOF_PER_SEC) */ tmp1 = rate << 16; phiIncr = tmp1 / 48000; tmp1 -= phiIncr * 48000; tmp1 <<= 10; phiIncr <<= 10; tmp2 = tmp1 / 48000; phiIncr += tmp2; tmp1 -= tmp2 * 48000; correctionPerGOF = tmp1 / GOF_PER_SEC; tmp1 -= correctionPerGOF * GOF_PER_SEC; correctionPerSec = tmp1; { struct dsp_src_task_scb src_task_scb = { 0x0028,0x00c8, 0x5555,0x0000, 0x0000,0x0000, src_buffer_addr,1, correctionPerGOF,correctionPerSec, RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_32, 0x0000,src_delay_buffer_addr, 0x0, 0x080,(src_delay_buffer_addr + (24 * 4)), 0,0, /* next_scb, sub_list_ptr */ 0,0, /* entry, this_spb */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_8, src_buffer_addr << 0x10, phiIncr, { 0xffff - ins->dac_volume_right,0xffff - ins->dac_volume_left, 0xffff - ins->dac_volume_right,0xffff - ins->dac_volume_left } }; if (ins->s16_up == NULL) { ins->s16_up = cs46xx_dsp_lookup_symbol (chip,"S16_UPSRC", SYMBOL_CODE); if (ins->s16_up == NULL) { snd_printk (KERN_ERR "dsp_spos: symbol S16_UPSRC not found\n"); return NULL; } } /* clear buffers */ _dsp_clear_sample_buffer (chip,src_buffer_addr,8); _dsp_clear_sample_buffer (chip,src_delay_buffer_addr,32); if (pass_through) { /* wont work with any other rate than the native DSP rate */ snd_assert (rate == 48000); scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb, dest,"DMAREADER",parent_scb, scb_child_type); } else { scb = _dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb, dest,ins->s16_up,parent_scb, scb_child_type); } } return scb;}#if 0 /* not used */struct dsp_scb_descriptor * cs46xx_dsp_create_filter_scb(struct snd_cs46xx * chip, char * scb_name, u16 buffer_addr, u32 dest, struct dsp_scb_descriptor * parent_scb, int scb_child_type) { struct dsp_scb_descriptor * scb; struct dsp_filter_scb 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;}#endif /* not used */struct dsp_scb_descriptor * cs46xx_dsp_create_mix_only_scb(struct snd_cs46xx * chip, char * scb_name, u16 mix_buffer_addr, u32 dest, struct dsp_scb_descriptor * parent_scb, int scb_child_type){ struct dsp_scb_descriptor * scb; struct dsp_mix_only_scb master_mix_scb = { /* 0 */ { 0, /* 1 */ 0, /* 2 */ mix_buffer_addr, /* 3 */ 0 /* */ }, { /* 4 */ 0, /* 5 */ 0, /* 6 */ 0, /* 7 */ 0, /* 8 */ 0x00000080 }, /* 9 */ 0,0, /* A */ 0,0, /* B */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_32, /* C */ (mix_buffer_addr + (16 * 4)) << 0x10, /* D */ 0, { /* E */ 0x8000,0x8000, /* F */ 0x8000,0x8000 } }; scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&master_mix_scb, dest,"S16_MIX",parent_scb, scb_child_type); return scb;}struct dsp_scb_descriptor * cs46xx_dsp_create_mix_to_ostream_scb(struct snd_cs46xx * chip, char * scb_name, u16 mix_buffer_addr, u16 writeback_spb, u32 dest, struct dsp_scb_descriptor * parent_scb, int scb_child_type){ struct dsp_scb_descriptor * scb; struct dsp_mix2_ostream_scb mix2_ostream_scb = { /* Basic (non scatter/gather) DMA requestor (4 ints) */ { DMA_RQ_C1_SOURCE_MOD64 + DMA_RQ_C1_DEST_ON_HOST + DMA_RQ_C1_DEST_MOD1024 + DMA_RQ_C1_WRITEBACK_SRC_FLAG + DMA_RQ_C1_WRITEBACK_DEST_FLAG + 15, DMA_RQ_C2_AC_NONE + DMA_RQ_C2_SIGNAL_DEST_PINGPONG + CS46XX_DSP_CAPTURE_CHANNEL, DMA_RQ_SD_SP_SAMPLE_ADDR + mix_buffer_addr, 0x0 }, { 0, 0, 0, 0, 0, }, 0,0, 0,writeback_spb, RSCONFIG_DMA_ENABLE + (19 << RSCONFIG_MAX_DMA_SIZE_SHIFT) + ((dest >> 4) << RSCONFIG_STREAM_NUM_SHIFT) + RSCONFIG_DMA_TO_HOST + RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64, (mix_buffer_addr + (32 * 4)) << 0x10, 1,0, 0x0001,0x0080, 0xFFFF,0 }; scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&mix2_ostream_scb, dest,"S16_MIX_TO_OSTREAM",parent_scb, scb_child_type); return scb;}struct dsp_scb_descriptor * cs46xx_dsp_create_vari_decimate_scb(struct snd_cs46xx * chip,char * scb_name, u16 vari_buffer_addr0, u16 vari_buffer_addr1, u32 dest, struct dsp_scb_descriptor * parent_scb, int scb_child_type){ struct dsp_scb_descriptor * scb; struct dsp_vari_decimate_scb vari_decimate_scb = { 0x0028,0x00c8, 0x5555,0x0000, 0x0000,0x0000, vari_buffer_addr0,vari_buffer_addr1, 0x0028,0x00c8, RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_256, 0xFF800000, 0, 0x0080,vari_buffer_addr1 + (25 * 4), 0,0, 0,0, RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_8, vari_buffer_addr0 << 0x10, 0x04000000, { 0x8000,0x8000, 0xFFFF,0xFFFF } }; scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&vari_decimate_scb, dest,"VARIDECIMATE",parent_scb, scb_child_type); return scb;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -