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

📄 omap2-audio-twl4030.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	ret = audio_twl4030_write(REG_EAR_CTL, RdReg);	if (ret) {		line = __LINE__;		goto disable_op_exit;	}	ret = audio_twl4030_write(REG_HS_SEL, 0x0);	if (ret) {		line = __LINE__;		goto disable_op_exit;	}	ret = audio_twl4030_write(REG_HFL_CTL, 0x0);	if (ret) {		line = __LINE__;		goto disable_op_exit;	}	ret = audio_twl4030_write(REG_HFR_CTL, 0x0);      disable_op_exit:	if (ret)		printk(KERN_ERR "Disable Output Error [%d] in Line %d\n", ret,		       line);	FN_OUT(ret);	return ret;}/** * @brief twl4030_enable_input - enable the input to the correct device *  Enable all the ADCs and path settings *  *NOTE* This will not set the gain *  Reason being that the gain setting can be done with CODEC power down *  *NOTE* This should be called with codec power down * * @return 0 if success else error value<0 */static int twl4030_enable_input(void){//#if defined(CONFIG_MACH_OMAP3EVM) || defined(CONFIG_MACH_OMAP3_BEAGLE)    u8 mic_en1 = 0;    u8 mic_en2 = 0;    u8 adc = 0;    int ret = 0;    u8 opt_ip = 0;    int line = 0;    FN_IN;	DPRINTK(KERN_INFO "Enable Input 0x%x HS=0x%x MM=0x%x SM=0x%x\n", current_input,		INPUT_HEADSET_MIC, INPUT_MAIN_MIC, INPUT_SUB_MIC);    ret = audio_twl4030_read(REG_OPTION);    if (ret < 0)        goto enable_ip_exit;    opt_ip = (ret &  ~(BIT_OPTION_ATXL1_EN_M | BIT_OPTION_ATXR1_EN_M |           BIT_OPTION_ATXL2_VTXL_EN_M | BIT_OPTION_ATXR2_VTXR_EN_M));    /* enable Aux-L and Aux-R i/p amplifiers */     opt_ip |= (BIT_OPTION_ATXL1_EN_M | BIT_OPTION_ATXR1_EN_M);    /* select auxilliary inputs for audio in Left */    mic_en1 = 0x14;    /* select auxilliary inputs for audio in Right */    mic_en2 = 0x14;    /* power control enable */    adc = 0x0A;    ret = audio_twl4030_write(REG_OPTION, opt_ip);    if (ret) {        line = __LINE__;        goto enable_ip_exit;    }    ret = audio_twl4030_write(REG_ANAMICL, mic_en1);    if (ret) {        line = __LINE__;        goto enable_ip_exit;    }    ret = audio_twl4030_write(REG_ANAMICR, mic_en2);    if (ret) {        line = __LINE__;        goto enable_ip_exit;    }    ret = audio_twl4030_write(REG_AVADC_CTL, adc);    if (ret) {        line = __LINE__;        goto enable_ip_exit;    }    /* Set off digital mics and select ADC o/p as i/p to Tx 1*/    ret = audio_twl4030_write(REG_ADCMICSEL, 0x0);    if (ret) {        line = __LINE__;        goto enable_ip_exit;    }    /* set gain <= 6dB on  Aux input */    ret = audio_twl4030_write(REG_ANAMIC_GAIN, 0x00);    if (ret) {        line = __LINE__;        goto enable_ip_exit;    }    /* Set Tx path volume control as 12dB */    ret = audio_twl4030_write(REG_ATXL1PGA, 0x0C);    ret = audio_twl4030_write(REG_ATXR1PGA, 0x0C);    ret = audio_twl4030_write(REG_AVTXL2PGA, 0x0C);    ret = audio_twl4030_write(REG_AVTXR2PGA, 0x0C);    ret = audio_twl4030_write(REG_DIGMIXING, 0x0);  /* No Karaoke */      enable_ip_exit:    if (ret)        printk(KERN_ERR "Error In Enable input[%d] in Line %d\n", ret,               line);    FN_OUT(ret);    return ret;}/** * @brief twl4030_disable_input - reset all the inputs *  *NOTE* This should be called with codec power down * * @return  0 if successful */static int twl4030_disable_input(void){	int ret = 0;	int line = 0;	FN_IN;	/* lets shut up all devices */	ret = audio_twl4030_write(REG_MICBIAS_CTL, 0x0);	if (ret) {		line = __LINE__;		goto disable_ip_exit;	}	ret = audio_twl4030_write(REG_ANAMICL, 0x0);	if (ret) {		line = __LINE__;		goto disable_ip_exit;	}	ret = audio_twl4030_write(REG_ANAMICR, 0x0);	if (ret) {		line = __LINE__;		goto disable_ip_exit;	}	ret = audio_twl4030_write(REG_AVADC_CTL, 0x0);	if (ret) {		line = __LINE__;		goto disable_ip_exit;	}	ret = audio_twl4030_write(REG_ADCMICSEL, 0x0);	if (ret) {		line = __LINE__;		goto disable_ip_exit;	}	ret = audio_twl4030_write(REG_DIGMIXING, 0x0);      disable_ip_exit:	if (ret)		printk(KERN_ERR "Error in disable of input [%d] in Line %d\n",		       ret, line);	FN_OUT(ret);	return ret;}/** * @brief twl4030_select_source - set up proper source * Call me with the Codec powered down * @param flag * @param val * * @return  0 if successful */static int twl4030_select_source(int flag, int val){	int ret = 0;	int temp = 0;	FN_IN;	switch (flag) {	case DIR_OUT:		/*		 * If more than one play device selected,		 * disable the device that is currently in use.		 */		if (hweight32(val) > 1)			val &= ~twl4030_local.outsrc;		/* can select multiple o/ps */		if ((val & SOUND_MASK_LINE1) == SOUND_MASK_LINE1) {			temp |= OUTPUT_STEREO_HEADSET;		}		if ((val & SOUND_MASK_SPEAKER) == SOUND_MASK_SPEAKER) {			temp |= OUTPUT_HANDS_FREE_CLASSD;		}		if ((val & SOUND_MASK_PHONEOUT) == SOUND_MASK_PHONEOUT) {			temp |= OUTPUT_MONO_EARPIECE;		}		if ((val & SOUND_MASK_CD) == SOUND_MASK_CD) {			temp |= OUTPUT_CARKIT;		}		current_output = temp;		/* toggle the source */		if (!(ret = twl4030_disable_output())) {			ret = twl4030_enable_output();		}		if (!ret) {			twl4030_local.outsrc = val;		}		break;	case DIR_IN:		/* if more than one device requested, reject the request */		if (hweight32(val) > 1)			return -EINVAL;		/* select multiple i/ps? */		if ((val & SOUND_MASK_LINE) == SOUND_MASK_LINE) {			temp |= INPUT_HEADSET_MIC;		}		if ((val & SOUND_MASK_MIC) == SOUND_MASK_MIC) {			temp |= INPUT_MAIN_MIC | INPUT_SUB_MIC;		}		if ((val & SOUND_MASK_RADIO) == SOUND_MASK_RADIO) {			temp |= INPUT_AUX;		}		if ((val & SOUND_MASK_CD) == SOUND_MASK_CD) {			temp |= INPUT_CARKIT;		}		current_input = temp;		/* Toggle the source */		if (!(ret = twl4030_disable_input())) {			ret = twl4030_enable_input();		}		if (!ret) {			twl4030_local.recsrc = val;		}		break;	default:		printk(KERN_WARNING PLATFORM_NAME "-" CODEC_NAME		       ": Wrong twl4030_selectsource flag specified\n");		ret = -EPERM;		break;	}	if (!ret) {		twl4030_local.mod_cnt++;	} else {		printk(KERN_ERR "Error selsrc Flag=%d,err=%d\n", flag, ret);	}	FN_OUT(ret);	return ret;}/** * @brief twl4030_setvolume - set the gain of the requested device * * @param flag device for which the gain is to be set * @param gain_l * @param gain_r * * @return error if this was not done, else returns 0 */static int twl4030_setvolume(int flag, u8 gain_l, u8 gain_r){	int ret = 0;	FN_IN;	if ((gain_l > AUDIO_MAX_OUTPUT_VOLUME)	    || (gain_r > AUDIO_MAX_OUTPUT_VOLUME)) {		printk(KERN_ERR "Invalid gain value %d %d\n", gain_l, gain_r);		return -EPERM;	}	DPRINTK	    ("FLAG=0x%02x GAIN_L=%d[0x%02x] GAIN_R=%d[0x%2x] [R=%x]"	     " [W=%x] [IP=0x%x] [OP=0x%x]\n",	     flag, gain_l, gain_l, gain_r, gain_r,	     (flag >= DIR_IN) ? 1 : 0,	     (flag < DIR_IN) ? 1 : 0,	     current_input,	     current_output);	switch (flag) {	case OUTPUT_VOLUME:		{			/* normal volume control */			u8 fine_val_l =			    (unsigned char)((gain_l * COMPUTE_PRECISION) /					    AUDIO_OUTPUT_INCREMENT);			u8 fine_val_r =			    (unsigned char)((gain_r * COMPUTE_PRECISION) /					    AUDIO_OUTPUT_INCREMENT);			/* Inverted power control big value is small volume */			u8 ana_val_r =			    (unsigned char)(((AUDIO_MAX_OUTPUT_VOLUME -			     gain_r) * COMPUTE_PRECISION) / ARX_APGA_INCR);			u8 ana_val_l =			    (unsigned char)(((AUDIO_MAX_OUTPUT_VOLUME -			     gain_l) * COMPUTE_PRECISION) / ARX_APGA_INCR);			/* default value at this time... make it ioctl ?? */			u8 coarse_val = AUDIO_DEF_COARSE_VOLUME_LEVEL;			DPRINTK("outputVol gain_l requested %d, set %d\n",				gain_l, fine_val_l);			DPRINTK("outputVol gain_r requested %d, set %d\n",				gain_r, fine_val_r);			/* I2S - SDRL2 and SDRR2 */			/* Digital boost */			ret = audio_twl4030_write(REG_ARXL2PGA,						coarse_val <<						BIT_ARXL2PGA_ARXL2PGA_CGAIN |						fine_val_l <<						BIT_ARXL2PGA_ARXL2PGA_FGAIN);			if (!ret) {				ret = audio_twl4030_write(REG_ARXR2PGA,						coarse_val <<						BIT_ARXL2PGA_ARXL2PGA_CGAIN						| fine_val_r <<						BIT_ARXR2PGA_ARXR2PGA_FGAIN);			}			/* Analog boost */			if (!ret) {				ret = audio_twl4030_write(REG_ARXL2_APGA_CTL,						BIT_ARXL2_APGA_CTL_ARXL2_PDZ_M						| BIT_ARXL2_APGA_CTL_ARXL2_DA_EN_M						| ana_val_l <<						BIT_ARXL2_APGA_CTL_ARXL2_GAIN_SET);			}			if (!ret) {				ret = audio_twl4030_write(REG_ARXR2_APGA_CTL,						BIT_ARXR2_APGA_CTL_ARXR2_PDZ_M						| BIT_ARXR2_APGA_CTL_ARXR2_DA_EN_M						| ana_val_r <<						BIT_ARXR2_APGA_CTL_ARXR2_GAIN_SET);			}			if (!ret) {				twl4030_local.play_volume =					    WRITE_LEFT_VOLUME(gain_l) |					    WRITE_RIGHT_VOLUME(gain_r);				DPRINTK("RESULT=play_vol=0x%x\n",					twl4030_local.play_volume);			}		}		break;	case OUTPUT_STEREO_HEADSET:		/* only if current output device is stereo headset */		if ((current_output & OUTPUT_STEREO_HEADSET) ==		    OUTPUT_STEREO_HEADSET) {			/* normal volume control */			u8 fine_val_l =			    (unsigned char)((gain_l * COMPUTE_PRECISION) /					    NON_LIN_INCREMENT);			u8 fine_val_r =			    (unsigned char)((gain_r * COMPUTE_PRECISION) /					    NON_LIN_INCREMENT);			u8 value_set[NON_LIN_GAIN_MAX] = NON_LIN_VALS;			/*HS_GAIN_SET */			DPRINTK("outputHS gain_l requested %d, set %d [0x%x]\n",				gain_l, fine_val_l, value_set[fine_val_l]);			DPRINTK("outputHS gain_r requested %d, set %d [0x%x]\n",				gain_r, fine_val_r, value_set[fine_val_r]);			/* Handle Mute request */			fine_val_l = (gain_l == 0) ? 0 : value_set[fine_val_l];			fine_val_r = (gain_r == 0) ? 0 : value_set[fine_val_r];			ret = audio_twl4030_write(REG_HS_GAIN_SET,						  (fine_val_l <<						   BIT_HS_GAIN_SET_HSL_GAIN) |						  (fine_val_r <<						   BIT_HS_GAIN_SET_HSR_GAIN));			if (!ret) {				twl4030_local.hset =				    WRITE_LEFT_VOLUME(gain_l) |				    WRITE_RIGHT_VOLUME(gain_r);				DPRINTK("RESULT=hset=0x%x\n",					twl4030_local.hset);			}		}		break;	case OUTPUT_HANDS_FREE_CLASSD:		if ((current_output & OUTPUT_HANDS_FREE_CLASSD) ==		    OUTPUT_HANDS_FREE_CLASSD) {			/* NOTE: CLASSD no special gain */			twl4030_local.classd =			    WRITE_LEFT_VOLUME(gain_l) |			    WRITE_RIGHT_VOLUME(gain_r);			DPRINTK("RESULT=classd=0x%x\n", twl4030_local.classd);		}		break;	case OUTPUT_MONO_EARPIECE:		if ((current_output & OUTPUT_MONO_EARPIECE) ==		    OUTPUT_MONO_EARPIECE) {			/* normal volume control */			u8 curr_val;			u8 fine_val_l =			    (unsigned char)((gain_l * COMPUTE_PRECISION) /					    NON_LIN_INCREMENT);			u8 value_set[NON_LIN_GAIN_MAX] = NON_LIN_VALS;			DPRINTK("outputHS gain_l requested %d, set %d [0x%x]\n",				gain_l, fine_val_l, value_set[fine_val_l]);			fine_val_l = (gain_l == 0) ? 0 : value_set[fine_val_l];			/*EAR_CTL */			curr_val = audio_twl4030_read(REG_EAR_CTL);			curr_val &= ~BIT_EAR_CTL_EAR_GAIN_M;			ret = audio_twl4030_write(REG_EAR_CTL, curr_val |						  (fine_val_l <<						  BIT_EAR_CTL_EAR_GAIN));			if (!ret) {				twl4030_local.ear = WRITE_LEFT_VOLUME(gain_l);				DPRINTK("RESULT=ear=0x%x\n", twl4030_local.ear);			}		}		break;	case OUTPUT_SIDETONE:		/* Sidetone Gain Control */		if (current_output) {			ret = audio_twl4030_write(REG_VSTPGA, gain_l);			if (!ret) {				twl4030_local.sidetone =				    WRITE_LEFT_VOLUME(gain_l);				DPRINTK("RESULT=sidetone=0x%x\n",				    twl4030_local.sidetone);			}		}		break;	case OUTPUT_CARKIT:		if ((current_output & OUTPUT_CARKIT) == OUTPUT_CARKIT) {			u8 curr_val;			u8 fine_val_l =			    (unsigned char)((gain_l * COMPUTE_PRECISION) /					    NON_LIN_INCREMENT);			u8 fine_val_r =			    (unsigned char)((gain_r * COMPUTE_PRECISION) /					    NON_LIN_INCREMENT);			u8 value_set[NON_LIN_GAIN_MAX] = NON_LIN_VALS;			DPRINTK("outputCkit gain_l req. %d, set %d [0x%x]\n",				gain_l, fine_val_l, value_set[fine_val_l]);			DPRINTK("outputCkit gain_r req. %d, set %d [0x%x]\n",				gain_r, fine_val_r, value_set[fine_val_r]);			fine_val_l = (gain_l == 0) ? 0 : value_set[fine_val_l];			fine_val_r = (gain_r == 0) ? 0 : value_set[fine_val_r];			/* Left gain */			curr_val = audio_twl4030_read(REG_PRECKL_CTL);			curr_val &= ~BIT_PRECKL_CTL_PRECKL_GAIN_M;			ret = audio_twl4030_write(REG_PRECKL_CTL, curr_val |						  (fine_val_l <<						  BIT_PRECKL_CTL_PRECKL_GAIN));			if (!ret) {				twl4030_local.carkit_out =						WRITE_LEFT_VOLUME(gain_l);				DPRINTK("RESULT=carkit=0x%x\n",						twl4030_local.carkit_out);			}			/* Right gain */			curr_val = audio_twl4030_read(REG_PRECKR_CTL);			curr_val &= ~BIT_PRECKR_CTL_PRECKR_GAIN_M;			ret = audio_twl4030_write(REG_PRECKR_CTL, curr_val |						  (fine_val_r <<						  BIT_PRECKR_CTL_PRECKR_GAIN));			if (!ret) {				twl4030_local.carkit_out =						WRITE_RIGHT_VOLUME(gain_r);				DPRINTK("RESULT=carkit_out=0x%x\n",						twl4030_local.carkit_out);			}		}		break;		/* Set input volume */	case INPUT_VOLUME:		{			u8 set_val_l = (unsigned char)					((gain_l * COMPUTE_PRECISION) /					AUDIO_INPUT_INCREMENT);			u8 set_val_r = (unsigned char)					((gain_r * COMPUTE_PRECISION) /					AUDIO_INPUT_INCREMENT);			/* NOTE: ANAMIC gain settings is handled by a			* default value			*/			DPRINTK("input gain_l requested %d, set %d\n", gain_l,				set_val_l);			DPRINTK("input gain_r requested %d, set %d\n", gain_r,				set_val_r);			/* I2S - TXL1 and TXR1 only */			ret = audio_twl4030_write(REG_ATXL1PGA,						set_val_l <<						BIT_ATXL1PGA_ATXL1PGA_GAIN);			if (!ret) {				ret = audio_twl4030_write(REG_ATXR1PGA,						set_val_r <<						BIT_ATXR1PGA_ATXR1PGA_GAIN);			}			if (!ret) {				twl4030_local.rec_volume =					    WRITE_LEFT_VOLUME(gain_l) |					    WRITE_RIGHT_VOLUME(gain_r);				DPRINTK("RESULT=rec_vol=0x%x\n",					twl4030_local.rec_volume);			}		}		break;	case INPUT_HEADSET_MIC:		if ((current_input & INPUT_HEADSET_MIC) == INPUT_HEADSET_MIC) {			u8 set_val_l =			    (unsigned char)((gain_l * COMPUTE_PRECISION) /					    MIC_AMP_INCR);			DPRINTK("anamic gain_l requested %d, set %d\n", gain_l,				set_val_l);			/* ANAMIC_GAIN */			ret =			    audio_twl4030_write(REG_ANAMIC_GAIN,						set_val_l <<						BIT_ANAMIC_GAIN_MICAMPL_GAIN);			if (!ret) {				twl4030_local.line =				    WRITE_LEFT_VOLUME(gain_l) |				    WRITE_RIGHT_VOLUME(gain_l);				DPRINTK("RESULT=line=0x%x\n",					twl4030_local.line);			}		}		break;	case INPUT_MAIN_MIC:

⌨️ 快捷键说明

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