int  mailbox_send_audiodsp(int overwrite,int num,int cmd,const char *data,int len)
{
	int res = -1;
	int time_out = 0;
	if(DSP_RD(DSP_STATUS) != DSP_STATUS_RUNING){
		printk("fatal error,dsp must be running before mailbox sent\n");
		return -1;
	}	
	DSP_WD(DSP_GET_EXTRA_INFO_FINISH, 0);
	while(time_out++ < 10){
		if((num == M2B_IRQ0_DSP_AUDIO_EFFECT) && (cmd == DSP_CMD_SET_HDMI_SR)){
			hdmi_sr = *(unsigned int *)data;
			DSP_PRNT("<hdmi to dsp mailbox> sr changed to %d\n",hdmi_sr);
			DSP_WD(DSP_HDMI_SR,hdmi_sr);
			res = dsp_mailbox_send(audiodsp_privdata(),overwrite,num,cmd,(char*)&hdmi_sr,sizeof(unsigned int));
			return res;
		}
		else{
			res = dsp_mailbox_send(audiodsp_privdata(),overwrite,num,cmd,data,len);
			msleep(10);
		}	
		if(DSP_RD(DSP_GET_EXTRA_INFO_FINISH) == 0x12345678)
		        break;
	}
	if(time_out == 10){
		printk("error,dsp transfer mailbox time out\n");
		return -1;
	}
	return res;
}
 int dsp_start( struct audiodsp_priv *priv, struct audiodsp_microcode *mcode)
 {
	int i;
	int res;
	mutex_lock(&priv->dsp_mutex);		
	halt_dsp(priv);
	if(priv->stream_fmt!=priv->last_stream_fmt) // remove the trick, bug fixed on dsp side
		{
		if(audiodsp_microcode_load(audiodsp_privdata(),mcode)!=0)
			{
			printk("load microcode error\n");
			res=-1;
			goto exit;
			}
		priv->last_stream_fmt=priv->stream_fmt;
		}
	if((res=dsp_set_stack(priv)))
		goto exit;
	if((res=dsp_set_heap(priv)))
		goto exit;
	if((res=dsp_set_stream_buffer(priv)))
		goto exit;
    if(!priv->dsp_is_started)
	    reset_dsp(priv);
    else{
        dsp_mailbox_send(priv,1,M2B_IRQ0_DSP_WAKEUP,0,0,0);
        msleep(1);/*waiting arc625 run again */
    }    
	priv->dsp_start_time=jiffies;
    
	for(i=0;i<1000;i++)
		{            
		if(DSP_RD(DSP_STATUS)==DSP_STATUS_RUNING)
			break;
		msleep(1);
		}
	if(i>=1000)
		{
		DSP_PRNT("dsp not running \n");
		res=-1;
		}
	else
		{
		DSP_PRNT("dsp status=%lx\n",DSP_RD(DSP_STATUS));
		priv->dsp_is_started=1;
		res=0;
		}
exit:
	mutex_unlock(&priv->dsp_mutex);		
	return res;
 }
void reset_dsp( struct audiodsp_priv *priv)
{
    halt_dsp(priv);

    //flush_and_inv_dcache_all();
    /* map DSP 0 address so that reset vector points to same vector table as ARC1 */
    CLEAR_MPEG_REG_MASK(AUD_ARC_CTL, (0xfff << 4));
 //   SET_MPEG_REG_MASK(SDRAM_CTL0,1);//arc mapping to ddr memory
    SET_MPEG_REG_MASK(AUD_ARC_CTL, ((AUDIO_DSP_START_PHY_ADDR)>> 20) << 4);
// decode option    
    if(IEC958_mode_codec){
      if(IEC958_mode_codec == 4){//dd+
		DSP_WD(DSP_DECODE_OPTION, decopt|(3<<30));
      }else{
		DSP_WD(DSP_DECODE_OPTION, decopt|(1<<31));//dd,dts
      }
    }
	else{
		DSP_WD(DSP_DECODE_OPTION, decopt&(~(1<<31)));
	}
    printk("reset dsp : dec opt=%x\n", DSP_RD(DSP_DECODE_OPTION));
    if(!priv->dsp_is_started){
        DSP_PRNT("dsp reset now\n");
        enable_dsp(1);
        }
    else{
       	dsp_mailbox_send(priv,1,M2B_IRQ0_DSP_WAKEUP,0,0,0);
        DSP_WD(DSP_STATUS, DSP_STATUS_WAKEUP);
        msleep(1);/*waiting arc625 run again */

    }

    return;    
}
int audiodsp_get_audioinfo(struct audiodsp_priv *priv)
{
	int ret = -1;
	int audio_info = 0;
       audio_info = DSP_RD(DSP_AUDIO_FORMAT_INFO);	
	if(priv->frame_format.valid == (CHANNEL_VALID|DATA_WIDTH_VALID|SAMPLE_RATE_VALID)){
		ret = 0;
		goto exit;
	}
	else if(audio_info){
		priv->frame_format.channel_num = audio_info&0xf;
		if(priv->frame_format.channel_num)
			priv->frame_format.valid |= CHANNEL_VALID;
		priv->frame_format.data_width= (audio_info>>4)&0x3f;
		if(priv->frame_format.data_width)
			priv->frame_format.valid |= DATA_WIDTH_VALID;
		priv->frame_format.sample_rate = (audio_info>>10);
		if(priv->frame_format.sample_rate)
			priv->frame_format.valid |= SAMPLE_RATE_VALID;
		ret = 0;
	}
	if(ret == 0){
		DSP_PRNT(" audiodsp got audioinfo:[ch num %d],[sr  %d]", \
		priv->frame_format.channel_num,priv->frame_format.sample_rate);
	}
exit:
	return ret;

}
Example #5
0
static void audiodsp_monitor(unsigned long arg)
{
	struct audiodsp_priv *priv=(struct audiodsp_priv *)arg;
	static unsigned long old_dsp_jiffies=0;
	static unsigned long jiffies_error=0;
	unsigned long dsp_jiffies;
	unsigned long dsp_status;

	
	dsp_jiffies=DSP_RD(DSP_JIFFIES);
	dsp_status=DSP_RD(DSP_STATUS);

	if(old_dsp_jiffies==dsp_jiffies)
		jiffies_error++;
	else
		{
		jiffies_error=0;
		old_dsp_jiffies=dsp_jiffies;
		}
	if(jiffies_error>5)
		{
		DSP_PRNT("Found audio dsp have some problem not running \n");
		DSP_PRNT("audio jiffies=%ld\n",old_dsp_jiffies);
		DSP_PRNT("audio status=%lx\n",dsp_status);
		}
	if(!dsp_check_status(priv) ){
		priv->dsp_abnormal_count++;
	}
	else
		priv->dsp_abnormal_count = 0;		
	if(priv->dsp_abnormal_count > 5 || jiffies_error > 5){
		priv->decode_fatal_err |= 0x2;
		priv->dsp_abnormal_count = 0;
		jiffies_error = 0;
	}
	priv->dsp_mointer.expires=jiffies+HZ;
	add_timer(&priv->dsp_mointer);
}
void halt_dsp( struct audiodsp_priv *priv)
{
    int i;
	if(DSP_RD(DSP_STATUS)==DSP_STATUS_RUNING)
		{
#ifndef AUDIODSP_RESET
		dsp_mailbox_send(priv,1,M2B_IRQ0_DSP_SLEEP,0,0,0);
        for(i = 0; i< 100;i++)
            {
                if(DSP_RD(DSP_STATUS)== DSP_STATUS_SLEEP)
                    break;
		        msleep(1);/*waiting arc2 sleep*/
            }
        if(i == 100)
           DSP_PRNT("warning: dsp is not sleeping when call dsp_stop\n"); 
#else
		dsp_mailbox_send(priv,1,M2B_IRQ0_DSP_HALT,0,0,0);
		msleep(1);/*waiting arc2 sleep*/
#endif
       }
#ifdef AUDIODSP_RESET	
	if(DSP_RD(DSP_STATUS)!=DSP_STATUS_RUNING)
		{
		DSP_WD(DSP_STATUS, DSP_STATUS_HALT);
		return ;
		}
#endif
    if(!priv->dsp_is_started){

	    enable_dsp(0);/*hardware halt the cpu*/
        DSP_WD(DSP_STATUS, DSP_STATUS_HALT);
        priv->last_stream_fmt=-1;/*mask the stream format is not valid*/
    }   
    else
        DSP_WD(DSP_STATUS, DSP_STATUS_SLEEP);
	
}
Example #7
0
void dsp_c_entry(void )
{
#if 0
    while(stop);
#ifndef __ARC600__
	if(DSP_RD(DSP_STATUS)==DSP_STATUS_RUNING)
	{/*halt the dsp */
		printk("audio dsp halted now\n");
		dsp_flush_printk_data();
		DSP_WD(DSP_STATUS,DSP_STATUS_HALT);
		arch_halt();
	}
	else
#endif
	{
		DSP_WD(DSP_STATUS,DSP_STATUS_RUNING);
	}
	printk("DSP version=%s,dsp clock %d\n",firmware_version,get_system_clk());
	
	
#if defined(ENABLE_EFUSE) || defined(ENABLE_FIRMWARE_ENCRYPT) 
	/*add by jeff begin*/
	add_data();
#endif

	DSP_WD(DSP_JIFFIES,0);
	dsp_memory_init();
#endif 
	dsp_irq_init();
#if 0
    dsp_timer_init();

	dsp_cache_init(1);
	dsp_mailbox_init();
#endif
	dsp_irq_enable();
#if 0
	init_device();
#endif
	start_system();
				
    while(1)
    {	
        //arch_sleep();
	//test_arc_run++;
	dsp_main();
    }
}
int   dsp_check_status(struct audiodsp_priv *priv)
{
	unsigned dsp_halt_score = 0;
	unsigned ablevel  = 0;
	int  pcmlevel = 0; 
	if(DSP_RD(DSP_STATUS) != DSP_STATUS_RUNING)
		return 1;	
	ablevel =READ_MPEG_REG(AIU_MEM_AIFIFO_LEVEL);
	pcmlevel = dsp_codec_get_bufer_data_len(priv);
	if((ablevel == priv->last_ablevel && ablevel > 50*1024)&& \
	    (pcmlevel == priv->last_pcmlevel && pcmlevel < 512)){
	    	priv->last_ablevel = ablevel;
		priv->last_pcmlevel = 	pcmlevel;
	    	printk("dsp not working ............\n");
	    	return 0;
	}
    	priv->last_ablevel = ablevel;
	priv->last_pcmlevel = 	pcmlevel;	
	return 1;
}
int audiodsp_start(void)
{
	struct audiodsp_priv *priv=audiodsp_privdata();
	struct audiodsp_microcode *pmcode;
	struct audio_info *audio_info;
	int ret,i;
	priv->frame_format.valid=0;
	priv->decode_error_count=0;
	priv->last_valid_pts=0;
	priv->out_len_after_last_valid_pts = 0;
	priv->decode_fatal_err = 0;
	priv->first_lookup_over = 0;
	pmcode=audiodsp_find_supoort_mcode(priv,priv->stream_fmt);
	if(pmcode==NULL)
	{
		DSP_PRNT("have not find a valid mcode for fmt(0x%x)\n",priv->stream_fmt);
		return -1;
	}

	stop_audiodsp_monitor(priv);
	dsp_stop(priv);
	ret=dsp_start(priv,pmcode);
	if(ret==0){
 		start_audiodsp_monitor(priv);

#ifdef CONFIG_AM_VDEC_REAL
	if((pmcode->fmt == MCODEC_FMT_COOK) || 
	   (pmcode->fmt == MCODEC_FMT_RAAC) || 
	   (pmcode->fmt == MCODEC_FMT_AMR)  || 
	   (pmcode->fmt == MCODEC_FMT_WMA)  ||
	   (pmcode->fmt == MCODEC_FMT_ADPCM)|| 
	   (pmcode->fmt == MCODEC_FMT_PCM)  ||
	   (pmcode->fmt == MCODEC_FMT_WMAPRO)||
	   (pmcode->fmt == MCODEC_FMT_ALAC)||
	  (pmcode->fmt & MCODEC_FMT_AC3) ||
	   (pmcode->fmt & MCODEC_FMT_EAC3) ||	  
	  (pmcode->fmt == MCODEC_FMT_APE) ||
	  (pmcode->fmt == MCODEC_FMT_FLAC))

	{
		DSP_PRNT("dsp send audio info\n");
    		for(i = 0; i< 2000;i++){
                if(DSP_RD(DSP_AUDIOINFO_STATUS) == DSP_AUDIOINFO_READY)//maybe at audiodsp side,INT not enabled yet,so wait a while
                    break;
    		     msleep(1);
            }
		if(i == 2000)
			DSP_PRNT("audiodsp not ready for info  \n");
            DSP_WD(DSP_AUDIOINFO_STATUS,0);
		    audio_info = get_audio_info();
		DSP_PRNT("kernel sent info first 4 byte[0x%x],[0x%x],[0x%x],[0x%x]\n\t",audio_info->extradata[0],\
			audio_info->extradata[1],audio_info->extradata[2],audio_info->extradata[3]);
		DSP_WD(DSP_GET_EXTRA_INFO_FINISH, 0);
		while(1){
		    dsp_mailbox_send(priv, 1, M2B_IRQ4_AUDIO_INFO, 0, (const char*)audio_info, sizeof(struct audio_info));
		    msleep(100);

		    if(DSP_RD(DSP_GET_EXTRA_INFO_FINISH) == 0x12345678)
		        break;
		}
    }
#endif
     }
	return ret;
}
Example #10
0
	unsigned long stream_buffer_end;
	unsigned long stream_buffer_size;	
	unsigned long user_read_offset; //the offset of the stream buffer which user space reading
}priv_data_t; 

static priv_data_t priv_data = {0};

static ssize_t pcmenc_ptr_show(struct class* class, struct class_attribute* attr,
    char* buf)
{
	  ssize_t ret = 0;
	  ret = sprintf(buf, "pcmenc runtime info:\n"
	                     "  pcmenc rd ptr :\t%x\n"    
	                     "  pcmenc wr ptr :\t%x\n"    
	                     "  pcmenc level  :\t%x\n",
	                     (DSP_RD(DSP_DECODE_51PCM_OUT_RD_ADDR)),
	                     (DSP_RD(DSP_DECODE_51PCM_OUT_WD_ADDR)),
	                     pcmenc_stream_content()
	                     );
  	return ret;
}
static struct class_attribute pcmenc_attrs[]={
  __ATTR_RO(pcmenc_ptr),
  __ATTR_NULL
};
static void create_pcmenc_attrs(struct class* class)
{
  int i=0;
  for(i=0; pcmenc_attrs[i].attr.name; i++){
    class_create_file(class, &pcmenc_attrs[i]);
  }
Example #11
0
u32 dsp_codec_get_current_pts(struct audiodsp_priv *priv)
{
#ifdef CONFIG_AM_PTSSERVER
    u32  pts;
    u32 delay_pts;
    int len;
    u64 frame_nums;
    int res;
    u32 offset, buffered_len, wp;

    mutex_lock(&priv->stream_buffer_mutex);

    if (priv->frame_format.channel_num == 0 || priv->frame_format.sample_rate == 0 || priv->frame_format.data_width == 0) {
        printk("unvalid audio format!\n");
	 mutex_unlock(&priv->stream_buffer_mutex);
        return -1;
    }
#if 0
    if (priv->stream_fmt == MCODEC_FMT_COOK) {
        pts = priv->cur_frame_info.offset;
        mutex_unlock(&priv->stream_buffer_mutex);
    } else
#endif
    {


        buffered_len = DSP_RD(DSP_BUFFERED_LEN);
        wp = DSP_RD(DSP_DECODE_OUT_WD_PTR);
        offset = DSP_RD(DSP_AFIFO_RD_OFFSET1);
        // before audio start, the pts always be at the first index
        if(!timestamp_apts_started()){
          offset = 0;
        }
        
        if (priv->stream_fmt == MCODEC_FMT_COOK || priv->stream_fmt == MCODEC_FMT_RAAC) {
            pts = DSP_RD(DSP_AFIFO_RD_OFFSET1);
            res = 0;
        } else {
            res = pts_lookup_offset(PTS_TYPE_AUDIO, offset, &pts, 300);
            //printk("pts_lookup_offset = %d, buffer_len = %d, res = %d\n", offset, buffered_len, res);

            if (!priv->first_lookup_over) {
                priv->first_lookup_over = 1;
                if (first_lookup_pts_failed(PTS_TYPE_AUDIO)) {

                    priv->out_len_after_last_valid_pts = 0;
                    priv->last_valid_pts = pts;

                    mutex_unlock(&priv->stream_buffer_mutex);
                    return pts;
                }
            }
        }

        if (res == 0) {
            //printk("check out pts == %x\n", pts);
            priv->out_len_after_last_valid_pts = 0;
            len = buffered_len + dsp_codec_get_bufer_data_len1(priv, wp);
            frame_nums = (len * 8 / (priv->frame_format.data_width * priv->frame_format.channel_num));
	     delay_pts = div64_u64(frame_nums*90*20, priv->frame_format.sample_rate/50);
            //printk("cal delay pts == %x\n", delay_pts);
            if (pts > delay_pts) {
                pts -= delay_pts;
            } else {
                pts = 0;
            }
            priv->last_valid_pts = pts;

            //printk("len = %d, data_width = %d, channel_num = %d, frame_nums = %lld, sample_rate = %d, pts = %d\n",
            //   len, priv->frame_format.data_width,priv->frame_format.channel_num, frame_nums, priv->frame_format.sample_rate, pts);
        }

        else if (priv->last_valid_pts >= 0) {
            pts = priv->last_valid_pts;
            len = priv->out_len_after_last_valid_pts;
            frame_nums = (len * 8 / (priv->frame_format.data_width * priv->frame_format.channel_num));
	     pts += div64_u64(frame_nums*90*20, priv->frame_format.sample_rate/50);

            //printk("last_pts = %d, len = %d, data_width = %d, channel_num = %d, frame_nums = %lld, sample_rate = %d, pts = %d\n",
            //    priv->last_valid_pts, len, priv->frame_format.data_width,priv->frame_format.channel_num, frame_nums, priv->frame_format.sample_rate, pts);
        }

        else {
            printk("checkout audio pts failed!\n");
            pts = -1;
        }

        mutex_unlock(&priv->stream_buffer_mutex);
    }
    return pts;
#endif
    return -1;
}
Example #12
0
static int audiodsp_ioctl(struct inode *node, struct file *file, unsigned int cmd,
		      unsigned long args)
{
	struct audiodsp_priv *priv=audiodsp_privdata();
	struct audiodsp_cmd *a_cmd;
	char name[64];
	int len;
	unsigned long pts;
	int ret=0;
	unsigned long *val=(unsigned long *)args;
#ifdef ENABLE_WAIT_FORMAT
	static int wait_format_times=0;
#endif	
	switch(cmd)
		{
		case AUDIODSP_SET_FMT:
			priv->stream_fmt=args;
            if(args == MCODEC_FMT_DTS)
              	IEC958_mode_codec = 1;
            else if(args == MCODEC_FMT_AC3)
            	IEC958_mode_codec = 2; 	
            else
            	IEC958_mode_codec = 0;
			break;
		case AUDIODSP_START:
			if(IEC958_mode_raw_last != IEC958_mode_raw || IEC958_mode_codec_last !=  IEC958_mode_codec)
			{
				IEC958_mode_raw_last = IEC958_mode_raw;
				IEC958_mode_codec_last = IEC958_mode_codec;
				aml_alsa_hw_reprepare();
			}	
			priv->decoded_nb_frames = 0;
			priv->format_wait_count = 0;
			if(priv->stream_fmt<=0)
				{
				DSP_PRNT("Audio dsp steam format have not set!\n");
				}
			else
				{
				ret=audiodsp_start();
				}
			break;
		case AUDIODSP_STOP:
			//DSP_PRNT("audiodsp command stop\n");
			stop_audiodsp_monitor(priv);
			dsp_stop(priv);
			priv->decoded_nb_frames = 0;
			priv->format_wait_count = 0;
			break;
#ifdef ENABLE_WAIT_FORMAT
		case AUDIODSP_DECODE_START:			
			if(priv->dsp_is_started)
				{
				dsp_codec_start(priv);
				wait_format_times=0;
				}
			else
				{
				DSP_PRNT("Audio dsp have not started\n");
				}			
			break;
		case AUDIODSP_WAIT_FORMAT:
			if(priv->dsp_is_started)
				{
				struct audio_info *audio_format;
				int ch = 0;
				audio_format = get_audio_info();
				
				wait_format_times++;
				
				if(wait_format_times>100){
					int audio_info = DSP_RD(DSP_AUDIO_FORMAT_INFO);
					if(audio_info){
						priv->frame_format.channel_num = audio_info&0xf;
						if(priv->frame_format.channel_num)
							priv->frame_format.valid |= CHANNEL_VALID;
						priv->frame_format.data_width= (audio_info>>4)&0x3f;
						if(priv->frame_format.data_width)
							priv->frame_format.valid |= DATA_WIDTH_VALID;
						priv->frame_format.sample_rate = (audio_info>>10);
						if(priv->frame_format.sample_rate)
							priv->frame_format.valid |= SAMPLE_RATE_VALID;
						DSP_PRNT("warning::got info from mailbox failed,read from regiser\n");
						ret = 0;
					}else{
						DSP_PRNT("dsp have not set the codec stream's format details,valid=%x\n",
						priv->frame_format.valid);		
						priv->format_wait_count++;
						if(priv->format_wait_count > 5){						
							if(audio_format->channels&&audio_format->sample_rate){
								priv->frame_format.channel_num = audio_format->channels>2?2:audio_format->channels;
								priv->frame_format.sample_rate = audio_format->sample_rate;
								priv->frame_format.data_width = 16;
								priv->frame_format.valid = CHANNEL_VALID|DATA_WIDTH_VALID|SAMPLE_RATE_VALID;
								DSP_PRNT("we have not got format details from dsp,so use the info got from the header parsed instead\n");
								ret = 0;
							}else{
								ret = -1;
							}
						}else{
							ret=-1;
						}
					}
				}else if(priv->frame_format.valid == (CHANNEL_VALID|DATA_WIDTH_VALID|SAMPLE_RATE_VALID)){
static irqreturn_t audiodsp_mailbox_irq(int irq, void *data)
{
	struct audiodsp_priv *priv=(struct audiodsp_priv *)data;
	unsigned long status;
	struct mail_msg msg;
	int i = 0;
#if MESON_CPU_TYPE < MESON_CPU_TYPE_MESON8	
	unsigned long fiq_mask;
#endif
	status=READ_VREG(MB1_REG);
#if MESON_CPU_TYPE < MESON_CPU_TYPE_MESON8	
	fiq_mask=READ_VREG(MB1_SEL);
	status=status&fiq_mask;
#endif
	if(status&(1<<M1B_IRQ0_PRINT))
		{
		get_mailbox_data(priv,M1B_IRQ0_PRINT,&msg);
		SYS_CLEAR_IRQ(M1B_IRQ0_PRINT);
	//	inv_dcache_range((unsigned  long )msg.data,(unsigned long)msg.data+msg.len);
	
		DSP_PRNT("%s", msg.data);
	    //audiodsp_work.buf = msg.data;
	    //schedule_work(&audiodsp_work.audiodsp_workqueue);		
		}
	if(status&(1<<M1B_IRQ1_BUF_OVERFLOW))
		{
		SYS_CLEAR_IRQ(M1B_IRQ1_BUF_OVERFLOW);
		DSP_PRNT("DSP BUF over flow\n");
		}
	if(status&(1<<M1B_IRQ2_BUF_UNDERFLOW))
		{
		SYS_CLEAR_IRQ(M1B_IRQ2_BUF_UNDERFLOW);
		DSP_PRNT("DSP BUF over flow\n");
		}
	if(status&(1<<M1B_IRQ3_DECODE_ERROR))
		{
		SYS_CLEAR_IRQ(M1B_IRQ3_DECODE_ERROR);
		priv->decode_error_count++;
		}
	if(status&(1<<M1B_IRQ4_DECODE_FINISH_FRAME))
		{
		struct frame_info *info;
		SYS_CLEAR_IRQ(M1B_IRQ4_DECODE_FINISH_FRAME);
		get_mailbox_data(priv,M1B_IRQ4_DECODE_FINISH_FRAME,&msg);
		info=(struct frame_info *)msg.data;
		if(info!=NULL)
			{
			priv->cur_frame_info.offset=info->offset;
			priv->cur_frame_info.buffered_len=info->buffered_len;
			}
		priv->decoded_nb_frames ++;		
		complete(&priv->decode_completion);
		}
	if(status& (1<<M1B_IRQ5_STREAM_FMT_CHANGED))
		{
		struct frame_fmt *fmt;
		SYS_CLEAR_IRQ(M1B_IRQ5_STREAM_FMT_CHANGED);
		get_mailbox_data(priv,M1B_IRQ5_STREAM_FMT_CHANGED,&msg);
		fmt=(void *)msg.data;
		//DSP_PRNT("frame format changed");
		if(fmt==NULL || (sizeof(struct frame_fmt )<msg.len))
			{
			DSP_PRNT("frame format message error\n");
			}
		else
			{
			DSP_PRNT("frame format changed,fmt->valid 0x%x\n",fmt->valid);
			if(fmt->valid&SUB_FMT_VALID)
				{
				priv->frame_format.sub_fmt=fmt->sub_fmt;
				priv->frame_format.valid|=SUB_FMT_VALID;
				}
			if(fmt->valid&CHANNEL_VALID)
				{
				priv->frame_format.channel_num=((fmt->channel_num > 2) ? 2 : (fmt->channel_num));
				priv->frame_format.valid|=CHANNEL_VALID;
				}
			if(fmt->valid&SAMPLE_RATE_VALID)
				{
				priv->frame_format.sample_rate=fmt->sample_rate;
				priv->frame_format.valid|=SAMPLE_RATE_VALID;
				}
			if(fmt->valid&DATA_WIDTH_VALID)
				{
				priv->frame_format.data_width=fmt->data_width;
				priv->frame_format.valid|=DATA_WIDTH_VALID;
				}
			}
		/*
			if(fmt->data.pcm_encoded_info){
				set_pcminfo_data(fmt->data.pcm_encoded_info);
			}
		*/	
			DSP_PRNT("audio info from dsp:sample_rate=%d channel_num=%d\n",priv->frame_format.sample_rate,priv->frame_format.channel_num);
		}
        if(status & (1<<M1B_IRQ8_IEC958_INFO)){
            struct digit_raw_output_info* info;
            SYS_CLEAR_IRQ(M1B_IRQ8_IEC958_INFO);
            get_mailbox_data(priv, M1B_IRQ8_IEC958_INFO, &msg);
            info = (void*)msg.data;
#if 1
            IEC958_bpf = info->bpf;
            IEC958_brst = info->brst;
            IEC958_length = info->length;
            IEC958_padsize = info->padsize;
            IEC958_mode = info->mode;
            IEC958_syncword1 = info->syncword1;
            IEC958_syncword2 = info->syncword2;
            IEC958_syncword3 = info->syncword3;
            IEC958_syncword1_mask = info->syncword1_mask;
            IEC958_syncword2_mask = info->syncword2_mask;
            IEC958_syncword3_mask = info->syncword3_mask;
            IEC958_chstat0_l = info->chstat0_l;
            IEC958_chstat0_r = info->chstat0_r;
            IEC958_chstat1_l = info->chstat1_l;
            IEC958_chstat1_r = info->chstat1_r;
#endif			
  //          IEC958_mode_codec = info->can_bypass;
            
            DSP_PRNT( "MAILBOX: got IEC958 info\n");
            //schedule_work(&audiodsp_work.audiodsp_workqueue);		
        }

    	if(status& (1<<M1B_IRQ5_STREAM_RD_WD_TEST)){
            DSP_WD((0x84100000-4096+20*20),0);
    		SYS_CLEAR_IRQ(M1B_IRQ5_STREAM_RD_WD_TEST);
    		get_mailbox_data(priv,M1B_IRQ5_STREAM_RD_WD_TEST,&msg);
            
            for(i = 0;i<12;i++){
                if((DSP_RD((0x84100000-512*1024+i*20)))!= (0xff00|i)){
                    DSP_PRNT("a9 read dsp reg error ,now 0x%lx, should be 0x%x \n",(DSP_RD((0x84100000-512*1024+i*20))),12-i);
                }
               // DSP_PRNT("A9 audio dsp reg%d value 0x%x\n",i,DSP_RD((0x84100000-4096+i*20)));
            }
            for(i = 0;i<12;i++){
                DSP_WD((0x84100000-512*1024+i*20),(i%2)?i:(0xf0|i));
               
            }
            DSP_WD((0x84100000-512*1024+20*20),DSP_STATUS_HALT);
        //    DSP_PRNT("A9 mail box handle finished\n");
           // dsp_mailbox_send(priv, 1, M1B_IRQ5_STREAM_RD_WD_TEST, 0, NULL,0);

        }

	if(status & (1<<M1B_IRQ7_DECODE_FATAL_ERR)){
		int err_code;
		
		SYS_CLEAR_IRQ(M1B_IRQ7_DECODE_FATAL_ERR);
		get_mailbox_data(priv,M1B_IRQ7_DECODE_FATAL_ERR,&msg);

		err_code = msg.cmd;
		priv->decode_fatal_err = err_code;

		if(err_code & 0x01){
			timestamp_pcrscr_set(timestamp_vpts_get());
			timestamp_pcrscr_enable(1);
		}
		else if(err_code & 0x02){
		printk("Set decode_fatal_err flag, Reset audiodsp!\n");
		}
	}

	return 0;
}