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

📄 sb_ess.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 4 页
字号:
 * * These registers specifically take care of recording levels. To make the * mapping from playback devices to recording devices every recording * devices = playback device + ES_REC_MIXER_RECDIFF */#define ES_REC_MIXER_RECBASE	(SOUND_MIXER_LINE3 + 1)#define ES_REC_MIXER_RECDIFF	(ES_REC_MIXER_RECBASE - SOUND_MIXER_SYNTH)#define ES_REC_MIXER_RECSYNTH	(SOUND_MIXER_SYNTH	 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECPCM		(SOUND_MIXER_PCM	 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECSPEAKER	(SOUND_MIXER_SPEAKER + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECLINE	(SOUND_MIXER_LINE	 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECMIC		(SOUND_MIXER_MIC	 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECCD		(SOUND_MIXER_CD		 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECIMIX	(SOUND_MIXER_IMIX	 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECALTPCM	(SOUND_MIXER_ALTPCM	 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECRECLEV	(SOUND_MIXER_RECLEV	 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECIGAIN	(SOUND_MIXER_IGAIN	 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECOGAIN	(SOUND_MIXER_OGAIN	 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECLINE1	(SOUND_MIXER_LINE1	 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECLINE2	(SOUND_MIXER_LINE2	 + ES_REC_MIXER_RECDIFF)#define ES_REC_MIXER_RECLINE3	(SOUND_MIXER_LINE3	 + ES_REC_MIXER_RECDIFF)static mixer_tab es688_mix = {MIX_ENT(SOUND_MIXER_VOLUME,			0x32, 7, 4, 0x32, 3, 4),MIX_ENT(SOUND_MIXER_BASS,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_TREBLE,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_SYNTH,			0x36, 7, 4, 0x36, 3, 4),MIX_ENT(SOUND_MIXER_PCM,			0x14, 7, 4, 0x14, 3, 4),MIX_ENT(SOUND_MIXER_SPEAKER,		0x3c, 2, 3, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE,			0x3e, 7, 4, 0x3e, 3, 4),MIX_ENT(SOUND_MIXER_MIC,			0x1a, 7, 4, 0x1a, 3, 4),MIX_ENT(SOUND_MIXER_CD,				0x38, 7, 4, 0x38, 3, 4),MIX_ENT(SOUND_MIXER_IMIX,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_ALTPCM,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_RECLEV,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_IGAIN,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_OGAIN,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE1,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE2,			0x3a, 7, 4, 0x3a, 3, 4),MIX_ENT(SOUND_MIXER_LINE3,			0x00, 0, 0, 0x00, 0, 0)};/* * The ES1688 specifics... hopefully correct... * - 6 bit master volume *   I was wrong, ES1888 docs say ES1688 didn't have it. * - RECLEV control * These may apply to ES688 too. I have no idea. */static mixer_tab es1688_mix = {MIX_ENT(SOUND_MIXER_VOLUME,			0x32, 7, 4, 0x32, 3, 4),MIX_ENT(SOUND_MIXER_BASS,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_TREBLE,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_SYNTH,			0x36, 7, 4, 0x36, 3, 4),MIX_ENT(SOUND_MIXER_PCM,			0x14, 7, 4, 0x14, 3, 4),MIX_ENT(SOUND_MIXER_SPEAKER,		0x3c, 2, 3, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE,			0x3e, 7, 4, 0x3e, 3, 4),MIX_ENT(SOUND_MIXER_MIC,			0x1a, 7, 4, 0x1a, 3, 4),MIX_ENT(SOUND_MIXER_CD,				0x38, 7, 4, 0x38, 3, 4),MIX_ENT(SOUND_MIXER_IMIX,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_ALTPCM,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_RECLEV,			0xb4, 7, 4, 0xb4, 3, 4),MIX_ENT(SOUND_MIXER_IGAIN,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_OGAIN,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE1,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE2,			0x3a, 7, 4, 0x3a, 3, 4),MIX_ENT(SOUND_MIXER_LINE3,			0x00, 0, 0, 0x00, 0, 0)};static mixer_tab es1688later_mix = {MIX_ENT(SOUND_MIXER_VOLUME,			0x60, 5, 6, 0x62, 5, 6),MIX_ENT(SOUND_MIXER_BASS,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_TREBLE,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_SYNTH,			0x36, 7, 4, 0x36, 3, 4),MIX_ENT(SOUND_MIXER_PCM,			0x14, 7, 4, 0x14, 3, 4),MIX_ENT(SOUND_MIXER_SPEAKER,		0x3c, 2, 3, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE,			0x3e, 7, 4, 0x3e, 3, 4),MIX_ENT(SOUND_MIXER_MIC,			0x1a, 7, 4, 0x1a, 3, 4),MIX_ENT(SOUND_MIXER_CD,				0x38, 7, 4, 0x38, 3, 4),MIX_ENT(SOUND_MIXER_IMIX,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_ALTPCM,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_RECLEV,			0xb4, 7, 4, 0xb4, 3, 4),MIX_ENT(SOUND_MIXER_IGAIN,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_OGAIN,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE1,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE2,			0x3a, 7, 4, 0x3a, 3, 4),MIX_ENT(SOUND_MIXER_LINE3,			0x00, 0, 0, 0x00, 0, 0)};/* * This one is for all ESS chips with a record mixer. * It's not used (yet) however */static mixer_tab es_rec_mix = {MIX_ENT(SOUND_MIXER_VOLUME,			0x60, 5, 6, 0x62, 5, 6),MIX_ENT(SOUND_MIXER_BASS,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_TREBLE,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_SYNTH,			0x36, 7, 4, 0x36, 3, 4),MIX_ENT(SOUND_MIXER_PCM,			0x14, 7, 4, 0x14, 3, 4),MIX_ENT(SOUND_MIXER_SPEAKER,		0x3c, 2, 3, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE,			0x3e, 7, 4, 0x3e, 3, 4),MIX_ENT(SOUND_MIXER_MIC,			0x1a, 7, 4, 0x1a, 3, 4),MIX_ENT(SOUND_MIXER_CD,				0x38, 7, 4, 0x38, 3, 4),MIX_ENT(SOUND_MIXER_IMIX,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_ALTPCM,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_RECLEV,			0xb4, 7, 4, 0xb4, 3, 4),MIX_ENT(SOUND_MIXER_IGAIN,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_OGAIN,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE1,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE2,			0x3a, 7, 4, 0x3a, 3, 4),MIX_ENT(SOUND_MIXER_LINE3,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECSYNTH,		0x6b, 7, 4, 0x6b, 3, 4),MIX_ENT(ES_REC_MIXER_RECPCM,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECSPEAKER,	0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECLINE,		0x6e, 7, 4, 0x6e, 3, 4),MIX_ENT(ES_REC_MIXER_RECMIC,		0x68, 7, 4, 0x68, 3, 4),MIX_ENT(ES_REC_MIXER_RECCD,			0x6a, 7, 4, 0x6a, 3, 4),MIX_ENT(ES_REC_MIXER_RECIMIX,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECALTPCM,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECRECLEV,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECIGAIN,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECOGAIN,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECLINE1,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECLINE2,		0x6c, 7, 4, 0x6c, 3, 4),MIX_ENT(ES_REC_MIXER_RECLINE3,		0x00, 0, 0, 0x00, 0, 0)};/* * This one is for ES1887. It's little different from es_rec_mix: it * has 0x7c for PCM playback level. This is because ES1887 uses * Audio 2 for playback. */static mixer_tab es1887_mix = {MIX_ENT(SOUND_MIXER_VOLUME,			0x60, 5, 6, 0x62, 5, 6),MIX_ENT(SOUND_MIXER_BASS,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_TREBLE,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_SYNTH,			0x36, 7, 4, 0x36, 3, 4),MIX_ENT(SOUND_MIXER_PCM,			0x7c, 7, 4, 0x7c, 3, 4),MIX_ENT(SOUND_MIXER_SPEAKER,		0x3c, 2, 3, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE,			0x3e, 7, 4, 0x3e, 3, 4),MIX_ENT(SOUND_MIXER_MIC,			0x1a, 7, 4, 0x1a, 3, 4),MIX_ENT(SOUND_MIXER_CD,				0x38, 7, 4, 0x38, 3, 4),MIX_ENT(SOUND_MIXER_IMIX,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_ALTPCM,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_RECLEV,			0xb4, 7, 4, 0xb4, 3, 4),MIX_ENT(SOUND_MIXER_IGAIN,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_OGAIN,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE1,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(SOUND_MIXER_LINE2,			0x3a, 7, 4, 0x3a, 3, 4),MIX_ENT(SOUND_MIXER_LINE3,			0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECSYNTH,		0x6b, 7, 4, 0x6b, 3, 4),MIX_ENT(ES_REC_MIXER_RECPCM,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECSPEAKER,	0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECLINE,		0x6e, 7, 4, 0x6e, 3, 4),MIX_ENT(ES_REC_MIXER_RECMIC,		0x68, 7, 4, 0x68, 3, 4),MIX_ENT(ES_REC_MIXER_RECCD,			0x6a, 7, 4, 0x6a, 3, 4),MIX_ENT(ES_REC_MIXER_RECIMIX,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECALTPCM,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECRECLEV,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECIGAIN,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECOGAIN,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECLINE1,		0x00, 0, 0, 0x00, 0, 0),MIX_ENT(ES_REC_MIXER_RECLINE2,		0x6c, 7, 4, 0x6c, 3, 4),MIX_ENT(ES_REC_MIXER_RECLINE3,		0x00, 0, 0, 0x00, 0, 0)};static int ess_has_rec_mixer (int submodel){	switch (submodel) {	case SUBMDL_ES1887:		return 1;	default:		return 0;	};};#ifdef FKS_LOGGINGstatic int ess_mixer_mon_regs[]	= { 0x70, 0x71, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7d, 0x7f	  , 0xa1, 0xa2, 0xa4, 0xa5, 0xa8, 0xa9	  , 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb9	  , 0x00};static void ess_show_mixerregs (sb_devc *devc){	int *mp = ess_mixer_mon_regs;return;	while (*mp != 0) {		printk (KERN_INFO "res (%x)=%x\n", *mp, (int)(ess_getmixer (devc, *mp)));		mp++;	}}#endifvoid ess_setmixer (sb_devc * devc, unsigned int port, unsigned int value){	unsigned long flags;#ifdef FKS_LOGGINGprintk(KERN_INFO "FKS: write mixer %x: %x\n", port, value);#endif	spin_lock_irqsave(&devc->lock, flags);	if (port >= 0xa0) {		ess_write (devc, port, value);	} else {		outb(((unsigned char) (port & 0xff)), MIXER_ADDR);		udelay(20);		outb(((unsigned char) (value & 0xff)), MIXER_DATA);		udelay(20);	};	spin_unlock_irqrestore(&devc->lock, flags);}unsigned int ess_getmixer (sb_devc * devc, unsigned int port){	unsigned int val;	unsigned long flags;	spin_lock_irqsave(&devc->lock, flags);	if (port >= 0xa0) {		val = ess_read (devc, port);	} else {		outb(((unsigned char) (port & 0xff)), MIXER_ADDR);		udelay(20);		val = inb(MIXER_DATA);		udelay(20);	}	spin_unlock_irqrestore(&devc->lock, flags);	return val;}static void ess_chgmixer	(sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val){	int value;	value = ess_getmixer (devc, reg);	value = (value & ~mask) | (val & mask);	ess_setmixer (devc, reg, value);}/* * ess_mixer_init must be called from sb_mixer_init */void ess_mixer_init (sb_devc * devc){	devc->mixer_caps = SOUND_CAP_EXCL_INPUT;	/*	* Take care of ES1887 specifics...	*/	switch (devc->submodel) {	case SUBMDL_ES1887:		devc->supported_devices		= ES1887_MIXER_DEVICES;		devc->supported_rec_devices	= ES1887_RECORDING_DEVICES;#ifdef FKS_LOGGINGprintk (KERN_INFO "FKS: ess_mixer_init dup = %d\n", devc->duplex);#endif		if (devc->duplex) {			devc->iomap				= &es1887_mix;		} else {			devc->iomap				= &es_rec_mix;		}		break;	default:		if (devc->submodel < 8) {			devc->supported_devices		= ES688_MIXER_DEVICES;			devc->supported_rec_devices	= ES688_RECORDING_DEVICES;			devc->iomap					= &es688_mix;		} else {			/*			 * es1688 has 4 bits master vol.			 * later chips have 6 bits (?)			 */			devc->supported_devices		= ES1688_MIXER_DEVICES;			devc->supported_rec_devices	= ES1688_RECORDING_DEVICES;			if (devc->submodel < 0x10) {				devc->iomap				= &es1688_mix;			} else {				devc->iomap				= &es1688later_mix;			}		}	}}/* * Changing playback levels at an ESS chip with record mixer means having to * take care of recording levels of recorded inputs (devc->recmask) too! */int ess_mixer_set(sb_devc *devc, int dev, int left, int right){	if (ess_has_rec_mixer (devc->submodel) && (devc->recmask & (1 << dev))) {		sb_common_mixer_set (devc, dev + ES_REC_MIXER_RECDIFF, left, right);	}	return sb_common_mixer_set (devc, dev, left, right);}/* * After a sb_dsp_reset extended register 0xb4 (RECLEV) is reset too. After * sb_dsp_reset RECLEV has to be restored. This is where ess_mixer_reload * helps. */void ess_mixer_reload (sb_devc *devc, int dev){	int left, right, value;	value = devc->levels[dev];	left  = value & 0x000000ff;	right = (value & 0x0000ff00) >> 8;	sb_common_mixer_set(devc, dev, left, right);}int es_rec_set_recmask(sb_devc * devc, int mask){	int i, i_mask, cur_mask, diff_mask;	int value, left, right;#ifdef FKS_LOGGINGprintk (KERN_INFO "FKS: es_rec_set_recmask mask = %x\n", mask);#endif	/*	 * Changing the recmask on an ESS chip with recording mixer means:	 * (1) Find the differences	 * (2) For "turned-on"  inputs: make the recording level the playback level	 * (3) For "turned-off" inputs: make the recording level zero	 */	cur_mask  = devc->recmask;	diff_mask = (cur_mask ^ mask);	for (i = 0; i < 32; i++) {		i_mask = (1 << i);		if (diff_mask & i_mask) {	/* Difference? (1)  */			if (mask & i_mask) {	/* Turn it on  (2)  */				value = devc->levels[i];				left  = value & 0x000000ff;				right = (value & 0x0000ff00) >> 8;			} else {				/* Turn it off (3)  */				left  = 0;				left  = 0;				right = 0;			}			sb_common_mixer_set(devc, i + ES_REC_MIXER_RECDIFF, left, right);		}	}	return mask;}int ess_set_recmask(sb_devc * devc, int *mask){	/* This applies to ESS chips with record mixers only! */	if (ess_has_rec_mixer (devc->submodel)) {		*mask	= es_rec_set_recmask (devc, *mask);		return 1;									/* Applied		*/	} else {		return 0;									/* Not applied	*/	}}/* * ess_mixer_reset must be called from sb_mixer_reset */int ess_mixer_reset (sb_devc * devc){	/*	 * Separate actions for ESS chips with a record mixer:	 */	if (ess_has_rec_mixer (devc->submodel)) {		switch (devc->submodel) {		case SUBMDL_ES1887:			/*			 * Separate actions for ES1887:			 * Change registers 7a and 1c to make the record mixer the			 * actual recording source.			 */			ess_chgmixer(devc, 0x7a, 0x18, 0x08);			ess_chgmixer(devc, 0x1c, 0x07, 0x07);			break;		};		/*		 * Call set_recmask for proper initialization		 */		devc->recmask = devc->supported_rec_devices;		es_rec_set_recmask(devc, 0);		devc->recmask = 0;		return 1;	/* We took care of recmask.				*/	} else {		return 0;	/* We didn't take care; caller do it	*/	}}/**************************************************************************** *																			* *								ESS midi									* *																			* ****************************************************************************//* * FKS: IRQ may be shared. Hm. And if so? Then What? */int ess_midi_init(sb_devc * devc, struct address_info *hw_config){	unsigned char   cfg, tmp;	cfg = ess_getmixer (devc, 0x40) & 0x03;	if (devc->submodel < 8) {		ess_setmixer (devc, 0x40, cfg | 0x03);	/* Enable OPL3 & joystick */		return 0;  					 /* ES688 doesn't support MPU401 mode */	}	tmp = (hw_config->io_base & 0x0f0) >> 4;	if (tmp > 3) {		ess_setmixer (devc, 0x40, cfg);		return 0;	}	cfg |= tmp << 3;	tmp = 1;		/* MPU enabled without interrupts */	/* May be shared: if so the value is -ve */	switch (abs(hw_config->irq)) {		case 9:			tmp = 0x4;			break;		case 5:			tmp = 0x5;			break;		case 7:			tmp = 0x6;			break;		case 10:			tmp = 0x7;			break;		default:			return 0;	}	cfg |= tmp << 5;	ess_setmixer (devc, 0x40, cfg | 0x03);	return 1;}

⌨️ 快捷键说明

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