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

📄 msp3400-kthreads.c

📁 V4l driver for DVB HD
💻 C
📖 第 1 页 / 共 3 页
字号:
{	struct msp_state *state = i2c_get_clientdata(client);	int val;	int rxsubchans = state->rxsubchans;	int newnicam = state->nicam_on;	int update = 0;	switch (state->mode) {	case MSP_MODE_FM_TERRA:		val = msp_read_dsp(client, 0x18);		if (val > 32767)			val -= 65536;		v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val);		if (val > 8192) {			rxsubchans = V4L2_TUNER_SUB_STEREO;		} else if (val < -4096) {			rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;		} else {			rxsubchans = V4L2_TUNER_SUB_MONO;		}		newnicam = 0;		break;	case MSP_MODE_FM_NICAM1:	case MSP_MODE_FM_NICAM2:	case MSP_MODE_AM_NICAM:		val = msp_read_dem(client, 0x23);		v4l_dbg(2, msp_debug, client, "nicam sync=%d, mode=%d\n",			val & 1, (val & 0x1e) >> 1);		if (val & 1) {			/* nicam synced */			switch ((val & 0x1e) >> 1)  {			case 0:			case 8:				rxsubchans = V4L2_TUNER_SUB_STEREO;				break;			case 1:			case 9:				rxsubchans = V4L2_TUNER_SUB_MONO;				break;			case 2:			case 10:				rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;				break;			default:				rxsubchans = V4L2_TUNER_SUB_MONO;				break;			}			newnicam = 1;		} else {			newnicam = 0;			rxsubchans = V4L2_TUNER_SUB_MONO;		}		break;	}	if (rxsubchans != state->rxsubchans) {		update = 1;		v4l_dbg(1, msp_debug, client, "watch: rxsubchans %02x => %02x\n",			state->rxsubchans, rxsubchans);		state->rxsubchans = rxsubchans;	}	if (newnicam != state->nicam_on) {		update = 1;		v4l_dbg(1, msp_debug, client, "watch: nicam %d => %d\n",			state->nicam_on, newnicam);		state->nicam_on = newnicam;	}	return update;}/* * A kernel thread for msp3400 control -- we don't want to block the * in the ioctl while doing the sound carrier & stereo detect *//* stereo/multilang monitoring */static void watch_stereo(struct i2c_client *client){	struct msp_state *state = i2c_get_clientdata(client);	if (msp_detect_stereo(client)) {		msp_set_audmode(client);	}	if (msp_once)		state->watch_stereo = 0;}int msp3400c_thread(void *data){	struct i2c_client *client = data;	struct msp_state *state = i2c_get_clientdata(client);	struct msp3400c_carrier_detect *cd;	int count, max1, max2, val1, val2, val, this;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	msp_setup_thread(state);#endif	v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n");	for (;;) {		v4l_dbg(2, msp_debug, client, "msp3400 thread: sleep\n");		msp_sleep(state, -1);		v4l_dbg(2, msp_debug, client, "msp3400 thread: wakeup\n");	restart:		v4l_dbg(2, msp_debug, client, "thread: restart scan\n");		state->restart = 0;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		if (state->rmmod || signal_pending(current))#else		if (kthread_should_stop())#endif			break;		if (state->radio || MSP_MODE_EXTERN == state->mode) {			/* no carrier scan, just unmute */			v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n");			state->scan_in_progress = 0;			state->rxsubchans = V4L2_TUNER_SUB_STEREO;			msp_set_audio(client);			continue;		}		/* mute audio */		state->scan_in_progress = 1;		msp_set_audio(client);		msp3400c_set_mode(client, MSP_MODE_AM_DETECT);		val1 = val2 = 0;		max1 = max2 = -1;		state->watch_stereo = 0;		state->nicam_on = 0;		/* wait for tuner to settle down after a channel change */		if (msp_sleep(state, 200))			goto restart;		/* carrier detect pass #1 -- main carrier */		cd = msp3400c_carrier_detect_main;		count = ARRAY_SIZE(msp3400c_carrier_detect_main);		if (msp_amsound && (state->v4l2_std & V4L2_STD_SECAM)) {			/* autodetect doesn't work well with AM ... */			max1 = 3;			count = 0;			v4l_dbg(1, msp_debug, client, "AM sound override\n");		}		for (this = 0; this < count; this++) {			msp3400c_set_carrier(client, cd[this].cdo, cd[this].cdo);			if (msp_sleep(state,100))				goto restart;			val = msp_read_dsp(client, 0x1b);			if (val > 32767)				val -= 65536;			if (val1 < val)				val1 = val, max1 = this;			v4l_dbg(1, msp_debug, client, "carrier1 val: %5d / %s\n", val,cd[this].name);		}		/* carrier detect pass #2 -- second (stereo) carrier */		switch (max1) {		case 1: /* 5.5 */			cd = msp3400c_carrier_detect_55;			count = ARRAY_SIZE(msp3400c_carrier_detect_55);			break;		case 3: /* 6.5 */			cd = msp3400c_carrier_detect_65;			count = ARRAY_SIZE(msp3400c_carrier_detect_65);			break;		case 0: /* 4.5 */		case 2: /* 6.0 */		default:			cd = NULL;			count = 0;			break;		}		if (msp_amsound && (state->v4l2_std & V4L2_STD_SECAM)) {			/* autodetect doesn't work well with AM ... */			cd = NULL;			count = 0;			max2 = 0;		}		for (this = 0; this < count; this++) {			msp3400c_set_carrier(client, cd[this].cdo, cd[this].cdo);			if (msp_sleep(state,100))				goto restart;			val = msp_read_dsp(client, 0x1b);			if (val > 32767)				val -= 65536;			if (val2 < val)				val2 = val, max2 = this;			v4l_dbg(1, msp_debug, client, "carrier2 val: %5d / %s\n", val,cd[this].name);		}		/* program the msp3400 according to the results */		state->main = msp3400c_carrier_detect_main[max1].cdo;		switch (max1) {		case 1: /* 5.5 */			if (max2 == 0) {				/* B/G FM-stereo */				state->second = msp3400c_carrier_detect_55[max2].cdo;				msp3400c_set_mode(client, MSP_MODE_FM_TERRA);				state->watch_stereo = 1;			} else if (max2 == 1 && state->has_nicam) {				/* B/G NICAM */				state->second = msp3400c_carrier_detect_55[max2].cdo;				msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);				state->nicam_on = 1;				state->watch_stereo = 1;			} else {				goto no_second;			}			break;		case 2: /* 6.0 */			/* PAL I NICAM */			state->second = MSP_CARRIER(6.552);			msp3400c_set_mode(client, MSP_MODE_FM_NICAM2);			state->nicam_on = 1;			state->watch_stereo = 1;			break;		case 3: /* 6.5 */			if (max2 == 1 || max2 == 2) {				/* D/K FM-stereo */				state->second = msp3400c_carrier_detect_65[max2].cdo;				msp3400c_set_mode(client, MSP_MODE_FM_TERRA);				state->watch_stereo = 1;			} else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) {				/* L NICAM or AM-mono */				state->second = msp3400c_carrier_detect_65[max2].cdo;				msp3400c_set_mode(client, MSP_MODE_AM_NICAM);				state->watch_stereo = 1;			} else if (max2 == 0 && state->has_nicam) {				/* D/K NICAM */				state->second = msp3400c_carrier_detect_65[max2].cdo;				msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);				state->nicam_on = 1;				state->watch_stereo = 1;			} else {				goto no_second;			}			break;		case 0: /* 4.5 */		default:		no_second:			state->second = msp3400c_carrier_detect_main[max1].cdo;			msp3400c_set_mode(client, MSP_MODE_FM_TERRA);			break;		}		msp3400c_set_carrier(client, state->second, state->main);		/* unmute */		state->scan_in_progress = 0;		msp3400c_set_audmode(client);		msp_set_audio(client);		if (msp_debug)			msp3400c_print_mode(client);		/* monitor tv audio mode, the first time don't wait		   so long to get a quick stereo/bilingual result */		count = 3;		while (state->watch_stereo) {			if (msp_sleep(state, count ? 1000 : 5000))				goto restart;			if (count) count--;			watch_stereo(client);		}	}	v4l_dbg(1, msp_debug, client, "thread: exit\n");#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	state->kthread = NULL;	if (state->notify != NULL)		up(state->notify);#endif	return 0;}int msp3410d_thread(void *data){	struct i2c_client *client = data;	struct msp_state *state = i2c_get_clientdata(client);	int val, i, std, count;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	msp_setup_thread(state);#endif	v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n");	for (;;) {		v4l_dbg(2, msp_debug, client, "msp3410 thread: sleep\n");		msp_sleep(state,-1);		v4l_dbg(2, msp_debug, client, "msp3410 thread: wakeup\n");	restart:		v4l_dbg(2, msp_debug, client, "thread: restart scan\n");		state->restart = 0;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		if (state->rmmod || signal_pending(current))#else		if (kthread_should_stop())#endif			break;		if (state->mode == MSP_MODE_EXTERN) {			/* no carrier scan needed, just unmute */			v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n");			state->scan_in_progress = 0;			msp_set_audio(client);			continue;		}		/* mute audio */		state->scan_in_progress = 1;		msp_set_audio(client);		/* start autodetect. Note: autodetect is not supported for		   NTSC-M and radio, hence we force the standard in those cases. */		if (state->radio)			std = 0x40;		else			std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;		state->watch_stereo = 0;		state->nicam_on = 0;		/* wait for tuner to settle down after a channel change */		if (msp_sleep(state, 200))			goto restart;		if (msp_debug)			v4l_dbg(2, msp_debug, client, "setting standard: %s (0x%04x)\n",			       msp_standard_std_name(std), std);		if (std != 1) {			/* programmed some specific mode */			val = std;		} else {			/* triggered autodetect */			msp_write_dem(client, 0x20, std);			for (;;) {				if (msp_sleep(state, 100))					goto restart;				/* check results */				val = msp_read_dem(client, 0x7e);				if (val < 0x07ff)					break;				v4l_dbg(2, msp_debug, client, "detection still in progress\n");			}		}		for (i = 0; msp_stdlist[i].name != NULL; i++)			if (msp_stdlist[i].retval == val)				break;		v4l_dbg(1, msp_debug, client, "current standard: %s (0x%04x)\n",			msp_standard_std_name(val), val);		state->main   = msp_stdlist[i].main;		state->second = msp_stdlist[i].second;		state->std = val;		state->rxsubchans = V4L2_TUNER_SUB_MONO;		if (msp_amsound && !state->radio && (state->v4l2_std & V4L2_STD_SECAM) &&				(val != 0x0009)) {			/* autodetection has failed, let backup */			v4l_dbg(1, msp_debug, client, "autodetection failed,"				" switching to backup standard: %s (0x%04x)\n",				msp_stdlist[8].name ? msp_stdlist[8].name : "unknown",val);			state->std = val = 0x0009;			msp_write_dem(client, 0x20, val);		}		/* set stereo */		switch (val) {		case 0x0008: /* B/G NICAM */		case 0x000a: /* I NICAM */		case 0x000b: /* D/K NICAM */			if (val == 0x000a)				state->mode = MSP_MODE_FM_NICAM2;

⌨️ 快捷键说明

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