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

📄 tda9887.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
		buf[2] |= adjust;	return 0;}static int tda9887_set_config(struct tda9887 *t, char *buf){	if (t->config & TDA9887_PORT1_ACTIVE)		buf[1] &= ~cOutputPort1Inactive;	if (t->config & TDA9887_PORT1_INACTIVE)		buf[1] |= cOutputPort1Inactive;	if (t->config & TDA9887_PORT2_ACTIVE)		buf[1] &= ~cOutputPort2Inactive;	if (t->config & TDA9887_PORT2_INACTIVE)		buf[1] |= cOutputPort2Inactive;	if (t->config & TDA9887_QSS)		buf[1] |= cQSS;	if (t->config & TDA9887_INTERCARRIER)		buf[1] &= ~cQSS;	if (t->config & TDA9887_AUTOMUTE)		buf[1] |= cAutoMuteFmActive;	if (t->config & TDA9887_DEEMPHASIS_MASK) {		buf[2] &= ~0x60;		switch (t->config & TDA9887_DEEMPHASIS_MASK) {		case TDA9887_DEEMPHASIS_NONE:			buf[2] |= cDeemphasisOFF;			break;		case TDA9887_DEEMPHASIS_50:			buf[2] |= cDeemphasisON | cDeemphasis50;			break;		case TDA9887_DEEMPHASIS_75:			buf[2] |= cDeemphasisON | cDeemphasis75;			break;		}	}	if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))		buf[1] &= ~cQSS;	return 0;}/* ---------------------------------------------------------------------- */static int tda9887_set_pinnacle(struct tda9887 *t, char *buf){	unsigned int bCarrierMode = UNSET;	if (t->std & V4L2_STD_625_50) {		if ((1 == t->pinnacle_id) || (7 == t->pinnacle_id)) {			bCarrierMode = cIntercarrier;		} else {			bCarrierMode = cQSS;		}	}	if (t->std & V4L2_STD_525_60) {		if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {			bCarrierMode = cIntercarrier;		} else {			bCarrierMode = cQSS;		}	}	if (bCarrierMode != UNSET) {		buf[1] &= ~0x04;		buf[1] |= bCarrierMode;	}	return 0;}/* ---------------------------------------------------------------------- */static char pal[] = "-";module_param_string(pal, pal, sizeof(pal), 0644);static char secam[] = "-";module_param_string(secam, secam, sizeof(secam), 0644);static int tda9887_fixup_std(struct tda9887 *t){	/* get more precise norm info from insmod option */	if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {		switch (pal[0]) {		case 'b':		case 'B':		case 'g':		case 'G':			tda9887_dbg("insmod fixup: PAL => PAL-BG\n");			t->std = V4L2_STD_PAL_BG;			break;		case 'i':		case 'I':			tda9887_dbg("insmod fixup: PAL => PAL-I\n");			t->std = V4L2_STD_PAL_I;			break;		case 'd':		case 'D':		case 'k':		case 'K':			tda9887_dbg("insmod fixup: PAL => PAL-DK\n");			t->std = V4L2_STD_PAL_DK;			break;		case '-':			/* default parameter, do nothing */			break;		default:			tda9887_info("pal= argument not recognised\n");			break;		}	}	if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {		switch (secam[0]) {		case 'd':		case 'D':		case 'k':		case 'K':			tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n");			t->std = V4L2_STD_SECAM_DK;			break;		case 'l':		case 'L':			tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");			t->std = V4L2_STD_SECAM_L;			break;		case '-':			/* default parameter, do nothing */			break;		default:			tda9887_info("secam= argument not recognised\n");			break;		}	}	return 0;}static int tda9887_status(struct tda9887 *t){	unsigned char buf[1];	int rc;	memset(buf,0,sizeof(buf));	if (1 != (rc = i2c_master_recv(&t->client,buf,1)))		tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);	dump_read_message(t, buf);	return 0;}static int tda9887_configure(struct tda9887 *t){	int rc;	memset(t->data,0,sizeof(t->data));	tda9887_set_tvnorm(t,t->data);	t->data[1] |= cOutputPort1Inactive;	t->data[1] |= cOutputPort2Inactive;	if (UNSET != t->pinnacle_id) {		tda9887_set_pinnacle(t,t->data);	}	tda9887_set_config(t,t->data);	tda9887_set_insmod(t,t->data);	if (t->mode == T_STANDBY) {		t->data[1] |= cForcedMuteAudioON;	}	tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",		t->data[1],t->data[2],t->data[3]);	if (debug > 1)		dump_write_message(t, t->data);	if (4 != (rc = i2c_master_send(&t->client,t->data,4)))		tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);	if (debug > 2) {		msleep_interruptible(1000);		tda9887_status(t);	}	return 0;}/* ---------------------------------------------------------------------- */static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind){	struct tda9887 *t;	client_template.adapter = adap;	client_template.addr    = addr;	if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))		return -ENOMEM;	memset(t,0,sizeof(*t));	t->client      = client_template;	t->std         = 0;	t->pinnacle_id = UNSET;	t->radio_mode = V4L2_TUNER_MODE_STEREO;	tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);	i2c_set_clientdata(&t->client, t);	i2c_attach_client(&t->client);	return 0;}static int tda9887_probe(struct i2c_adapter *adap){#ifdef I2C_CLASS_TV_ANALOG	if (adap->class & I2C_CLASS_TV_ANALOG)		return i2c_probe(adap, &addr_data, tda9887_attach);#else	switch (adap->id) {	case I2C_HW_B_BT848:	case I2C_HW_B_RIVA:	case I2C_HW_SAA7134:		return i2c_probe(adap, &addr_data, tda9887_attach);		break;	}#endif	return 0;}static int tda9887_detach(struct i2c_client *client){	struct tda9887 *t = i2c_get_clientdata(client);	i2c_detach_client(client);	kfree(t);	return 0;}#define SWITCH_V4L2	if (!t->using_v4l2 && debug) \			  tda9887_info("switching to v4l2\n"); \			  t->using_v4l2 = 1;#define CHECK_V4L2	if (t->using_v4l2) { if (debug) \			  tda9887_info("ignore v4l1 call\n"); \			  return 0; }static inttda9887_command(struct i2c_client *client, unsigned int cmd, void *arg){	struct tda9887 *t = i2c_get_clientdata(client);	switch (cmd) {	/* --- configuration --- */	case AUDC_SET_RADIO:	{		t->mode = T_RADIO;		tda9887_configure(t);		break;	}	case TUNER_SET_STANDBY:	{		t->mode = T_STANDBY;		tda9887_configure(t);		break;	}	case AUDC_CONFIG_PINNACLE:	{		int *i = arg;		t->pinnacle_id = *i;		tda9887_configure(t);		break;	}	case TDA9887_SET_CONFIG:	{		int *i = arg;		t->config = *i;		tda9887_configure(t);		break;	}	/* --- v4l ioctls --- */	/* take care: bttv does userspace copying, we'll get a	   kernel pointer here... */	case VIDIOCSCHAN:	{		static const v4l2_std_id map[] = {			[ VIDEO_MODE_PAL   ] = V4L2_STD_PAL,			[ VIDEO_MODE_NTSC  ] = V4L2_STD_NTSC_M,			[ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,			[ 4 /* bttv */     ] = V4L2_STD_PAL_M,			[ 5 /* bttv */     ] = V4L2_STD_PAL_N,			[ 6 /* bttv */     ] = V4L2_STD_NTSC_M_JP,		};		struct video_channel *vc = arg;		CHECK_V4L2;		t->mode = T_ANALOG_TV;		if (vc->norm < ARRAY_SIZE(map))			t->std = map[vc->norm];		tda9887_fixup_std(t);		tda9887_configure(t);		break;	}	case VIDIOC_S_STD:	{		v4l2_std_id *id = arg;		SWITCH_V4L2;		t->mode = T_ANALOG_TV;		t->std   = *id;		tda9887_fixup_std(t);		tda9887_configure(t);		break;	}	case VIDIOC_S_FREQUENCY:	{		struct v4l2_frequency *f = arg;		SWITCH_V4L2;		if (V4L2_TUNER_ANALOG_TV == f->type) {			if (t->mode == T_ANALOG_TV)				return 0;			t->mode = T_ANALOG_TV;		}		if (V4L2_TUNER_RADIO == f->type) {			if (t->mode == T_RADIO)				return 0;			t->mode = T_RADIO;		}		tda9887_configure(t);		break;	}	case VIDIOC_G_TUNER:	{		static int AFC_BITS_2_kHz[] = {			-12500,  -37500,  -62500,  -97500,			-112500, -137500, -162500, -187500,			187500,  162500,  137500,  112500,			97500 ,  62500,   37500 ,  12500		};		struct v4l2_tuner* tuner = arg;		if (t->mode == T_RADIO) {			__u8 reg = 0;			tuner->afc=0;			if (1 == i2c_master_recv(&t->client,&reg,1))				tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];		}		break;	}	case VIDIOC_S_TUNER:	{		struct v4l2_tuner* tuner = arg;		if (t->mode == T_RADIO) {			t->radio_mode = tuner->audmode;			tda9887_configure (t);		}		break;	}	case VIDIOC_LOG_STATUS:	{		tda9887_info("Data bytes: b=%02x c=%02x e=%02x\n", t->data[1], t->data[2], t->data[3]);		break;	}	default:		/* nothing */		break;	}	return 0;}static int tda9887_suspend(struct device * dev, pm_message_t state){	struct i2c_client *c = container_of(dev, struct i2c_client, dev);	struct tda9887 *t = i2c_get_clientdata(c);	tda9887_dbg("suspend\n");	return 0;}static int tda9887_resume(struct device * dev){	struct i2c_client *c = container_of(dev, struct i2c_client, dev);	struct tda9887 *t = i2c_get_clientdata(c);	tda9887_dbg("resume\n");	tda9887_configure(t);	return 0;}/* ----------------------------------------------------------------------- */static struct i2c_driver driver = {	.owner          = THIS_MODULE,	.name           = "i2c tda9887 driver",	.id             = -1, /* FIXME */	.flags          = I2C_DF_NOTIFY,	.attach_adapter = tda9887_probe,	.detach_client  = tda9887_detach,	.command        = tda9887_command,	.driver = {		.suspend = tda9887_suspend,		.resume  = tda9887_resume,	},};static struct i2c_client client_template ={	.name      = "tda9887",	.flags     = I2C_CLIENT_ALLOW_USE,	.driver    = &driver,};static int __init tda9887_init_module(void){	return i2c_add_driver(&driver);}static void __exit tda9887_cleanup_module(void){	i2c_del_driver(&driver);}module_init(tda9887_init_module);module_exit(tda9887_cleanup_module);/* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- * Local variables: * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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