📄 dsp_spos_scb_lib.c
字号:
static dsp_scb_descriptor_t * cs46xx_dsp_create_pcm_serial_input_scb(cs46xx_t * chip,char * scb_name,u32 dest, dsp_scb_descriptor_t * input_scb, dsp_scb_descriptor_t * parent_scb, int scb_child_type){ dsp_scb_descriptor_t * scb; pcm_serial_input_scb_t pcm_serial_input_scb = { { 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, 0,0, 0,0, RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_16, 0, /* 0xD */ 0,input_scb->address, { /* 0xE */ 0x8000,0x8000, /* 0xF */ 0x8000,0x8000 } }; scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&pcm_serial_input_scb, dest,"PCMSERIALINPUTTASK",parent_scb, scb_child_type); return scb;}static dsp_scb_descriptor_t * cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest, u16 hfg_scb_address, u16 asynch_buffer_address, dsp_scb_descriptor_t * parent_scb, int scb_child_type){ dsp_scb_descriptor_t * scb; asynch_fg_tx_scb_t asynch_fg_tx_scb = { 0xfc00,0x03ff, /* Prototype sample buffer size of 256 dwords */ 0x0058,0x0028, /* Min Delta 7 dwords == 28 bytes */ /* : Max delta 25 dwords == 100 bytes */ 0,hfg_scb_address, /* Point to HFG task SCB */ 0,0, /* Initialize current Delta and Consumer ptr adjustment count */ 0, /* Initialize accumulated Phi to 0 */ 0,0x2aab, /* Const 1/3 */ { 0, /* Define the unused elements */ 0, 0 }, 0,0, 0,dest + AFGTxAccumPhi, RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_256, /* Stereo, 256 dword */ (asynch_buffer_address) << 0x10, /* This should be automagically synchronized to the producer pointer */ /* There is no correct initial value, it will depend upon the detected rate etc */ 0x18000000, /* Phi increment for approx 32k operation */ 0x8000,0x8000, /* Volume controls are unused at this time */ 0x8000,0x8000 }; scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_tx_scb, dest,"ASYNCHFGTXCODE",parent_scb, scb_child_type); return scb;}dsp_scb_descriptor_t * cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest, u16 hfg_scb_address, u16 asynch_buffer_address, dsp_scb_descriptor_t * parent_scb, int scb_child_type){ dsp_spos_instance_t * ins = chip->dsp_spos_instance; dsp_scb_descriptor_t * scb; asynch_fg_rx_scb_t asynch_fg_rx_scb = { 0xfe00,0x01ff, /* Prototype sample buffer size of 128 dwords */ 0x0064,0x001c, /* Min Delta 7 dwords == 28 bytes */ /* : Max delta 25 dwords == 100 bytes */ 0,hfg_scb_address, /* Point to HFG task SCB */ 0,0, /* Initialize current Delta and Consumer ptr adjustment count */ { 0, /* Define the unused elements */ 0, 0, 0, 0 }, 0,0, 0,dest, RSCONFIG_MODULO_128 | RSCONFIG_SAMPLE_16STEREO, /* Stereo, 128 dword */ ( (asynch_buffer_address + (16 * 4)) << 0x10), /* This should be automagically synchrinized to the producer pointer */ /* There is no correct initial value, it will depend upon the detected rate etc */ 0x18000000, /* Set IEC958 input volume */ 0xffff - ins->spdif_input_volume_right,0xffff - ins->spdif_input_volume_left, 0xffff - ins->spdif_input_volume_right,0xffff - ins->spdif_input_volume_left, }; scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&asynch_fg_rx_scb, dest,"ASYNCHFGRXCODE",parent_scb, scb_child_type); return scb;}#if 0 /* not used */dsp_scb_descriptor_t * cs46xx_dsp_create_output_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest, u16 snoop_buffer_address, dsp_scb_descriptor_t * snoop_scb, dsp_scb_descriptor_t * parent_scb, int scb_child_type){ dsp_scb_descriptor_t * scb; output_snoop_scb_t output_snoop_scb = { { 0, /* not used. Zero */ 0, 0, 0, }, { 0, /* not used. Zero */ 0, 0, 0, 0 }, 0,0, 0,0, RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64, snoop_buffer_address << 0x10, 0,0, 0, 0,snoop_scb->address }; scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&output_snoop_scb, dest,"OUTPUTSNOOP",parent_scb, scb_child_type); return scb;}#endif /* not used */dsp_scb_descriptor_t * cs46xx_dsp_create_spio_write_scb(cs46xx_t * chip,char * scb_name,u32 dest, dsp_scb_descriptor_t * parent_scb, int scb_child_type){ dsp_scb_descriptor_t * scb; spio_write_scb_t spio_write_scb = { 0,0, /* SPIOWAddress2:SPIOWAddress1; */ 0, /* SPIOWData1; */ 0, /* SPIOWData2; */ 0,0, /* SPIOWAddress4:SPIOWAddress3; */ 0, /* SPIOWData3; */ 0, /* SPIOWData4; */ 0,0, /* SPIOWDataPtr:Unused1; */ { 0,0 }, /* Unused2[2]; */ 0,0, /* SPIOWChildPtr:SPIOWSiblingPtr; */ 0,0, /* SPIOWThisPtr:SPIOWEntryPoint; */ { 0, 0, 0, 0, 0 /* Unused3[5]; */ } }; scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&spio_write_scb, dest,"SPIOWRITE",parent_scb, scb_child_type); return scb;}dsp_scb_descriptor_t * cs46xx_dsp_create_magic_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest, u16 snoop_buffer_address, dsp_scb_descriptor_t * snoop_scb, dsp_scb_descriptor_t * parent_scb, int scb_child_type){ dsp_scb_descriptor_t * scb; magic_snoop_task_t magic_snoop_scb = { /* 0 */ 0, /* i0 */ /* 1 */ 0, /* i1 */ /* 2 */ snoop_buffer_address << 0x10, /* 3 */ 0,snoop_scb->address, /* 4 */ 0, /* i3 */ /* 5 */ 0, /* i4 */ /* 6 */ 0, /* i5 */ /* 7 */ 0, /* i6 */ /* 8 */ 0, /* i7 */ /* 9 */ 0,0, /* next_scb, sub_list_ptr */ /* A */ 0,0, /* entry_point, this_ptr */ /* B */ RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_64, /* C */ snoop_buffer_address << 0x10, /* D */ 0, /* E */ { 0x8000,0x8000, /* F */ 0xffff,0xffff } }; scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&magic_snoop_scb, dest,"MAGICSNOOPTASK",parent_scb, scb_child_type); return scb;}static dsp_scb_descriptor_t * find_next_free_scb (cs46xx_t * chip,dsp_scb_descriptor_t * from){ dsp_spos_instance_t * ins = chip->dsp_spos_instance; dsp_scb_descriptor_t * scb = from; while (scb->next_scb_ptr != ins->the_null_scb) { snd_assert (scb->next_scb_ptr != NULL, return NULL); scb = scb->next_scb_ptr; } return scb;}static u32 pcm_reader_buffer_addr[DSP_MAX_PCM_CHANNELS] = { 0x0600, /* 1 */ 0x1500, /* 2 */ 0x1580, /* 3 */ 0x1600, /* 4 */ 0x1680, /* 5 */ 0x1700, /* 6 */ 0x1780, /* 7 */ 0x1800, /* 8 */ 0x1880, /* 9 */ 0x1900, /* 10 */ 0x1980, /* 11 */ 0x1A00, /* 12 */ 0x1A80, /* 13 */ 0x1B00, /* 14 */ 0x1B80, /* 15 */ 0x1C00, /* 16 */ 0x1C80, /* 17 */ 0x1D00, /* 18 */ 0x1D80, /* 19 */ 0x1E00, /* 20 */ 0x1E80, /* 21 */ 0x1F00, /* 22 */ 0x1F80, /* 23 */ 0x2000, /* 24 */ 0x2080, /* 25 */ 0x2100, /* 26 */ 0x2180, /* 27 */ 0x2200, /* 28 */ 0x2280, /* 29 */ 0x2300, /* 30 */ 0x2380, /* 31 */ 0x2400, /* 32 */};static u32 src_output_buffer_addr[DSP_MAX_SRC_NR] = { 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, 0x2A80, 0x2B00};pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip, u32 sample_rate, void * private_data, u32 hw_dma_addr, int pcm_channel_id){ dsp_spos_instance_t * ins = chip->dsp_spos_instance; dsp_scb_descriptor_t * src_scb = NULL,* pcm_scb, * mixer_scb = NULL; dsp_scb_descriptor_t * src_parent_scb = NULL; /* dsp_scb_descriptor_t * pcm_parent_scb; */ char scb_name[DSP_MAX_SCB_NAME]; int i,pcm_index = -1, insert_point, src_index = -1,pass_through = 0; unsigned long flags; switch (pcm_channel_id) { case DSP_PCM_MAIN_CHANNEL: mixer_scb = ins->master_mix_scb; break; case DSP_PCM_REAR_CHANNEL: mixer_scb = ins->rear_mix_scb; break; case DSP_PCM_CENTER_LFE_CHANNEL: mixer_scb = ins->center_lfe_mix_scb; break; case DSP_PCM_S71_CHANNEL: /* TODO */ snd_assert(0); break; case DSP_IEC958_CHANNEL: snd_assert (ins->asynch_tx_scb != NULL, return NULL); mixer_scb = ins->asynch_tx_scb; /* if sample rate is set to 48khz we pass the Sample Rate Converted (which could alter the raw data stream ...) */ if (sample_rate == 48000) { snd_printdd ("IEC958 pass through\n"); /* Hack to bypass creating a new SRC */ pass_through = 1; } break; default: snd_assert (0); return NULL; } /* default sample rate is 44100 */ if (!sample_rate) sample_rate = 44100; /* search for a already created SRC SCB with the same sample rate */ for (i = 0; i < DSP_MAX_PCM_CHANNELS && (pcm_index == -1 || src_scb == NULL); ++i) { /* virtual channel reserved for capture */ if (i == CS46XX_DSP_CAPTURE_CHANNEL) continue; if (ins->pcm_channels[i].active) { if (!src_scb && ins->pcm_channels[i].sample_rate == sample_rate && ins->pcm_channels[i].mixer_scb == mixer_scb) { src_scb = ins->pcm_channels[i].src_scb; ins->pcm_channels[i].src_scb->ref_count ++; src_index = ins->pcm_channels[i].src_slot; } } else if (pcm_index == -1) { pcm_index = i; } } if (pcm_index == -1) { snd_printk (KERN_ERR "dsp_spos: no free PCM channel\n"); return NULL; } if (src_scb == NULL) { if (ins->nsrc_scb >= DSP_MAX_SRC_NR) { snd_printk(KERN_ERR "dsp_spos: to many SRC instances\n!"); return NULL; } /* find a free slot */ for (i = 0; i < DSP_MAX_SRC_NR; ++i) { if (ins->src_scb_slots[i] == 0) { src_index = i; ins->src_scb_slots[i] = 1; break; } } snd_assert (src_index != -1,return NULL); /* we need to create a new SRC SCB */ if (mixer_scb->sub_list_ptr == ins->the_null_scb) { src_parent_scb = mixer_scb; insert_point = SCB_ON_PARENT_SUBLIST_SCB; } else { src_parent_scb = find_next_free_scb(chip,mixer_scb->sub_list_ptr); insert_point = SCB_ON_PARENT_NEXT_SCB; } snprintf (scb_name,DSP_MAX_SCB_NAME,"SrcTask_SCB%d",src_index);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -