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

📄 cx88-tvaudio.c

📁 底层驱动开发
💻 C
📖 第 1 页 / 共 3 页
字号:
		{ AUD_DEEMPH1_G0,	0x0D80 },		{ AUD_DEEMPH1_A0,	0x6262 },		{ AUD_DEEMPH1_B0,	0x1C29 },		{ AUD_DEEMPH1_A1,	0x3FC66},		{ AUD_DEEMPH1_B1,	0x399A},		{ AUD_POLYPH80SCALEFAC,	0x0003},		{ /* end of list */ },	};	static const struct rlist fm_deemph_75[] = {		{ AUD_DEEMPH0_G0,	0x091B },		{ AUD_DEEMPH0_A0,	0x6B68 },		{ AUD_DEEMPH0_B0,	0x11EC },		{ AUD_DEEMPH0_A1,	0x3FC66},		{ AUD_DEEMPH0_B1,	0x399A },		{ AUD_DEEMPH1_G0,	0x0AA0 },		{ AUD_DEEMPH1_A0,	0x6B68 },		{ AUD_DEEMPH1_B0,	0x11EC },		{ AUD_DEEMPH1_A1,	0x3FC66},		{ AUD_DEEMPH1_B1,	0x399A},		{ AUD_POLYPH80SCALEFAC,	0x0003},		{ /* end of list */ },	};	/* It is enough to leave default values? */	static const struct rlist fm_no_deemph[] = {		{ AUD_POLYPH80SCALEFAC,	0x0003},		{ /* end of list */ },	};	dprintk("%s (status: unknown)\n",__FUNCTION__);	set_audio_start(core, SEL_FMRADIO);	switch (deemph)	{		case FM_NO_DEEMPH:			set_audio_registers(core, fm_no_deemph);			break;		case FM_DEEMPH_50:			set_audio_registers(core, fm_deemph_50);			break;		case FM_DEEMPH_75:			set_audio_registers(core, fm_deemph_75);			break;	}	set_audio_finish(core, EN_FMRADIO_AUTO_STEREO);}/* ----------------------------------------------------------- */void cx88_set_tvaudio(struct cx88_core *core){	switch (core->tvaudio) {	case WW_BTSC:		set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);		break;	case WW_NICAM_BGDKL:		set_audio_standard_NICAM_L(core,0);		break;	case WW_NICAM_I:		set_audio_standard_PAL_I(core,0);		break;	case WW_A2_BG:	case WW_A2_DK:	case WW_A2_M:	set_audio_standard_A2(core, EN_A2_FORCE_MONO1);		break;	case WW_EIAJ:		set_audio_standard_EIAJ(core);		break;	case WW_FM:		set_audio_standard_FM(core,FM_NO_DEEMPH);		break;	case WW_SYSTEM_L_AM:		set_audio_standard_NICAM_L(core, 1);		break;	case WW_NONE:	default:		printk("%s/0: unknown tv audio mode [%d]\n",		core->name, core->tvaudio);		break;	}	return;}void cx88_newstation(struct cx88_core *core){	core->audiomode_manual = UNSET;	switch (core->tvaudio) {	case WW_SYSTEM_L_AM:		/* try nicam ... */		core->audiomode_current = V4L2_TUNER_MODE_STEREO;		set_audio_standard_NICAM_L(core, 1);		break;	}}void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t){	static char *m[] = {"stereo", "dual mono", "mono", "sap"};	static char *p[] = {"no pilot", "pilot c1", "pilot c2", "?"};	u32 reg,mode,pilot;	reg   = cx_read(AUD_STATUS);	mode  = reg & 0x03;	pilot = (reg >> 2) & 0x03;	if (core->astat != reg)		dprintk("AUD_STATUS: 0x%x [%s/%s] ctl=%s\n",			reg, m[mode], p[pilot],			aud_ctl_names[cx_read(AUD_CTL) & 63]);	core->astat = reg;/* TODO       Reading from AUD_STATUS is not enough       for auto-detecting sap/dual-fm/nicam.       Add some code here later.*/# if 0	t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |		V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;	t->rxsubchans = V4L2_TUNER_SUB_MONO;	t->audmode    = V4L2_TUNER_MODE_MONO;	switch (core->tvaudio) {	case WW_BTSC:		t->capability = V4L2_TUNER_CAP_STEREO |			V4L2_TUNER_CAP_SAP;		t->rxsubchans = V4L2_TUNER_SUB_STEREO;		if (1 == pilot) {			/* SAP */			t->rxsubchans |= V4L2_TUNER_SUB_SAP;		}		break;	case WW_A2_BG:	case WW_A2_DK:	case WW_A2_M:		if (1 == pilot) {			/* stereo */			t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;			if (0 == mode)				t->audmode = V4L2_TUNER_MODE_STEREO;		}		if (2 == pilot) {			/* dual language -- FIXME */			t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;			t->audmode = V4L2_TUNER_MODE_LANG1;		}		break;	case WW_NICAM_BGDKL:		if (0 == mode) {			t->audmode = V4L2_TUNER_MODE_STEREO;			t->rxsubchans |= V4L2_TUNER_SUB_STEREO;		}		break;	case WW_SYSTEM_L_AM:		if (0x0 == mode && !(cx_read(AUD_INIT) & 0x04)) {			t->audmode = V4L2_TUNER_MODE_STEREO;			t->rxsubchans |= V4L2_TUNER_SUB_STEREO;		}		break ;	default:		/* nothing */		break;	}# endif	return;}void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual){	u32 ctl  = UNSET;	u32 mask = UNSET;	if (manual) {		core->audiomode_manual = mode;	} else {		if (UNSET != core->audiomode_manual)			return;	}	core->audiomode_current = mode;	switch (core->tvaudio) {	case WW_BTSC:		switch (mode) {		case V4L2_TUNER_MODE_MONO:			set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_MONO);			break;		case V4L2_TUNER_MODE_LANG1:			set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);			break;		case V4L2_TUNER_MODE_LANG2:			set_audio_standard_BTSC(core, 1, EN_BTSC_FORCE_SAP);			break;		case V4L2_TUNER_MODE_STEREO:			set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_STEREO);			break;		}		break;	case WW_A2_BG:	case WW_A2_DK:	case WW_A2_M:		switch (mode) {		case V4L2_TUNER_MODE_MONO:		case V4L2_TUNER_MODE_LANG1:		set_audio_standard_A2(core, EN_A2_FORCE_MONO1);			break;		case V4L2_TUNER_MODE_LANG2:		set_audio_standard_A2(core, EN_A2_FORCE_MONO2);			break;		case V4L2_TUNER_MODE_STEREO:		set_audio_standard_A2(core, EN_A2_FORCE_STEREO);			break;		}		break;	case WW_NICAM_BGDKL:		switch (mode) {		case V4L2_TUNER_MODE_MONO:			ctl  = EN_NICAM_FORCE_MONO1;			mask = 0x3f;			break;		case V4L2_TUNER_MODE_LANG1:			ctl  = EN_NICAM_AUTO_MONO2;			mask = 0x3f;			break;		case V4L2_TUNER_MODE_STEREO:			ctl  = EN_NICAM_FORCE_STEREO | EN_DMTRX_LR;			mask = 0x93f;			break;		}		break;	case WW_SYSTEM_L_AM:		switch (mode) {		case V4L2_TUNER_MODE_MONO:		case V4L2_TUNER_MODE_LANG1:  /* FIXME */			set_audio_standard_NICAM_L(core, 0);			break;		case V4L2_TUNER_MODE_STEREO:			set_audio_standard_NICAM_L(core, 1);			break;		}		break;	case WW_NICAM_I:		switch (mode) {		case V4L2_TUNER_MODE_MONO:		case V4L2_TUNER_MODE_LANG1:			set_audio_standard_PAL_I(core, 0);			break;		case V4L2_TUNER_MODE_STEREO:			set_audio_standard_PAL_I(core, 1);			break;		}		break;	case WW_FM:		switch (mode) {		case V4L2_TUNER_MODE_MONO:			ctl  = EN_FMRADIO_FORCE_MONO;			mask = 0x3f;			break;		case V4L2_TUNER_MODE_STEREO:			ctl  = EN_FMRADIO_AUTO_STEREO;			mask = 0x3f;			break;		}		break;	}	if (UNSET != ctl) {		dprintk("cx88_set_stereo: mask 0x%x, ctl 0x%x "			"[status=0x%x,ctl=0x%x,vol=0x%x]\n",			mask, ctl, cx_read(AUD_STATUS),			cx_read(AUD_CTL), cx_sread(SHADOW_AUD_VOL_CTL));		cx_andor(AUD_CTL, mask, ctl);	}	return;}int cx88_audio_thread(void *data){	struct cx88_core *core = data;	struct v4l2_tuner t;	u32 mode = 0;	dprintk("cx88: tvaudio thread started\n");	for (;;) {		msleep_interruptible(1000);		if (kthread_should_stop())			break;		/* just monitor the audio status for now ... */		memset(&t,0,sizeof(t));		cx88_get_stereo(core,&t);		if (UNSET != core->audiomode_manual)			/* manually set, don't do anything. */			continue;		/* monitor signal */		if (t.rxsubchans & V4L2_TUNER_SUB_STEREO)			mode = V4L2_TUNER_MODE_STEREO;		else			mode = V4L2_TUNER_MODE_MONO;		if (mode == core->audiomode_current)			continue;		/* automatically switch to best available mode */		cx88_set_stereo(core, mode, 0);	}	dprintk("cx88: tvaudio thread exiting\n");	return 0;}/* ----------------------------------------------------------- */EXPORT_SYMBOL(cx88_set_tvaudio);EXPORT_SYMBOL(cx88_newstation);EXPORT_SYMBOL(cx88_set_stereo);EXPORT_SYMBOL(cx88_get_stereo);EXPORT_SYMBOL(cx88_audio_thread);/* * Local variables: * c-basic-offset: 8 * End: * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off */

⌨️ 快捷键说明

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