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

📄 dmasound_awacs.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 5 页
字号:
static voidawacs_burgundy_wcw(unsigned addr, unsigned val){	out_le32(&awacs->codec_ctrl, addr + 0x200c00 + (val & 0xff));	awacs_burgundy_busy_wait();	out_le32(&awacs->codec_ctrl, addr + 0x200d00 +((val>>8) & 0xff));	awacs_burgundy_busy_wait();	out_le32(&awacs->codec_ctrl, addr + 0x200e00 +((val>>16) & 0xff));	awacs_burgundy_busy_wait();	out_le32(&awacs->codec_ctrl, addr + 0x200f00 +((val>>24) & 0xff));	awacs_burgundy_busy_wait();}static unsignedawacs_burgundy_rcw(unsigned addr){	unsigned val = 0;	unsigned long flags;	/* should have timeouts here */	save_flags(flags); cli();	out_le32(&awacs->codec_ctrl, addr + 0x100000);	awacs_burgundy_busy_wait();	awacs_burgundy_extend_wait();	val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;	out_le32(&awacs->codec_ctrl, addr + 0x100100);	awacs_burgundy_busy_wait();	awacs_burgundy_extend_wait();	val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<8;	out_le32(&awacs->codec_ctrl, addr + 0x100200);	awacs_burgundy_busy_wait();	awacs_burgundy_extend_wait();	val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<16;	out_le32(&awacs->codec_ctrl, addr + 0x100300);	awacs_burgundy_busy_wait();	awacs_burgundy_extend_wait();	val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<24;	restore_flags(flags);	return val;}static voidawacs_burgundy_wcb(unsigned addr, unsigned val){	out_le32(&awacs->codec_ctrl, addr + 0x300000 + (val & 0xff));	awacs_burgundy_busy_wait();}static unsignedawacs_burgundy_rcb(unsigned addr){	unsigned val = 0;	unsigned long flags;	/* should have timeouts here */	save_flags(flags); cli();	out_le32(&awacs->codec_ctrl, addr + 0x100000);	awacs_burgundy_busy_wait();	awacs_burgundy_extend_wait();	val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;	restore_flags(flags);	return val;}static intawacs_burgundy_check(void){	/* Checks to see the chip is alive and kicking */	int error = in_le32(&awacs->codec_ctrl) & MASK_ERRCODE;	return error == 0xf0000;}static intawacs_burgundy_init(void){	if (awacs_burgundy_check()) {		printk(KERN_WARNING "dmasound_pmac: burgundy not working :-(\n");		return 1;	}	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_OUTPUTENABLES,			   DEF_BURGUNDY_OUTPUTENABLES);	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,			   DEF_BURGUNDY_MORE_OUTPUTENABLES);	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_OUTPUTSELECTS,			   DEF_BURGUNDY_OUTPUTSELECTS);	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL21,			   DEF_BURGUNDY_INPSEL21);	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL3,			   DEF_BURGUNDY_INPSEL3);	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINCD,			   DEF_BURGUNDY_GAINCD);	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINLINE,			   DEF_BURGUNDY_GAINLINE);	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMIC,			   DEF_BURGUNDY_GAINMIC);	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMODEM,			   DEF_BURGUNDY_GAINMODEM);	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER,			   DEF_BURGUNDY_ATTENSPEAKER);	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENLINEOUT,			   DEF_BURGUNDY_ATTENLINEOUT);	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENHP,			   DEF_BURGUNDY_ATTENHP);	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_MASTER_VOLUME,			   DEF_BURGUNDY_MASTER_VOLUME);	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLCD,			   DEF_BURGUNDY_VOLCD);	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLLINE,			   DEF_BURGUNDY_VOLLINE);	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLMIC,			   DEF_BURGUNDY_VOLMIC);	return 0;}static voidawacs_burgundy_write_volume(unsigned address, int volume){	int hardvolume,lvolume,rvolume;	lvolume = (volume & 0xff) ? (volume & 0xff) + 155 : 0;	rvolume = ((volume >>8)&0xff) ? ((volume >> 8)&0xff ) + 155 : 0;	hardvolume = lvolume + (rvolume << 16);	awacs_burgundy_wcw(address, hardvolume);}static intawacs_burgundy_read_volume(unsigned address){	int softvolume,wvolume;	wvolume = awacs_burgundy_rcw(address);	softvolume = (wvolume & 0xff) - 155;	softvolume += (((wvolume >> 16) & 0xff) - 155)<<8;	return softvolume > 0 ? softvolume : 0;}static intawacs_burgundy_read_mvolume(unsigned address){	int lvolume,rvolume,wvolume;	wvolume = awacs_burgundy_rcw(address);	wvolume &= 0xffff;	rvolume = (wvolume & 0xff) - 155;	lvolume = ((wvolume & 0xff00)>>8) - 155;	return lvolume + (rvolume << 8);}static voidawacs_burgundy_write_mvolume(unsigned address, int volume){	int lvolume,rvolume,hardvolume;	lvolume = (volume &0xff) ? (volume & 0xff) + 155 :0;	rvolume = ((volume >>8) & 0xff) ? (volume >> 8) + 155 :0;	hardvolume = lvolume + (rvolume << 8);	hardvolume += (hardvolume << 16);	awacs_burgundy_wcw(address, hardvolume);}/* End burgundy functions *//* Set up output volumes on machines with the 'perch/whisper' extension card. * this has an SGS i2c chip (7433) which is accessed using the cuda. * * TODO: split this out and make use of the other parts of the SGS chip to * do Bass, Treble etc. */static voidawacs_enable_amp(int spkr_vol){#ifdef CONFIG_ADB_CUDA	struct adb_request req;	awacs_spkr_vol = spkr_vol;	if (sys_ctrler != SYS_CTRLER_CUDA)		return;	/* turn on headphones */	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,		     0x8a, 4, 0);	while (!req.complete) cuda_poll();	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,		     0x8a, 6, 0);	while (!req.complete) cuda_poll();	/* turn on speaker */	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,		     0x8a, 3, (100 - (spkr_vol & 0xff)) * 32 / 100);	while (!req.complete) cuda_poll();	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,		     0x8a, 5, (100 - ((spkr_vol >> 8) & 0xff)) * 32 / 100);	while (!req.complete) cuda_poll();	cuda_request(&req, NULL, 5, CUDA_PACKET,		     CUDA_GET_SET_IIC, 0x8a, 1, 0x29);	while (!req.complete) cuda_poll();#endif /* CONFIG_ADB_CUDA */}/*** Mid level stuff *********************************************************//* * /dev/mixer abstraction */static void do_line_lev(int data){		line_lev = data ;		awacs_reg[0] &= ~MASK_MUX_AUDIN;		if ((data & 0xff) >= 50)			awacs_reg[0] |= MASK_MUX_AUDIN;		awacs_write(MASK_ADDR0 | awacs_reg[0]);}static void do_ip_gain(int data){	ip_gain = data ;	data &= 0xff;	awacs_reg[0] &= ~MASK_GAINLINE;	if (awacs_revision == AWACS_SCREAMER) {		awacs_reg[6] &= ~MASK_MIC_BOOST ;		if (data >= 33) {			awacs_reg[0] |= MASK_GAINLINE;			if( data >= 66)				awacs_reg[6] |= MASK_MIC_BOOST ;		}		awacs_write(MASK_ADDR6 | awacs_reg[6]) ;	} else {		if (data >= 50)			awacs_reg[0] |= MASK_GAINLINE;	}	awacs_write(MASK_ADDR0 | awacs_reg[0]);}static void do_mic_lev(int data){	mic_lev = data ;	data &= 0xff;	awacs_reg[0] &= ~MASK_MUX_MIC;	if (data >= 50)		awacs_reg[0] |= MASK_MUX_MIC;	awacs_write(MASK_ADDR0 | awacs_reg[0]);}static void do_cd_lev(int data){	cd_lev = data ;	awacs_reg[0] &= ~MASK_MUX_CD;	if ((data & 0xff) >= 50)		awacs_reg[0] |= MASK_MUX_CD;	awacs_write(MASK_ADDR0 | awacs_reg[0]);}static void do_rec_lev(int data){	int left, right ;	rec_lev = data ;	/* need to fudge this to use the volume setter routine */	left = 100 - (data & 0xff) ; if( left < 0 ) left = 0 ;	right = 100 - ((data >> 8) & 0xff) ; if( right < 0 ) right = 0 ;	left |= (right << 8 );	left = awacs_volume_setter(left, 0, 0, 4);}static void do_passthru_vol(int data){	passthru_vol = data ;	awacs_reg[1] &= ~MASK_LOOPTHRU;	if (awacs_revision == AWACS_SCREAMER) {		if( data ) { /* switch it on for non-zero */			awacs_reg[1] |= MASK_LOOPTHRU;			awacs_write(MASK_ADDR1 | awacs_reg[1]);		}		data = awacs_volume_setter(data, 5, 0, 6) ;	} else {		if ((data & 0xff) >= 50)			awacs_reg[1] |= MASK_LOOPTHRU;		awacs_write(MASK_ADDR1 | awacs_reg[1]);		data = (awacs_reg[1] & MASK_LOOPTHRU)? 100: 0;	}}static int awacs_mixer_ioctl(u_int cmd, u_long arg){	int data;	int rc;	switch (cmd) {	case SOUND_MIXER_READ_CAPS:		/* say we will allow multiple inputs?  prob. wrong			so I'm switching it to single */		return IOCTL_OUT(arg, 1);	case SOUND_MIXER_READ_DEVMASK:		data  = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER			| SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD			| SOUND_MASK_IGAIN | SOUND_MASK_RECLEV			| SOUND_MASK_ALTPCM			| SOUND_MASK_MONITOR;		rc = IOCTL_OUT(arg, data);		break;	case SOUND_MIXER_READ_RECMASK:		data = SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD;		rc = IOCTL_OUT(arg, data);		break;	case SOUND_MIXER_READ_RECSRC:		data = 0;		if (awacs_reg[0] & MASK_MUX_AUDIN)			data |= SOUND_MASK_LINE;		if (awacs_reg[0] & MASK_MUX_MIC)			data |= SOUND_MASK_MIC;		if (awacs_reg[0] & MASK_MUX_CD)			data |= SOUND_MASK_CD;		rc = IOCTL_OUT(arg, data);		break;	case SOUND_MIXER_WRITE_RECSRC:		IOCTL_IN(arg, data);		data &= (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD);		awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC				  | MASK_MUX_AUDIN);		if (data & SOUND_MASK_LINE)			awacs_reg[0] |= MASK_MUX_AUDIN;		if (data & SOUND_MASK_MIC)			awacs_reg[0] |= MASK_MUX_MIC;		if (data & SOUND_MASK_CD)			awacs_reg[0] |= MASK_MUX_CD;		awacs_write(awacs_reg[0] | MASK_ADDR0);		rc = IOCTL_OUT(arg, data);		break;	case SOUND_MIXER_READ_STEREODEVS:		data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER| SOUND_MASK_RECLEV  ;		if (awacs_revision == AWACS_SCREAMER)			data |= SOUND_MASK_MONITOR ;		rc = IOCTL_OUT(arg, data);		break;	case SOUND_MIXER_WRITE_VOLUME:		IOCTL_IN(arg, data);		line_vol = data ;		awacs_volume_setter(data, 2, 0, 6);		/* fall through */	case SOUND_MIXER_READ_VOLUME:		rc = IOCTL_OUT(arg, line_vol);		break;	case SOUND_MIXER_WRITE_SPEAKER:		IOCTL_IN(arg, data);		spk_vol = data ;		if (has_perch)			awacs_enable_amp(data);		else			(void)awacs_volume_setter(data, 4, MASK_CMUTE, 6);		/* fall though */	case SOUND_MIXER_READ_SPEAKER:		rc = IOCTL_OUT(arg, spk_vol);		break;	case SOUND_MIXER_WRITE_ALTPCM:	/* really bell volume */		IOCTL_IN(arg, data);		beep_vol = data & 0xff;		/* fall through */	case SOUND_MIXER_READ_ALTPCM:		rc = IOCTL_OUT(arg, beep_vol);		break;	case SOUND_MIXER_WRITE_LINE:		IOCTL_IN(arg, data);		do_line_lev(data) ;		/* fall through */	case SOUND_MIXER_READ_LINE:		rc = IOCTL_OUT(arg, line_lev);		break;	case SOUND_MIXER_WRITE_IGAIN:		IOCTL_IN(arg, data);		do_ip_gain(data) ;		/* fall through */	case SOUND_MIXER_READ_IGAIN:		rc = IOCTL_OUT(arg, ip_gain);		break;	case SOUND_MIXER_WRITE_MIC:		IOCTL_IN(arg, data);		do_mic_lev(data);		/* fall through */	case SOUND_MIXER_READ_MIC:		rc = IOCTL_OUT(arg, mic_lev);		break;	case SOUND_MIXER_WRITE_CD:		IOCTL_IN(arg, data);		do_cd_lev(data);		/* fall through */	case SOUND_MIXER_READ_CD:		rc = IOCTL_OUT(arg, cd_lev);		break;	case SOUND_MIXER_WRITE_RECLEV:		IOCTL_IN(arg, data);		do_rec_lev(data) ;		/* fall through */	case SOUND_MIXER_READ_RECLEV:		rc = IOCTL_OUT(arg, rec_lev);		break;	case MIXER_WRITE(SOUND_MIXER_MONITOR):		IOCTL_IN(arg, data);		do_passthru_vol(data) ;		/* fall through */	case MIXER_READ(SOUND_MIXER_MONITOR):		rc = IOCTL_OUT(arg, passthru_vol);		break;	default:		rc = -EINVAL;	}		return rc;}static void awacs_mixer_init(void){	awacs_volume_setter(line_vol, 2, 0, 6);	if (has_perch)		awacs_enable_amp(spk_vol);	else		(void)awacs_volume_setter(spk_vol, 4, MASK_CMUTE, 6);	do_line_lev(line_lev) ;	do_ip_gain(ip_gain) ;	do_mic_lev(mic_lev) ;	do_cd_lev(cd_lev) ;	do_rec_lev(rec_lev) ;	do_passthru_vol(passthru_vol) ;}static int burgundy_mixer_ioctl(u_int cmd, u_long arg){	int data;	int rc;	/* We are, we are, we are... Burgundy or better */	switch(cmd) {	case SOUND_MIXER_READ_DEVMASK:		data = SOUND_MASK_VOLUME | SOUND_MASK_CD |			SOUND_MASK_LINE | SOUND_MASK_MIC |			SOUND_MASK_SPEAKER | SOUND_MASK_ALTPCM;		rc = IOCTL_OUT(arg, data);		break;	case SOUND_MIXER_READ_RECMASK:		data = SOUND_MASK_LINE | SOUND_MASK_MIC			| SOUND_MASK_CD;		rc = IOCTL_OUT(arg, data);		break;

⌨️ 快捷键说明

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