⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsp_spos.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	dsp_spos_instance_t * ins = chip->dsp_spos_instance;	dsp_scb_descriptor_t * desc = NULL;	int index;	if (ins->nscb == DSP_MAX_SCB_DESC - 1) {		snd_printk(KERN_ERR "dsp_spos: got no place for other SCB\n");		return NULL;	}	index = find_free_scb_index (ins);	strcpy(ins->scbs[index].scb_name, name);	ins->scbs[index].address = dest;	ins->scbs[index].index = index;	ins->scbs[index].proc_info = NULL;	ins->scbs[index].ref_count = 1;	ins->scbs[index].deleted = 0;	spin_lock_init(&ins->scbs[index].lock);	desc = (ins->scbs + index);	ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER);	if (index > ins->scb_highest_frag_index)		ins->scb_highest_frag_index = index;	if (index == ins->nscb)		ins->nscb++;	return desc;}static dsp_task_descriptor_t * _map_task_tree (cs46xx_t *chip,char * name,u32 dest,u32 size){	dsp_spos_instance_t * ins = chip->dsp_spos_instance;	dsp_task_descriptor_t * desc = NULL;	if (ins->ntask == DSP_MAX_TASK_DESC - 1) {		snd_printk(KERN_ERR "dsp_spos: got no place for other TASK\n");		return NULL;	}	strcpy(ins->tasks[ins->ntask].task_name,name);	ins->tasks[ins->ntask].address = dest;	ins->tasks[ins->ntask].size = size;	/* quick find in list */	ins->tasks[ins->ntask].index = ins->ntask;	desc = (ins->tasks + ins->ntask);	ins->ntask++;	add_symbol (chip,name,dest,SYMBOL_PARAMETER);	return desc;}dsp_scb_descriptor_t * cs46xx_dsp_create_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest){	dsp_scb_descriptor_t * desc;	desc = _map_scb (chip,name,dest);	if (desc) {		_dsp_create_scb(chip,scb_data,dest);	} else {		snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n");	}	return desc;}static dsp_task_descriptor_t *  cs46xx_dsp_create_task_tree (cs46xx_t *chip,char * name, u32 * task_data,u32 dest,int size){	dsp_task_descriptor_t * desc;	desc = _map_task_tree (chip,name,dest,size);	if (desc) {		_dsp_create_task_tree(chip,task_data,dest,size);	} else {		snd_printk(KERN_ERR "dsp_spos: failed to map TASK\n");	}	return desc;}int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip){	dsp_spos_instance_t * ins = chip->dsp_spos_instance;	symbol_entry_t * fg_task_tree_header_code;	symbol_entry_t * task_tree_header_code;	symbol_entry_t * task_tree_thread;	symbol_entry_t * null_algorithm;	symbol_entry_t * magic_snoop_task;	dsp_scb_descriptor_t * timing_master_scb;	dsp_scb_descriptor_t * codec_out_scb;	dsp_scb_descriptor_t * codec_in_scb;	dsp_scb_descriptor_t * src_task_scb;	dsp_scb_descriptor_t * master_mix_scb;	dsp_scb_descriptor_t * rear_mix_scb;	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 * 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;	static spos_control_block_t sposcb = {		/* 0 */ HFG_TREE_SCB,HFG_STACK,		/* 1 */ SPOSCB_ADDR,BG_TREE_SCB_ADDR,		/* 2 */ DSP_SPOS_DC,0,		/* 3 */ DSP_SPOS_DC,DSP_SPOS_DC,		/* 4 */ 0,0,		/* 5 */ DSP_SPOS_UU,0,		/* 6 */ FG_TASK_HEADER_ADDR,0,		/* 7 */ 0,0,		/* 8 */ DSP_SPOS_UU,DSP_SPOS_DC,		/* 9 */ 0,		/* A */ 0,HFG_FIRST_EXECUTE_MODE,		/* B */ DSP_SPOS_UU,DSP_SPOS_UU,		/* C */ DSP_SPOS_DC_DC,		/* D */ DSP_SPOS_DC_DC,		/* E */ DSP_SPOS_DC_DC,		/* F */ DSP_SPOS_DC_DC	};	cs46xx_dsp_create_task_tree(chip, "sposCB", (u32 *)&sposcb, SPOSCB_ADDR, 0x10);	null_algorithm  = cs46xx_dsp_lookup_symbol(chip, "NULLALGORITHM", SYMBOL_CODE);	if (null_algorithm == NULL) {		snd_printk(KERN_ERR "dsp_spos: symbol NULLALGORITHM not found\n");		return -EIO;	}	fg_task_tree_header_code = cs46xx_dsp_lookup_symbol(chip, "FGTASKTREEHEADERCODE", SYMBOL_CODE);  	if (fg_task_tree_header_code == NULL) {		snd_printk(KERN_ERR "dsp_spos: symbol FGTASKTREEHEADERCODE not found\n");		return -EIO;	}	task_tree_header_code = cs46xx_dsp_lookup_symbol(chip, "TASKTREEHEADERCODE", SYMBOL_CODE);  	if (task_tree_header_code == NULL) {		snd_printk(KERN_ERR "dsp_spos: symbol TASKTREEHEADERCODE not found\n");		return -EIO;	}  	task_tree_thread = cs46xx_dsp_lookup_symbol(chip, "TASKTREETHREAD", SYMBOL_CODE);	if (task_tree_thread == NULL) {		snd_printk(KERN_ERR "dsp_spos: symbol TASKTREETHREAD not found\n");		return -EIO;	}	magic_snoop_task = cs46xx_dsp_lookup_symbol(chip, "MAGICSNOOPTASK", SYMBOL_CODE);	if (magic_snoop_task == NULL) {		snd_printk(KERN_ERR "dsp_spos: symbol MAGICSNOOPTASK not found\n");		return -EIO;	}  	{		/* create the null SCB */		static generic_scb_t null_scb = {			{ 0, 0, 0, 0 },			{ 0, 0, 0, 0, 0 },			NULL_SCB_ADDR, NULL_SCB_ADDR,			0, 0, 0, 0, 0,			{				0,0,				0,0,			}		};		null_scb.entry_point = null_algorithm->address;		ins->the_null_scb = cs46xx_dsp_create_scb(chip, "nullSCB", (u32 *)&null_scb, NULL_SCB_ADDR);		ins->the_null_scb->task_entry = null_algorithm;		ins->the_null_scb->sub_list_ptr = ins->the_null_scb;		ins->the_null_scb->next_scb_ptr = ins->the_null_scb;		ins->the_null_scb->parent_scb_ptr = NULL;		cs46xx_dsp_proc_register_scb_desc (chip,ins->the_null_scb);	}	{		/* setup foreground task tree */		static task_tree_control_block_t fg_task_tree_hdr =  {			{ FG_TASK_HEADER_ADDR | (DSP_SPOS_DC << 0x10),			  DSP_SPOS_DC_DC,			  DSP_SPOS_DC_DC,			  0x0000,DSP_SPOS_DC,			  DSP_SPOS_DC, DSP_SPOS_DC,			  DSP_SPOS_DC_DC,			  DSP_SPOS_DC_DC,			  DSP_SPOS_DC_DC,			  DSP_SPOS_DC,DSP_SPOS_DC },    			{				BG_TREE_SCB_ADDR,TIMINGMASTER_SCB_ADDR, 				0,				FG_TASK_HEADER_ADDR + TCBData,                  			},			{    				4,0,				1,0,				2,SPOSCB_ADDR + HFGFlags,				0,0,				FG_TASK_HEADER_ADDR + TCBContextBlk,FG_STACK			},			{				DSP_SPOS_DC,0,				DSP_SPOS_DC,DSP_SPOS_DC,				DSP_SPOS_DC,DSP_SPOS_DC,				DSP_SPOS_DC,DSP_SPOS_DC,				DSP_SPOS_DC,DSP_SPOS_DC,				DSP_SPOS_DCDC,				DSP_SPOS_UU,1,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC 			},                                               			{ 				FG_INTERVAL_TIMER_PERIOD,DSP_SPOS_UU,				0,0			}		};		fg_task_tree_hdr.links.entry_point = fg_task_tree_header_code->address;		fg_task_tree_hdr.context_blk.stack0 = task_tree_thread->address;		cs46xx_dsp_create_task_tree(chip,"FGtaskTreeHdr",(u32 *)&fg_task_tree_hdr,FG_TASK_HEADER_ADDR,0x35);	}	{		/* setup foreground task tree */		static task_tree_control_block_t bg_task_tree_hdr =  {			{ DSP_SPOS_DC_DC,			  DSP_SPOS_DC_DC,			  DSP_SPOS_DC_DC,			  DSP_SPOS_DC, DSP_SPOS_DC,			  DSP_SPOS_DC, DSP_SPOS_DC,			  DSP_SPOS_DC_DC,			  DSP_SPOS_DC_DC,			  DSP_SPOS_DC_DC,			  DSP_SPOS_DC,DSP_SPOS_DC },    			{				NULL_SCB_ADDR,NULL_SCB_ADDR,  /* Set up the background to do nothing */				0,				BG_TREE_SCB_ADDR + TCBData,			},			{    				9999,0,				0,1,				0,SPOSCB_ADDR + HFGFlags,				0,0,				BG_TREE_SCB_ADDR + TCBContextBlk,BG_STACK			},			{				DSP_SPOS_DC,0,				DSP_SPOS_DC,DSP_SPOS_DC,				DSP_SPOS_DC,DSP_SPOS_DC,				DSP_SPOS_DC,DSP_SPOS_DC,				DSP_SPOS_DC,DSP_SPOS_DC,				DSP_SPOS_DCDC,				DSP_SPOS_UU,1,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC,				DSP_SPOS_DCDC 			},                                               			{ 				BG_INTERVAL_TIMER_PERIOD,DSP_SPOS_UU,				0,0			}		};		bg_task_tree_hdr.links.entry_point = task_tree_header_code->address;		bg_task_tree_hdr.context_blk.stack0 = task_tree_thread->address;		cs46xx_dsp_create_task_tree(chip,"BGtaskTreeHdr",(u32 *)&bg_task_tree_hdr,BG_TREE_SCB_ADDR,0x35);	}	/* create timing master SCB */	timing_master_scb = cs46xx_dsp_create_timing_master_scb(chip);	/* create the CODEC output task */	codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_I",0x0010,0x0000,							MASTERMIX_SCB_ADDR,							CODECOUT_SCB_ADDR,timing_master_scb,							SCB_ON_PARENT_SUBLIST_SCB);	if (!codec_out_scb) goto _fail_end;	/* create the master mix SCB */	master_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"MasterMixSCB",							MIX_SAMPLE_BUF1,MASTERMIX_SCB_ADDR,							codec_out_scb,							SCB_ON_PARENT_SUBLIST_SCB);	ins->master_mix_scb = master_mix_scb;	if (!master_mix_scb) goto _fail_end;	/* create codec in */	codec_in_scb = cs46xx_dsp_create_codec_in_scb(chip,"CodecInSCB",0x0010,0x00A0,						      CODEC_INPUT_BUF1,						      CODECIN_SCB_ADDR,codec_out_scb,						      SCB_ON_PARENT_NEXT_SCB);	if (!codec_in_scb) goto _fail_end;	ins->codec_in_scb = codec_in_scb;	/* create write back scb */	write_back_scb = cs46xx_dsp_create_mix_to_ostream_scb(chip,"WriteBackSCB",							      WRITE_BACK_BUF1,WRITE_BACK_SPB,							      WRITEBACK_SCB_ADDR,							      timing_master_scb,							      SCB_ON_PARENT_NEXT_SCB);	if (!write_back_scb) goto _fail_end;	{		static mix2_ostream_spb_t mix2_ostream_spb = {			0x00020000,			0x0000ffff		};    		/* dirty hack ... */		_dsp_create_task_tree (chip,(u32 *)&mix2_ostream_spb,WRITE_BACK_SPB,2);	}	/* input sample converter */	vari_decimate_scb = cs46xx_dsp_create_vari_decimate_scb(chip,"VariDecimateSCB",								VARI_DECIMATE_BUF0,								VARI_DECIMATE_BUF1,								VARIDECIMATE_SCB_ADDR,								write_back_scb,								SCB_ON_PARENT_SUBLIST_SCB);	if (!vari_decimate_scb) goto _fail_end;	/* create the record mixer SCB */	record_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"RecordMixerSCB",							MIX_SAMPLE_BUF2,							RECORD_MIXER_SCB_ADDR,							vari_decimate_scb,							SCB_ON_PARENT_SUBLIST_SCB);	ins->record_mixer_scb = record_mix_scb;	if (!record_mix_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,						      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,							     clfe_codec_out_scb,							     SCB_ON_PARENT_NEXT_SCB);    	if (!magic_snoop_scb) goto _fail_end;	ins->ref_snoop_scb = magic_snoop_scb;	/* SP IO access */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -