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

📄 tvaudio.c

📁 saa7134-0.2.9.tar.gz 电视卡驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	mode = VIDEO_SOUND_MONO;	if(-1 == (dsr = chip_read2(chip,TDA9874A_DSR)))		return mode;	if(-1 == (nsr = chip_read2(chip,TDA9874A_NSR)))		return mode;	if(-1 == (necr = chip_read2(chip,TDA9874A_NECR)))		return mode;	/* need to store dsr/nsr somewhere */	chip->shadow.bytes[MAXREGS-2] = dsr;	chip->shadow.bytes[MAXREGS-1] = nsr;	if(tda9874a_mode) {		/* Note: DSR.RSSF and DSR.AMSTAT bits are also checked.		 * If NICAM auto-muting is enabled, DSR.AMSTAT=1 indicates		 * that sound has (temporarily) switched from NICAM to		 * mono FM (or AM) on 1st sound carrier due to high NICAM bit		 * error count. So in fact there is no stereo in this case :-(		 * But changing the mode to VIDEO_SOUND_MONO would switch		 * external 4052 multiplexer in audio_hook().		 */#if 0		if((nsr & 0x02) && !(dsr & 0x10)) /* NSR.S/MB=1 and DSR.AMSTAT=0 */			mode |= VIDEO_SOUND_STEREO;#else		if(nsr & 0x02) /* NSR.S/MB=1 */			mode |= VIDEO_SOUND_STEREO;#endif		if(nsr & 0x01) /* NSR.D/SB=1 */ 			mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;	} else {		if(dsr & 0x02) /* DSR.IDSTE=1 */			mode |= VIDEO_SOUND_STEREO;		if(dsr & 0x04) /* DSR.IDDUA=1 */			mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;	}	dprintk("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",		 dsr, nsr, necr, mode);	return mode;}static void tda9874a_setmode(struct CHIPSTATE *chip, int mode){	/* Disable/enable NICAM auto-muting (based on DSR.RSSF status bit). */	/* If auto-muting is disabled, we can hear a signal of degrading quality. */	if(tda9874a_mode) {		if(chip->shadow.bytes[MAXREGS-2] & 0x20) /* DSR.RSSF=1 */			tda9874a_NCONR &= 0xfe; /* enable */		else			tda9874a_NCONR |= 0x01; /* disable */		chip_write(chip, TDA9874A_NCONR, tda9874a_NCONR);	}	/* Note: TDA9874A supports automatic FM dematrixing (FMMR register)	 * and has auto-select function for audio output (AOSR register).	 * Old TDA9874H doesn't support these features.	 * TDA9874A also has additional mono output pin (OUTM), which	 * on same (all?) tv-cards is not used, anyway (as well as MONOIN).	 */	if(tda9874a_dic == 0x11) {		int aosr = 0x80;		int mdacosr = (tda9874a_mode) ? 0x82:0x80;		switch(mode) {		case VIDEO_SOUND_MONO:		case VIDEO_SOUND_STEREO:			break;		case VIDEO_SOUND_LANG1:			aosr = 0x80; /* auto-select, dual A/A */			mdacosr = (tda9874a_mode) ? 0x82:0x80;			break;		case VIDEO_SOUND_LANG2:			aosr = 0xa0; /* auto-select, dual B/B */			mdacosr = (tda9874a_mode) ? 0x83:0x81;			break;		default:			chip->mode = 0;			return;		}		chip_write(chip, TDA9874A_AOSR, aosr);		chip_write(chip, TDA9874A_MDACOSR, mdacosr);		dprintk("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",			mode, aosr, mdacosr);	} else { /* dic == 0x07 */		int fmmr,aosr;		switch(mode) {		case VIDEO_SOUND_MONO:			fmmr = 0x00; /* mono */			aosr = 0x10; /* A/A */			break;		case VIDEO_SOUND_STEREO:			if(tda9874a_mode) {				fmmr = 0x00;				aosr = 0x00; /* handled by NICAM auto-mute */			} else {				fmmr = (tda9874a_ESP == 1) ? 0x05 : 0x04; /* stereo */				aosr = 0x00;			}			break;		case VIDEO_SOUND_LANG1:			fmmr = 0x02; /* dual */			aosr = 0x10; /* dual A/A */			break;		case VIDEO_SOUND_LANG2:			fmmr = 0x02; /* dual */			aosr = 0x20; /* dual B/B */			break;		default:			chip->mode = 0;			return;		}		chip_write(chip, TDA9874A_FMMR, fmmr);		chip_write(chip, TDA9874A_AOSR, aosr);		dprintk("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",			mode, fmmr, aosr);	}}static int tda9874a_checkit(struct CHIPSTATE *chip){	int dic,sic;	/* device id. and software id. codes */	if(-1 == (dic = chip_read2(chip,TDA9874A_DIC)))		return 0;	if(-1 == (sic = chip_read2(chip,TDA9874A_SIC)))		return 0;	dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);	if((dic == 0x11)||(dic == 0x07)) {		printk("tvaudio: found tda9874%s.\n", (dic == 0x11) ? "a":"h");		tda9874a_dic = dic;	/* remember device id. */		return 1;	}	return 0;	/* not found */}static int tda9874a_initialize(struct CHIPSTATE *chip){	if (tda9874a_SIF > 2)		tda9874a_SIF = 1;	if (tda9874a_STD >= 8)		tda9874a_STD = 0;	if(tda9874a_AMSEL > 1)		tda9874a_AMSEL = 0;	if(tda9874a_SIF == 1)		tda9874a_GCONR = 0xc0;	/* sound IF input 1 */	else		tda9874a_GCONR = 0xc1;	/* sound IF input 2 */	tda9874a_ESP = tda9874a_STD;	tda9874a_mode = (tda9874a_STD < 5) ? 0 : 1;	if(tda9874a_AMSEL == 0)		tda9874a_NCONR = 0x01; /* auto-mute: analog mono input */	else		tda9874a_NCONR = 0x05; /* auto-mute: 1st carrier FM or AM */	tda9874a_setup(chip);	return 0;}/* ---------------------------------------------------------------------- *//* audio chip descriptions - defines+functions for tea6420                */#define TEA6300_VL         0x00  /* volume left */#define TEA6300_VR         0x01  /* volume right */#define TEA6300_BA         0x02  /* bass */#define TEA6300_TR         0x03  /* treble */#define TEA6300_FA         0x04  /* fader control */#define TEA6300_S          0x05  /* switch register */                                 /* values for those registers: */#define TEA6300_S_SA       0x01  /* stereo A input */#define TEA6300_S_SB       0x02  /* stereo B */#define TEA6300_S_SC       0x04  /* stereo C */#define TEA6300_S_GMU      0x80  /* general mute */#define TEA6420_S_SA       0x00  /* stereo A input */#define TEA6420_S_SB       0x01  /* stereo B */#define TEA6420_S_SC       0x02  /* stereo C */#define TEA6420_S_SD       0x03  /* stereo D */#define TEA6420_S_SE       0x04  /* stereo E */#define TEA6420_S_GMU      0x05  /* general mute */static int tea6300_shift10(int val) { return val >> 10; }static int tea6300_shift12(int val) { return val >> 12; }/* ---------------------------------------------------------------------- *//* audio chip descriptions - defines+functions for tda8425                */#define TDA8425_VL         0x00  /* volume left */#define TDA8425_VR         0x01  /* volume right */#define TDA8425_BA         0x02  /* bass */#define TDA8425_TR         0x03  /* treble */#define TDA8425_S1         0x08  /* switch functions */                                 /* values for those registers: */#define TDA8425_S1_OFF     0xEE  /* audio off (mute on) */#define TDA8425_S1_CH1     0xCE  /* audio channel 1 (mute off) - "linear stereo" mode */#define TDA8425_S1_CH2     0xCF  /* audio channel 2 (mute off) - "linear stereo" mode */#define TDA8425_S1_MU      0x20  /* mute bit */#define TDA8425_S1_STEREO  0x18  /* stereo bits */#define TDA8425_S1_STEREO_SPATIAL 0x18 /* spatial stereo */#define TDA8425_S1_STEREO_LINEAR  0x08 /* linear stereo */#define TDA8425_S1_STEREO_PSEUDO  0x10 /* pseudo stereo */#define TDA8425_S1_STEREO_MONO    0x00 /* forced mono */#define TDA8425_S1_ML      0x06        /* language selector */#define TDA8425_S1_ML_SOUND_A 0x02     /* sound a */#define TDA8425_S1_ML_SOUND_B 0x04     /* sound b */#define TDA8425_S1_ML_STEREO  0x06     /* stereo */#define TDA8425_S1_IS      0x01        /* channel selector */static int tda8425_shift10(int val) { return (val >> 10) | 0xc0; }static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; }static int tda8425_initialize(struct CHIPSTATE *chip){	struct CHIPDESC *desc = chiplist + chip->type;	int inputmap[8] = { /* tuner	*/ TDA8425_S1_CH2, /* radio  */ TDA8425_S1_CH1,			    /* extern	*/ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF,			    /* off	*/ TDA8425_S1_OFF, /* on     */ TDA8425_S1_CH2};	if (chip->c.adapter->id == (I2C_ALGO_BIT | I2C_HW_B_RIVA)) {		memcpy (desc->inputmap, inputmap, sizeof (inputmap));	}	return 0;}static void tda8425_setmode(struct CHIPSTATE *chip, int mode){	int s1 = chip->shadow.bytes[TDA8425_S1+1] & 0xe1;		if (mode & VIDEO_SOUND_LANG1) {		s1 |= TDA8425_S1_ML_SOUND_A;		s1 |= TDA8425_S1_STEREO_PSEUDO;	} else if (mode & VIDEO_SOUND_LANG2) {		s1 |= TDA8425_S1_ML_SOUND_B;		s1 |= TDA8425_S1_STEREO_PSEUDO;			} else {		s1 |= TDA8425_S1_ML_STEREO;				if (mode & VIDEO_SOUND_MONO)			s1 |= TDA8425_S1_STEREO_MONO;		if (mode & VIDEO_SOUND_STEREO)			s1 |= TDA8425_S1_STEREO_SPATIAL;	}	chip_write(chip,TDA8425_S1,s1);}/* ---------------------------------------------------------------------- *//* audio chip descriptions - defines+functions for pic16c54 (PV951)       *//* the registers of 16C54, I2C sub address. */#define PIC16C54_REG_KEY_CODE     0x01	       /* Not use. */#define PIC16C54_REG_MISC         0x02/* bit definition of the RESET register, I2C data. */#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */                                            /*        code of remote controller */#define PIC16C54_MISC_MTS_MAIN         0x02 /* bit 1 */#define PIC16C54_MISC_MTS_SAP          0x04 /* bit 2 */#define PIC16C54_MISC_MTS_BOTH         0x08 /* bit 3 */#define PIC16C54_MISC_SND_MUTE         0x10 /* bit 4, Mute Audio(Line-in and Tuner) */#define PIC16C54_MISC_SND_NOTMUTE      0x20 /* bit 5 */#define PIC16C54_MISC_SWITCH_TUNER     0x40 /* bit 6	, Switch to Line-in */#define PIC16C54_MISC_SWITCH_LINE      0x80 /* bit 7	, Switch to Tuner *//* ---------------------------------------------------------------------- *//* audio chip descriptions - defines+functions for TA8874Z                */// write 1st byte#define TA8874Z_LED_STE	0x80#define TA8874Z_LED_BIL	0x40#define TA8874Z_LED_EXT	0x20#define TA8874Z_MONO_SET	0x10#define TA8874Z_MUTE	0x08#define TA8874Z_F_MONO	0x04#define TA8874Z_MODE_SUB	0x02#define TA8874Z_MODE_MAIN	0x01// write 2nd byte//#define TA8874Z_TI	0x80  // test mode#define TA8874Z_SEPARATION	0x3f#define TA8874Z_SEPARATION_DEFAULT	0x10// read#define TA8874Z_B1	0x80#define TA8874Z_B0	0x40#define TA8874Z_CHAG_FLAG	0x20//        B1 B0// mono    L  H// stereo  L  L// BIL     H  Lstatic int ta8874z_getmode(struct CHIPSTATE *chip){	int val, mode;		val = chip_read(chip);	mode = VIDEO_SOUND_MONO;	if (val & TA8874Z_B1){		mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;	}else if (!(val & TA8874Z_B0)){		mode |= VIDEO_SOUND_STEREO;	}	//dprintk ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode);	return mode;}static audiocmd ta8874z_stereo = { 2, {0, TA8874Z_SEPARATION_DEFAULT}};static audiocmd ta8874z_mono = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}};static audiocmd ta8874z_main = {2, { 0, TA8874Z_SEPARATION_DEFAULT}};static audiocmd ta8874z_sub = {2, { TA8874Z_MODE_SUB, TA8874Z_SEPARATION_DEFAULT}};static void ta8874z_setmode(struct CHIPSTATE *chip, int mode){	int update = 1;	audiocmd *t = NULL;	dprintk("ta8874z_setmode(): mode: 0x%02x\n", mode);	switch(mode){	case VIDEO_SOUND_MONO:		t = &ta8874z_mono;		break;	case VIDEO_SOUND_STEREO:		t = &ta8874z_stereo;		break;	case VIDEO_SOUND_LANG1:		t = &ta8874z_main;		break;	case VIDEO_SOUND_LANG2:		t = &ta8874z_sub;		break;	default:		update = 0;	}	if(update)		chip_cmd(chip, "TA8874Z", t);}static int ta8874z_checkit(struct CHIPSTATE *chip){	int rc;	rc = chip_read(chip);	return ((rc & 0x1f) == 0x1f) ? 1 : 0;}/* ---------------------------------------------------------------------- *//* audio chip descriptions - struct CHIPDESC                              *//* insmod options to enable/disable individual audio chips */int tda8425  = 1;int tda9840  = 1;int tda9850  = 1;int tda9855  = 1;int tda9873  = 1;int tda9874a = 1;int tea6300  = 0;  // address clash with msp34xxint tea6420  = 1;int pic16c54 = 1;int ta8874z  = 0;  // address clash with tda9840MODULE_PARM(tda8425,"i");MODULE_PARM(tda9840,"i");MODULE_PARM(tda9850,"i");MODULE_PARM(tda9855,"i");MODULE_PARM(tda9873,"i");MODULE_PARM(tda9874a,"i");MODULE_PARM(tea6300,"i");MODULE_PARM(tea6420,"i");MODULE_PARM(pic16c54,"i");MODULE_PARM(ta8874z,"i");static struct CHIPDESC chiplist[] = {	{		.name       = "tda9840",		.id         = I2C_DRIVERID_TDA9840,		.insmodopt  = &tda9840,		.addr_lo    = I2C_TDA9840 >> 1,		.addr_hi    = I2C_TDA9840 >> 1,		.registers  = 5,		.getmode    = tda9840_getmode,		.setmode    = tda9840_setmode,		.checkmode  = generic_checkmode,	        .init       = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN				/* ,TDA9840_SW, TDA9840_MONO */} }	},	{		.name       = "tda9873h",		.id         = I2C_DRIVERID_TDA9873,		.checkit    = tda9873_checkit,		.insmodopt  = &tda9873,		.addr_lo    = I2C_TDA985x_L >> 1,		.addr_hi    = I2C_TDA985x_H >> 1,		.registers  = 3,		.flags      = CHIP_HAS_INPUTSEL,		.getmode    = tda9873_getmode,		.setmode    = tda9873_setmode,		.checkmode  = generic_checkmode,		.init       = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } },		.inputreg   = TDA9873_SW,		.inputmute  = TDA9873_MUTE | TDA9873_AUTOMUTE,		.inputmap   = {0xa0, 0xa2, 0xa0, 0xa0, 0xc0},		.inputmask  = TDA9873_INP_MASK|TDA9873_MUTE|TDA9873_AUTOMUTE,			},	{		.name       = "tda9874h/a",		.id         = I2C_DRIVERID_TDA9874,

⌨️ 快捷键说明

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