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

📄 tveeprom.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
			++i;		} else {			TVEEPROM_KERN_ERR("Encountered bad packet header [%02x]. "				   "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);			return;		}		dprintk(1, "%3d [%02x] ", len, eeprom_data[i]);		for(j = 1; j < len; j++) {			dprintk(1, "%02x ", eeprom_data[i + j]);		}		dprintk(1, "\n");		/* process by tag */		tag = eeprom_data[i];		switch (tag) {		case 0x00:			tuner = eeprom_data[i+6];			t_format = eeprom_data[i+5];			tvee->has_radio = eeprom_data[i+len-1];			tvee->model =				eeprom_data[i+8] +				(eeprom_data[i+9] << 8);			tvee->revision = eeprom_data[i+10] +				(eeprom_data[i+11] << 8) +				(eeprom_data[i+12] << 16);			break;		case 0x01:			tvee->serial_number =				eeprom_data[i+6] +				(eeprom_data[i+7] << 8) +				(eeprom_data[i+8] << 16);			break;		case 0x02:			tvee->audio_processor = eeprom_data[i+2] & 0x0f;			break;		case 0x04:			tvee->serial_number =				eeprom_data[i+5] +				(eeprom_data[i+6] << 8) +				(eeprom_data[i+7] << 16);			break;		case 0x05:			tvee->audio_processor = eeprom_data[i+1] & 0x0f;			break;		case 0x06:			tvee->model =				eeprom_data[i+1] +				(eeprom_data[i+2] << 8);			tvee->revision = eeprom_data[i+5] +				(eeprom_data[i+6] << 8) +				(eeprom_data[i+7] << 16);			break;		case 0x0a:			tuner = eeprom_data[i+2];			t_format = eeprom_data[i+1];			break;		case 0x0e:			tvee->has_radio = eeprom_data[i+1];			break;		default:			dprintk(1, "Not sure what to do with tag [%02x]\n", tag);			/* dump the rest of the packet? */		}	}	if (!done) {		TVEEPROM_KERN_ERR("Ran out of data!\n");		return;	}	if (tvee->revision != 0) {		tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f);		tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f);		tvee->rev_str[2] = 32 + ((tvee->revision >>  6) & 0x3f);		tvee->rev_str[3] = 32 + ( tvee->revision        & 0x3f);		tvee->rev_str[4] = 0;	}        if (hasRadioTuner(tuner) && !tvee->has_radio) {	    TVEEPROM_KERN_INFO("The eeprom says no radio is present, but the tuner type\n");	    TVEEPROM_KERN_INFO("indicates otherwise. I will assume that radio is present.\n");            tvee->has_radio = 1;        }	if (tuner < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {		tvee->tuner_type = hauppauge_tuner[tuner].id;		t_name = hauppauge_tuner[tuner].name;	} else {		t_name = "<unknown>";	}	tvee->tuner_formats = 0;	t_fmt_name = "<none>";	for (i = 0; i < 8; i++) {		if (t_format & (1<<i)) {			tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;			/* yuck */			t_fmt_name = hauppauge_tuner_fmt[i].name;		}	}#if 0	if (t_format < sizeof(hauppauge_tuner_fmt)/sizeof(struct HAUPPAUGE_TUNER_FMT)) {		tvee->tuner_formats = hauppauge_tuner_fmt[t_format].id;		t_fmt_name = hauppauge_tuner_fmt[t_format].name;	} else {		t_fmt_name = "<unknown>";	}#endif	TVEEPROM_KERN_INFO("Hauppauge: model = %d, rev = %s, serial# = %d\n",		   tvee->model,		   tvee->rev_str,		   tvee->serial_number);	TVEEPROM_KERN_INFO("tuner = %s (idx = %d, type = %d)\n",		   t_name,		   tuner,		   tvee->tuner_type);	TVEEPROM_KERN_INFO("tuner fmt = %s (eeprom = 0x%02x, v4l2 = 0x%08x)\n",		   t_fmt_name,		   t_format,		   tvee->tuner_formats);	TVEEPROM_KERN_INFO("audio_processor = %s (type = %d)\n",		   STRM(sndtype,tvee->audio_processor),		   tvee->audio_processor);}EXPORT_SYMBOL(tveeprom_hauppauge_analog);/* ----------------------------------------------------------------------- *//* generic helper functions                                                */int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len){	unsigned char buf;	int err;	dprintk(1, "%s\n",__FUNCTION__);	buf = 0;	if (1 != (err = i2c_master_send(c,&buf,1))) {		printk(KERN_INFO "tveeprom(%s): Huh, no eeprom present (err=%d)?\n",		       c->name,err);		return -1;	}	if (len != (err = i2c_master_recv(c,eedata,len))) {		printk(KERN_WARNING "tveeprom(%s): i2c eeprom read error (err=%d)\n",		       c->name,err);		return -1;	}	return 0;}EXPORT_SYMBOL(tveeprom_read);int tveeprom_dump(unsigned char *eedata, int len){	int i;	dprintk(1, "%s\n",__FUNCTION__);	for (i = 0; i < len; i++) {		if (0 == (i % 16))			printk(KERN_INFO "tveeprom: %02x:",i);		printk(" %02x",eedata[i]);		if (15 == (i % 16))			printk("\n");	}	return 0;}EXPORT_SYMBOL(tveeprom_dump);/* ----------------------------------------------------------------------- *//* needed for ivtv.sf.net at the moment.  Should go away in the long       *//* run, just call the exported tveeprom_* directly, there is no point in   *//* using the indirect way via i2c_driver->command()                        */#ifndef I2C_DRIVERID_TVEEPROM# define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2#endifstatic unsigned short normal_i2c[] = {	0xa0 >> 1,	I2C_CLIENT_END,};static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };I2C_CLIENT_INSMOD;struct i2c_driver i2c_driver_tveeprom;static inttveeprom_command(struct i2c_client *client,		 unsigned int       cmd,		 void              *arg){	struct tveeprom eeprom;	u32 *eeprom_props = arg;	u8 *buf;	switch (cmd) {	case 0:		buf = kmalloc(256,GFP_KERNEL);		memset(buf,0,256);		tveeprom_read(client,buf,256);		tveeprom_hauppauge_analog(&eeprom,buf);		kfree(buf);		eeprom_props[0] = eeprom.tuner_type;		eeprom_props[1] = eeprom.tuner_formats;		eeprom_props[2] = eeprom.model;		eeprom_props[3] = eeprom.revision;		break;	default:		return -EINVAL;	}	return 0;}static inttveeprom_detect_client(struct i2c_adapter *adapter,		       int                 address,		       int                 kind){	struct i2c_client *client;	dprintk(1,"%s: id 0x%x @ 0x%x\n",__FUNCTION__,	       adapter->id, address << 1);	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);	if (NULL == client)		return -ENOMEM;	memset(client, 0, sizeof(struct i2c_client));	client->addr = address;	client->adapter = adapter;	client->driver = &i2c_driver_tveeprom;	client->flags = I2C_CLIENT_ALLOW_USE;	snprintf(client->name, sizeof(client->name), "tveeprom");        i2c_attach_client(client);	return 0;}static inttveeprom_attach_adapter (struct i2c_adapter *adapter){	dprintk(1,"%s: id 0x%x\n",__FUNCTION__,adapter->id);	if (adapter->id != (I2C_ALGO_BIT | I2C_HW_B_BT848))		return 0;	return i2c_probe(adapter, &addr_data, tveeprom_detect_client);}static inttveeprom_detach_client (struct i2c_client *client){	int err;	err = i2c_detach_client(client);	if (err < 0)		return err;	kfree(client);	return 0;}struct i2c_driver i2c_driver_tveeprom = {	.owner          = THIS_MODULE,	.name           = "tveeprom",	.id             = I2C_DRIVERID_TVEEPROM,	.flags          = I2C_DF_NOTIFY,	.attach_adapter = tveeprom_attach_adapter,	.detach_client  = tveeprom_detach_client,	.command        = tveeprom_command,};static int __init tveeprom_init(void){	return i2c_add_driver(&i2c_driver_tveeprom);}static void __exit tveeprom_exit(void){	i2c_del_driver(&i2c_driver_tveeprom);}module_init(tveeprom_init);module_exit(tveeprom_exit);/* * Local variables: * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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