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

📄 opti92x-ad1848.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	spin_unlock_irqrestore(&chip->lock, flags);}#define snd_opti9xx_write_mask(chip, reg, value, mask)	\	snd_opti9xx_write(chip, reg,			\		(snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))static int __devinit snd_opti9xx_configure(opti9xx_t *chip){	unsigned char wss_base_bits;	unsigned char irq_bits;	unsigned char dma_bits;	unsigned char mpu_port_bits = 0;	unsigned char mpu_irq_bits;	switch (chip->hardware) {#ifndef OPTi93X	case OPTi9XX_HW_82C924:		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);	case OPTi9XX_HW_82C925:		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);#ifdef CS4231		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);#else		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);#endif	/* CS4231 */		break;	case OPTi9XX_HW_82C928:	case OPTi9XX_HW_82C929:		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);		/*		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xa2, 0xae);		*/		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c);#ifdef CS4231		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);#else		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);#endif	/* CS4231 */		break;#else	/* OPTi93X */	case OPTi9XX_HW_82C930:	case OPTi9XX_HW_82C931:	case OPTi9XX_HW_82C933:		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x03);		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0x00, 0xff);		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0x10 |			(chip->hardware == OPTi9XX_HW_82C930 ? 0x00 : 0x04),			0x34);		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x20, 0xbf);		break;#endif	/* OPTi93X */	default:		snd_printk("chip %d not supported\n", chip->hardware);		return -EINVAL;	}	switch (chip->wss_base) {	case 0x530:		wss_base_bits = 0x00;		break;	case 0x604:		wss_base_bits = 0x03;		break;	case 0xe80:		wss_base_bits = 0x01;		break;	case 0xf40:		wss_base_bits = 0x02;		break;	default:		snd_printk("WSS port 0x%lx not valid\n", chip->wss_base);		goto __skip_base;	}	snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);__skip_base:	switch (chip->irq) {//#ifdef OPTi93X	case 5:		irq_bits = 0x05;		break;//#endif	/* OPTi93X */	case 7:		irq_bits = 0x01;		break;	case 9:		irq_bits = 0x02;		break;	case 10:		irq_bits = 0x03;		break;	case 11:		irq_bits = 0x04;		break;	default:		snd_printk("WSS irq # %d not valid\n", chip->irq);		goto __skip_resources;	}	switch (chip->dma1) {	case 0:		dma_bits = 0x01;		break;	case 1:		dma_bits = 0x02;		break;	case 3:		dma_bits = 0x03;		break;	default:		snd_printk("WSS dma1 # %d not valid\n", chip->dma1);		goto __skip_resources;	}#if defined(CS4231) || defined(OPTi93X)	if (chip->dma1 == chip->dma2) {		snd_printk("don't want to share dmas\n");		return -EBUSY;	}	switch (chip->dma2) {	case 0:	case 1:		break;	default:		snd_printk("WSS dma2 # %d not valid\n", chip->dma2);		goto __skip_resources;	}	dma_bits |= 0x04;#endif	/* CS4231 || OPTi93X */#ifndef OPTi93X	 outb(irq_bits << 3 | dma_bits, chip->wss_base);#else /* OPTi93X */	snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));#endif /* OPTi93X */__skip_resources:	if (chip->hardware > OPTi9XX_HW_82C928) {		switch (chip->mpu_port) {		case 0:		case -1:			break;		case 0x300:			mpu_port_bits = 0x03;			break;		case 0x310:			mpu_port_bits = 0x02;			break;		case 0x320:			mpu_port_bits = 0x01;			break;		case 0x330:			mpu_port_bits = 0x00;			break;		default:			snd_printk("MPU-401 port 0x%lx not valid\n",				chip->mpu_port);			goto __skip_mpu;		}		switch (chip->mpu_irq) {		case 5:			mpu_irq_bits = 0x02;			break;		case 7:			mpu_irq_bits = 0x03;			break;		case 9:			mpu_irq_bits = 0x00;			break;		case 10:			mpu_irq_bits = 0x01;			break;		default:			snd_printk("MPU-401 irq # %d not valid\n",				chip->mpu_irq);			goto __skip_mpu;		}		snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6),			(chip->mpu_port <= 0) ? 0x00 :				0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,			0xf8);	}__skip_mpu:	return 0;}#ifdef OPTi93Xstatic unsigned char snd_opti93x_default_image[32] ={	0x00,		/* 00/00 - l_mixout_outctrl */	0x00,		/* 01/01 - r_mixout_outctrl */	0x88,		/* 02/02 - l_cd_inctrl */	0x88,		/* 03/03 - r_cd_inctrl */	0x88,		/* 04/04 - l_a1/fm_inctrl */	0x88,		/* 05/05 - r_a1/fm_inctrl */	0x80,		/* 06/06 - l_dac_inctrl */	0x80,		/* 07/07 - r_dac_inctrl */	0x00,		/* 08/08 - ply_dataform_reg */	0x00,		/* 09/09 - if_conf */	0x00,		/* 0a/10 - pin_ctrl */	0x00,		/* 0b/11 - err_init_reg */	0x0a,		/* 0c/12 - id_reg */	0x00,		/* 0d/13 - reserved */	0x00,		/* 0e/14 - ply_upcount_reg */	0x00,		/* 0f/15 - ply_lowcount_reg */	0x88,		/* 10/16 - reserved/l_a1_inctrl */	0x88,		/* 11/17 - reserved/r_a1_inctrl */	0x88,		/* 12/18 - l_line_inctrl */	0x88,		/* 13/19 - r_line_inctrl */	0x88,		/* 14/20 - l_mic_inctrl */	0x88,		/* 15/21 - r_mic_inctrl */	0x80,		/* 16/22 - l_out_outctrl */	0x80,		/* 17/23 - r_out_outctrl */	0x00,		/* 18/24 - reserved */	0x00,		/* 19/25 - reserved */	0x00,		/* 1a/26 - reserved */	0x00,		/* 1b/27 - reserved */	0x00,		/* 1c/28 - cap_dataform_reg */	0x00,		/* 1d/29 - reserved */	0x00,		/* 1e/30 - cap_upcount_reg */	0x00		/* 1f/31 - cap_lowcount_reg */};static int snd_opti93x_busy_wait(opti93x_t *chip){	int timeout;	for (timeout = 250; timeout-- > 0; udelay(10))		if (!(inb(OPTi93X_PORT(chip, INDEX)) & OPTi93X_INIT))			return 0;	snd_printk("chip still busy.\n");	return -EBUSY;}static unsigned char snd_opti93x_in(opti93x_t *chip, unsigned char reg){	snd_opti93x_busy_wait(chip);	outb(chip->mce_bit | (reg & 0x1f), OPTi93X_PORT(chip, INDEX));	return inb(OPTi93X_PORT(chip, DATA));}static void snd_opti93x_out(opti93x_t *chip, unsigned char reg,			    unsigned char value){	snd_opti93x_busy_wait(chip);	outb(chip->mce_bit | (reg & 0x1f), OPTi93X_PORT(chip, INDEX));	outb(value, OPTi93X_PORT(chip, DATA));}static void snd_opti93x_out_image(opti93x_t *chip, unsigned char reg,				  unsigned char value){	snd_opti93x_out(chip, reg, chip->image[reg] = value);}static void snd_opti93x_out_mask(opti93x_t *chip, unsigned char reg,				 unsigned char mask, unsigned char value){	snd_opti93x_out_image(chip, reg,		(chip->image[reg] & ~mask) | (value & mask));}static void snd_opti93x_mce_up(opti93x_t *chip){	snd_opti93x_busy_wait(chip);	chip->mce_bit = OPTi93X_MCE;	if (!(inb(OPTi93X_PORT(chip, INDEX)) & OPTi93X_MCE))		outb(chip->mce_bit, OPTi93X_PORT(chip, INDEX));}static void snd_opti93x_mce_down(opti93x_t *chip){	snd_opti93x_busy_wait(chip);	chip->mce_bit = 0;	if (inb(OPTi93X_PORT(chip, INDEX)) & OPTi93X_MCE)		outb(chip->mce_bit, OPTi93X_PORT(chip, INDEX));}#define snd_opti93x_mute_reg(chip, reg, mute)	\	snd_opti93x_out(chip, reg, mute ? 0x80 : chip->image[reg]);static void snd_opti93x_mute(opti93x_t *chip, int mute){	mute = mute ? 1 : 0;	if (chip->mute == mute)		return;	chip->mute = mute;	snd_opti93x_mute_reg(chip, OPTi93X_CD_LEFT_INPUT, mute);	snd_opti93x_mute_reg(chip, OPTi93X_CD_RIGHT_INPUT, mute);	switch (chip->hardware) {	case OPTi9XX_HW_82C930:		snd_opti93x_mute_reg(chip, OPTi930_AUX_LEFT_INPUT, mute);		snd_opti93x_mute_reg(chip, OPTi930_AUX_RIGHT_INPUT, mute);		break;	case OPTi9XX_HW_82C931:	case OPTi9XX_HW_82C933:		snd_opti93x_mute_reg(chip, OPTi931_FM_LEFT_INPUT, mute);		snd_opti93x_mute_reg(chip, OPTi931_FM_RIGHT_INPUT, mute);		snd_opti93x_mute_reg(chip, OPTi931_AUX_LEFT_INPUT, mute);		snd_opti93x_mute_reg(chip, OPTi931_AUX_RIGHT_INPUT, mute);	}	snd_opti93x_mute_reg(chip, OPTi93X_DAC_LEFT, mute);	snd_opti93x_mute_reg(chip, OPTi93X_DAC_RIGHT, mute);	snd_opti93x_mute_reg(chip, OPTi93X_LINE_LEFT_INPUT, mute);	snd_opti93x_mute_reg(chip, OPTi93X_LINE_RIGHT_INPUT, mute);	snd_opti93x_mute_reg(chip, OPTi93X_MIC_LEFT_INPUT, mute);	snd_opti93x_mute_reg(chip, OPTi93X_MIC_RIGHT_INPUT, mute);	snd_opti93x_mute_reg(chip, OPTi93X_OUT_LEFT, mute);	snd_opti93x_mute_reg(chip, OPTi93X_OUT_RIGHT, mute);}static unsigned int snd_opti93x_get_count(unsigned char format,					  unsigned int size){	switch (format & 0xe0) {	case OPTi93X_LINEAR_16_LIT:	case OPTi93X_LINEAR_16_BIG:		size >>= 1;		break;	case OPTi93X_ADPCM_16:		return size >> 2;	}	return (format & OPTi93X_STEREO) ? (size >> 1) : size;}static unsigned int rates[] = {  5512,  6615,  8000,  9600, 11025, 16000, 				18900, 22050, 27428, 32000, 33075, 37800,				44100, 48000 };#define RATES ARRAY_SIZE(rates)static snd_pcm_hw_constraint_list_t hw_constraints_rates = {	.count = RATES,	.list = rates,	.mask = 0,};static unsigned char bits[] = {  0x01,  0x0f,  0x00,  0x0e,  0x03,  0x02,				 0x05,  0x07,  0x04,  0x06,  0x0d,  0x09,				 0x0b,  0x0c};static unsigned char snd_opti93x_get_freq(unsigned int rate){	unsigned int i;	for (i = 0; i < RATES; i++) {		if (rate == rates[i])			return bits[i];	}	snd_BUG();	return bits[RATES-1];}static unsigned char snd_opti93x_get_format(opti93x_t *chip,					    unsigned int format, int channels){	unsigned char retval = OPTi93X_LINEAR_8;	switch (format) {	case SNDRV_PCM_FORMAT_MU_LAW:		retval = OPTi93X_ULAW_8;		break;	case SNDRV_PCM_FORMAT_A_LAW:		retval = OPTi93X_ALAW_8;		break;	case SNDRV_PCM_FORMAT_S16_LE:		retval = OPTi93X_LINEAR_16_LIT;		break;	case SNDRV_PCM_FORMAT_S16_BE:		retval = OPTi93X_LINEAR_16_BIG;		break;	case SNDRV_PCM_FORMAT_IMA_ADPCM:		retval = OPTi93X_ADPCM_16;	}	return (channels > 1) ? (retval | OPTi93X_STEREO) : retval;}static void snd_opti93x_playback_format(opti93x_t *chip, unsigned char fmt){	unsigned char mask;	snd_opti93x_mute(chip, 1);	snd_opti93x_mce_up(chip);	mask = (chip->mode & OPTi93X_MODE_CAPTURE) ? 0xf0 : 0xff;	snd_opti93x_out_mask(chip, OPTi93X_PLAY_FORMAT, mask, fmt);	snd_opti93x_mce_down(chip);	snd_opti93x_mute(chip, 0);}static void snd_opti93x_capture_format(opti93x_t *chip, unsigned char fmt){	snd_opti93x_mute(chip, 1);	snd_opti93x_mce_up(chip);	if (!(chip->mode & OPTi93X_MODE_PLAY))		snd_opti93x_out_mask(chip, OPTi93X_PLAY_FORMAT, 0x0f, fmt);	else		fmt = chip->image[OPTi93X_PLAY_FORMAT] & 0xf0;	snd_opti93x_out_image(chip, OPTi93X_CAPT_FORMAT, fmt);	snd_opti93x_mce_down(chip);	snd_opti93x_mute(chip, 0);}static int snd_opti93x_open(opti93x_t *chip, unsigned int mode){	unsigned long flags;	spin_lock_irqsave(&chip->lock, flags);	if (chip->mode & mode) {		spin_unlock_irqrestore(&chip->lock, flags);		return -EAGAIN;	}

⌨️ 快捷键说明

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