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

📄 saa7114.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
static struct i2c_client_address_data addr_data = {	.normal_i2c		= normal_i2c,	.normal_i2c_range	= normal_i2c_range,	.probe			= probe,	.probe_range		= probe_range,	.ignore			= ignore,	.ignore_range		= ignore_range,	.force			= force};static int saa7114_i2c_id = 0;static struct i2c_driver i2c_driver_saa7114;static intsaa7114_detect_client (struct i2c_adapter *adapter,		       int                 address,		       int                 kind){	int i, err[30];	short int hoff = SAA_7114_NTSC_HOFFSET;	short int voff = SAA_7114_NTSC_VOFFSET;	short int w = SAA_7114_NTSC_WIDTH;	short int h = SAA_7114_NTSC_HEIGHT;	struct i2c_client *client;	struct saa7114 *decoder;	dprintk(1,		KERN_INFO		"saa7114.c: detecting saa7114 client on address 0x%x\n",		address << 1);	/* Check if the adapter supports the needed features */	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))		return 0;	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);	if (client == 0)		return -ENOMEM;	memset(client, 0, sizeof(struct i2c_client));	client->addr = address;	client->adapter = adapter;	client->driver = &i2c_driver_saa7114;	client->flags = I2C_CLIENT_ALLOW_USE;	client->id = saa7114_i2c_id++;	snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1,		"saa7114[%d]", client->id);	decoder = kmalloc(sizeof(struct saa7114), GFP_KERNEL);	if (decoder == NULL) {		kfree(client);		return -ENOMEM;	}	memset(decoder, 0, sizeof(struct saa7114));	decoder->norm = VIDEO_MODE_NTSC;	decoder->input = -1;	decoder->enable = 1;	decoder->bright = 32768;	decoder->contrast = 32768;	decoder->hue = 32768;	decoder->sat = 32768;	decoder->playback = 0;	// initially capture mode useda	i2c_set_clientdata(client, decoder);	memcpy(decoder->reg, init, sizeof(init));	decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff);	// hoffset low	decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f;	// hoffset high	decoder->reg[REG_ADDR(0x96)] = LOBYTE(w);	// width low	decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f;	// width high	decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff);	// voffset low	decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f;	// voffset high	decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2);	// height low	decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f;	// height high	decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w);	// out width low	decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f;	// out width high	decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h);	// out height low	decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f;	// out height high	decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff);	// hoffset low	decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f;	// hoffset high	decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w);	// width low	decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f;	// width high	decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff);	// voffset low	decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f;	// voffset high	decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2);	// height low	decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f;	// height high	decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w);	// out width low	decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f;	// out width high	decoder->reg[REG_ADDR(0xce)] = LOBYTE(h);	// out height low	decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f;	// out height high	decoder->reg[REG_ADDR(0xb8)] =	    LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));	decoder->reg[REG_ADDR(0xb9)] =	    HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));	decoder->reg[REG_ADDR(0xba)] =	    LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));	decoder->reg[REG_ADDR(0xbb)] =	    HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));	decoder->reg[REG_ADDR(0xbc)] =	    LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));	decoder->reg[REG_ADDR(0xbd)] =	    HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));	decoder->reg[REG_ADDR(0xbe)] =	    LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));	decoder->reg[REG_ADDR(0xbf)] =	    HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));	decoder->reg[REG_ADDR(0xe8)] =	    LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));	decoder->reg[REG_ADDR(0xe9)] =	    HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));	decoder->reg[REG_ADDR(0xea)] =	    LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));	decoder->reg[REG_ADDR(0xeb)] =	    HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));	decoder->reg[REG_ADDR(0xec)] =	    LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));	decoder->reg[REG_ADDR(0xed)] =	    HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));	decoder->reg[REG_ADDR(0xee)] =	    LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));	decoder->reg[REG_ADDR(0xef)] =	    HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));	decoder->reg[REG_ADDR(0x13)] = 0x80;	// RTC0 on	decoder->reg[REG_ADDR(0x87)] = 0x01;	// I-Port	decoder->reg[REG_ADDR(0x12)] = 0xc9;	// RTS0	decoder->reg[REG_ADDR(0x02)] = 0xc0;	// set composite1 input, aveasy	decoder->reg[REG_ADDR(0x09)] = 0x00;	// chrominance trap	decoder->reg[REG_ADDR(0x0e)] |= 1;	// combfilter on	dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n",		I2C_NAME(client));	err[0] =	    saa7114_write_block(client, decoder->reg + (0x20 << 1),				0x10 << 1);	err[1] =	    saa7114_write_block(client, decoder->reg + (0x30 << 1),				0x10 << 1);	err[2] =	    saa7114_write_block(client, decoder->reg + (0x63 << 1),				(0x7f + 1 - 0x63) << 1);	err[3] =	    saa7114_write_block(client, decoder->reg + (0x89 << 1),				6 << 1);	err[4] =	    saa7114_write_block(client, decoder->reg + (0xb8 << 1),				8 << 1);	err[5] =	    saa7114_write_block(client, decoder->reg + (0xe8 << 1),				8 << 1);	for (i = 0; i <= 5; i++) {		if (err[i] < 0) {			dprintk(1,				KERN_ERR				"%s_attach: init error %d at stage %d, leaving attach.\n",				I2C_NAME(client), i, err[i]);			kfree(decoder);			kfree(client);			return 0;		}	}	for (i = 6; i < 8; i++) {		dprintk(1,			KERN_DEBUG			"%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",			I2C_NAME(client), i, saa7114_read(client, i),			decoder->reg[REG_ADDR(i)]);	}	dprintk(1,		KERN_DEBUG		"%s_attach: performing decoder reset sequence\n",		I2C_NAME(client));	err[6] = saa7114_write(client, 0x80, 0x06);	// i-port and scaler backend clock selection, task A&B off	err[7] = saa7114_write(client, 0x88, 0xd8);	// sw reset scaler	err[8] = saa7114_write(client, 0x88, 0xf8);	// sw reset scaler release	for (i = 6; i <= 8; i++) {		if (err[i] < 0) {			dprintk(1,				KERN_ERR				"%s_attach: init error %d at stage %d, leaving attach.\n",				I2C_NAME(client), i, err[i]);			kfree(decoder);			kfree(client);			return 0;		}	}	dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n",		I2C_NAME(client));	err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);	err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1);	// big seq	err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1);	// slicer	err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1);	// ?	err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1);	// ?	err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1);	// Task A	err[15] =	    saa7114_write_block(client, decoder->reg + (0x94 << 1),				12 << 1);	err[16] =	    saa7114_write_block(client, decoder->reg + (0xa0 << 1),				8 << 1);	err[17] =	    saa7114_write_block(client, decoder->reg + (0xa8 << 1),				8 << 1);	err[18] =	    saa7114_write_block(client, decoder->reg + (0xb0 << 1),				8 << 1);	err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1);	// Task B	err[15] =	    saa7114_write_block(client, decoder->reg + (0xc4 << 1),				12 << 1);	err[16] =	    saa7114_write_block(client, decoder->reg + (0xd0 << 1),				8 << 1);	err[17] =	    saa7114_write_block(client, decoder->reg + (0xd8 << 1),				8 << 1);	err[18] =	    saa7114_write_block(client, decoder->reg + (0xe0 << 1),				8 << 1);	for (i = 9; i <= 18; i++) {		if (err[i] < 0) {			dprintk(1,				KERN_ERR				"%s_attach: init error %d at stage %d, leaving attach.\n",				I2C_NAME(client), i, err[i]);			kfree(decoder);			kfree(client);			return 0;		}	}	for (i = 6; i < 8; i++) {		dprintk(1,			KERN_DEBUG			"%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",			I2C_NAME(client), i, saa7114_read(client, i),			decoder->reg[REG_ADDR(i)]);	}	for (i = 0x11; i <= 0x13; i++) {		dprintk(1,			KERN_DEBUG			"%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",			I2C_NAME(client), i, saa7114_read(client, i),			decoder->reg[REG_ADDR(i)]);	}	dprintk(1, KERN_DEBUG "%s_attach: setting video input\n",		I2C_NAME(client));	err[19] =	    saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);	err[20] =	    saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);	err[21] =	    saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);	for (i = 19; i <= 21; i++) {		if (err[i] < 0) {			dprintk(1,				KERN_ERR				"%s_attach: init error %d at stage %d, leaving attach.\n",				I2C_NAME(client), i, err[i]);			kfree(decoder);			kfree(client);			return 0;		}	}	dprintk(1,		KERN_DEBUG		"%s_attach: performing decoder reset sequence\n",		I2C_NAME(client));	err[22] = saa7114_write(client, 0x88, 0xd8);	// sw reset scaler	err[23] = saa7114_write(client, 0x88, 0xf8);	// sw reset scaler release	err[24] = saa7114_write(client, 0x80, 0x36);	// i-port and scaler backend clock selection, task A&B off	for (i = 22; i <= 24; i++) {		if (err[i] < 0) {			dprintk(1,				KERN_ERR				"%s_attach: init error %d at stage %d, leaving attach.\n",				I2C_NAME(client), i, err[i]);			kfree(decoder);			kfree(client);			return 0;		}	}	err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);	err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);	err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);	dprintk(1,		KERN_INFO		"%s_attach: chip version %x, decoder status 0x%02x\n",		I2C_NAME(client), saa7114_read(client, 0x00) >> 4,		saa7114_read(client, 0x1f));	dprintk(1,		KERN_DEBUG		"%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n",		I2C_NAME(client), saa7114_read(client, 0x88),		saa7114_read(client, 0x8f));	for (i = 0x94; i < 0x96; i++) {		dprintk(1,			KERN_DEBUG			"%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",			I2C_NAME(client), i, saa7114_read(client, i),			decoder->reg[REG_ADDR(i)]);	}	i = i2c_attach_client(client);	if (i) {		kfree(client);		kfree(decoder);		return i;	}	//i = saa7114_write_block(client, init, sizeof(init));	i = 0;	if (i < 0) {		dprintk(1, KERN_ERR "%s_attach error: init status %d\n",			I2C_NAME(client), i);	} else {		dprintk(1,			KERN_INFO			"%s_attach: chip version %x at address 0x%x\n",			I2C_NAME(client), saa7114_read(client, 0x00) >> 4,			client->addr << 1);	}	return 0;}static intsaa7114_attach_adapter (struct i2c_adapter *adapter){	dprintk(1,		KERN_INFO		"saa7114.c: starting probe for adapter %s (0x%x)\n",		I2C_NAME(adapter), adapter->id);	return i2c_probe(adapter, &addr_data, &saa7114_detect_client);}static intsaa7114_detach_client (struct i2c_client *client){	struct saa7114 *decoder = i2c_get_clientdata(client);	int err;	err = i2c_detach_client(client);	if (err) {		return err;	}	kfree(decoder);	kfree(client);	return 0;}/* ----------------------------------------------------------------------- */static struct i2c_driver i2c_driver_saa7114 = {	.owner = THIS_MODULE,	.name = "saa7114",	.id = I2C_DRIVERID_SAA7114,	.flags = I2C_DF_NOTIFY,	.attach_adapter = saa7114_attach_adapter,	.detach_client = saa7114_detach_client,	.command = saa7114_command,};static int __initsaa7114_init (void){	return i2c_add_driver(&i2c_driver_saa7114);}static void __exitsaa7114_exit (void){	i2c_del_driver(&i2c_driver_saa7114);}module_init(saa7114_init);module_exit(saa7114_exit);

⌨️ 快捷键说明

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