Esempio n. 1
0
static void rk610_delayedwork_fun(struct work_struct *work)
{
    struct snd_soc_codec *codec = rk610_codec_codec;
	DBG("--------%s----------\n",__FUNCTION__);

	spk_ctrl_fun(GPIO_HIGH);
	#if OUT_CAPLESS
	rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
	#else
	rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
	#endif
}
static int rk610_codec_mute(struct snd_soc_dai *dai, int mute)
{
    struct snd_soc_codec *codec = dai->codec;
	struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
    printk("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute);

    if (mute)
	{
		rk610_codec_write(codec,ACCELCODEC_R17, 0xFF);  //AOL
		rk610_codec_write(codec,ACCELCODEC_R18, 0xFF);  //AOR
        rk610_codec_write(codec,ACCELCODEC_R19, 0xFF);  //AOM
        rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);  //soft mute
	//add for standby
	//	if(!dai->capture_active)
	//	{
	//		rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE);
	//		rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
	//		rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
	//	}
    }
	else
	{
	//	rk610_codec_write(codec,ACCELCODEC_R1D, 0x2a);  //setup Vmid and Vref, other module power down
	//	rk610_codec_write(codec,ACCELCODEC_R1E, 0x40);  ///|ASC_PDASDML_ENABLE);
		rk610_codec_write(codec,ACCELCODEC_R17, Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN);  //AOL Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN);  //AOL
		rk610_codec_write(codec,ACCELCODEC_R18, Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //Volume_Codec_PA|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN);  //AOR
        rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_ACTIVE_L|ASC_INT_ACTIVE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);
		rk610_codec_write(codec,ACCELCODEC_R19, 0x7F);  //AOM

		if(rk610_codec->pa_enable_time == 0)
			msleep(300);
		#if OUT_CAPLESS
    	rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
    	#else
    	rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
		#endif
	//	schedule_delayed_work(&rk610_codec->rk610_delayed_work, 0);
	//	rk610_codec_reg_read();
		if(rk610_codec->hdmi_ndet){
			if(rk610_codec->pa_enable_time == 0 )
				spk_ctrl_fun(GPIO_HIGH);
			else if(rk610_codec->pa_enable_time > 0 && rk610_codec->pa_enable_time < 300){
				spk_ctrl_fun(GPIO_HIGH);
				msleep(rk610_codec->pa_enable_time)	;
			}
			else if(rk610_codec->pa_enable_time >=300 && rk610_codec->pa_enable_time < 1000)
				msleep(rk610_codec->pa_enable_time);
		}
    }

    return 0;
}
static int rk610_codec_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params,
				struct snd_soc_dai *dai)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_codec *codec = rtd->codec;
	struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
	unsigned int dai_fmt = rtd->card->dai_link[0].dai_fmt;

	u16 iface = rk610_codec_read_reg_cache(codec, ACCELCODEC_R09) & 0x1f3;
	u16 srate = rk610_codec_read_reg_cache(codec, ACCELCODEC_R00) & 0x180;
	int coeff;

	coeff = get_coeff(rk610_codec->sysclk, params_rate(params));
	DBG("Enter::%s----%d  rk610_codec->sysclk=%d coeff = %d\n",__FUNCTION__,__LINE__,rk610_codec->sysclk, coeff);
	/* bit size */
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		break;
	case SNDRV_PCM_FORMAT_S20_3LE:
		iface |= 0x0004;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		iface |= 0x0008;
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		iface |= 0x000c;
		break;
	}
	DBG("Enter::%s----%d  iface=%x srate =%x rate=%d\n",__FUNCTION__,__LINE__,iface,srate,params_rate(params));

//	rk610_codec_write(codec,ACCELCODEC_R0C, 0x17);
	rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);   //soft mute
	//必须先将clk和EN_INT都disable掉,否则切换bclk分频值可能导致codec内部时序混乱掉,
	//表现出来的现象是,以后的音乐都变成了噪音,而且就算把输入codec的I2S_DATAOUT断开也一样出噪音
	rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_DISABLE);  //0x00

	/* set iface & srate */
	if ((dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
		iface |= ASC_INVERT_BCLK;//翻转BCLK  master状态送出的少了半个时钟,导致未到最大音量的时候破音、

	rk610_codec_write(codec, ACCELCODEC_R09, iface);
	if (coeff >= 0){
	//    rk610_codec_write(codec, ACCELCODEC_R00, srate|coeff_div[coeff].bclk);
		rk610_codec_write(codec, ACCELCODEC_R0A, (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb|ASC_CLKNODIV|ASC_CLK_ENABLE);
	}
	rk610_codec_write(codec,ACCELCODEC_R0B, gR0BReg);

	return 0;
}
Esempio n. 4
0
static void rk610_delayedwork_fun(struct work_struct *work)
{
    struct snd_soc_codec *codec = rk610_codec_codec;
	struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);	
	struct rk610_codec_platform_data *pdata= rk610_codec->pdata;	
	DBG("--------%s----------\n",__FUNCTION__);
	if(!pdata->boot_depop){
		#if OUT_CAPLESS
		rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
		#else
		rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
		#endif
	}
	spk_ctrl_fun(GPIO_HIGH);
}
Esempio n. 5
0
static int rk610_codec_set_bias_level(struct snd_soc_codec *codec,
				 enum snd_soc_bias_level level)
{
	struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
	DBG("Enter::%s----%d now_level =%d  old_level = %d\n",__FUNCTION__,__LINE__,level,codec->dapm.bias_level);
	switch (level) {
	case SND_SOC_BIAS_ON:
		break;
	case SND_SOC_BIAS_PREPARE:
		/* VREF, VMID=2x50k, digital enabled */
	//	rk610_codec_write(codec, ACCELCODEC_R1D, pwr_reg | 0x0080);
		break;

	case SND_SOC_BIAS_STANDBY:
#if RESUME_PROBLEM	
		if(rk610_codec->rk610_workstatus == SND_SOC_DAPM_STREAM_RESUME)
		{
			DBG("rk610 is resume,have not into standby\n");
			rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_NOP;
			break;
		}
#endif
		printk("rk610 standby\n");
		spk_ctrl_fun(GPIO_LOW);
		rk610_codec_write(codec,ACCELCODEC_R0A, ASC_CLK_DISABLE);
		rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE);
		rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
		rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
		break;

	case SND_SOC_BIAS_OFF:
		printk("rk610 power off\n");
		spk_ctrl_fun(GPIO_LOW);
		rk610_codec_write(codec,ACCELCODEC_R0A, ASC_CLK_DISABLE);		
		rk610_codec_write(codec, ACCELCODEC_R1D, 0xFF);
		rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
		rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
		break;
	}

	codec->dapm.bias_level = level;

	return 0;
}
Esempio n. 6
0
static ssize_t RK610_PROC_write(struct file *file, const char __user *buffer,
			   unsigned long len, void *data)
{
	char *cookie_pot; 
	char *p;
	int reg;
	int value;
	
	cookie_pot = (char *)vmalloc( len );
	if (!cookie_pot) 
	{
		return -ENOMEM;
	} 
	else 
	{
		if (copy_from_user( cookie_pot, buffer, len )) 
			return -EFAULT;
	}

	switch(cookie_pot[0])
	{
	case 'p':
		spk_ctrl_fun(GPIO_HIGH);
		break;
	case 'o':
		spk_ctrl_fun(GPIO_LOW);
		break;		
	case 'r':
	case 'R':
		printk("Read reg debug\n");		
		if(cookie_pot[1] ==':')
		{
			strsep(&cookie_pot,":");
			while((p=strsep(&cookie_pot,",")))
			{
				reg = simple_strtol(p,NULL,16);
				value = rk610_codec_read(rk610_codec_codec,reg);
				printk("wm8994_read:0x%04x = 0x%04x\n",reg,value);
			}
			printk("\n");
		}
		else
		{
			printk("Error Read reg debug.\n");
			printk("For example: echo 'r:22,23,24,25'>wm8994_ts\n");
		}
		break;
	case 'w':
	case 'W':
		printk("Write reg debug\n");		
		if(cookie_pot[1] ==':')
		{
			strsep(&cookie_pot,":");
			while((p=strsep(&cookie_pot,"=")))
			{
				reg = simple_strtol(p,NULL,16);
				p=strsep(&cookie_pot,",");
				value = simple_strtol(p,NULL,16);
				rk610_codec_write(rk610_codec_codec,reg,value);
				printk("wm8994_write:0x%04x = 0x%04x\n",reg,value);
			}
			printk("\n");
		}
		else
		{
			printk("Error Write reg debug.\n");
			printk("For example: w:22=0,23=0,24=0,25=0\n");
		}
		break;	
	case 'D' :
		printk("Dump reg\n");
		rk610_codec_reg_read();
		break;
	}

	return len;
}
Esempio n. 7
0
void rk610_codec_reg_set(void)
{
    struct snd_soc_codec *codec = rk610_codec_codec;
    unsigned int digital_gain;
	unsigned int mic_vol = Volume_Input;
	rk610_codec_write(codec,ACCELCODEC_R1D, 0x30);
	rk610_codec_write(codec,ACCELCODEC_R1E, 0x40);

#ifdef USE_LPF
	// Route R-LPF->R-Mixer, L-LPF->L-Mixer
	rk610_codec_write(codec,ACCELCODEC_R15, 0xC1);
#else
	// Route RDAC->R-Mixer, LDAC->L->Mixer
	rk610_codec_write(codec,ACCELCODEC_R15, 0x0C);
#endif
	// With Cap Output, VMID ramp up slow
	rk610_codec_write(codec,ACCELCODEC_R1A, 0x14);
    mdelay(10);

	rk610_codec_write(codec,ACCELCODEC_R0C, 0x10|ASC_INPUT_VOL_0DB);   //LIL
    rk610_codec_write(codec,ACCELCODEC_R0D, 0x10|ASC_INPUT_VOL_0DB);   //LIR

#ifdef USE_MIC_IN
	if(mic_vol > 0x07)
	{
		rk610_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT|ASC_MIC_BOOST_20DB);   //Select MIC input
		mic_vol -= 0x07;
	}	
	else
		rk610_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT);   //Select MIC input
    rk610_codec_write(codec,ACCELCODEC_R1C, ASC_DEM_ENABLE);  //0x00);  //use default value
#else
    rk610_codec_write(codec,ACCELCODEC_R12, 0x4c);   //Select Line input
#endif

    rk610_codec_write(codec,ACCELCODEC_R0E, 0x10|mic_vol);   //MIC
	
	// Diable route PGA->R/L Mixer, PGA gain 0db.
    rk610_codec_write(codec,ACCELCODEC_R13, 0x05 | 0 << 3);
    rk610_codec_write(codec,ACCELCODEC_R14, 0x05 | 0 << 3);

    //2soft mute
    rk610_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);   //soft mute

    //2set default SR and clk
    rk610_codec_write(codec,ACCELCODEC_R0A, ASC_NORMAL_MODE|(0x10 << 1)|ASC_CLKNODIV|ASC_CLK_DISABLE);
    gR0AReg = ASC_NORMAL_MODE|(0x10 << 1)|ASC_CLKNODIV|ASC_CLK_DISABLE;
    //2Config audio  interface
    rk610_codec_write(codec,ACCELCODEC_R09, ASC_I2S_MODE|ASC_16BIT_MODE|ASC_NORMAL_LRCLK|ASC_LRSWAP_DISABLE|ASC_MASTER_MODE|ASC_NORMAL_BCLK);
    rk610_codec_write(codec,ACCELCODEC_R00, ASC_HPF_ENABLE|ASC_DSM_MODE_ENABLE|ASC_SCRAMBLE_ENABLE|ASC_DITHER_ENABLE|ASC_BCLKDIV_4);
    //2volume,input,output
    digital_gain = Volume_Output;
    rk610_codec_write(codec,ACCELCODEC_R05, (digital_gain >> 8) & 0xFF);
    rk610_codec_write(codec,ACCELCODEC_R06, digital_gain & 0xFF);
    rk610_codec_write(codec,ACCELCODEC_R07, (digital_gain >> 8) & 0xFF);
    rk610_codec_write(codec,ACCELCODEC_R08, digital_gain & 0xFF);

    rk610_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_ENABLE|ASC_INT_ENABLE);
    gR0BReg = ASC_DEC_ENABLE|ASC_INT_ENABLE;  //ASC_DEC_DISABLE|ASC_INT_ENABLE;


//	#if OUT_CAPLESS
//	rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE);
//	#else
//	rk610_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
//	#endif
}
Esempio n. 8
0
static int rk610_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
		unsigned int fmt)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
	u16 iface = 0;

	spk_ctrl_fun(GPIO_LOW);
	rk610_codec_write(codec,ACCELCODEC_R1D, 0x2a);  //setup Vmid and Vref, other module power down
	rk610_codec_write(codec,ACCELCODEC_R1E, 0x40);  ///|ASC_PDASDML_ENABLE);

	/* set master/slave audio interface */
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		iface = 0x0040;
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		iface = 0x0000;
		break;
	default:
		return -EINVAL;
	}

	/* interface format */
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		iface |= 0x0002;
		break;
	case SND_SOC_DAIFMT_RIGHT_J:
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		iface |= 0x0001;
		break;
	case SND_SOC_DAIFMT_DSP_A:
		iface |= 0x0003;
		break;
	case SND_SOC_DAIFMT_DSP_B:
		iface |= 0x0013;
		break;
	default:
		return -EINVAL;
	}

	/* clock inversion */
	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		break;
	case SND_SOC_DAIFMT_IB_IF:
		iface |= 0x0090;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		iface |= 0x0080;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		iface |= 0x0010;
		break;
	default:
		return -EINVAL;
	}

	DBG("Enter::%s----%d  iface=%x\n",__FUNCTION__,__LINE__,iface);
	rk610_codec_write(codec, ACCELCODEC_R09, iface);
	return 0;
}