Exemplo n.º 1
0
/**
 *  if normal clock, i2s clock is twice of 958 clock, so the divisor for i2s is 8, but 4 for 958
 *  if over clock, the devisor for i2s is 8, but for 958 should be 1, because 958 should be 4 times speed according to i2s
 *  This is dolby digital plus's spec
 * */

void audio_util_set_dac_format(unsigned format)
{
  	WRITE_MPEG_REG(AIU_CLK_CTRL,		 (0 << 12) | // 958 divisor more, if true, divided by 2, 4, 6, 8.
							(1 <<  8) | // alrclk skew: 1=alrclk transitions on the cycle before msb is sent
							(1 <<  6) | // invert aoclk
                                                        (1 <<  7) | // invert lrclk
#if OVERCLOCK == 1
							(3 <<  4) | // 958 divisor: 0=no div; 1=div by 2; 2=div by 3; 3=div by 4.
							(3 <<  2) | // i2s divisor: 0=no div; 1=div by 2; 2=div by 4; 3=div by 8.
#else
							(1 <<  4) | // 958 divisor: 0=no div; 1=div by 2; 2=div by 3; 3=div by 4.
							(2 <<  2) | // i2s divisor: 0=no div; 1=div by 2; 2=div by 4; 3=div by 8.
#endif
							(1 <<  1) |
							(1 <<  0)); // enable I2S clock
    if (format == AUDIO_ALGOUT_DAC_FORMAT_DSP) {
        WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 1, 8, 2);
    } else if (format == AUDIO_ALGOUT_DAC_FORMAT_LEFT_JUSTIFY) {
        WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 0, 8, 2);
    }
 	if(dac_mute_const == 0x800000)
    	WRITE_MPEG_REG(AIU_I2S_DAC_CFG, 	0x000f);	// Payload 24-bit, Msb first, alrclk = aoclk/64.mute const 0x800000
    else
    	WRITE_MPEG_REG(AIU_I2S_DAC_CFG, 	0x0007);	// Payload 24-bit, Msb first, alrclk = aoclk/64
	WRITE_MPEG_REG(AIU_I2S_SOURCE_DESC, 0x0001);	// four 2-channel
Exemplo n.º 2
0
void audio_set_aiubuf(u32 addr, u32 size)
{
    WRITE_MPEG_REG(AIU_MEM_I2S_START_PTR, addr & 0xffffffc0);
    WRITE_MPEG_REG(AIU_MEM_I2S_RD_PTR, addr & 0xffffffc0);
    WRITE_MPEG_REG(AIU_MEM_I2S_END_PTR, (addr & 0xffffffc0) + (size & 0xffffffc0) - 64);   //this is for 16bit 2 channel
	
    WRITE_MPEG_REG(AIU_I2S_MISC,		0x0004);	// Hold I2S
	WRITE_MPEG_REG(AIU_I2S_MUTE_SWAP,	0x0000);	// No mute, no swap
	// As the default amclk is 24.576MHz, set i2s and iec958 divisor appropriately so as not to exceed the maximum sample rate.
	WRITE_MPEG_REG(AIU_I2S_MISC,		0x0010 );	// Release hold and force audio data to left or right
	
	WRITE_MPEG_REG(AIU_MEM_I2S_MASKS,		(24 << 16) |	// [31:16] IRQ block.
								(0x3 << 8) |	// [15: 8] chan_mem_mask. Each bit indicates which channels exist in memory
								(0x3 << 0));	// [ 7: 0] chan_rd_mask.  Each bit indicates which channels are READ from memory

    // 16 bit PCM mode
    //  WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 1, 6, 1);
	// Set init high then low to initilize the I2S memory logic
	WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 1, 0, 1 );
	WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 0, 0, 1 );

	WRITE_MPEG_REG(AIU_MEM_I2S_BUF_CNTL, 1 | (0 << 1));
    WRITE_MPEG_REG(AIU_MEM_I2S_BUF_CNTL, 0 | (0 << 1));

    audio_out_buf_ready = 1;
}
Exemplo n.º 3
0
//extern void audio_in_enabled(int flag);

void audio_in_i2s_enable(int flag)
{
  	int rd = 0, start=0;
	if(flag){
          /* reset only when start i2s input */
reset_again:
	     WRITE_MPEG_REG_BITS(AUDIN_FIFO0_CTRL, 1, 1, 1); // reset FIFO 0
            WRITE_MPEG_REG(AUDIN_FIFO0_PTR, 0);
            rd = READ_MPEG_REG(AUDIN_FIFO0_PTR);
            start = READ_MPEG_REG(AUDIN_FIFO0_START);
            if(rd != start){
              printk("error %08x, %08x !!!!!!!!!!!!!!!!!!!!!!!!\n", rd, start);
              goto reset_again;
            }
		if(audioin_mode == 	SPDIFIN_MODE)
			WRITE_MPEG_REG(AUDIN_SPDIF_MODE, READ_MPEG_REG(AUDIN_SPDIF_MODE)| (1<<31));
		else
			WRITE_MPEG_REG_BITS(AUDIN_I2SIN_CTRL, 1, I2SIN_EN, 1);

	}else{
		if(audioin_mode == 	SPDIFIN_MODE)	
			WRITE_MPEG_REG(AUDIN_SPDIF_MODE, READ_MPEG_REG(AUDIN_SPDIF_MODE)& ~(1<<31));
		else
			WRITE_MPEG_REG_BITS(AUDIN_I2SIN_CTRL, 0, I2SIN_EN, 1);
	}
Exemplo n.º 4
0
void audio_enable_ouput(int flag)
{
    if (flag) {
        WRITE_MPEG_REG(AIU_RST_SOFT, 0x05);
        READ_MPEG_REG(AIU_I2S_SYNC);
        WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 3, 1, 2);

        if (ENABLE_IEC958) {
            if(IEC958_MODE == AIU_958_MODE_RAW)   
            {
              audio_hw_958_raw();
            }
            //else
            {
              WRITE_MPEG_REG(AIU_958_FORCE_LEFT, 0);
              WRITE_MPEG_REG_BITS(AIU_958_DCU_FF_CTRL, 1, 0, 1);
              //WRITE_MPEG_REG(AIU_958_DCU_FF_CTRL, 1);

              WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 3, 1, 2);
            }
        }
        // Maybe cause POP noise
        //audio_i2s_unmute();
    } else {
        WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 0, 1, 2);

        if (ENABLE_IEC958) {
            WRITE_MPEG_REG(AIU_958_DCU_FF_CTRL, 0);
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 1, 2);
        }
        // Maybe cause POP noise
        //audio_i2s_mute();
    }
    audio_out_enabled(flag);
}
Exemplo n.º 5
0
static void init_vdin(int width, int format)
{
    WRITE_MPEG_REG(PERIPHS_PIN_MUX_0, READ_MPEG_REG(PERIPHS_PIN_MUX_0)|
                              ((1 << 10)    | // pm_gpioA_lcd_in_de
                               (1 << 9)     | // pm_gpioA_lcd_in_vs
                               (1 << 8)     | // pm_gpioA_lcd_in_hs
                               (1 << 7)     | // pm_gpioA_lcd_in_clk
                               (1 << 6)));     // pm_gpioA_lcd_in
    
    WRITE_MPEG_REG_BITS(VDIN_ASFIFO_CTRL2, 0x39, 2, 6); 

    //if(format==TVIN_SIG_FMT_HDMI_1440x480I_60Hz){
    if(width == 1440){
        // ratio
        WRITE_CBUS_REG_BITS(VDIN_ASFIFO_CTRL2, 1, 16, 4);
    	// en
        WRITE_CBUS_REG_BITS(VDIN_ASFIFO_CTRL2, 1, 24, 1);
        // manual reset, rst = 1 & 0
        WRITE_CBUS_REG_BITS(VDIN_ASFIFO_CTRL2, 1, 25, 1);
        WRITE_CBUS_REG_BITS(VDIN_ASFIFO_CTRL2, 0, 25, 1);

        // output_width_m1
        WRITE_MPEG_REG(VDIN_INTF_WIDTHM1, width/2 - 1);  
    }
    else{
        WRITE_MPEG_REG_BITS(VDIN_ASFIFO_CTRL2, 0, 16, 10);
        WRITE_MPEG_REG(VDIN_INTF_WIDTHM1, width - 1);  
    }
    //vdin0_select_in(6, 2, 1, 0, 0, width);
    //vdin0_set_matrix_rgb2ycbcr(0);
}    
/*
special call by the audiodsp,add these code,as there are three cases for 958 s/pdif output
1)NONE-PCM  raw output ,only available when ac3/dts audio,when raw output mode is selected by user.
2)PCM  output for  all audio, when pcm mode is selected by user .
3)PCM  output for audios except ac3/dts,when raw output mode is selected by user
*/
static void aml_hw_iec958_init(void)
{
    _aiu_958_raw_setting_t set;
    _aiu_958_channel_status_t chstat;
    unsigned start,size;
	memset((void*)(&set), 0, sizeof(set));
	memset((void*)(&chstat), 0, sizeof(chstat));
	set.chan_stat = &chstat;
   	/* case 1,raw mode enabled */
	if(IEC958_mode_codec){
	  if(IEC958_mode_codec == 1){ //dts, use raw sync-word mode
	    	IEC958_MODE = AIU_958_MODE_RAW;
			printk("iec958 mode RAW\n");
	  }	
	  else{ //ac3,use the same pcm mode as i2s configuration
		IEC958_MODE = AIU_958_MODE_PCM_RAW;
		printk("iec958 mode %s\n",(I2S_MODE == AIU_I2S_MODE_PCM32)?"PCM32_RAW":((I2S_MODE == AIU_I2S_MODE_PCM24)?"PCM24_RAW":"PCM16_RAW"));				
	  }	
	}else{	/* case 2,3 */
	  if(I2S_MODE == AIU_I2S_MODE_PCM32)
	  	IEC958_MODE = AIU_958_MODE_PCM32;
	  else if(I2S_MODE == AIU_I2S_MODE_PCM24)
	  	IEC958_MODE = AIU_958_MODE_PCM24;
	  else		
	  	IEC958_MODE = AIU_958_MODE_PCM16;
  	  printk("iec958 mode %s\n",(I2S_MODE == AIU_I2S_MODE_PCM32)?"PCM32":((I2S_MODE == AIU_I2S_MODE_PCM24)?"PCM24":"PCM16"));
	}

	if(IEC958_MODE == AIU_958_MODE_PCM16 || IEC958_MODE == AIU_958_MODE_PCM24 ||
	  IEC958_MODE == AIU_958_MODE_PCM32){
	    set.chan_stat->chstat0_l = 0x0100;
		set.chan_stat->chstat0_r = 0x0100;
		set.chan_stat->chstat1_l = 0X200;
		set.chan_stat->chstat1_r = 0X200;              
        start = (aml_pcm_playback_phy_start_addr);
        size = aml_pcm_playback_phy_end_addr - aml_pcm_playback_phy_start_addr;
		audio_set_958outbuf(start, size, 0);
	  }else{
		set.chan_stat->chstat0_l = 0x1902;//NONE-PCM
		set.chan_stat->chstat0_r = 0x1902;
		set.chan_stat->chstat1_l = 0X200;
		set.chan_stat->chstat1_r = 0X200;
        // start = ((aml_pcm_playback_phy_end_addr + 4096)&(~127));
        // size  = aml_pcm_playback_phy_end_addr - aml_pcm_playback_phy_start_addr;
        start = aml_iec958_playback_start_phy;
        size = aml_iec958_playback_size;
		audio_set_958outbuf(start, size, (IEC958_MODE == AIU_958_MODE_RAW)?1:0);
		memset((void*)aml_iec958_playback_start_addr,0,size);
		
	}
	audio_set_958_mode(IEC958_MODE, &set);
	if(IEC958_mode_codec == 4)  //dd+
		WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 0, 4, 2); // 4x than i2s
	else
		WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 3, 4, 2);
	iec958_notify_hdmi_info();


}
Exemplo n.º 7
0
void audio_hw_958_enable(unsigned flag)
{
    if (ENABLE_IEC958) {
        WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, flag, 2, 1);
        WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, flag, 1, 1);
        WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, flag, 0, 1);
    }
}
Exemplo n.º 8
0
void audio_i2s_swap_left_right(unsigned int flag)
{
	if (ENABLE_IEC958)
	{
		WRITE_MPEG_REG_BITS(AIU_958_CTRL, flag, 1, 2);
	}
	WRITE_MPEG_REG_BITS(AIU_I2S_MUTE_SWAP, flag, 0, 2);
Exemplo n.º 9
0
// iec958 and i2s clock are separated after M6TV.
void audio_util_set_dac_958_format(unsigned format)
{
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL,0,12,1);// 958 divisor more, if true, divided by 2, 4, 6, 8
#if IEC958_OVERCLOCK == 1
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL,3,4,2);// 958 divisor: 0=no div; 1=div by 2; 2=div by 3; 3=div by 4.
#else
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL,1,4,2);// 958 divisor: 0=no div; 1=div by 2; 2=div by 3; 3=div by 4.
#endif
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL,1,1,1);// enable 958 clock
}
Exemplo n.º 10
0
/* power gate control for iec958 audio out */
unsigned audio_spdifout_pg_enable(unsigned char enable)
{
	if(enable){
			WRITE_MPEG_REG_BITS( HHI_MPLL_CNTL8, 1,14, 1);					
			AUDIO_CLK_GATE_ON(AIU_IEC958);
			AUDIO_CLK_GATE_ON(AIU_ICE958_AMCLK);
	}
	else{
			AUDIO_CLK_GATE_OFF(AIU_IEC958);
			AUDIO_CLK_GATE_OFF(AIU_ICE958_AMCLK);	
			WRITE_MPEG_REG_BITS( HHI_MPLL_CNTL8, 0,14, 1);								
	}
	return 0;
}
Exemplo n.º 11
0
void audio_out_i2s_enable(unsigned flag)
{
    if (flag) {
        WRITE_MPEG_REG(AIU_RST_SOFT, 0x01);
        READ_MPEG_REG(AIU_I2S_SYNC);
        WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 3, 1, 2);
        // Maybe cause POP noise
        // audio_i2s_unmute();
    } else {
        WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 0, 1, 2);

        // Maybe cause POP noise
        // audio_i2s_mute();
    }
    //audio_out_enabled(flag);
}
Exemplo n.º 12
0
void audio_hw_958_enable(unsigned flag)
{
    if (ENABLE_IEC958)
    {
    		if(flag){
        		WRITE_MPEG_REG(AIU_RST_SOFT, 0x04);
	              WRITE_MPEG_REG(AIU_958_FORCE_LEFT, 0);
	              WRITE_MPEG_REG_BITS(AIU_958_DCU_FF_CTRL, 1, 0, 1);
	              WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 3, 1, 2);
    		}
		else{
	             WRITE_MPEG_REG(AIU_958_DCU_FF_CTRL, 0);
	             WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 1, 2);			
		}	
    }
}
Exemplo n.º 13
0
void audio_in_spdif_enable(int flag)
{
		WRITE_MPEG_REG_BITS(AUDIN_FIFO1_CTRL, 1, 1, 1); // reset FIFO 1
		if(flag){
		}else{
		}
}
Exemplo n.º 14
0
static void vdin0_set_matrix_rgb2ycbcr (int mode)
{
   WRITE_MPEG_REG_BITS(VDIN_MATRIX_CTRL, 1, 0, 1);

   if (mode == 0) //ycbcr not full range, 601 conversion 
   {

        WRITE_MPEG_REG(VDIN_MATRIX_PRE_OFFSET0_1, 0x0);
        WRITE_MPEG_REG(VDIN_MATRIX_PRE_OFFSET2, 0x0);
        
        //0.257     0.504   0.098
        //-0.148    -0.291  0.439
        //0.439     -0.368 -0.071
        WRITE_MPEG_REG(VDIN_MATRIX_COEF00_01, (0x107 << 16) |
                              0x204);
        WRITE_MPEG_REG(VDIN_MATRIX_COEF02_10, (0x64 << 16) |
                              0x1f68);
        WRITE_MPEG_REG(VDIN_MATRIX_COEF11_12, (0x1ed6 << 16) |
                                 0x1c2);
        WRITE_MPEG_REG(VDIN_MATRIX_COEF20_21, (0x1c2 << 16) | 
                             0x1e87);
        WRITE_MPEG_REG(VDIN_MATRIX_COEF22, 0x1fb7);
        WRITE_MPEG_REG(VDIN_MATRIX_OFFSET0_1, (0x40 << 16) | 0x0200);
        WRITE_MPEG_REG(VDIN_MATRIX_OFFSET2, 0x0200);
   } 
   else if (mode == 1) //ycbcr full range, 601 conversion
   {
   }

}
void audio_set_958outbuf(u32 addr, u32 size,int flag)
{
    if (ENABLE_IEC958) {
        WRITE_MPEG_REG(AIU_MEM_IEC958_START_PTR, addr & 0xffffffc0);
        WRITE_MPEG_REG(AIU_MEM_IEC958_RD_PTR, addr & 0xffffffc0);
        if(flag == 0){
          WRITE_MPEG_REG(AIU_MEM_IEC958_END_PTR, (addr & 0xffffffc0) + (size & 0xffffffc0) - 64);    // this is for 16bit 2 channel
        }else{
          WRITE_MPEG_REG(AIU_MEM_IEC958_END_PTR, (addr & 0xffffffc0) + (size & 0xffffffc0) - 1);    // this is for RAW mode
        }

        WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 0, 1);
        WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 0, 1);

        WRITE_MPEG_REG(AIU_MEM_IEC958_BUF_CNTL, 1 | (0 << 1));
        WRITE_MPEG_REG(AIU_MEM_IEC958_BUF_CNTL, 0 | (0 << 1));
    }
}
static vmode_t nulldisp_validate_vmode(char *mode)
{
    const vinfo_t *info = get_valid_vinfo(mode);
    int viu1_select = READ_MPEG_REG(VPU_VIU_VENC_MUX_CTRL)&0x3;
    
    WRITE_MPEG_REG_BITS (VPU_VIU_VENC_MUX_CTRL, (viu1_select+1)&0x3, 2, 2); //viu2_select should be different from viu1_select (to fix viu1 video smooth problem)

    if (info)
        return info->mode;

    return VMODE_MAX;
}
Exemplo n.º 17
0
void aml_spdif_play(void)
{
	_aiu_958_raw_setting_t set;
	_aiu_958_channel_status_t chstat;
	struct snd_pcm_substream substream;
	struct snd_pcm_runtime runtime;
	substream.runtime = &runtime;
	
runtime.rate = 48000;
	runtime.format = SNDRV_PCM_FORMAT_S16_LE;
	runtime.channels = 2;
	runtime.sample_bits = 16;
	memset((void *)(&set), 0, sizeof(set));
	memset((void *)(&chstat), 0, sizeof(chstat));
	set.chan_stat = &chstat;
	set.chan_stat->chstat0_l = 0x0100;
	set.chan_stat->chstat0_r = 0x0100;
	set.chan_stat->chstat1_l = 0X200;
	set.chan_stat->chstat1_r = 0X200;
	audio_hw_958_enable(0);
	if (last_iec_clock != AUDIO_CLK_FREQ_48) {
		ALSA_PRINT("enterd %s,set_clock:%d,sample_rate=%d\n", __func__,
			   last_iec_clock, AUDIO_CLK_FREQ_48);
		
last_iec_clock = AUDIO_CLK_FREQ_48;
		audio_set_958_clk(AUDIO_CLK_FREQ_48, AUDIO_CLK_256FS);
	
}
	audio_util_set_dac_958_format(AUDIO_ALGOUT_DAC_FORMAT_DSP);
	memset(iec958buf, 0, sizeof(iec958buf));
	audio_set_958outbuf((virt_to_phys(iec958buf) + 63) & (~63), 128, 2, 0);
	audio_set_958_mode(AIU_958_MODE_PCM16, &set);
#if OVERCLOCK == 1 || IEC958_OVERCLOCK == 1
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 3, 4, 2);	/* 512fs divide 4 == 128fs */
#else
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 1, 4, 2);	/* 256fs divide 2 == 128fs */
#endif
	aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM, &substream);
Exemplo n.º 18
0
void audio_in_i2s_enable(int flag)
{
  int rd = 0, start=0;
		if(flag){
          /* reset only when start i2s input */
reset_again:
		    WRITE_MPEG_REG_BITS(AUDIN_FIFO0_CTRL, 1, 1, 1); // reset FIFO 0
            WRITE_MPEG_REG(AUDIN_FIFO0_PTR, 0);
            rd = READ_MPEG_REG(AUDIN_FIFO0_PTR);
            start = READ_MPEG_REG(AUDIN_FIFO0_START);
            if(rd != start){
              printk("error %08x, %08x !!!!!!!!!!!!!!!!!!!!!!!!\n", rd, start);
              goto reset_again;
            }

        	WRITE_MPEG_REG_BITS(AUDIN_I2SIN_CTRL, 1, I2SIN_EN, 1);
		}else{
				WRITE_MPEG_REG_BITS(AUDIN_I2SIN_CTRL, 0, I2SIN_EN, 1);
		}
        in_error_flag = 0;
        in_error = 0;
        audio_in_enabled(flag);
}
Exemplo n.º 19
0
void esparser_start_search(u32 parser_type, u32 phys_addr, u32 len)
{
        wmb();
        // reset the Write and read pointer to zero again
        WRITE_MPEG_REG(PFIFO_RD_PTR, 0);
        WRITE_MPEG_REG(PFIFO_WR_PTR, 0);

        WRITE_MPEG_REG_BITS(PARSER_CONTROL, len, ES_PACK_SIZE_BIT, ES_PACK_SIZE_WID);
        WRITE_MPEG_REG_BITS(PARSER_CONTROL,
                            parser_type | PARSER_WRITE | PARSER_AUTOSEARCH,
                            ES_CTRL_BIT, ES_CTRL_WID);

        WRITE_MPEG_REG(PARSER_FETCH_ADDR, phys_addr);
        WRITE_MPEG_REG(PARSER_FETCH_CMD,
                       (7 << FETCH_ENDIAN) | len);

        search_done = 0;

        WRITE_MPEG_REG(PARSER_FETCH_ADDR, search_pattern_map);

        WRITE_MPEG_REG(PARSER_FETCH_CMD,
                       (7 << FETCH_ENDIAN) | SEARCH_PATTERN_LEN);
}
Exemplo n.º 20
0
static int sii5293_tvin_open(tvin_frontend_t *fe, enum tvin_port_e port)
{
	sii5293_vdin *devp = container_of(fe,sii5293_vdin,tvin_frontend);

	/*copy the vdin_parm_s to local device parameter*/
	if( !memcpy(&devp->vdin_parm,fe->private_data,sizeof(vdin_parm_t)) )
	{
		printk("[%s] copy vdin parm error.\n",__func__);
	}

	enable_vdin_pinmux();

	WRITE_MPEG_REG_BITS(VDIN_ASFIFO_CTRL2, 0x39, 2, 6); 

	return 0;
}
Exemplo n.º 21
0
void audio_in_spdif_enable(int flag)
{
  int rd = 0, start=0;

	if(flag){
reset_again:
	     WRITE_MPEG_REG_BITS(AUDIN_FIFO1_CTRL, 1, 1, 1); // reset FIFO 0
            WRITE_MPEG_REG(AUDIN_FIFO1_PTR, 0);
            rd = READ_MPEG_REG(AUDIN_FIFO1_PTR);
            start = READ_MPEG_REG(AUDIN_FIFO1_START);
            if(rd != start){
              printk("error %08x, %08x !!!!!!!!!!!!!!!!!!!!!!!!\n", rd, start);
              goto reset_again;
            }
		WRITE_MPEG_REG(AUDIN_SPDIF_MODE, READ_MPEG_REG(AUDIN_SPDIF_MODE)| (1<<31));		
	}else{
		WRITE_MPEG_REG(AUDIN_SPDIF_MODE, READ_MPEG_REG(AUDIN_SPDIF_MODE)& ~(1<<31));				
	}
}
Exemplo n.º 22
0
void audio_set_i2s_mode(u32 mode)
{
    const unsigned short mask[4] = {
        0x303,                  /* 2x16 */
        0x303,                  /* 2x24 */
        0x303,                 /* 8x24 */
        0x303,                  /* 2x32 */
    };

    if (mode < sizeof(mask)/ sizeof(unsigned short)) {
       /* four two channels stream */
        WRITE_MPEG_REG(AIU_I2S_SOURCE_DESC, 1);

        if (mode == AIU_I2S_MODE_PCM16) {
            WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 1, 6, 1);
            WRITE_MPEG_REG_BITS(AIU_I2S_SOURCE_DESC, 0, 5, 1);
        } else if(mode == AIU_I2S_MODE_PCM32){
            WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 0, 6, 1);
            WRITE_MPEG_REG_BITS(AIU_I2S_SOURCE_DESC, 1, 5, 1);
        }else if(mode == AIU_I2S_MODE_PCM24){
            WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 0, 6, 1);
            WRITE_MPEG_REG_BITS(AIU_I2S_SOURCE_DESC, 1, 5, 1);
        }

        WRITE_MPEG_REG_BITS(AIU_MEM_I2S_MASKS, mask[mode], 0, 16);

        //WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 1, 0, 1);
        //WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 0, 0, 1);

        if (ENABLE_IEC958) {
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_MASKS, mask[mode], 0,
                                16);
            //WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 0, 1);
            //WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 0, 1);
        }
    }

}
Exemplo n.º 23
0
void audio_util_set_dac_i2s_format(unsigned format)
{	
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL,1,6,1);//invert aoclk
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL,1,7,1);//invert lrclk
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL,1,8,2);// alrclk skew: 1=alrclk transitions on the cycle before msb is sent
#if OVERCLOCK == 1
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL,3,2,2);// i2s divisor: 0=no div; 1=div by 2; 2=div by 4; 3=div by 8.
#else
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL,2,2,2); // i2s divisor: 0=no div; 1=div by 2; 2=div by 4; 3=div by 8.
#endif
	WRITE_MPEG_REG_BITS(AIU_CLK_CTRL,1,0,1);// enable I2S clock
	
    if (format == AUDIO_ALGOUT_DAC_FORMAT_DSP) {
        WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 1, 8, 2);
    } else if (format == AUDIO_ALGOUT_DAC_FORMAT_LEFT_JUSTIFY) {
        WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 0, 8, 2);
    }
 	if(dac_mute_const == 0x800000)
    	WRITE_MPEG_REG(AIU_I2S_DAC_CFG, 	0x000f);	// Payload 24-bit, Msb first, alrclk = aoclk/64.mute const 0x800000
    else
    	WRITE_MPEG_REG(AIU_I2S_DAC_CFG, 	0x0007);	// Payload 24-bit, Msb first, alrclk = aoclk/64
	WRITE_MPEG_REG(AIU_I2S_SOURCE_DESC, 0x0001);	// four 2-channel	
}
Exemplo n.º 24
0
void audio_hw_958_raw()
{
    if (ENABLE_IEC958) {
         WRITE_MPEG_REG(AIU_958_MISC, 1);
         WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 8, 1);  // raw
         WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 7, 1);  // 8bit 
         WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 3, 3); // endian
    }

    WRITE_MPEG_REG(AIU_958_BPF, IEC958_bpf);
    WRITE_MPEG_REG(AIU_958_BRST, IEC958_brst);
    WRITE_MPEG_REG(AIU_958_LENGTH, IEC958_length);
    WRITE_MPEG_REG(AIU_958_PADDSIZE, IEC958_padsize);
    WRITE_MPEG_REG_BITS(AIU_958_DCU_FF_CTRL, 0, 2, 2);// disable int
    
    if(IEC958_mode == 1){ // search in byte
      WRITE_MPEG_REG_BITS(AIU_958_DCU_FF_CTRL, 7, 4, 3);
    }else if(IEC958_mode == 2) { // search in word
      WRITE_MPEG_REG_BITS(AIU_958_DCU_FF_CTRL, 5, 4, 3);
    }else{
      WRITE_MPEG_REG_BITS(AIU_958_DCU_FF_CTRL, 0, 4, 3);
    }
    WRITE_MPEG_REG(AIU_958_CHSTAT_L0, IEC958_chstat0_l);
    WRITE_MPEG_REG(AIU_958_CHSTAT_L1, IEC958_chstat1_l);
    WRITE_MPEG_REG(AIU_958_CHSTAT_R0, IEC958_chstat0_r);
    WRITE_MPEG_REG(AIU_958_CHSTAT_R1, IEC958_chstat1_r);

    WRITE_MPEG_REG(AIU_958_SYNWORD1, IEC958_syncword1);
    WRITE_MPEG_REG(AIU_958_SYNWORD2, IEC958_syncword2);
    WRITE_MPEG_REG(AIU_958_SYNWORD3, IEC958_syncword3);
    WRITE_MPEG_REG(AIU_958_SYNWORD1_MASK, IEC958_syncword1_mask);
    WRITE_MPEG_REG(AIU_958_SYNWORD2_MASK, IEC958_syncword2_mask);
    WRITE_MPEG_REG(AIU_958_SYNWORD3_MASK, IEC958_syncword3_mask);

    //printk("%s: %d\n", __func__, __LINE__);
    //printk("\tBPF: %x\n", IEC958_bpf);
    //printk("\tBRST: %x\n", IEC958_brst);
    //printk("\tLENGTH: %x\n", IEC958_length);
    //printk("\tPADDSIZE: %x\n", IEC958_length);
    //printk("\tsyncword: %x, %x, %x\n\n", IEC958_syncword1, IEC958_syncword2, IEC958_syncword3);
    
}
Exemplo n.º 25
0
};

EXPORT_SYMBOL_GPL(aml_i2s_dai);

static const struct snd_soc_component_driver aml_component = { 
.name =
	    "aml-i2s-dai",
};

static int aml_i2s_dai_probe(struct platform_device *pdev)
{
	struct aml_i2s *i2s = NULL;
	int ret = 0;
	printk(KERN_DEBUG "enter %s\n", __func__);

	i2s = kzalloc(sizeof(struct aml_i2s), GFP_KERNEL);
	if (!i2s) {
		dev_err(&pdev->dev, "Can't allocate aml_i2s\n");
		ret = -ENOMEM;
		goto exit;
	}
	dev_set_drvdata(&pdev->dev, i2s);

	if (of_property_read_u32(pdev->dev.of_node, "clk_src_mpll", &i2s->mpll)) {
		printk(KERN_INFO
		       "i2s get no clk src setting in dts, use the default mpll 0\n");
		i2s->mpll = 0;
	}
	/* enable i2s MPLL and power gate first */
	WRITE_MPEG_REG_BITS(MPLL_I2S_CNTL, 1, 14, 1);
	audio_aiu_pg_enable(1);
	/* enable the mclk because m8 codec need it to setup */
	if (i2s->old_samplerate != 48000) {
		ALSA_PRINT("enterd %s,old_samplerate:%d,sample_rate=%d\n",
			   __func__, i2s->old_samplerate, 48000);
		
Exemplo n.º 26
0
void audio_set_958_mode(unsigned mode, _aiu_958_raw_setting_t * set)
{
    if(mode == AIU_958_MODE_PCM_RAW)
    	mode = AIU_958_MODE_PCM16; //use 958 raw pcm mode
    if (mode == AIU_958_MODE_RAW) {
        
        audio_hw_958_raw();
        if (ENABLE_IEC958) {
            WRITE_MPEG_REG(AIU_958_MISC, 1);
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 8, 1);  // raw
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 7, 1);  // 8bit 
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 3, 3); // endian
        }
        
        //printk("IEC958 RAW\n");
    }else if(mode == AIU_958_MODE_PCM32){
        audio_hw_set_958_pcm24(set);
        if(ENABLE_IEC958){
            WRITE_MPEG_REG(AIU_958_MISC, 0x2020 | (1 << 7));
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 8, 1);  // pcm
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 7, 1);  // 16bit
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 3, 3); // endian
        }
        //printk("IEC958 PCM32 \n");
    }else if (mode == AIU_958_MODE_PCM24) {
        audio_hw_set_958_pcm24(set);
        if (ENABLE_IEC958) {
            WRITE_MPEG_REG(AIU_958_MISC, 0x2020 | (1 << 7));
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 8, 1);  // pcm
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 7, 1);  // 16bit
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 3, 3); // endian

        }
        //printk("IEC958 24bit\n");
    } else if (mode == AIU_958_MODE_PCM16) {
        audio_hw_set_958_pcm24(set);
        if (ENABLE_IEC958) {
            WRITE_MPEG_REG(AIU_958_MISC, 0x2042);
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 8, 1);  // pcm
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 7, 1);  // 16bit
            WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 3, 3); // endian

        }
        //printk("IEC958 16bit\n");
    }

    audio_hw_958_reset(0, 1);

    WRITE_MPEG_REG(AIU_958_FORCE_LEFT, 1);
}
Exemplo n.º 27
0
void audio_i2s_mute(void)
{
    WRITE_MPEG_REG_BITS(AIU_I2S_MUTE_SWAP, 0xff, 8, 8);
    WRITE_MPEG_REG_BITS(AIU_958_CTRL, 3, 3, 2);
}
Exemplo n.º 28
0
void audio_set_clk(unsigned freq, unsigned fs_config)
{
    int i;
    struct clk *clk;
    int xtal = 0;
    
    int (*audio_clock_config)[2];
    
   // if (fs_config == AUDIO_CLK_256FS) {
   if(1){
		int index=0;
		switch(freq)
		{
			case AUDIO_CLK_FREQ_192:
				index=4;
				break;
			case AUDIO_CLK_FREQ_96:
				index=3;
				break;
			case AUDIO_CLK_FREQ_48:
				index=2;
				break;
			case AUDIO_CLK_FREQ_441:
				index=1;
				break;
			case AUDIO_CLK_FREQ_32:
				index=0;
				break;
			case AUDIO_CLK_FREQ_8:
				index = 5;
				break;
			case AUDIO_CLK_FREQ_11:
				index = 6;
				break;
			case AUDIO_CLK_FREQ_12:
				index = 7;
				break;
			case AUDIO_CLK_FREQ_16:
				index = 8;
				break;
			case AUDIO_CLK_FREQ_22:
				index = 9;
				break;
			case AUDIO_CLK_FREQ_24:
				index = 10;
				break;
			default:
				index=0;
				break;
		};
	// get system crystal freq
		clk=clk_get_sys("clk_xtal", NULL);
		if(!clk)
		{
			printk(KERN_ERR "can't find clk %s for AUDIO PLL SETTING!\n\n","clk_xtal");
			//return -1;
		}
		else
		{
			xtal=clk_get_rate(clk);
			xtal=xtal/1000000;
			if(xtal>=24 && xtal <=25)/*current only support 24,25*/
			{
				xtal-=24;
			}
			else
			{
				printk(KERN_WARNING "UNsupport xtal setting for audio xtal=%d,default to 24M\n",xtal);	
				xtal=0;
			}
		}
		
		audio_clock_config = audio_clock_config_table[xtal];		
	
#ifdef CONFIG_SND_AML_M3
	if (((clk_get_rate(clk)==24000000)&&(get_ddr_pll_clk()==516000000)&&(index=2))) // 48k
	{
		WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 8)); // audio clock off
		WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) | (1 << 15)); // audio pll off
		WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 4, 9, 3); // select ddr
		WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 42-1, 0, 8); // 516/42
		WRITE_MPEG_REG_BITS(AIU_CODEC_ADC_LRCLK_CTRL, 64-1, 0, 12);//set codec adc ratio---lrclk
		WRITE_MPEG_REG_BITS(AIU_CODEC_DAC_LRCLK_CTRL, 64-1, 0, 12);//set codec dac ratio---lrclk
		WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1<<23));// gate audac_clkpi
		WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1 << 8));
		printk(KERN_INFO "audio 48k clock from ddr pll %dM\n", 516);
		return;
	}
	else if (((clk_get_rate(clk)==24000000)&&(get_ddr_pll_clk()==508000000)&&(index=1))) // 44.1k
	{
		WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 8)); // audio clock off
		WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) | (1 << 15)); // audio pll off
		WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 4, 9, 3); // select ddr
		WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 45-1, 0, 8); // 508/45
		WRITE_MPEG_REG_BITS(AIU_CODEC_ADC_LRCLK_CTRL, 64-1, 0, 12);//set codec adc ratio---lrclk
		WRITE_MPEG_REG_BITS(AIU_CODEC_DAC_LRCLK_CTRL, 64-1, 0, 12);//set codec dac ratio---lrclk
		WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1<<23));// gate audac_clkpi
		WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1 << 8));
		printk(KERN_INFO "audio 44.1k clock from ddr pll %dM\n", 508);
		return;
	}
	else if (((clk_get_rate(clk)==24000000)&&(get_ddr_pll_clk()==486000000)&&(index=1))) // 44.1k
	{
		WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 8)); // audio clock off
		WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) | (1 << 15)); // audio pll off
		WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 4, 9, 3); // select ddr
		WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 43-1, 0, 8); // 486/42
		WRITE_MPEG_REG_BITS(AIU_CODEC_ADC_LRCLK_CTRL, 64-1, 0, 12);//set codec adc ratio---lrclk
		WRITE_MPEG_REG_BITS(AIU_CODEC_DAC_LRCLK_CTRL, 64-1, 0, 12);//set codec dac ratio---lrclk
		WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1<<23));// gate audac_clkpi
		WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1 << 8));
		printk(KERN_INFO "audio 44.1k clock from ddr pll %dM\n", 486);
		return;
	}
	else if (((clk_get_rate(clk)==24000000)&&(get_ddr_pll_clk()==474000000)&&(index=1))) // 44.1k
	{
		WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 8)); // audio clock off
		WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) | (1 << 15)); // audio pll off
		WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 4, 9, 3); // select ddr
		WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 42-1, 0, 8); // 474/42
		WRITE_MPEG_REG_BITS(AIU_CODEC_ADC_LRCLK_CTRL, 64-1, 0, 12);//set codec adc ratio---lrclk
		WRITE_MPEG_REG_BITS(AIU_CODEC_DAC_LRCLK_CTRL, 64-1, 0, 12);//set codec dac ratio---lrclk
		WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1<<23));// gate audac_clkpi
		WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1 << 8));
		printk(KERN_INFO "audio 44.1k clock from ddr pll %dM\n", 474);
		return;
	}
#endif		

    // gate the clock off
    WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 8));

//#ifdef CONFIG_SND_AML_M3
#ifdef CONFIG_ARCH_MESON3
    WRITE_MPEG_REG(HHI_AUD_PLL_CNTL2, 0x065e31ff);
    WRITE_MPEG_REG(HHI_AUD_PLL_CNTL3, 0x9649a941);
		// select Audio PLL as MCLK source
		//WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 9));
		WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 0, 9, 3);    
		//WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 25-1, 0, 8); 
		
		WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 13-1, 0, 8); 
#endif		
    // Put the PLL to sleep
    WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) | (1 << 15));//found

//#ifdef CONFIG_SND_AML_M3
#ifdef CONFIG_ARCH_MESON3
		WRITE_MPEG_REG_BITS(AIU_CODEC_ADC_LRCLK_CTRL, 64-1, 0, 12);//set codec adc ratio---lrclk
		WRITE_MPEG_REG_BITS(AIU_CODEC_DAC_LRCLK_CTRL, 64-1, 0, 12);//set codec dac ratio---lrclk
#endif		
    // Bring out of reset but keep bypassed to allow to stablize
    //Wr( HHI_AUD_PLL_CNTL, (1 << 15) | (0 << 14) | (hiu_reg & 0x3FFF) );
    WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, (1 << 15) | (audio_clock_config[index][0] & 0x7FFF) );//found
    // Set the XD value
    WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, (READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(0xff << 0)) | audio_clock_config[index][1]);//found
    // delay 5uS
	//udelay(5);
	for (i = 0; i < 500000; i++) ;
    // Bring the PLL out of sleep
    WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) & ~(1 << 15));//found
    
    // gate the clock on
    WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1 << 8));//found
#if ((defined CONFIG_SND_AML_M1) || (defined CONFIG_SND_AML_M2)||(defined CONFIG_SND_AML_M3))
		WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) |(1<<23));// gate audac_clkpi
#endif    
    // delay 2uS
	//udelay(2);
	for (i = 0; i < 200000; i++) ;

    } else if (fs_config == AUDIO_CLK_384FS) {
    }
}
Exemplo n.º 29
0
void audio_i2s_swap_left_right(unsigned int flag)
{
	WRITE_MPEG_REG_BITS(AIU_I2S_MUTE_SWAP, flag, 0, 2);
}
Exemplo n.º 30
0
1)NONE-PCM  raw output ,only available when ac3/dts audio,when raw output mode is selected by user.
2)PCM  output for  all audio, when pcm mode is selected by user .
3)PCM  output for audios except ac3/dts,when raw output mode is selected by user
*/
void aml_hw_iec958_init(struct snd_pcm_substream *substream)
{
	_aiu_958_raw_setting_t set;
	_aiu_958_channel_status_t chstat;
	unsigned i2s_mode, iec958_mode;
	unsigned start, size;
	int sample_rate;
	struct snd_dma_buffer *buf = &substream->dma_buffer;
	struct snd_pcm_runtime *runtime = substream->runtime;
	if (buf == NULL && runtime == NULL) {
		
printk("buf/0x%x runtime/0x%x\n", (unsigned)buf,
			(unsigned)runtime);
		
return;
	}

	i2s_mode = AIU_I2S_MODE_PCM16;
	sample_rate = AUDIO_CLK_FREQ_48;
	memset((void *)(&set), 0, sizeof(set));
	memset((void *)(&chstat), 0, sizeof(chstat));
	set.chan_stat = &chstat;
	printk("----aml_hw_iec958_init,runtime->rate=%d--\n", runtime->rate);
	
switch (runtime->rate) {
	case 192000:
		sample_rate = AUDIO_CLK_FREQ_192;
		break;
	case 176400:
		sample_rate = AUDIO_CLK_FREQ_1764;
		break;
	case 96000:
		sample_rate = AUDIO_CLK_FREQ_96;
		break;
	case 88200:
		sample_rate = AUDIO_CLK_FREQ_882;
		break;
	case 48000:
		sample_rate = AUDIO_CLK_FREQ_48;
		break;
	case 44100:
		sample_rate = AUDIO_CLK_FREQ_441;
		break;
	case 32000:
		sample_rate = AUDIO_CLK_FREQ_32;
		break;
	case 8000:
		sample_rate = AUDIO_CLK_FREQ_8;
		break;
	case 11025:
		sample_rate = AUDIO_CLK_FREQ_11;
		break;
	case 16000:
		sample_rate = AUDIO_CLK_FREQ_16;
		break;
	case 22050:
		sample_rate = AUDIO_CLK_FREQ_22;
		break;
	case 12000:
		sample_rate = AUDIO_CLK_FREQ_12;
		break;
	case 24000:
		sample_rate = AUDIO_CLK_FREQ_22;
		break;
	default:
		sample_rate = AUDIO_CLK_FREQ_441;
		break;
	};
	audio_hw_958_enable(0);
	if (last_iec_clock != sample_rate) {
		ALSA_PRINT("enterd %s,set_clock:%d,sample_rate=%d\n", __func__,
			   last_iec_clock, sample_rate);
		
last_iec_clock = sample_rate;
		audio_set_958_clk(sample_rate, AUDIO_CLK_256FS);
	}
	printk("----aml_hw_iec958_init,runtime->rate=%d,sample_rate=%d--\n",
	       runtime->rate, sample_rate);
	audio_util_set_dac_958_format(AUDIO_ALGOUT_DAC_FORMAT_DSP);
	/*clear the same source function as new raw data output */
	WRITE_MPEG_REG_BITS(AIU_I2S_MISC, 0, 3, 1);
	switch (runtime->format) {
	case SNDRV_PCM_FORMAT_S32_LE:
		i2s_mode = AIU_I2S_MODE_PCM32;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		i2s_mode = AIU_I2S_MODE_PCM24;
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		i2s_mode = AIU_I2S_MODE_PCM16;
		break;
	}

	/* audio_set_i2s_mode(i2s_mode); */
	/* case 1,raw mode enabled */
	if (IEC958_mode_codec) {
		if (IEC958_mode_codec == 1) {	/* dts, use raw sync-word mode */
			iec958_mode = AIU_958_MODE_RAW;
			printk("iec958 mode RAW\n");
		} else {	/* ac3,use the same pcm mode as i2s configuration */
			iec958_mode = AIU_958_MODE_PCM_RAW;
			printk("iec958 mode %s\n",
			       (i2s_mode ==
				AIU_I2S_MODE_PCM32) ? "PCM32_RAW" : ((I2S_MODE
								      ==
								      AIU_I2S_MODE_PCM24)
								     ?
								     "PCM24_RAW"
								     :
								     "PCM16_RAW"));
		
}
	} else {
		if (i2s_mode == AIU_I2S_MODE_PCM32)
			iec958_mode = AIU_958_MODE_PCM32;
		else if (i2s_mode == AIU_I2S_MODE_PCM24)
			iec958_mode = AIU_958_MODE_PCM24;
		else
			iec958_mode = AIU_958_MODE_PCM16;
		printk("iec958 mode %s\n",
		       (i2s_mode ==
			AIU_I2S_MODE_PCM32) ? "PCM32" : ((i2s_mode ==
							  AIU_I2S_MODE_PCM24) ?
							 "PCM24" : "PCM16"));
	
}
	if (iec958_mode == AIU_958_MODE_PCM16
	    || iec958_mode == AIU_958_MODE_PCM24
	    || iec958_mode == AIU_958_MODE_PCM32) {
		set.chan_stat->chstat0_l = 0x0100;
		set.chan_stat->chstat0_r = 0x0100;
		set.chan_stat->chstat1_l = 0x200;
		set.chan_stat->chstat1_r = 0x200;
		if (sample_rate == AUDIO_CLK_FREQ_882) {
			
printk("----sample_rate==AUDIO_CLK_FREQ_882---\n");
			set.chan_stat->chstat1_l = 0x800;
			set.chan_stat->chstat1_r = 0x800;
		}

		if (sample_rate == AUDIO_CLK_FREQ_96) {
			
printk("----sample_rate==AUDIO_CLK_FREQ_96---\n");
			set.chan_stat->chstat1_l = 0xa00;
			set.chan_stat->chstat1_r = 0xa00;
		}
		start = buf->addr;
		size = snd_pcm_lib_buffer_bytes(substream);
		audio_set_958outbuf(start, size, runtime->channels, 0);
		/* audio_set_i2s_mode(AIU_I2S_MODE_PCM16); */
		/* audio_set_aiubuf(start, size); */
	} else {

		set.chan_stat->chstat0_l = 0x1902;
		set.chan_stat->chstat0_r = 0x1902;
		if (IEC958_mode_codec == 4 || IEC958_mode_codec == 5) {	/* DD+ */
			if (runtime->rate == 32000) {
				set.chan_stat->chstat1_l = 0x300;
				set.chan_stat->chstat1_r = 0x300;
			} else if (runtime->rate == 44100) {
				set.chan_stat->chstat1_l = 0xc00;
				set.chan_stat->chstat1_r = 0xc00;
			} else {
				set.chan_stat->chstat1_l = 0Xe00;
				set.chan_stat->chstat1_r = 0Xe00;
			}
		} else {	/* DTS,DD */
			if (runtime->rate == 32000) {
				set.chan_stat->chstat1_l = 0x300;
				set.chan_stat->chstat1_r = 0x300;
			} else if (runtime->rate == 44100) {
				set.chan_stat->chstat1_l = 0;
				set.chan_stat->chstat1_r = 0;
			} else {
				set.chan_stat->chstat1_l = 0x200;
				set.chan_stat->chstat1_r = 0x200;
			}
		}
		start = buf->addr;
		size = snd_pcm_lib_buffer_bytes(substream);
		audio_set_958outbuf(start, size, runtime->channels,
				    (iec958_mode == AIU_958_MODE_RAW) ? 1 : 0);
		memset((void *)buf->area, 0, size);
	
}
	ALSA_DEBUG("aiu 958 pcm buffer size %d \n", size);
	audio_set_958_mode(iec958_mode, &set);
	if (IEC958_mode_codec == 4 || IEC958_mode_codec == 5
	    || IEC958_mode_codec == 7 || IEC958_mode_codec == 8) {
		WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 0, 4, 2);	/* 4x than i2s */
		printk("IEC958_mode_codec/%d  4x than i2s\n",
		       IEC958_mode_codec);
	} else {
#if OVERCLOCK == 1 || IEC958_OVERCLOCK == 1
		WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 3, 4, 2);	/* 512fs divide 4 == 128fs */
#else
		WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 1, 4, 2);	/* 256fs divide 2 == 128fs */
#endif
	}
	if (IEC958_mode_codec == 2) {
		aout_notifier_call_chain(AOUT_EVENT_RAWDATA_AC_3, substream);
	
} else if (IEC958_mode_codec == 3) {
		aout_notifier_call_chain(AOUT_EVENT_RAWDATA_DTS, substream);
	
} else if (IEC958_mode_codec == 4) {
		aout_notifier_call_chain(AOUT_EVENT_RAWDATA_DOBLY_DIGITAL_PLUS,