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

📄 msp3400.c

📁 powerpc内核mpc8241linux系统下char驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	case MSP_MODE_FM_NICAM1:	case MSP_MODE_FM_NICAM2:		dprintk("msp3400: NICAM setstereo: %d\n",mode);		msp->stereo = mode;		msp3400c_setcarrier(msp->bus,msp->second,msp->main);		nicam=0x0100;		break;	default:		/* can't do stereo - abort here */		return;	}	/* switch audio */	switch (mode) {	case VIDEO_SOUND_STEREO:		msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0008,0x0020|nicam);		msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0009,0x0020|nicam);		msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x000a,0x0020|nicam);#if 0		msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0005,0x4000);#endif		break;	case VIDEO_SOUND_MONO:	case VIDEO_SOUND_LANG1:		msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0008,0x0000|nicam);		msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0009,0x0000|nicam);		msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x000a,0x0000|nicam);		break;	case VIDEO_SOUND_LANG2:		msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0008,0x0010|nicam);		msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0009,0x0010|nicam);		msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x000a,0x0010|nicam);		break;	}}static voidmsp3400c_print_mode(struct msp3400c *msp){	if (msp->main == msp->second) {		printk("msp3400: mono sound carrier: %d.%03d MHz\n",		       msp->main/910000,(msp->main/910)%1000);	} else {		printk("msp3400: main sound carrier: %d.%03d MHz\n",		       msp->main/910000,(msp->main/910)%1000);	}	if (msp->mode == MSP_MODE_FM_NICAM1 ||	    msp->mode == MSP_MODE_FM_NICAM2)		printk("msp3400: NICAM carrier     : %d.%03d MHz\n",		       msp->second/910000,(msp->second/910)%1000);	if (msp->mode == MSP_MODE_FM_TERRA &&	    msp->main != msp->second) {		printk("msp3400: FM-stereo carrier : %d.%03d MHz\n",		       msp->second/910000,(msp->second/910)%1000);	}}/* ----------------------------------------------------------------------- */struct REGISTER_DUMP {	int   addr;	char *name;};struct REGISTER_DUMP d1[] = {	{ 0x007e, "autodetect" },	{ 0x0023, "C_AD_BITS " },	{ 0x0038, "ADD_BITS  " },	{ 0x003e, "CIB_BITS  " },	{ 0x0057, "ERROR_RATE" },};/* * A kernel thread for msp3400 control -- we don't want to block the * in the ioctl while doing the sound carrier & stereo detect */static void msp3400c_stereo_wake(unsigned long data){	struct msp3400c *msp = (struct msp3400c*)data;   /* XXX alpha ??? */	wake_up_interruptible(&msp->wq);}static int msp3400c_thread(void *data){	struct msp3400c *msp = data;    	struct CARRIER_DETECT *cd;	int                   count, max1,max2,val1,val2, val,this;	int                   newstereo;	LOCK_FLAGS;    #ifdef __SMP__	lock_kernel();#endif    	exit_mm(current);	current->session = 1;	current->pgrp = 1;	sigfillset(&current->blocked);	current->fs->umask = 0;	strcpy(current->comm,"msp3400");	msp->wq     = NULL;	msp->thread = current;#ifdef __SMP__	unlock_kernel();#endif	dprintk("msp3400: thread: start\n");	if(msp->notify != NULL)		up(msp->notify);			for (;;) {		if (msp->rmmod)			goto done;		if (debug > 1)			printk("msp3400: thread: sleep\n");		interruptible_sleep_on(&msp->wq);		if (debug > 1)			printk("msp3400: thread: wakeup\n");		if (msp->rmmod || signal_pending(current))			goto done;		if (VIDEO_MODE_RADIO == msp->norm)			continue;  /* nothing to do */			msp->active = 1;		if (msp->watch_stereo) {			/* do that stereo/multilang handling */			LOCK_I2C_BUS(msp->bus);			newstereo = msp->stereo;			switch (msp->mode) {			case MSP_MODE_FM_TERRA:				val = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x18);				dprintk("msp3400: stereo detect register: %d\n",val);						if (val > 4096) {					newstereo = VIDEO_SOUND_STEREO;				} else if (val < -4096) {					newstereo = VIDEO_SOUND_LANG1;				} else {					newstereo = VIDEO_SOUND_MONO;				}				break;			case MSP_MODE_FM_NICAM1:			case MSP_MODE_FM_NICAM2:				val = msp3400c_read(msp->bus, I2C_MSP3400C_DEM, 0x23);				switch ((val & 0x1e) >> 1)  {				case 0:				case 8:					newstereo = VIDEO_SOUND_STEREO;					break;				default:					newstereo = VIDEO_SOUND_MONO;					break;				}				break;			}			if (msp->stereo != newstereo) {				dprintk("msp3400: watch: stereo %d ==> %d\n",					msp->stereo,newstereo);				msp3400c_setstereo(msp,newstereo);			}			UNLOCK_I2C_BUS(msp->bus);			if (msp->watch_stereo) {				del_timer(&msp->wake_stereo);				msp->wake_stereo.expires = jiffies + 5*HZ;				add_timer(&msp->wake_stereo);			}			msp->active = 0;			continue;		}		restart:		LOCK_I2C_BUS(msp->bus);		msp3400c_setvolume(msp->bus, 0, 0);		msp3400c_setmode(msp, MSP_MODE_AM_DETECT);		val1 = val2 = 0;		max1 = max2 = -1;		del_timer(&msp->wake_stereo);		msp->watch_stereo = 0;		/* carrier detect pass #1 -- main carrier */		cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main);		for (this = 0; this < count; this++) {			msp3400c_setcarrier(msp->bus, cd[this].cdo,cd[this].cdo);			UNLOCK_I2C_BUS(msp->bus);			current->state   = TASK_INTERRUPTIBLE;			schedule_timeout(HZ/25);			if (signal_pending(current))				goto done;			if (msp->restart) {				msp->restart = 0;				goto restart;			}			LOCK_I2C_BUS(msp->bus);			val = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1b);			if (val1 < val)				val1 = val, max1 = this;			dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name);		}		/* carrier detect pass #2 -- second (stereo) carrier */		switch (max1) {		case 1: /* 5.5 */			cd = carrier_detect_55; count = CARRIER_COUNT(carrier_detect_55);			break;		case 3: /* 6.5 */			cd = carrier_detect_65; count = CARRIER_COUNT(carrier_detect_65);			break;		case 0: /* 4.5 */		case 2: /* 6.0 */		default:			cd = NULL; count = 0;			break;		}		for (this = 0; this < count; this++) {			msp3400c_setcarrier(msp->bus, cd[this].cdo,cd[this].cdo);			UNLOCK_I2C_BUS(msp->bus);			current->state   = TASK_INTERRUPTIBLE;			schedule_timeout(HZ/25);			if (signal_pending(current))				goto done;			if (msp->restart) {				msp->restart = 0;				goto restart;			}			LOCK_I2C_BUS(msp->bus);			val = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1b);			if (val2 < val)				val2 = val, max2 = this;			dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name);		}		/* programm the msp3400 according to the results */		msp->main   = carrier_detect_main[max1].cdo;		switch (max1) {		case 1: /* 5.5 */			if (max2 == 0) {				/* B/G FM-stereo */				msp->second = carrier_detect_55[max2].cdo;				msp3400c_setmode(msp, MSP_MODE_FM_TERRA);				msp3400c_setstereo(msp, VIDEO_SOUND_MONO);				msp->watch_stereo = 1;			} else if (max2 == 1 && msp->nicam) {				/* B/G NICAM */				msp->second = carrier_detect_55[max2].cdo;				msp3400c_setmode(msp, MSP_MODE_FM_NICAM1);				msp3400c_setcarrier(msp->bus, msp->second, msp->main);				msp->watch_stereo = 1;			} else {				goto no_second;			}			break;		case 2: /* 6.0 */			/* PAL I NICAM */			msp->second = MSP_CARRIER(6.552);			msp3400c_setmode(msp, MSP_MODE_FM_NICAM2);			msp3400c_setcarrier(msp->bus, msp->second, msp->main);			msp->watch_stereo = 1;			break;		case 3: /* 6.5 */			if (max2 == 1 || max2 == 2) {				/* D/K FM-stereo */				msp->second = carrier_detect_65[max2].cdo;				msp3400c_setmode(msp, MSP_MODE_FM_TERRA);				msp3400c_setstereo(msp, VIDEO_SOUND_MONO);				msp->watch_stereo = 1;			} else if (max2 == 0 && msp->nicam) {				/* D/K NICAM */				msp->second = carrier_detect_65[max2].cdo;				msp3400c_setmode(msp, MSP_MODE_FM_NICAM1);				msp3400c_setcarrier(msp->bus, msp->second, msp->main);				msp->watch_stereo = 1;			} else {				goto no_second;			}			break;		case 0: /* 4.5 */		default:		no_second:			msp->second = carrier_detect_main[max1].cdo;			msp3400c_setmode(msp, MSP_MODE_FM_TERRA);			msp3400c_setcarrier(msp->bus, msp->second, msp->main);			break;		}		/* unmute */		msp3400c_setvolume(msp->bus, msp->left, msp->right);		UNLOCK_I2C_BUS(msp->bus);		if (msp->watch_stereo) {			del_timer(&msp->wake_stereo);			msp->wake_stereo.expires = jiffies + 2*HZ;			add_timer(&msp->wake_stereo);		}		if (debug)			msp3400c_print_mode(msp);				msp->active = 0;	}done:	dprintk("msp3400: thread: exit\n");	msp->active = 0;	msp->thread = NULL;	if(msp->notify != NULL)		up(msp->notify);	return 0;}#if 0 /* not finished yet */static int msp3410d_thread(void *data){	unsigned long flags;	struct msp3400c *msp = data;	struct semaphore sem = MUTEX_LOCKED;	int              i, val;	/* lock_kernel(); */    	exit_mm(current);	current->session = 1;	current->pgrp = 1;	sigfillset(&current->blocked);	current->fs->umask = 0;	strcpy(current->comm,"msp3410 (nicam)");	msp->wait   = &sem;	msp->thread = current;	/* unlock_kernel(); */	dprintk("msp3410: thread: start\n");	if(msp->notify != NULL)		up(msp->notify);			for (;;) {		if (msp->rmmod)			goto done;		dprintk("msp3410: thread: sleep\n");		down_interruptible(&sem);		dprintk("msp3410: thread: wakeup\n");		if (msp->rmmod)			goto done;			if (VIDEO_MODE_RADIO == msp->norm)			continue;  /* nothing to do */			msp->active = 1;	restart:		LOCK_I2C_BUS(msp->bus);		/* mute */		msp3400c_setvolume(msp->bus, 0);		/* quick & dirty hack:		   get the audio proccessor into some useful state */		msp3400c_setmode(msp, MSP_MODE_FM_NICAM1);		/* kick autodetect */		msp3400c_write(msp->bus, I2C_MSP3400C_DFP, 0x20, 0x01);		msp3400c_write(msp->bus, I2C_MSP3400C_DFP, 0x21, 0x01);		UNLOCK_I2C_BUS(msp->bus);		/* wait 1 sec */		current->state = TASK_INTERRUPTIBLE;		current->timeout = jiffies + HZ;		schedule();		if (signal_pending(current))			goto done;		if (msp->restart) {			msp->restart = 0;			goto restart;		}			LOCK_I2C_BUS(msp->bus);		/* debug register dump */		for (i = 0; i < sizeof(d1)/sizeof(struct REGISTER_DUMP); i++) {			val = msp3400c_read(msp->bus,I2C_MSP3400C_DEM,d1[i].addr);			printk(KERN_DEBUG "msp3400: %s = 0x%x\n",d1[i].name,val);		}			/* unmute */		msp3400c_setvolume(msp->bus, msp->volume);		UNLOCK_I2C_BUS(msp->bus);		msp->active = 0;	}done:	dprintk("msp3410: thread: exit\n");	msp->wait   = NULL;	msp->active = 0;	msp->thread = NULL;	if(msp->notify != NULL)		up(msp->notify);	return 0;}#endif/* ----------------------------------------------------------------------- *//* mixer stuff -- with the modular sound driver in 2.1.x we can easily     *//* register the msp3400 as mixer device                                    */#ifdef REGISTER_MIXER#include <linux/sound.h>#include <linux/soundcard.h>#include <asm/uaccess.h>

⌨️ 快捷键说明

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