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

📄 omap-audio-tsc2101.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 3 页
字号:
 * ********************************************************************************/static int mixer_release(struct inode *inode, struct file *file){	/* Any mixer specific Un-initialization */	omap_tsc2101_disable();	return 0;}/********************************************************************************* * * mixer_ioctl() * ********************************************************************************/static intmixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg){	int val;	int gain;	int ret = 0;	int nr = _IOC_NR(cmd);	/*	 * We only accept mixer (type 'M') ioctls.	 */	FN_IN;	if (_IOC_TYPE(cmd) != 'M')		return -EINVAL;	DPRINTK(" 0x%08x\n", cmd);	if (cmd == SOUND_MIXER_INFO) {		struct mixer_info mi;		strncpy(mi.id, "TSC2101", sizeof(mi.id));		strncpy(mi.name, "TI TSC2101", sizeof(mi.name));		mi.modify_counter = tsc2101_local.mod_cnt;		FN_OUT(1);		return copy_to_user((void *)arg, &mi, sizeof(mi));	}	if (_IOC_DIR(cmd) & _IOC_WRITE) {		ret = get_user(val, (int *)arg);		if (ret)			goto out;		/* Ignore separate left/right channel for now,		 * even the codec does support it.		 */		gain = val & 255;		switch (nr) {		case SOUND_MIXER_VOLUME:			tsc2101_local.volume = val;			tsc2101_local.mod_cnt++;			ret = tsc2101_update(SET_VOLUME, gain);			break;		case SOUND_MIXER_LINE:			tsc2101_local.line = val;			tsc2101_local.mod_cnt++;			ret = tsc2101_update(SET_LINE, gain);			break;		case SOUND_MIXER_MIC:			tsc2101_local.mic = val;			tsc2101_local.mod_cnt++;			ret = tsc2101_update(SET_LINE, gain);			break;		case SOUND_MIXER_RECSRC:			break;		default:			ret = -EINVAL;		}	}	if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {		ret = 0;		switch (nr) {		case SOUND_MIXER_VOLUME:			val = tsc2101_local.volume;			break;		case SOUND_MIXER_LINE:			val = tsc2101_local.line;			break;		case SOUND_MIXER_MIC:			val = tsc2101_local.mic;			break;		case SOUND_MIXER_RECSRC:			val = REC_MASK;			break;		case SOUND_MIXER_RECMASK:			val = REC_MASK;			break;		case SOUND_MIXER_DEVMASK:			val = DEV_MASK;			break;		case SOUND_MIXER_CAPS:			val = 0;			break;		case SOUND_MIXER_STEREODEVS:			val = 0;			break;		default:			val = 0;			ret = -EINVAL;			break;		}		if (ret == 0)			ret = put_user(val, (int *)arg);	}      out:	FN_OUT(0);	return ret;}/********************************************************************************* * * omap_set_samplerate() * ********************************************************************************/int omap_set_samplerate(long sample_rate){	u8 count = 0;	u16 data = 0;	/* wait for any frame to complete */	udelay(125);	/* Search for the right sample rate */	while ((reg_info[count].sample_rate != sample_rate) &&	       (count < NUMBER_SAMPLE_RATES_SUPPORTED)) {		count++;	}	if (count == NUMBER_SAMPLE_RATES_SUPPORTED) {		printk(KERN_ERR "Invalid Sample Rate %d requested\n",		       (int)sample_rate);		return -EPERM;	}	/* Set AC1 */	data = audio_tsc2101_read(TSC2101_AUDIO_CTRL_1);	/*Clear prev settings */	data &= ~(AC1_DACFS(0x07) | AC1_ADCFS(0x07));	data |=	    AC1_DACFS(reg_info[count].divisor) | AC1_ADCFS(reg_info[count].							   divisor);	audio_tsc2101_write(TSC2101_AUDIO_CTRL_1, data);	/* Set the AC3 */	data = audio_tsc2101_read(TSC2101_AUDIO_CTRL_3);	/*Clear prev settings */	data &= ~(AC3_REFFS | AC3_SLVMS);	data |= (reg_info[count].fs_44kHz) ? AC3_REFFS : 0;#ifdef TSC_MASTER	data |= AC3_SLVMS;#endif				/* #ifdef TSC_MASTER */	audio_tsc2101_write(TSC2101_AUDIO_CTRL_3, data);	/* program the PLLs */	if (reg_info[count].fs_44kHz) {		/* 44.1 khz - 12 MHz Mclk */		audio_tsc2101_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL | PLL1_PVAL(1) | PLL1_I_VAL(7));	/* PVAL 1; I_VAL 7 */		audio_tsc2101_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x1490));	/* D_VAL 5264 */	} else {		/* 48 khz - 12 Mhz Mclk */		audio_tsc2101_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL | PLL1_PVAL(1) | PLL1_I_VAL(8));	/* PVAL 1; I_VAL 8 */		audio_tsc2101_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x780));	/* D_VAL 1920 */	}	audio_samplerate = sample_rate;	/* Call Mcbsp Sample rate function */	omap_mcbsp_set_rate(AUDIO_MCBSP, sample_rate, DEFAULT_BITPERSAMPLE);	return 0;}/********************************************************************************* * * omap_tsc2101_initialize() [hw_init() ] * ********************************************************************************/static void omap_tsc2101_initialize(void *dummy){	DPRINTK("omap_tsc2101_initialize entry\n");	/* initialize with default sample rate */	audio_samplerate = AUDIO_RATE_DEFAULT;	omap_mcbsp_begin(AUDIO_MCBSP);	omap_tsc2101_enable();	tsc2101_configure();#ifdef TEST_KEYCLICK	tsc2101_testkeyclick();#endif#ifdef TONE_GEN	toneGen();#endif	DPRINTK("omap_tsc2101_initialize exit\n");}/********************************************************************************* * * omap_tsc2101_shutdown() [hw_shutdown() ] * ********************************************************************************/static void omap_tsc2101_shutdown(void *dummy){	/*	   Turn off codec after it is done.	   Can't do it immediately, since it may still have	   buffered data.	   Wait 20ms (arbitrary value) and then turn it off.	 */	FN_IN;	set_current_state(TASK_INTERRUPTIBLE);	schedule_timeout(2);	omap_mcbsp_end(AUDIO_MCBSP);	audio_tsc2101_write(TSC2101_CODEC_POWER_CTRL,			    ~(CPC_SP1PWDN | CPC_SP2PWDN | CPC_BASSBC));	omap_tsc2101_disable();	FN_OUT(0);}/********************************************************************************* * * tsc2101_configure * ********************************************************************************/static inline void tsc2101_configure(){	FN_IN;	audio_tsc2101_write(TSC2101_CODEC_POWER_CTRL, 0x0000);	/*Headset Input not muted */	/*AGC for Headset In off */	audio_tsc2101_write(TSC2101_HEADSET_GAIN_CTRL, HGC_ADPGA_HED(0x7D));	/*Mute Analog Sidetone */	/*Select MIC_INHED input for headset */	/*Cell Phone In not connected */	audio_tsc2101_write(TSC2101_MIXER_PGA_CTRL,			    MPC_ASTMU | MPC_ASTG(0x40) | MPC_MICADC);	/* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled */	/* 1dB AGC hysteresis */	/* MICes bias 2V */	audio_tsc2101_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));	/* Set codec output volume */	audio_tsc2101_write(TSC2101_DAC_GAIN_CTRL, 0x0000);	/* DAC left and right routed to SPK2 */	/* SPK1/2 unmuted */	audio_tsc2101_write(TSC2101_AUDIO_CTRL_5,			    AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |			    AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 |			    AC5_HDSCPTC);	/* OUT8P/N muted, CPOUT muted */	audio_tsc2101_write(TSC2101_AUDIO_CTRL_6,			    AC6_MUTLSPK | AC6_MUTSPK2 | AC6_LDSCPTC |			    AC6_VGNDSCPTC);	/* Headset/Hook switch detect disabled */	audio_tsc2101_write(TSC2101_AUDIO_CTRL_7, 0x0000);	/* Initialize the AIC23 internal state */	/*	   The AIC23 uses 9 bits for register control.  The	   extra bit gets placed in the LSB of the subregister	   address, and the address is shifted by one.	   the volume control is only for earphone not line out	   line input volume can be controlled but not in following code	   which pick the default value 0dB	 */	/* Left line input volume control */	tsc2101_local.line = DEFAULT_INPUT_VOLUME;	tsc2101_local.mic = DEFAULT_INPUT_VOLUME;	tsc2101_update(SET_LINE, DEFAULT_INPUT_VOLUME);	/* Left/Right headphone channel volume control */	/* Zero-cross detect on */	tsc2101_local.volume = DEFAULT_VOLUME;	tsc2101_update(SET_VOLUME, DEFAULT_VOLUME);	/* clock configuration */	omap_set_samplerate(audio_samplerate);#ifdef TSC_DUMP_REGISTERS	tsc2101_dumpRegisters();#endif	FN_OUT(0);}#ifdef PROC_SUPPORTstatic void tsc2101_start(){	FN_IN;	audio_tsc2101_write(TSC2101_CODEC_POWER_CTRL, 0x0000);	/*Headset Input not muted */	/*AGC for Headset In off */	audio_tsc2101_write(TSC2101_HEADSET_GAIN_CTRL, HGC_ADPGA_HED(0x7D));	/*Mute Analog Sidetone */	/*Select MIC_INHED input for headset */	/*Cell Phone In not connected */	audio_tsc2101_write(TSC2101_MIXER_PGA_CTRL,			    MPC_ASTMU | MPC_ASTG(0x40) | MPC_MICADC);	/* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled */	/* 1dB AGC hysteresis */	/* MICes bias 2V */	audio_tsc2101_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));	/* Set codec output volume */	audio_tsc2101_write(TSC2101_DAC_GAIN_CTRL, 0x0000);	/* DAC left and right routed to SPK2 */	/* SPK1/2 unmuted */	audio_tsc2101_write(TSC2101_AUDIO_CTRL_5,			    AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |			    AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 |			    AC5_HDSCPTC);	/* OUT8P/N muted, CPOUT muted */	audio_tsc2101_write(TSC2101_AUDIO_CTRL_6,			    AC6_MUTLSPK | AC6_MUTSPK2 | AC6_LDSCPTC |			    AC6_VGNDSCPTC);	/* Headset/Hook switch detect disabled */	audio_tsc2101_write(TSC2101_AUDIO_CTRL_7, 0x0000);	/* Initialize the AIC23 internal state */	/*	   The AIC23 uses 9 bits for register control.  The	   extra bit gets placed in the LSB of the subregister	   address, and the address is shifted by one.	   the volume control is only for earphone not line out	   line input volume can be controlled but not in following code	   which pick the default value 0dB	 */	/* Left line input volume control */	tsc2101_local.line = DEFAULT_INPUT_VOLUME;	tsc2101_local.mic = DEFAULT_INPUT_VOLUME;	tsc2101_update(SET_LINE, DEFAULT_INPUT_VOLUME);	/* Left/Right headphone channel volume control */	/* Zero-cross detect on */

⌨️ 快捷键说明

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