📄 saa7110.c
字号:
switch (decoder->norm) { case VIDEO_MODE_NTSC: res |= DECODER_STATUS_NTSC; break; case VIDEO_MODE_PAL: res |= DECODER_STATUS_PAL; break; case VIDEO_MODE_SECAM: res |= DECODER_STATUS_SECAM; break; } *(int *) arg = res; } break; case DECODER_SET_NORM: v = *(int *) arg; if (decoder->norm != v) { decoder->norm = v; //saa7110_write(client, 0x06, 0x03); switch (v) { case VIDEO_MODE_NTSC: saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x50); saa7110_write(client, 0x11, 0x2C); //saa7110_write(client, 0x2E, 0x81); dprintk(1, KERN_INFO "%s: switched to NTSC\n", I2C_NAME(client)); break; case VIDEO_MODE_PAL: saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client, 0x2E, 0x9A); dprintk(1, KERN_INFO "%s: switched to PAL\n", I2C_NAME(client)); break; case VIDEO_MODE_SECAM: saa7110_write(client, 0x0D, 0x87); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client, 0x2E, 0x9A); dprintk(1, KERN_INFO "%s: switched to SECAM\n", I2C_NAME(client)); break; case VIDEO_MODE_AUTO: dprintk(1, KERN_INFO "%s: TV standard detection...\n", I2C_NAME(client)); decoder->norm = determine_norm(client); *(int *) arg = decoder->norm; break; default: return -EPERM; } } break; case DECODER_SET_INPUT: v = *(int *) arg; if (v < 0 || v > SAA7110_MAX_INPUT) { dprintk(1, KERN_INFO "%s: input=%d not available\n", I2C_NAME(client), v); return -EINVAL; } if (decoder->input != v) { saa7110_selmux(client, v); dprintk(1, KERN_INFO "%s: switched to input=%d\n", I2C_NAME(client), v); } break; case DECODER_SET_OUTPUT: v = *(int *) arg; /* not much choice of outputs */ if (v != 0) return -EINVAL; break; case DECODER_ENABLE_OUTPUT: v = *(int *) arg; if (decoder->enable != v) { decoder->enable = v; saa7110_write(client, 0x0E, v ? 0x18 : 0x80); dprintk(1, KERN_INFO "%s: YUV %s\n", I2C_NAME(client), v ? "on" : "off"); } break; case DECODER_SET_PICTURE: { struct video_picture *pic = arg; if (decoder->bright != pic->brightness) { /* We want 0 to 255 we get 0-65535 */ decoder->bright = pic->brightness; saa7110_write(client, 0x19, decoder->bright >> 8); } if (decoder->contrast != pic->contrast) { /* We want 0 to 127 we get 0-65535 */ decoder->contrast = pic->contrast; saa7110_write(client, 0x13, decoder->contrast >> 9); } if (decoder->sat != pic->colour) { /* We want 0 to 127 we get 0-65535 */ decoder->sat = pic->colour; saa7110_write(client, 0x12, decoder->sat >> 9); } if (decoder->hue != pic->hue) { /* We want -128 to 127 we get 0-65535 */ decoder->hue = pic->hue; saa7110_write(client, 0x07, (decoder->hue >> 8) - 128); } } break; case DECODER_DUMP: for (v = 0; v < 0x34; v += 16) { int j; dprintk(1, KERN_INFO "%s: %03x\n", I2C_NAME(client), v); for (j = 0; j < 16; j++) { dprintk(1, KERN_INFO " %02x", decoder->reg[v + j]); } dprintk(1, KERN_INFO "\n"); } break; default: dprintk(1, KERN_INFO "unknown saa7110_command??(%d)\n", cmd); return -EINVAL; } return 0;}/* ----------------------------------------------------------------------- *//* * Generic i2c probe * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' */static unsigned short normal_i2c[] = { I2C_SAA7110 >> 1, (I2C_SAA7110 >> 1) + 1, I2C_CLIENT_END};static unsigned short ignore = I2C_CLIENT_END; static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore,};static struct i2c_driver i2c_driver_saa7110;static intsaa7110_detect_client (struct i2c_adapter *adapter, int address, int kind){ struct i2c_client *client; struct saa7110 *decoder; int rv; dprintk(1, KERN_INFO "saa7110.c: detecting saa7110 client on address 0x%x\n", address << 1); /* Check if the adapter supports the needed features */ if (!i2c_check_functionality (adapter, I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_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_saa7110; client->flags = I2C_CLIENT_ALLOW_USE; strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client))); decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL); if (decoder == 0) { kfree(client); return -ENOMEM; } memset(decoder, 0, sizeof(struct saa7110)); decoder->norm = VIDEO_MODE_PAL; decoder->input = 0; decoder->enable = 1; decoder->bright = 32768; decoder->contrast = 32768; decoder->hue = 32768; decoder->sat = 32768; init_waitqueue_head(&decoder->wq); i2c_set_clientdata(client, decoder); rv = i2c_attach_client(client); if (rv) { kfree(client); kfree(decoder); return rv; } rv = saa7110_write_block(client, initseq, sizeof(initseq)); if (rv < 0) dprintk(1, KERN_ERR "%s_attach: init status %d\n", I2C_NAME(client), rv); else { int ver, status; saa7110_write(client, 0x21, 0x10); saa7110_write(client, 0x0e, 0x18); saa7110_write(client, 0x0D, 0x04); ver = saa7110_read(client); saa7110_write(client, 0x0D, 0x06); //mdelay(150); status = saa7110_read(client); dprintk(1, KERN_INFO "%s_attach: SAA7110A version %x at 0x%02x, status=0x%02x\n", I2C_NAME(client), ver, client->addr << 1, status); saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client, 0x2E, 0x9A); } //saa7110_selmux(client,0); //determine_norm(client); /* setup and implicit mode 0 select has been performed */ return 0;}static intsaa7110_attach_adapter (struct i2c_adapter *adapter){ dprintk(1, KERN_INFO "saa7110.c: starting probe for adapter %s (0x%x)\n", I2C_NAME(adapter), adapter->id); return i2c_probe(adapter, &addr_data, &saa7110_detect_client);}static intsaa7110_detach_client (struct i2c_client *client){ struct saa7110 *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_saa7110 = { .owner = THIS_MODULE, .name = "saa7110", .id = I2C_DRIVERID_SAA7110, .flags = I2C_DF_NOTIFY, .attach_adapter = saa7110_attach_adapter, .detach_client = saa7110_detach_client, .command = saa7110_command,};static int __initsaa7110_init (void){ return i2c_add_driver(&i2c_driver_saa7110);}static void __exitsaa7110_exit (void){ i2c_del_driver(&i2c_driver_saa7110);}module_init(saa7110_init);module_exit(saa7110_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -