From 3218e41f071a9f2deac43fc54453a28e94084cc8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 13 Oct 2008 12:28:39 +0200 Subject: zoran: set adapter class to I2C_CLASS_TV_ANALOG From: Jean Delvare The adapter class of the zoran driver was never set. However, converting i2c drivers used by zoran to the new i2c API requires this field to be correct. Priority: normal Signed-off-by: Jean Delvare Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_card.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index 081b72a45..d5026ae51 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -818,6 +818,7 @@ zoran_register_i2c (struct zoran *zr) memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template, sizeof(struct i2c_algo_bit_data)); zr->i2c_algo.data = zr; + zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG; zr->i2c_adapter.id = I2C_HW_B_ZR36067; zr->i2c_adapter.client_register = zoran_i2c_client_register; zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister; -- cgit v1.2.3 From d098443fdc6c9f2a0b9d38062694bea0b21ec1bc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Sep 2008 12:58:20 +0200 Subject: adv7170: convert i2c driver for new i2c API From: Hans Verkuil - Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API - Cleanups - Use v4l_dbg/v4l_info to have uniform kernel messages Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/adv7170.c | 257 +++++++++--------------------------- 1 file changed, 62 insertions(+), 195 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/adv7170.c b/linux/drivers/media/video/adv7170.c index 54ef7aa63..0a319ad8e 100644 --- a/linux/drivers/media/video/adv7170.c +++ b/linux/drivers/media/video/adv7170.c @@ -29,44 +29,25 @@ */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include +#include #include - -#include "compat.h" +#include +#include #include #include +#include +#include +#include "compat.h" MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver"); MODULE_AUTHOR("Maxim Yevtyushkin"); MODULE_LICENSE("GPL"); - -#define I2C_NAME(x) (x)->name - - static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -#define dprintk(num, format, args...) \ - do { \ - if (debug >= num) \ - printk(format, ##args); \ - } while (0) - /* ----------------------------------------------------------------------- */ struct adv7170 { @@ -81,21 +62,12 @@ struct adv7170 { int sat; }; -#define I2C_ADV7170 0xd4 -#define I2C_ADV7171 0x54 - -static char adv7170_name[] = "adv7170"; -static char adv7171_name[] = "adv7171"; - static char *inputs[] = { "pass_through", "play_back" }; static char *norms[] = { "PAL", "NTSC" }; /* ----------------------------------------------------------------------- */ -static inline int -adv7170_write (struct i2c_client *client, - u8 reg, - u8 value) +static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value) { struct adv7170 *encoder = i2c_get_clientdata(client); @@ -103,17 +75,13 @@ adv7170_write (struct i2c_client *client, return i2c_smbus_write_byte_data(client, reg, value); } -static inline int -adv7170_read (struct i2c_client *client, - u8 reg) +static inline int adv7170_read(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); } -static int -adv7170_write_block (struct i2c_client *client, - const u8 *data, - unsigned int len) +static int adv7170_write_block(struct i2c_client *client, + const u8 *data, unsigned int len) { int ret = -1; u8 reg; @@ -134,33 +102,25 @@ adv7170_write_block (struct i2c_client *client, encoder->reg[reg++] = data[1]; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + } while (len >= 2 && data[0] == reg && block_len < 32); + ret = i2c_master_send(client, block_data, block_len); + if (ret < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - if ((ret = adv7170_write(client, reg, - *data++)) < 0) + ret = adv7170_write(client, reg, *data++); + if (ret < 0) break; len -= 2; } } - return ret; } /* ----------------------------------------------------------------------- */ -// Output filter: S-Video Composite - -#define MR050 0x11 //0x09 -#define MR060 0x14 //0x0c - -//--------------------------------------------------------------------------- #define TR0MODE 0x4c #define TR0RST 0x80 @@ -168,7 +128,6 @@ adv7170_write_block (struct i2c_client *client, #define TR1CAPT 0x00 #define TR1PLAY 0x00 - static const unsigned char init_NTSC[] = { 0x00, 0x10, // MR0 0x01, 0x20, // MR1 @@ -228,15 +187,11 @@ static const unsigned char init_PAL[] = { }; -static int -adv7170_command (struct i2c_client *client, - unsigned int cmd, - void * arg) +static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) { struct adv7170 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: #if 0 /* keep */ /* This is just for testing!!! */ @@ -255,18 +210,16 @@ adv7170_command (struct i2c_client *client, VIDEO_ENCODER_NTSC; cap->inputs = 2; cap->outputs = 1; - } break; + } case ENCODER_SET_NORM: { int iarg = *(int *) arg; - dprintk(1, KERN_DEBUG "%s_command: set norm %d", - I2C_NAME(client), iarg); + v4l_dbg(1, debug, client, "set norm %d\n", iarg); switch (iarg) { - case VIDEO_MODE_NTSC: adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); @@ -286,16 +239,13 @@ adv7170_command (struct i2c_client *client, break; default: - dprintk(1, KERN_ERR "%s: illegal norm: %d\n", - I2C_NAME(client), iarg); + v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); return -EINVAL; - } - dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client), - norms[iarg]); + v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); encoder->norm = iarg; - } break; + } case ENCODER_SET_INPUT: { @@ -305,19 +255,17 @@ adv7170_command (struct i2c_client *client, *iarg = 1: input is from ZR36060 *iarg = 2: color bar */ - dprintk(1, KERN_DEBUG "%s_command: set input from %s\n", - I2C_NAME(client), + v4l_dbg(1, debug, client, "set input from %s\n", iarg == 0 ? "decoder" : "ZR36060"); switch (iarg) { - case 0: adv7170_write(client, 0x01, 0x20); adv7170_write(client, 0x08, TR1CAPT); /* TR1 */ adv7170_write(client, 0x02, 0x0e); // Enable genlock adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); - //udelay(10); + /* udelay(10); */ break; case 1: @@ -326,20 +274,17 @@ adv7170_command (struct i2c_client *client, adv7170_write(client, 0x02, 0x08); adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); - //udelay(10); + /* udelay(10); */ break; default: - dprintk(1, KERN_ERR "%s: illegal input: %d\n", - I2C_NAME(client), iarg); + v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); return -EINVAL; - } - dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client), - inputs[iarg]); + v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); encoder->input = iarg; - } break; + } case ENCODER_SET_OUTPUT: { @@ -349,16 +294,16 @@ adv7170_command (struct i2c_client *client, if (*iarg != 0) { return -EINVAL; } - } break; + } case ENCODER_ENABLE_OUTPUT: { int *iarg = arg; encoder->enable = !!*iarg; - } break; + } default: return -EINVAL; @@ -369,149 +314,71 @@ adv7170_command (struct i2c_client *client, /* ----------------------------------------------------------------------- */ -/* - * Generic i2c probe - * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' - */ -static unsigned short normal_i2c[] = - { I2C_ADV7170 >> 1, (I2C_ADV7170 >> 1) + 1, - I2C_ADV7171 >> 1, (I2C_ADV7171 >> 1) + 1, +static unsigned short normal_i2c[] = { + 0xd4 >> 1, 0xd6 >> 1, /* adv7170 IDs */ + 0x54 >> 1, 0x56 >> 1, /* adv7171 IDs */ I2C_CLIENT_END }; -static unsigned short ignore = I2C_CLIENT_END; +I2C_CLIENT_INSMOD; -static struct i2c_client_address_data addr_data = { - .normal_i2c = normal_i2c, - .probe = &ignore, - .ignore = &ignore, -}; - -static struct i2c_driver i2c_driver_adv7170; - -static int -adv7170_detect_client (struct i2c_adapter *adapter, - int address, - int kind) +static int adv7170_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - int i; - struct i2c_client *client; struct adv7170 *encoder; - char *dname; - - dprintk(1, - KERN_INFO - "adv7170.c: detecting adv7170 client on address 0x%x\n", - address << 1); + int i; /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return 0; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) - return -ENOMEM; - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver_adv7170; - if ((client->addr == I2C_ADV7170 >> 1) || - (client->addr == (I2C_ADV7170 >> 1) + 1)) { - dname = adv7170_name; - } else if ((client->addr == I2C_ADV7171 >> 1) || - (client->addr == (I2C_ADV7171 >> 1) + 1)) { - dname = adv7171_name; - } else { - /* We should never get here!!! */ - kfree(client); - return 0; - } - strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client))); + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL); - if (encoder == NULL) { - kfree(client); + if (encoder == NULL) return -ENOMEM; - } encoder->norm = VIDEO_MODE_NTSC; encoder->input = 0; encoder->enable = 1; i2c_set_clientdata(client, encoder); - i = i2c_attach_client(client); - if (i) { - kfree(client); - kfree(encoder); - return i; - } - i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); if (i >= 0) { i = adv7170_write(client, 0x07, TR0MODE | TR0RST); i = adv7170_write(client, 0x07, TR0MODE); i = adv7170_read(client, 0x12); - dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%02x\n", - I2C_NAME(client), i & 1, client->addr << 1); - } - if (i < 0) { - dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n", - I2C_NAME(client), i); + v4l_dbg(1, debug, client, "revision %d\n", i & 1); } - + if (i < 0) + v4l_dbg(1, debug, client, "init error 0x%x\n", i); return 0; } -static int -adv7170_attach_adapter (struct i2c_adapter *adapter) -{ - dprintk(1, - KERN_INFO - "adv7170.c: starting probe for adapter %s (0x%x)\n", - I2C_NAME(adapter), adapter->id); - return i2c_probe(adapter, &addr_data, &adv7170_detect_client); -} - -static int -adv7170_detach_client (struct i2c_client *client) +static int adv7170_remove(struct i2c_client *client) { - struct adv7170 *encoder = i2c_get_clientdata(client); - int err; - - err = i2c_detach_client(client); - if (err) { - return err; - } - - kfree(encoder); - kfree(client); - + kfree(i2c_get_clientdata(client)); return 0; } /* ----------------------------------------------------------------------- */ -static struct i2c_driver i2c_driver_adv7170 = { - .driver = { - .name = "adv7170", /* name */ - }, - - .id = I2C_DRIVERID_ADV7170, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id adv7170_id[] = { + { "adv7170", 0 }, + { "adv7171", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adv7170_id); - .attach_adapter = adv7170_attach_adapter, - .detach_client = adv7170_detach_client, +#endif +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "adv7170", + .driverid = I2C_DRIVERID_ADV7170, .command = adv7170_command, + .probe = adv7170_probe, + .remove = adv7170_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = adv7170_id, +#endif }; - -static int __init -adv7170_init (void) -{ - return i2c_add_driver(&i2c_driver_adv7170); -} - -static void __exit -adv7170_exit (void) -{ - i2c_del_driver(&i2c_driver_adv7170); -} - -module_init(adv7170_init); -module_exit(adv7170_exit); -- cgit v1.2.3 From 0f243aeeea0282a1ae687a98b4e6b7239b42f843 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Sep 2008 12:58:46 +0200 Subject: adv7175: convert i2c driver for new i2c API From: Hans Verkuil - Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API - Cleanups - Use v4l_dbg/v4l_info to have uniform kernel messages Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/adv7175.c | 247 ++++++++++-------------------------- 1 file changed, 64 insertions(+), 183 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/adv7175.c b/linux/drivers/media/video/adv7175.c index b8618c021..281a3f53c 100644 --- a/linux/drivers/media/video/adv7175.c +++ b/linux/drivers/media/video/adv7175.c @@ -25,44 +25,25 @@ */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include +#include #include - +#include +#include #include #include +#include +#include #include "compat.h" MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver"); MODULE_AUTHOR("Dave Perks"); MODULE_LICENSE("GPL"); - -#define I2C_NAME(s) (s)->name - - static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -#define dprintk(num, format, args...) \ - do { \ - if (debug >= num) \ - printk(format, ##args); \ - } while (0) - /* ----------------------------------------------------------------------- */ struct adv7175 { @@ -78,33 +59,23 @@ struct adv7175 { #define I2C_ADV7175 0xd4 #define I2C_ADV7176 0x54 -static char adv7175_name[] = "adv7175"; -static char adv7176_name[] = "adv7176"; - static char *inputs[] = { "pass_through", "play_back", "color_bar" }; static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" }; /* ----------------------------------------------------------------------- */ -static inline int -adv7175_write (struct i2c_client *client, - u8 reg, - u8 value) +static inline int adv7175_write(struct i2c_client *client, u8 reg, u8 value) { return i2c_smbus_write_byte_data(client, reg, value); } -static inline int -adv7175_read (struct i2c_client *client, - u8 reg) +static inline int adv7175_read(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); } -static int -adv7175_write_block (struct i2c_client *client, - const u8 *data, - unsigned int len) +static int adv7175_write_block(struct i2c_client *client, + const u8 *data, unsigned int len) { int ret = -1; u8 reg; @@ -124,18 +95,17 @@ adv7175_write_block (struct i2c_client *client, reg++; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + } while (len >= 2 && data[0] == reg && block_len < 32); + ret = i2c_master_send(client, block_data, block_len); + if (ret < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - if ((ret = adv7175_write(client, reg, - *data++)) < 0) + ret = adv7175_write(client, reg, *data++); + if (ret < 0) break; len -= 2; } @@ -144,13 +114,11 @@ adv7175_write_block (struct i2c_client *client, return ret; } -static void -set_subcarrier_freq (struct i2c_client *client, - int pass_through) +static void set_subcarrier_freq(struct i2c_client *client, int pass_through) { /* for some reason pass_through NTSC needs * a different sub-carrier freq to remain stable. */ - if(pass_through) + if (pass_through) adv7175_write(client, 0x02, 0x00); else adv7175_write(client, 0x02, 0x55); @@ -161,12 +129,12 @@ set_subcarrier_freq (struct i2c_client *client, } /* ----------------------------------------------------------------------- */ -// Output filter: S-Video Composite +/* Output filter: S-Video Composite */ -#define MR050 0x11 //0x09 -#define MR060 0x14 //0x0c +#define MR050 0x11 /* 0x09 */ +#define MR060 0x14 /* 0x0c */ -//--------------------------------------------------------------------------- +/* ----------------------------------------------------------------------- */ #define TR0MODE 0x46 #define TR0RST 0x80 @@ -217,15 +185,11 @@ static const unsigned char init_ntsc[] = { 0x06, 0x1a, /* subc. phase */ }; -static int -adv7175_command (struct i2c_client *client, - unsigned int cmd, - void *arg) +static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) { struct adv7175 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: /* This is just for testing!!! */ adv7175_write_block(client, init_common, @@ -243,15 +207,14 @@ adv7175_command (struct i2c_client *client, VIDEO_ENCODER_SECAM; /* well, hacky */ cap->inputs = 2; cap->outputs = 1; - } break; + } case ENCODER_SET_NORM: { int iarg = *(int *) arg; switch (iarg) { - case VIDEO_MODE_NTSC: adv7175_write_block(client, init_ntsc, sizeof(init_ntsc)); @@ -285,16 +248,13 @@ adv7175_command (struct i2c_client *client, adv7175_write(client, 0x07, TR0MODE); break; default: - dprintk(1, KERN_ERR "%s: illegal norm: %d\n", - I2C_NAME(client), iarg); + v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); return -EINVAL; - } - dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client), - norms[iarg]); + v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); encoder->norm = iarg; - } break; + } case ENCODER_SET_INPUT: { @@ -305,7 +265,6 @@ adv7175_command (struct i2c_client *client, *iarg = 2: color bar */ switch (iarg) { - case 0: adv7175_write(client, 0x01, 0x00); @@ -332,7 +291,7 @@ adv7175_command (struct i2c_client *client, adv7175_write(client, 0x0d, 0x49); adv7175_write(client, 0x07, TR0MODE | TR0RST); adv7175_write(client, 0x07, TR0MODE); - //udelay(10); + /* udelay(10); */ break; case 2: @@ -344,39 +303,35 @@ adv7175_command (struct i2c_client *client, adv7175_write(client, 0x0d, 0x49); adv7175_write(client, 0x07, TR0MODE | TR0RST); adv7175_write(client, 0x07, TR0MODE); - //udelay(10); + /* udelay(10); */ break; default: - dprintk(1, KERN_ERR "%s: illegal input: %d\n", - I2C_NAME(client), iarg); + v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); return -EINVAL; - } - dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client), - inputs[iarg]); + v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); encoder->input = iarg; - } break; + } case ENCODER_SET_OUTPUT: { int *iarg = arg; /* not much choice of outputs */ - if (*iarg != 0) { + if (*iarg != 0) return -EINVAL; - } - } break; + } case ENCODER_ENABLE_OUTPUT: { int *iarg = arg; encoder->enable = !!*iarg; - } break; + } default: return -EINVAL; @@ -391,145 +346,71 @@ adv7175_command (struct i2c_client *client, * Generic i2c probe * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' */ -static unsigned short normal_i2c[] = - { I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1, +static unsigned short normal_i2c[] = { + I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1, I2C_ADV7176 >> 1, (I2C_ADV7176 >> 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_adv7175; +I2C_CLIENT_INSMOD; -static int -adv7175_detect_client (struct i2c_adapter *adapter, - int address, - int kind) +static int adv7175_probe(struct i2c_client *client, + const struct i2c_device_id *id) { int i; - struct i2c_client *client; struct adv7175 *encoder; - char *dname; - - dprintk(1, - KERN_INFO - "adv7175.c: detecting adv7175 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; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) - return -ENOMEM; - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver_adv7175; - if ((client->addr == I2C_ADV7175 >> 1) || - (client->addr == (I2C_ADV7175 >> 1) + 1)) { - dname = adv7175_name; - } else if ((client->addr == I2C_ADV7176 >> 1) || - (client->addr == (I2C_ADV7176 >> 1) + 1)) { - dname = adv7176_name; - } else { - /* We should never get here!!! */ - kfree(client); - return 0; - } - strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client))); + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL); - if (encoder == NULL) { - kfree(client); + if (encoder == NULL) return -ENOMEM; - } encoder->norm = VIDEO_MODE_PAL; encoder->input = 0; encoder->enable = 1; i2c_set_clientdata(client, encoder); - i = i2c_attach_client(client); - if (i) { - kfree(client); - kfree(encoder); - return i; - } - i = adv7175_write_block(client, init_common, sizeof(init_common)); if (i >= 0) { i = adv7175_write(client, 0x07, TR0MODE | TR0RST); i = adv7175_write(client, 0x07, TR0MODE); i = adv7175_read(client, 0x12); - dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%x\n", - I2C_NAME(client), i & 1, client->addr << 1); + v4l_dbg(1, debug, client, "revision %d\n", i & 1); } - if (i < 0) { - dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n", - I2C_NAME(client), i); - } - + if (i < 0) + v4l_dbg(1, debug, client, "init error 0x%x\n", i); return 0; } -static int -adv7175_attach_adapter (struct i2c_adapter *adapter) -{ - dprintk(1, - KERN_INFO - "adv7175.c: starting probe for adapter %s (0x%x)\n", - I2C_NAME(adapter), adapter->id); - return i2c_probe(adapter, &addr_data, &adv7175_detect_client); -} - -static int -adv7175_detach_client (struct i2c_client *client) +static int adv7175_remove(struct i2c_client *client) { - struct adv7175 *encoder = i2c_get_clientdata(client); - int err; - - err = i2c_detach_client(client); - if (err) { - return err; - } - - kfree(encoder); - kfree(client); - + kfree(i2c_get_clientdata(client)); return 0; } /* ----------------------------------------------------------------------- */ -static struct i2c_driver i2c_driver_adv7175 = { - .driver = { - .name = "adv7175", /* name */ - }, - - .id = I2C_DRIVERID_ADV7175, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id adv7175_id[] = { + { "adv7175", 0 }, + { "adv7176", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adv7175_id); +#endif - .attach_adapter = adv7175_attach_adapter, - .detach_client = adv7175_detach_client, +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "adv7175", + .driverid = I2C_DRIVERID_ADV7175, .command = adv7175_command, + .probe = adv7175_probe, + .remove = adv7175_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = adv7175_id, +#endif }; - -static int __init -adv7175_init (void) -{ - return i2c_add_driver(&i2c_driver_adv7175); -} - -static void __exit -adv7175_exit (void) -{ - i2c_del_driver(&i2c_driver_adv7175); -} - -module_init(adv7175_init); -module_exit(adv7175_exit); -- cgit v1.2.3 From 52eabd27505064c67b4ac7fb7cf3f02991c85d51 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 13 Oct 2008 12:30:15 +0200 Subject: bt819: convert i2c driver for new i2c API From: Hans Verkuil - Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API - Cleanups - Use v4l_dbg/v4l_info to have uniform kernel messages Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/bt819.c | 325 +++++++++++--------------------------- 1 file changed, 96 insertions(+), 229 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt819.c b/linux/drivers/media/video/bt819.c index 90be239cc..201dd9277 100644 --- a/linux/drivers/media/video/bt819.c +++ b/linux/drivers/media/video/bt819.c @@ -29,45 +29,26 @@ */ #include -#include #include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include +#include #include - +#include +#include #include #include - +#include +#include #include "compat.h" MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); MODULE_AUTHOR("Mike Bernson & Dave Perks"); MODULE_LICENSE("GPL"); - -#define I2C_NAME(s) (s)->name - - static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -#define dprintk(num, format, args...) \ - do { \ - if (debug >= num) \ - printk(format, ##args); \ - } while (0) - /* ----------------------------------------------------------------------- */ struct bt819 { @@ -98,14 +79,9 @@ static struct timing timing_data[] = { {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000}, }; -#define I2C_BT819 0x8a - /* ----------------------------------------------------------------------- */ -static inline int -bt819_write (struct i2c_client *client, - u8 reg, - u8 value) +static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value) { struct bt819 *decoder = i2c_get_clientdata(client); @@ -113,24 +89,15 @@ bt819_write (struct i2c_client *client, return i2c_smbus_write_byte_data(client, reg, value); } -static inline int -bt819_setbit (struct i2c_client *client, - u8 reg, - u8 bit, - u8 value) +static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value) { struct bt819 *decoder = i2c_get_clientdata(client); return bt819_write(client, reg, - (decoder-> - reg[reg] & ~(1 << bit)) | - (value ? (1 << bit) : 0)); + (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0)); } -static int -bt819_write_block (struct i2c_client *client, - const u8 *data, - unsigned int len) +static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len) { int ret = -1; u8 reg; @@ -151,10 +118,9 @@ bt819_write_block (struct i2c_client *client, decoder->reg[reg++] = data[1]; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + } while (len >= 2 && data[0] == reg && block_len < 32); + ret = i2c_master_send(client, block_data, block_len); + if (ret < 0) break; } } else { @@ -170,20 +136,17 @@ bt819_write_block (struct i2c_client *client, return ret; } -static inline int -bt819_read (struct i2c_client *client, - u8 reg) +static inline int bt819_read(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); } -static int -bt819_init (struct i2c_client *client) +static int bt819_init(struct i2c_client *client) { struct bt819 *decoder = i2c_get_clientdata(client); static unsigned char init[] = { - //0x1f, 0x00, /* Reset */ + /*0x1f, 0x00,*/ /* Reset */ 0x01, 0x59, /* 0x01 input format */ 0x02, 0x00, /* 0x02 temporal decimation */ 0x03, 0x12, /* 0x03 Cropping msb */ @@ -219,12 +182,10 @@ bt819_init (struct i2c_client *client) struct timing *timing = &timing_data[decoder->norm]; init[0x03 * 2 - 1] = - (((timing->vdelay >> 8) & 0x03) << 6) | (((timing-> - vactive >> 8) & - 0x03) << 4) | - (((timing->hdelay >> 8) & 0x03) << 2) | ((timing-> - hactive >> 8) & - 0x03); + (((timing->vdelay >> 8) & 0x03) << 6) | + (((timing->vactive >> 8) & 0x03) << 4) | + (((timing->hdelay >> 8) & 0x03) << 2) | + ((timing->hactive >> 8) & 0x03); init[0x04 * 2 - 1] = timing->vdelay & 0xff; init[0x05 * 2 - 1] = timing->vactive & 0xff; init[0x06 * 2 - 1] = timing->hdelay & 0xff; @@ -239,27 +200,22 @@ bt819_init (struct i2c_client *client) /* init */ return bt819_write_block(client, init, sizeof(init)); - } /* ----------------------------------------------------------------------- */ -static int -bt819_command (struct i2c_client *client, - unsigned int cmd, - void *arg) +static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) { int temp; struct bt819 *decoder = i2c_get_clientdata(client); - if (!decoder->initialized) { // First call to bt819_init could be - bt819_init(client); // without #FRST = 0 + if (!decoder->initialized) { /* First call to bt819_init could be */ + bt819_init(client); /* without #FRST = 0 */ decoder->initialized = 1; } switch (cmd) { - case 0: /* This is just for testing!!! */ bt819_init(client); @@ -275,8 +231,8 @@ bt819_command (struct i2c_client *client, VIDEO_DECODER_CCIR; cap->inputs = 8; cap->outputs = 1; - } break; + } case DECODER_GET_STATUS: { @@ -286,9 +242,9 @@ bt819_command (struct i2c_client *client, status = bt819_read(client, 0x00); res = 0; - if ((status & 0x80)) { + if ((status & 0x80)) res |= DECODER_STATUS_GOOD; - } + switch (decoder->norm) { case VIDEO_MODE_NTSC: res |= DECODER_STATUS_NTSC; @@ -298,28 +254,25 @@ bt819_command (struct i2c_client *client, break; default: case VIDEO_MODE_AUTO: - if ((status & 0x10)) { + if ((status & 0x10)) res |= DECODER_STATUS_PAL; - } else { + else res |= DECODER_STATUS_NTSC; - } break; } res |= DECODER_STATUS_COLOR; *iarg = res; - dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client), - *iarg); - } + v4l_dbg(1, debug, client, "get status %x\n", *iarg); break; + } case DECODER_SET_NORM: { int *iarg = arg; struct timing *timing = NULL; - dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client), - *iarg); + v4l_dbg(1, debug, client, "set norm %x\n", *iarg); switch (*iarg) { case VIDEO_MODE_NTSC: @@ -328,7 +281,7 @@ bt819_command (struct i2c_client *client, bt819_setbit(client, 0x01, 5, 0); bt819_write(client, 0x18, 0x68); bt819_write(client, 0x19, 0x5d); - //bt819_setbit(client, 0x1a, 5, 1); + /* bt819_setbit(client, 0x1a, 5, 1); */ timing = &timing_data[VIDEO_MODE_NTSC]; break; case VIDEO_MODE_PAL: @@ -337,7 +290,7 @@ bt819_command (struct i2c_client *client, bt819_setbit(client, 0x01, 5, 1); bt819_write(client, 0x18, 0x7f); bt819_write(client, 0x19, 0x72); - //bt819_setbit(client, 0x1a, 5, 0); + /* bt819_setbit(client, 0x1a, 5, 0); */ timing = &timing_data[VIDEO_MODE_PAL]; break; case VIDEO_MODE_AUTO: @@ -345,10 +298,7 @@ bt819_command (struct i2c_client *client, bt819_setbit(client, 0x01, 1, 0); break; default: - dprintk(1, - KERN_ERR - "%s: unsupported norm %d\n", - I2C_NAME(client), *iarg); + v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg); return -EINVAL; } @@ -367,19 +317,17 @@ bt819_command (struct i2c_client *client, } decoder->norm = *iarg; - } break; + } case DECODER_SET_INPUT: { int *iarg = arg; - dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client), - *iarg); + v4l_dbg(1, debug, client, "set input %x\n", *iarg); - if (*iarg < 0 || *iarg > 7) { + if (*iarg < 0 || *iarg > 7) return -EINVAL; - } if (decoder->input != *iarg) { decoder->input = *iarg; @@ -392,52 +340,42 @@ bt819_command (struct i2c_client *client, bt819_setbit(client, 0x1a, 1, 0); } } - } break; + } case DECODER_SET_OUTPUT: { int *iarg = arg; - dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client), - *iarg); + v4l_dbg(1, debug, client, "set output %x\n", *iarg); /* not much choice of outputs */ - if (*iarg != 0) { + if (*iarg != 0) return -EINVAL; - } - } break; + } case DECODER_ENABLE_OUTPUT: { int *iarg = arg; int enable = (*iarg != 0); - dprintk(1, KERN_INFO "%s: enable output %x\n", - I2C_NAME(client), *iarg); + v4l_dbg(1, debug, client, "enable output %x\n", *iarg); if (decoder->enable != enable) { decoder->enable = enable; - - if (decoder->enable) { - bt819_setbit(client, 0x16, 7, 0); - } else { - bt819_setbit(client, 0x16, 7, 1); - } + bt819_setbit(client, 0x16, 7, !enable); } - } break; + } case DECODER_SET_PICTURE: { struct video_picture *pic = arg; - dprintk(1, - KERN_INFO - "%s: set picture brightness %d contrast %d colour %d\n", - I2C_NAME(client), pic->brightness, pic->contrast, - pic->colour); + v4l_dbg(1, debug, client, + "set picture brightness %d contrast %d colour %d\n", + pic->brightness, pic->contrast, pic->colour); if (decoder->bright != pic->brightness) { @@ -475,8 +413,8 @@ bt819_command (struct i2c_client *client, bt819_write(client, 0x0f, 128 - (decoder->hue >> 8)); } - } break; + } default: return -EINVAL; @@ -487,55 +425,44 @@ bt819_command (struct i2c_client *client, /* ----------------------------------------------------------------------- */ -/* - * Generic i2c probe - * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' - */ -static unsigned short normal_i2c[] = { - I2C_BT819 >> 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 unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END }; -static struct i2c_driver i2c_driver_bt819; +I2C_CLIENT_INSMOD; -static int -bt819_detect_client (struct i2c_adapter *adapter, - int address, - int kind) +static int bt819_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - int i, id; + int i, ver; struct bt819 *decoder; - struct i2c_client *client; - - dprintk(1, - KERN_INFO - "bt819: detecting bt819 client on address 0x%x\n", - address << 1); + const char *name; /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return 0; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) - return -ENOMEM; - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver_bt819; + ver = bt819_read(client, 0x17); + switch (ver & 0xf0) { + case 0x70: + name = "bt819a"; + break; + case 0x60: + name = "bt817a"; + break; + case 0x20: + name = "bt815a"; + break; + default: + v4l_dbg(1, debug, client, + "unknown chip version 0x%02x\n", ver); + return -ENODEV; + } + + v4l_info(client, "%s found @ 0x%x (%s)\n", name, + client->addr << 1, client->adapter->name); decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL); - if (decoder == NULL) { - kfree(client); + if (decoder == NULL) return -ENOMEM; - } decoder->norm = VIDEO_MODE_NTSC; decoder->input = 0; decoder->enable = 1; @@ -546,97 +473,37 @@ bt819_detect_client (struct i2c_adapter *adapter, decoder->initialized = 0; i2c_set_clientdata(client, decoder); - id = bt819_read(client, 0x17); - switch (id & 0xf0) { - case 0x70: - strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client))); - break; - case 0x60: - strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client))); - break; - case 0x20: - strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client))); - break; - default: - dprintk(1, - KERN_ERR - "bt819: unknown chip version 0x%x (ver 0x%x)\n", - id & 0xf0, id & 0x0f); - kfree(decoder); - kfree(client); - return 0; - } - - i = i2c_attach_client(client); - if (i) { - kfree(client); - kfree(decoder); - return i; - } - i = bt819_init(client); - if (i < 0) { - dprintk(1, KERN_ERR "%s_attach: init status %d\n", - I2C_NAME(client), i); - } else { - dprintk(1, - KERN_INFO - "%s_attach: chip version 0x%x at address 0x%x\n", - I2C_NAME(client), id & 0x0f, - client->addr << 1); - } - + if (i < 0) + v4l_dbg(1, debug, client, "init status %d\n", i); return 0; } -static int -bt819_attach_adapter (struct i2c_adapter *adapter) -{ - return i2c_probe(adapter, &addr_data, &bt819_detect_client); -} - -static int -bt819_detach_client (struct i2c_client *client) +static int bt819_remove(struct i2c_client *client) { - struct bt819 *decoder = i2c_get_clientdata(client); - int err; - - err = i2c_detach_client(client); - if (err) { - return err; - } - - kfree(decoder); - kfree(client); - + kfree(i2c_get_clientdata(client)); return 0; } /* ----------------------------------------------------------------------- */ -static struct i2c_driver i2c_driver_bt819 = { - .driver = { - .name = "bt819", - }, - - .id = I2C_DRIVERID_BT819, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id bt819_id[] = { + { "bt819a", 0 }, + { "bt817a", 0 }, + { "bt815a", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, bt819_id); - .attach_adapter = bt819_attach_adapter, - .detach_client = bt819_detach_client, +#endif +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "bt819", + .driverid = I2C_DRIVERID_BT819, .command = bt819_command, + .probe = bt819_probe, + .remove = bt819_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = bt819_id, +#endif }; - -static int __init -bt819_init_module (void) -{ - return i2c_add_driver(&i2c_driver_bt819); -} - -static void __exit -bt819_exit (void) -{ - i2c_del_driver(&i2c_driver_bt819); -} - -module_init(bt819_init_module); -module_exit(bt819_exit); -- cgit v1.2.3 From a9422cc0001d003314b8ade0251ef5c3ce4cb3cc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Sep 2008 12:59:35 +0200 Subject: bt856: convert i2c driver for new i2c API From: Hans Verkuil - Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API - Cleanups - Use v4l_dbg/v4l_info to have uniform kernel messages Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/bt856.c | 222 +++++++++----------------------------- 1 file changed, 53 insertions(+), 169 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt856.c b/linux/drivers/media/video/bt856.c index e31c9d4b9..89c4061c7 100644 --- a/linux/drivers/media/video/bt856.c +++ b/linux/drivers/media/video/bt856.c @@ -29,44 +29,25 @@ */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include #include +#include +#include #include -#include -#include -#include -#include - +#include +#include #include "compat.h" -#include MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); MODULE_AUTHOR("Mike Bernson & Dave Perks"); MODULE_LICENSE("GPL"); - -#define I2C_NAME(s) (s)->name - - static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -#define dprintk(num, format, args...) \ - do { \ - if (debug >= num) \ - printk(format, ##args); \ - } while (0) - /* ----------------------------------------------------------------------- */ #define BT856_REG_OFFSET 0xDA @@ -79,14 +60,9 @@ struct bt856 { int enable; }; -#define I2C_BT856 0x88 - /* ----------------------------------------------------------------------- */ -static inline int -bt856_write (struct i2c_client *client, - u8 reg, - u8 value) +static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value) { struct bt856 *encoder = i2c_get_clientdata(client); @@ -94,46 +70,36 @@ bt856_write (struct i2c_client *client, return i2c_smbus_write_byte_data(client, reg, value); } -static inline int -bt856_setbit (struct i2c_client *client, - u8 reg, - u8 bit, - u8 value) +static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value) { struct bt856 *encoder = i2c_get_clientdata(client); return bt856_write(client, reg, - (encoder-> - reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | - (value ? (1 << bit) : 0)); + (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | + (value ? (1 << bit) : 0)); } -static void -bt856_dump (struct i2c_client *client) +static void bt856_dump(struct i2c_client *client) { int i; struct bt856 *encoder = i2c_get_clientdata(client); - printk(KERN_INFO "%s: register dump:", I2C_NAME(client)); + v4l_info(client, "register dump:\n"); for (i = 0; i < BT856_NR_REG; i += 2) - printk(" %02x", encoder->reg[i]); - printk("\n"); + printk(KERN_CONT " %02x", encoder->reg[i]); + printk(KERN_CONT "\n"); } /* ----------------------------------------------------------------------- */ -static int -bt856_command (struct i2c_client *client, - unsigned int cmd, - void *arg) +static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) { struct bt856 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: /* This is just for testing!!! */ - dprintk(1, KERN_INFO "bt856: init\n"); + v4l_dbg(1, debug, client, "init\n"); bt856_write(client, 0xdc, 0x18); bt856_write(client, 0xda, 0); bt856_write(client, 0xde, 0); @@ -143,7 +109,6 @@ bt856_command (struct i2c_client *client, bt856_setbit(client, 0xdc, 4, 1); switch (encoder->norm) { - case VIDEO_MODE_NTSC: bt856_setbit(client, 0xdc, 2, 0); break; @@ -164,26 +129,23 @@ bt856_command (struct i2c_client *client, { struct video_encoder_capability *cap = arg; - dprintk(1, KERN_INFO "%s: get capabilities\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "get capabilities\n"); cap->flags = VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC | VIDEO_ENCODER_CCIR; cap->inputs = 2; cap->outputs = 1; - } break; + } case ENCODER_SET_NORM: { int *iarg = arg; - dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client), - *iarg); + v4l_dbg(1, debug, client, "set norm %d\n", *iarg); switch (*iarg) { - case VIDEO_MODE_NTSC: bt856_setbit(client, 0xdc, 2, 0); break; @@ -196,27 +158,23 @@ bt856_command (struct i2c_client *client, default: return -EINVAL; - } encoder->norm = *iarg; if (debug != 0) bt856_dump(client); - } break; + } case ENCODER_SET_INPUT: { int *iarg = arg; - dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client), - *iarg); + v4l_dbg(1, debug, client, "set input %d\n", *iarg); /* We only have video bus. * iarg = 0: input is from bt819 * iarg = 1: input is from ZR36060 */ - switch (*iarg) { - case 0: bt856_setbit(client, 0xde, 4, 0); bt856_setbit(client, 0xde, 3, 1); @@ -235,27 +193,24 @@ bt856_command (struct i2c_client *client, break; default: return -EINVAL; - } if (debug != 0) bt856_dump(client); - } break; + } case ENCODER_SET_OUTPUT: { int *iarg = arg; - dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client), - *iarg); + v4l_dbg(1, debug, client, "set output %d\n", *iarg); /* not much choice of outputs */ - if (*iarg != 0) { + if (*iarg != 0) return -EINVAL; - } - } break; + } case ENCODER_ENABLE_OUTPUT: { @@ -263,10 +218,9 @@ bt856_command (struct i2c_client *client, encoder->enable = !!*iarg; - dprintk(1, KERN_INFO "%s: enable output %d\n", - I2C_NAME(client), encoder->enable); - } + v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); break; + } default: return -EINVAL; @@ -277,64 +231,29 @@ bt856_command (struct i2c_client *client, /* ----------------------------------------------------------------------- */ -/* - * Generic i2c probe - * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' - */ -static unsigned short normal_i2c[] = { I2C_BT856 >> 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 unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; -static struct i2c_driver i2c_driver_bt856; +I2C_CLIENT_INSMOD; -static int -bt856_detect_client (struct i2c_adapter *adapter, - int address, - int kind) +static int bt856_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - int i; - struct i2c_client *client; struct bt856 *encoder; - dprintk(1, - KERN_INFO - "bt856.c: detecting bt856 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; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) - return -ENOMEM; - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver_bt856; - strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client))); + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); - if (encoder == NULL) { - kfree(client); + if (encoder == NULL) return -ENOMEM; - } encoder->norm = VIDEO_MODE_NTSC; encoder->enable = 1; i2c_set_clientdata(client, encoder); - i = i2c_attach_client(client); - if (i) { - kfree(client); - kfree(encoder); - return i; - } - bt856_write(client, 0xdc, 0x18); bt856_write(client, 0xda, 0); bt856_write(client, 0xde, 0); @@ -360,65 +279,30 @@ bt856_detect_client (struct i2c_adapter *adapter, if (debug != 0) bt856_dump(client); - - dprintk(1, KERN_INFO "%s_attach: at address 0x%x\n", I2C_NAME(client), - client->addr << 1); - return 0; } -static int -bt856_attach_adapter (struct i2c_adapter *adapter) +static int bt856_remove(struct i2c_client *client) { - dprintk(1, - KERN_INFO - "bt856.c: starting probe for adapter %s (0x%x)\n", - I2C_NAME(adapter), adapter->id); - return i2c_probe(adapter, &addr_data, &bt856_detect_client); -} - -static int -bt856_detach_client (struct i2c_client *client) -{ - struct bt856 *encoder = i2c_get_clientdata(client); - int err; - - err = i2c_detach_client(client); - if (err) { - return err; - } - - kfree(encoder); - kfree(client); - + kfree(i2c_get_clientdata(client)); return 0; } -/* ----------------------------------------------------------------------- */ - -static struct i2c_driver i2c_driver_bt856 = { - .driver = { - .name = "bt856", - }, - - .id = I2C_DRIVERID_BT856, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id bt856_id[] = { + { "bt856", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, bt856_id); +#endif - .attach_adapter = bt856_attach_adapter, - .detach_client = bt856_detach_client, +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "bt856", + .driverid = I2C_DRIVERID_BT856, .command = bt856_command, + .probe = bt856_probe, + .remove = bt856_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = bt856_id, +#endif }; - -static int __init -bt856_init (void) -{ - return i2c_add_driver(&i2c_driver_bt856); -} - -static void __exit -bt856_exit (void) -{ - i2c_del_driver(&i2c_driver_bt856); -} - -module_init(bt856_init); -module_exit(bt856_exit); -- cgit v1.2.3 From 722fa17a0730051e3f7c0ba5a93e3a20c6bb237b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Sep 2008 12:59:54 +0200 Subject: bt866: convert i2c driver for new i2c API From: Hans Verkuil - Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API - Cleanups - Use v4l_dbg/v4l_info to have uniform kernel messages Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/bt866.c | 261 +++++++++++++------------------------- 1 file changed, 88 insertions(+), 173 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bt866.c b/linux/drivers/media/video/bt866.c index 89161e867..aaa985c8e 100644 --- a/linux/drivers/media/video/bt866.c +++ b/linux/drivers/media/video/bt866.c @@ -29,43 +29,29 @@ */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include #include - -#include "compat.h" +#include #include -#include - #include +#include +#include +#include "compat.h" +MODULE_DESCRIPTION("Brooktree-866 video encoder driver"); +MODULE_AUTHOR("Mike Bernson & Dave Perks"); MODULE_LICENSE("GPL"); -#define BT866_DEVNAME "bt866" -#define I2C_BT866 0x88 - -MODULE_LICENSE("GPL"); - -#define DEBUG(x) /* Debug driver */ +static int debug; +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* ----------------------------------------------------------------------- */ struct bt866 { - struct i2c_client *i2c; - int addr; - unsigned char reg[256]; + u8 reg[256]; int norm; int enable; @@ -75,20 +61,45 @@ struct bt866 { int sat; }; -static int bt866_write(struct bt866 *dev, - unsigned char subaddr, unsigned char data); +static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data) +{ + struct bt866 *encoder = i2c_get_clientdata(client); + u8 buffer[2]; + int err; + + buffer[0] = subaddr; + buffer[1] = data; + + encoder->reg[subaddr] = data; + + v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data); -static int bt866_do_command(struct bt866 *encoder, - unsigned int cmd, void *arg) + for (err = 0; err < 3;) { + if (i2c_master_send(client, buffer, 2) == 2) + break; + err++; + v4l_warn(client, "error #%d writing to 0x%02x\n", + err, subaddr); + schedule_timeout_interruptible(msecs_to_jiffies(100)); + } + if (err == 3) { + v4l_warn(client, "giving up\n"); + return -1; + } + + return 0; +} + +static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) { + struct bt866 *encoder = i2c_get_clientdata(client); + switch (cmd) { case ENCODER_GET_CAPABILITIES: { struct video_encoder_capability *cap = arg; - DEBUG(printk - (KERN_INFO "%s: get capabilities\n", - encoder->i2c->name)); + v4l_dbg(1, debug, client, "get capabilities\n"); cap->flags = VIDEO_ENCODER_PAL @@ -96,18 +107,16 @@ static int bt866_do_command(struct bt866 *encoder, | VIDEO_ENCODER_CCIR; cap->inputs = 2; cap->outputs = 1; + break; } - break; case ENCODER_SET_NORM: { int *iarg = arg; - DEBUG(printk(KERN_INFO "%s: set norm %d\n", - encoder->i2c->name, *iarg)); + v4l_dbg(1, debug, client, "set norm %d\n", *iarg); switch (*iarg) { - case VIDEO_MODE_NTSC: break; @@ -116,11 +125,10 @@ static int bt866_do_command(struct bt866 *encoder, default: return -EINVAL; - } encoder->norm = *iarg; + break; } - break; case ENCODER_SET_INPUT: { @@ -156,7 +164,7 @@ static int bt866_do_command(struct bt866 *encoder, u8 val; for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) - bt866_write(encoder, init[i], init[i+1]); + bt866_write(client, init[i], init[i+1]); val = encoder->reg[0xdc]; @@ -165,17 +173,16 @@ static int bt866_do_command(struct bt866 *encoder, else val &= ~0x40; /* !CBSWAP */ - bt866_write(encoder, 0xdc, val); + bt866_write(client, 0xdc, val); val = encoder->reg[0xcc]; if (*iarg == 2) val |= 0x01; /* OSDBAR */ else val &= ~0x01; /* !OSDBAR */ - bt866_write(encoder, 0xcc, val); + bt866_write(client, 0xcc, val); - DEBUG(printk(KERN_INFO "%s: set input %d\n", - encoder->i2c->name, *iarg)); + v4l_dbg(1, debug, client, "set input %d\n", *iarg); switch (*iarg) { case 0: @@ -184,48 +191,44 @@ static int bt866_do_command(struct bt866 *encoder, break; default: return -EINVAL; - } + break; } - break; case ENCODER_SET_OUTPUT: { int *iarg = arg; - DEBUG(printk(KERN_INFO "%s: set output %d\n", - encoder->i2c->name, *iarg)); + v4l_dbg(1, debug, client, "set output %d\n", *iarg); /* not much choice of outputs */ if (*iarg != 0) return -EINVAL; + break; } - break; case ENCODER_ENABLE_OUTPUT: { int *iarg = arg; encoder->enable = !!*iarg; - DEBUG(printk - (KERN_INFO "%s: enable output %d\n", - encoder->i2c->name, encoder->enable)); + v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); + break; } - break; case 4711: { int *iarg = arg; __u8 val; - printk("bt866: square = %d\n", *iarg); + v4l_dbg(1, debug, client, "square %d\n", *iarg); val = encoder->reg[0xdc]; if (*iarg) val |= 1; /* SQUARE */ else val &= ~1; /* !SQUARE */ - bt866_write(encoder, 0xdc, val); + bt866_write(client, 0xdc, val); break; } @@ -236,141 +239,53 @@ static int bt866_do_command(struct bt866 *encoder, return 0; } -static int bt866_write(struct bt866 *encoder, - unsigned char subaddr, unsigned char data) -{ - unsigned char buffer[2]; - int err; - - buffer[0] = subaddr; - buffer[1] = data; - - encoder->reg[subaddr] = data; +static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; - DEBUG(printk - ("%s: write 0x%02X = 0x%02X\n", - encoder->i2c->name, subaddr, data)); +I2C_CLIENT_INSMOD; - for (err = 0; err < 3;) { - if (i2c_master_send(encoder->i2c, buffer, 2) == 2) - break; - err++; - printk(KERN_WARNING "%s: I/O error #%d " - "(write 0x%02x/0x%02x)\n", - encoder->i2c->name, err, encoder->addr, subaddr); - schedule_timeout_interruptible(msecs_to_jiffies(100)); - } - if (err == 3) { - printk(KERN_WARNING "%s: giving up\n", - encoder->i2c->name); - return -1; - } - - return 0; -} - -static int bt866_attach(struct i2c_adapter *adapter); -static int bt866_detach(struct i2c_client *client); -static int bt866_command(struct i2c_client *client, - unsigned int cmd, void *arg); - - -/* Addresses to scan */ -static unsigned short normal_i2c[] = {I2C_BT866>>1, I2C_CLIENT_END}; -static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; -static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; - -static struct i2c_client_address_data addr_data = { - normal_i2c, - probe, - ignore, -}; - -static struct i2c_driver i2c_driver_bt866 = { - .driver.name = BT866_DEVNAME, - .id = I2C_DRIVERID_BT866, - .attach_adapter = bt866_attach, - .detach_client = bt866_detach, - .command = bt866_command -}; - - -static struct i2c_client bt866_client_tmpl = -{ - .name = "(nil)", - .addr = 0, - .adapter = NULL, - .driver = &i2c_driver_bt866, -}; - -static int bt866_found_proc(struct i2c_adapter *adapter, - int addr, int kind) +static int bt866_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct bt866 *encoder; - struct i2c_client *client; - client = kzalloc(sizeof(*client), GFP_KERNEL); - if (client == NULL) - return -ENOMEM; - memcpy(client, &bt866_client_tmpl, sizeof(*client)); + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); - if (encoder == NULL) { - kfree(client); + if (encoder == NULL) return -ENOMEM; - } i2c_set_clientdata(client, encoder); - client->adapter = adapter; - client->addr = addr; - sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id); - - encoder->i2c = client; - encoder->addr = addr; - //encoder->encoder_type = ENCODER_TYPE_UNKNOWN; - - /* initialize */ - - i2c_attach_client(client); - return 0; } -static int bt866_attach(struct i2c_adapter *adapter) +static int bt866_remove(struct i2c_client *client) { - if (adapter->id == I2C_HW_B_ZR36067) - return i2c_probe(adapter, &addr_data, bt866_found_proc); + kfree(i2c_get_clientdata(client)); return 0; } -static int bt866_detach(struct i2c_client *client) +static int bt866_legacy_probe(struct i2c_adapter *adapter) { - struct bt866 *encoder = i2c_get_clientdata(client); - - i2c_detach_client(client); - kfree(encoder); - kfree(client); - - return 0; + return adapter->id == I2C_HW_B_ZR36067; } -static int bt866_command(struct i2c_client *client, - unsigned int cmd, void *arg) -{ - struct bt866 *encoder = i2c_get_clientdata(client); - return bt866_do_command(encoder, cmd, arg); -} - -static int __devinit bt866_init(void) -{ - i2c_add_driver(&i2c_driver_bt866); - return 0; -} - -static void __devexit bt866_exit(void) -{ - i2c_del_driver(&i2c_driver_bt866); -} - -module_init(bt866_init); -module_exit(bt866_exit); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id bt866_id[] = { + { "bt866", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, bt866_id); +#endif + +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "bt866", + .driverid = I2C_DRIVERID_BT866, + .command = bt866_command, + .probe = bt866_probe, + .remove = bt866_remove, + .legacy_probe = bt866_legacy_probe, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = bt866_id, +#endif +}; -- cgit v1.2.3 From c3bf7763d1737346c1e8f813f21ac60dde93943e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Sep 2008 13:00:14 +0200 Subject: ks0127: convert i2c driver for new i2c API From: Hans Verkuil - Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API - Cleanups - Use v4l_dbg/v4l_info to have uniform kernel messages Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ks0127.c | 478 +++++++++++++++++-------------------- 1 file changed, 215 insertions(+), 263 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/ks0127.c b/linux/drivers/media/video/ks0127.c index b21b6f097..16526165b 100644 --- a/linux/drivers/media/video/ks0127.c +++ b/linux/drivers/media/video/ks0127.c @@ -33,28 +33,21 @@ * V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard */ -#ifndef __KERNEL__ -#define __KERNEL__ -#endif - #include #include #include #include #include -#include -#include -#include "ks0127.h" - #include #include +#include +#include +#include "ks0127.h" #include "compat.h" -#define dprintk if (debug) printk - -/* i2c identification */ -#define I2C_KS0127_ADDON 0xD8 -#define I2C_KS0127_ONBOARD 0xDA +MODULE_DESCRIPTION("KS0127 video decoder driver"); +MODULE_AUTHOR("Ryan Drake"); +MODULE_LICENSE("GPL"); #define KS_TYPE_UNKNOWN 0 #define KS_TYPE_0122S 1 @@ -205,8 +198,6 @@ struct adjust { }; struct ks0127 { - struct i2c_client *client; - unsigned char addr; int format_width; int format_height; int cap_width; @@ -221,16 +212,18 @@ static int debug; /* insmod parameter */ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug output"); -MODULE_LICENSE("GPL"); static u8 reg_defaults[64]; - - static void init_reg_defaults(void) { + static int initialized; u8 *table = reg_defaults; + if (initialized) + return; + initialized = 1; + table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */ table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */ table[KS_CMDC] = 0x00; /* Test options */ @@ -309,50 +302,53 @@ static void init_reg_defaults(void) * An explanation from kayork@mail.utexas.edu: * * During I2C reads, the KS0127 only samples for a stop condition - * during the place where the acknoledge bit should be. Any standard + * during the place where the acknowledge bit should be. Any standard * I2C implementation (correctly) throws in another clock transition * at the 9th bit, and the KS0127 will not recognize the stop condition * and will continue to clock out data. * * So we have to do the read ourself. Big deal. - workaround in i2c-algo-bit + * workaround in i2c-algo-bit */ -static u8 ks0127_read(struct ks0127 *ks, u8 reg) +static u8 ks0127_read(struct i2c_client *c, u8 reg) { - struct i2c_client *c = ks->client; char val = 0; struct i2c_msg msgs[] = { - {c->addr, 0, sizeof(reg), ®}, - {c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}}; + { c->addr, 0, sizeof(reg), ® }, + { c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val } + }; int ret; ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs)); if (ret != ARRAY_SIZE(msgs)) - dprintk("ks0127_write error\n"); + v4l_dbg(1, debug, c, "read error\n"); return val; } -static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val) +static void ks0127_write(struct i2c_client *c, u8 reg, u8 val) { - char msg[] = {reg, val}; + struct ks0127 *ks = i2c_get_clientdata(c); + char msg[] = { reg, val }; - if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg)) - dprintk("ks0127_write error\n"); + if (i2c_master_send(c, msg, sizeof(msg)) != sizeof(msg)) + v4l_dbg(1, debug, c, "write error\n"); ks->regs[reg] = val; } /* generic bit-twiddling */ -static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v) +static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v) { + struct ks0127 *ks = i2c_get_clientdata(client); + u8 val = ks->regs[reg]; val = (val & and_v) | or_v; - ks0127_write(ks, reg, val); + ks0127_write(client, reg, val); } @@ -360,73 +356,69 @@ static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v) /**************************************************************************** * ks0127 private api ****************************************************************************/ -static void ks0127_reset(struct ks0127* ks) +static void ks0127_reset(struct i2c_client *c) { - int i; + struct ks0127 *ks = i2c_get_clientdata(c); u8 *table = reg_defaults; + int i; ks->ks_type = KS_TYPE_UNKNOWN; - dprintk("ks0127: reset\n"); + v4l_dbg(1, debug, c, "reset\n"); msleep(1); /* initialize all registers to known values */ /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */ - for(i = 1; i < 33; i++) - ks0127_write(ks, i, table[i]); + for (i = 1; i < 33; i++) + ks0127_write(c, i, table[i]); - for(i = 35; i < 40; i++) - ks0127_write(ks, i, table[i]); + for (i = 35; i < 40; i++) + ks0127_write(c, i, table[i]); - for(i = 41; i < 56; i++) - ks0127_write(ks, i, table[i]); + for (i = 41; i < 56; i++) + ks0127_write(c, i, table[i]); - for(i = 58; i < 64; i++) - ks0127_write(ks, i, table[i]); + for (i = 58; i < 64; i++) + ks0127_write(c, i, table[i]); - if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) { + if ((ks0127_read(c, KS_STAT) & 0x80) == 0) { ks->ks_type = KS_TYPE_0122S; - dprintk("ks0127: ks0122s Found\n"); + v4l_dbg(1, debug, c, "ks0122s found\n"); return; } - switch(ks0127_read(ks, KS_CMDE) & 0x0f) { - + switch (ks0127_read(c, KS_CMDE) & 0x0f) { case 0: ks->ks_type = KS_TYPE_0127; - dprintk("ks0127: ks0127 found\n"); + v4l_dbg(1, debug, c, "ks0127 found\n"); break; case 9: ks->ks_type = KS_TYPE_0127B; - dprintk("ks0127: ks0127B Revision A found\n"); + v4l_dbg(1, debug, c, "ks0127B Revision A found\n"); break; default: - dprintk("ks0127: unknown revision\n"); + v4l_dbg(1, debug, c, "unknown revision\n"); break; } } -static int ks0127_command(struct i2c_client *client, - unsigned int cmd, void *arg) +static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) { - struct ks0127 *ks = i2c_get_clientdata(client); - - int *iarg = (int*)arg; - + struct ks0127 *ks = i2c_get_clientdata(c); + int *iarg = (int *)arg; int status; if (!ks) return -ENODEV; switch (cmd) { - case DECODER_INIT: - dprintk("ks0127: command DECODER_INIT\n"); - ks0127_reset(ks); + v4l_dbg(1, debug, c, "DECODER_INIT\n"); + ks0127_reset(c); break; case DECODER_SET_INPUT: @@ -437,161 +429,160 @@ static int ks0127_command(struct i2c_client *client, case KS_INPUT_COMPOSITE_4: case KS_INPUT_COMPOSITE_5: case KS_INPUT_COMPOSITE_6: - dprintk("ks0127: command DECODER_SET_INPUT %d: " - "Composite\n", *iarg); + v4l_dbg(1, debug, c, + "DECODER_SET_INPUT %d: Composite\n", *iarg); /* autodetect 50/60 Hz */ - ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); + ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); /* VSE=0 */ - ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); + ks0127_and_or(c, KS_CMDA, ~0x40, 0x00); /* set input line */ - ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); + ks0127_and_or(c, KS_CMDB, 0xb0, *iarg); /* non-freerunning mode */ - ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); + ks0127_and_or(c, KS_CMDC, 0x70, 0x0a); /* analog input */ - ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); + ks0127_and_or(c, KS_CMDD, 0x03, 0x00); /* enable chroma demodulation */ - ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); + ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00); /* chroma trap, HYBWR=1 */ - ks0127_and_or(ks, KS_LUMA, 0x00, + ks0127_and_or(c, KS_LUMA, 0x00, (reg_defaults[KS_LUMA])|0x0c); /* scaler fullbw, luma comb off */ - ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); + ks0127_and_or(c, KS_VERTIA, 0x08, 0x81); /* manual chroma comb .25 .5 .25 */ - ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90); + ks0127_and_or(c, KS_VERTIC, 0x0f, 0x90); /* chroma path delay */ - ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90); + ks0127_and_or(c, KS_CHROMB, 0x0f, 0x90); - ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); - ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); - ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); - ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); + ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]); + ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]); + ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]); + ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]); break; case KS_INPUT_SVIDEO_1: case KS_INPUT_SVIDEO_2: case KS_INPUT_SVIDEO_3: - dprintk("ks0127: command DECODER_SET_INPUT %d: " - "S-Video\n", *iarg); + v4l_dbg(1, debug, c, + "DECODER_SET_INPUT %d: S-Video\n", *iarg); /* autodetect 50/60 Hz */ - ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); + ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); /* VSE=0 */ - ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); + ks0127_and_or(c, KS_CMDA, ~0x40, 0x00); /* set input line */ - ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); + ks0127_and_or(c, KS_CMDB, 0xb0, *iarg); /* non-freerunning mode */ - ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); + ks0127_and_or(c, KS_CMDC, 0x70, 0x0a); /* analog input */ - ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); + ks0127_and_or(c, KS_CMDD, 0x03, 0x00); /* enable chroma demodulation */ - ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); - ks0127_and_or(ks, KS_LUMA, 0x00, + ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00); + ks0127_and_or(c, KS_LUMA, 0x00, reg_defaults[KS_LUMA]); /* disable luma comb */ - ks0127_and_or(ks, KS_VERTIA, 0x08, + ks0127_and_or(c, KS_VERTIA, 0x08, (reg_defaults[KS_VERTIA]&0xf0)|0x01); - ks0127_and_or(ks, KS_VERTIC, 0x0f, + ks0127_and_or(c, KS_VERTIC, 0x0f, reg_defaults[KS_VERTIC]&0xf0); - ks0127_and_or(ks, KS_CHROMB, 0x0f, + ks0127_and_or(c, KS_CHROMB, 0x0f, reg_defaults[KS_CHROMB]&0xf0); - ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); - ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); - ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); - ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); + ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]); + ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]); + ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]); + ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]); break; case KS_INPUT_YUV656: - dprintk("ks0127: command DECODER_SET_INPUT 15: " - "YUV656\n"); + v4l_dbg(1, debug, c, + "DECODER_SET_INPUT 15: YUV656\n"); if (ks->norm == VIDEO_MODE_NTSC || ks->norm == KS_STD_PAL_M) /* force 60 Hz */ - ks0127_and_or(ks, KS_CMDA, 0xfc, 0x03); + ks0127_and_or(c, KS_CMDA, 0xfc, 0x03); else /* force 50 Hz */ - ks0127_and_or(ks, KS_CMDA, 0xfc, 0x02); + ks0127_and_or(c, KS_CMDA, 0xfc, 0x02); - ks0127_and_or(ks, KS_CMDA, 0xff, 0x40); /* VSE=1 */ + ks0127_and_or(c, KS_CMDA, 0xff, 0x40); /* VSE=1 */ /* set input line and VALIGN */ - ks0127_and_or(ks, KS_CMDB, 0xb0, (*iarg | 0x40)); + ks0127_and_or(c, KS_CMDB, 0xb0, (*iarg | 0x40)); /* freerunning mode, */ /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/ - ks0127_and_or(ks, KS_CMDC, 0x70, 0x87); + ks0127_and_or(c, KS_CMDC, 0x70, 0x87); /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */ - ks0127_and_or(ks, KS_CMDD, 0x03, 0x08); + ks0127_and_or(c, KS_CMDD, 0x03, 0x08); /* disable chroma demodulation */ - ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30); + ks0127_and_or(c, KS_CTRACK, 0xcf, 0x30); /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */ - ks0127_and_or(ks, KS_LUMA, 0x00, 0x71); - ks0127_and_or(ks, KS_VERTIC, 0x0f, + ks0127_and_or(c, KS_LUMA, 0x00, 0x71); + ks0127_and_or(c, KS_VERTIC, 0x0f, reg_defaults[KS_VERTIC]&0xf0); /* scaler fullbw, luma comb off */ - ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); + ks0127_and_or(c, KS_VERTIA, 0x08, 0x81); - ks0127_and_or(ks, KS_CHROMB, 0x0f, + ks0127_and_or(c, KS_CHROMB, 0x0f, reg_defaults[KS_CHROMB]&0xf0); - ks0127_and_or(ks, KS_CON, 0x00, 0x00); - ks0127_and_or(ks, KS_BRT, 0x00, 32); /* spec: 34 */ + ks0127_and_or(c, KS_CON, 0x00, 0x00); + ks0127_and_or(c, KS_BRT, 0x00, 32); /* spec: 34 */ /* spec: 229 (e5) */ - ks0127_and_or(ks, KS_SAT, 0x00, 0xe8); - ks0127_and_or(ks, KS_HUE, 0x00, 0); + ks0127_and_or(c, KS_SAT, 0x00, 0xe8); + ks0127_and_or(c, KS_HUE, 0x00, 0); - ks0127_and_or(ks, KS_UGAIN, 0x00, 238); - ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00); + ks0127_and_or(c, KS_UGAIN, 0x00, 238); + ks0127_and_or(c, KS_VGAIN, 0x00, 0x00); /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */ - ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f); - ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00); + ks0127_and_or(c, KS_UVOFFH, 0x00, 0x4f); + ks0127_and_or(c, KS_UVOFFL, 0x00, 0x00); break; default: - dprintk("ks0127: command DECODER_SET_INPUT: " - "Unknown input %d\n", *iarg); + v4l_dbg(1, debug, c, + "DECODER_SET_INPUT: Unknown input %d\n", *iarg); break; } /* hack: CDMLPF sometimes spontaneously switches on; */ /* force back off */ - ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]); + ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]); break; case DECODER_SET_OUTPUT: switch(*iarg) { case KS_OUTPUT_YUV656E: - dprintk("ks0127: command DECODER_SET_OUTPUT: " - "OUTPUT_YUV656E (Missing)\n"); + v4l_dbg(1, debug, c, + "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n"); return -EINVAL; - break; case KS_OUTPUT_EXV: - dprintk("ks0127: command DECODER_SET_OUTPUT: " - "OUTPUT_EXV\n"); - ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09); + v4l_dbg(1, debug, c, + "DECODER_SET_OUTPUT: OUTPUT_EXV\n"); + ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09); break; } break; - case DECODER_SET_NORM: //sam This block mixes old and new norm names... + case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */ /* Set to automatic SECAM/Fsc mode */ - ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); + ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); ks->norm = *iarg; - switch(*iarg) - { + switch (*iarg) { /* this is untested !! */ /* It just detects PAL_N/NTSC_M (no special frequencies) */ /* And you have to set the standard a second time afterwards */ case VIDEO_MODE_AUTO: - dprintk("ks0127: command DECODER_SET_NORM: AUTO\n"); + v4l_dbg(1, debug, c, + "DECODER_SET_NORM: AUTO\n"); /* The chip determines the format */ /* based on the current field rate */ - ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); - ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); + ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); + ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); /* This is wrong for PAL ! As I said, */ /* you need to set the standard once again !! */ ks->format_height = 240; @@ -599,84 +590,86 @@ static int ks0127_command(struct i2c_client *client, break; case VIDEO_MODE_NTSC: - dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n"); - ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); + v4l_dbg(1, debug, c, + "DECODER_SET_NORM: NTSC_M\n"); + ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); ks->format_height = 240; ks->format_width = 704; break; case KS_STD_NTSC_N: - dprintk("ks0127: command KS0127_SET_STANDARD: " - "NTSC_N (fixme)\n"); - ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); + v4l_dbg(1, debug, c, + "KS0127_SET_NORM: NTSC_N (fixme)\n"); + ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); ks->format_height = 240; ks->format_width = 704; break; case VIDEO_MODE_PAL: - dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n"); - ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); + v4l_dbg(1, debug, c, + "DECODER_SET_NORM: PAL_N\n"); + ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); ks->format_height = 290; ks->format_width = 704; break; case KS_STD_PAL_M: - dprintk("ks0127: command KS0127_SET_STANDARD: " - "PAL_M (fixme)\n"); - ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); + v4l_dbg(1, debug, c, + "KS0127_SET_NORM: PAL_M (fixme)\n"); + ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); ks->format_height = 290; ks->format_width = 704; break; case VIDEO_MODE_SECAM: - dprintk("ks0127: command KS0127_SET_STANDARD: " - "SECAM\n"); + v4l_dbg(1, debug, c, + "KS0127_SET_NORM: SECAM\n"); ks->format_height = 290; ks->format_width = 704; /* set to secam autodetection */ - ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20); - ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); + ks0127_and_or(c, KS_CHROMA, 0xdf, 0x20); + ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); schedule_timeout_interruptible(HZ/10+1); /* did it autodetect? */ - if (ks0127_read(ks, KS_DEMOD) & 0x40) + if (ks0127_read(c, KS_DEMOD) & 0x40) break; /* force to secam mode */ - ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f); + ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f); break; default: - dprintk("ks0127: command DECODER_SET_NORM: " - "Unknown norm %d\n", *iarg); + v4l_dbg(1, debug, c, + "DECODER_SET_NORM: Unknown norm %d\n", *iarg); break; } break; case DECODER_SET_PICTURE: - dprintk("ks0127: command DECODER_SET_PICTURE " - "not yet supported (fixme)\n"); + v4l_dbg(1, debug, c, + "DECODER_SET_PICTURE: not yet supported\n"); return -EINVAL; - //sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE - //sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE - //sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? - //sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE - //sam todo: KS0127_SET_AGC_MODE: - //sam todo: KS0127_SET_AGC: - //sam todo: KS0127_SET_CHROMA_MODE: - //sam todo: KS0127_SET_PIXCLK_MODE: - //sam todo: KS0127_SET_GAMMA_MODE: - //sam todo: KS0127_SET_UGAIN: - //sam todo: KS0127_SET_VGAIN: - //sam todo: KS0127_SET_INVALY: - //sam todo: KS0127_SET_INVALU: - //sam todo: KS0127_SET_INVALV: - //sam todo: KS0127_SET_UNUSEY: - //sam todo: KS0127_SET_UNUSEU: - //sam todo: KS0127_SET_UNUSEV: - //sam todo: KS0127_SET_VSALIGN_MODE: + /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */ + /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */ + /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */ + /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */ + /* sam todo: KS0127_SET_AGC_MODE: */ + /* sam todo: KS0127_SET_AGC: */ + /* sam todo: KS0127_SET_CHROMA_MODE: */ + /* sam todo: KS0127_SET_PIXCLK_MODE: */ + /* sam todo: KS0127_SET_GAMMA_MODE: */ + /* sam todo: KS0127_SET_UGAIN: */ + /* sam todo: KS0127_SET_VGAIN: */ + /* sam todo: KS0127_SET_INVALY: */ + /* sam todo: KS0127_SET_INVALU: */ + /* sam todo: KS0127_SET_INVALV: */ + /* sam todo: KS0127_SET_UNUSEY: */ + /* sam todo: KS0127_SET_UNUSEU: */ + /* sam todo: KS0127_SET_UNUSEV: */ + /* sam todo: KS0127_SET_VSALIGN_MODE: */ case DECODER_ENABLE_OUTPUT: { @@ -685,34 +678,32 @@ static int ks0127_command(struct i2c_client *client, iarg = arg; enable = (*iarg != 0); if (enable) { - dprintk("ks0127: command " - "DECODER_ENABLE_OUTPUT on " - "(%d)\n", enable); + v4l_dbg(1, debug, c, + "DECODER_ENABLE_OUTPUT on\n"); /* All output pins on */ - ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30); + ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30); /* Obey the OEN pin */ - ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00); + ks0127_and_or(c, KS_CDEM, 0x7f, 0x00); } else { - dprintk("ks0127: command " - "DECODER_ENABLE_OUTPUT off " - "(%d)\n", enable); + v4l_dbg(1, debug, c, + "DECODER_ENABLE_OUTPUT off\n"); /* Video output pins off */ - ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00); + ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00); /* Ignore the OEN pin */ - ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80); + ks0127_and_or(c, KS_CDEM, 0x7f, 0x80); } - } break; + } - //sam todo: KS0127_SET_OUTPUT_MODE: - //sam todo: KS0127_SET_WIDTH: - //sam todo: KS0127_SET_HEIGHT: - //sam todo: KS0127_SET_HSCALE: + /* sam todo: KS0127_SET_OUTPUT_MODE: */ + /* sam todo: KS0127_SET_WIDTH: */ + /* sam todo: KS0127_SET_HEIGHT: */ + /* sam todo: KS0127_SET_HSCALE: */ case DECODER_GET_STATUS: - dprintk("ks0127: command DECODER_GET_STATUS\n"); + v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n"); *iarg = 0; - status = ks0127_read(ks, KS_STAT); + status = ks0127_read(c, KS_STAT); if (!(status & 0x20)) /* NOVID not set */ *iarg = (*iarg | DECODER_STATUS_GOOD); if ((status & 0x01)) /* CLOCK set */ @@ -723,124 +714,85 @@ static int ks0127_command(struct i2c_client *client, *iarg = (*iarg | DECODER_STATUS_NTSC); break; - //Catch any unknown command + /* Catch any unknown command */ default: - dprintk("ks0127: command unknown: %04X\n", cmd); + v4l_dbg(1, debug, c, "unknown: 0x%08x\n", cmd); return -EINVAL; } return 0; } - - -static int ks0127_probe(struct i2c_adapter *adapter); -static int ks0127_detach(struct i2c_client *client); -static int ks0127_command(struct i2c_client *client, - unsigned int cmd, void *arg); - - - /* Addresses to scan */ -static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1, - I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END}; -static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; -static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; -static struct i2c_client_address_data addr_data = { - normal_i2c, - probe, - ignore, -}; +#define I2C_KS0127_ADDON 0xD8 +#define I2C_KS0127_ONBOARD 0xDA -static struct i2c_driver i2c_driver_ks0127 = { - .driver.name = "ks0127", - .id = I2C_DRIVERID_KS0127, - .attach_adapter = ks0127_probe, - .detach_client = ks0127_detach, - .command = ks0127_command +static unsigned short normal_i2c[] = { + I2C_KS0127_ADDON >> 1, + I2C_KS0127_ONBOARD >> 1, + I2C_CLIENT_END }; -static struct i2c_client ks0127_client_tmpl = -{ - .name = "(ks0127 unset)", - .addr = 0, - .adapter = NULL, - .driver = &i2c_driver_ks0127, -}; +I2C_CLIENT_INSMOD; -static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind) +static int ks0127_probe(struct i2c_client *c, const struct i2c_device_id *id) { struct ks0127 *ks; - struct i2c_client *client; - client = kzalloc(sizeof(*client), GFP_KERNEL); - if (client == NULL) - return -ENOMEM; - memcpy(client, &ks0127_client_tmpl, sizeof(*client)); + v4l_info(c, "%s chip found @ 0x%x (%s)\n", + c->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board", + c->addr << 1, c->adapter->name); ks = kzalloc(sizeof(*ks), GFP_KERNEL); - if (ks == NULL) { - kfree(client); + if (ks == NULL) return -ENOMEM; - } - i2c_set_clientdata(client, ks); - client->adapter = adapter; - client->addr = addr; - sprintf(client->name, "ks0127-%02x", adapter->id); + i2c_set_clientdata(c, ks); - ks->client = client; - ks->addr = addr; ks->ks_type = KS_TYPE_UNKNOWN; /* power up */ - ks0127_write(ks, KS_CMDA, 0x2c); + init_reg_defaults(); + ks0127_write(c, KS_CMDA, 0x2c); mdelay(10); /* reset the device */ - ks0127_reset(ks); - printk(KERN_INFO "ks0127: attach: %s video decoder\n", - ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board"); - - i2c_attach_client(client); - return 0; -} - - -static int ks0127_probe(struct i2c_adapter *adapter) -{ - if (adapter->id == I2C_HW_B_ZR36067) - return i2c_probe(adapter, &addr_data, ks0127_found_proc); + ks0127_reset(c); return 0; } -static int ks0127_detach(struct i2c_client *client) +static int ks0127_remove(struct i2c_client *c) { - struct ks0127 *ks = i2c_get_clientdata(client); + struct ks0127 *ks = i2c_get_clientdata(c); - ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/ - ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */ + ks0127_write(c, KS_OFMTA, 0x20); /* tristate */ + ks0127_write(c, KS_CMDA, 0x2c | 0x80); /* power down */ - i2c_detach_client(client); kfree(ks); - kfree(client); - - dprintk("ks0127: detach\n"); return 0; } - -static int __devinit ks0127_init_module(void) -{ - init_reg_defaults(); - return i2c_add_driver(&i2c_driver_ks0127); -} - -static void __devexit ks0127_cleanup_module(void) +static int ks0127_legacy_probe(struct i2c_adapter *adapter) { - i2c_del_driver(&i2c_driver_ks0127); + return adapter->id == I2C_HW_B_ZR36067; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id ks0127_id[] = { + { "ks0127", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ks0127_id); +#endif -module_init(ks0127_init_module); -module_exit(ks0127_cleanup_module); +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "ks0127", + .driverid = I2C_DRIVERID_KS0127, + .command = ks0127_command, + .probe = ks0127_probe, + .remove = ks0127_remove, + .legacy_probe = ks0127_legacy_probe, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = ks0127_id, +#endif +}; -- cgit v1.2.3 From a91428972d553bfd60f584e73cdf880f7195087e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Sep 2008 13:00:32 +0200 Subject: saa7110: convert i2c driver for new i2c API From: Hans Verkuil - Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API - Cleanups - Use v4l_dbg/v4l_info to have uniform kernel messages Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7110.c | 248 ++++++++++-------------------------- 1 file changed, 69 insertions(+), 179 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7110.c b/linux/drivers/media/video/saa7110.c index 0692e4bef..15eb8bd7a 100644 --- a/linux/drivers/media/video/saa7110.c +++ b/linux/drivers/media/video/saa7110.c @@ -31,37 +31,25 @@ #include #include #include -#include #include +#include +#include +#include +#include +#include +#include "compat.h" MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); MODULE_AUTHOR("Pauline Middelink"); MODULE_LICENSE("GPL"); -#include - -#define I2C_NAME(s) (s)->name - -#include "compat.h" -#include -#include -#include - static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -#define dprintk(num, format, args...) \ - do { \ - if (debug >= num) \ - printk(format, ##args); \ - } while (0) - #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ #define SAA7110_MAX_OUTPUT 0 /* its a decoder only */ -#define I2C_SAA7110 0x9C /* or 0x9E */ - #define SAA7110_NR_REG 0x35 struct saa7110 { @@ -82,10 +70,7 @@ struct saa7110 { /* I2C support functions */ /* ----------------------------------------------------------------------- */ -static int -saa7110_write (struct i2c_client *client, - u8 reg, - u8 value) +static int saa7110_write(struct i2c_client *client, u8 reg, u8 value) { struct saa7110 *decoder = i2c_get_clientdata(client); @@ -93,10 +78,7 @@ saa7110_write (struct i2c_client *client, return i2c_smbus_write_byte_data(client, reg, value); } -static int -saa7110_write_block (struct i2c_client *client, - const u8 *data, - unsigned int len) +static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsigned int len) { int ret = -1; u8 reg = *data; /* first register to write to */ @@ -116,8 +98,8 @@ saa7110_write_block (struct i2c_client *client, memcpy(decoder->reg + reg, data + 1, len - 1); } else { for (++data, --len; len; len--) { - if ((ret = saa7110_write(client, reg++, - *data++)) < 0) + ret = saa7110_write(client, reg++, *data++); + if (ret < 0) break; } } @@ -125,8 +107,7 @@ saa7110_write_block (struct i2c_client *client, return ret; } -static inline int -saa7110_read (struct i2c_client *client) +static inline int saa7110_read(struct i2c_client *client) { return i2c_smbus_read_byte(client); } @@ -139,9 +120,7 @@ saa7110_read (struct i2c_client *client) #define FRESP_06H_SVIDEO 0x83 //0xC0 -static int -saa7110_selmux (struct i2c_client *client, - int chan) +static int saa7110_selmux(struct i2c_client *client, int chan) { static const unsigned char modes[9][8] = { /* mode 0 */ @@ -198,8 +177,7 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = { /* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02 }; -static int -determine_norm (struct i2c_client *client) +static int determine_norm(struct i2c_client *client) { DEFINE_WAIT(wait); struct saa7110 *decoder = i2c_get_clientdata(client); @@ -213,29 +191,23 @@ determine_norm (struct i2c_client *client) finish_wait(&decoder->wq, &wait); status = saa7110_read(client); if (status & 0x40) { - dprintk(1, KERN_INFO "%s: status=0x%02x (no signal)\n", - I2C_NAME(client), status); + v4l_dbg(1, debug, client, "status=0x%02x (no signal)\n", status); return decoder->norm; // no change } if ((status & 3) == 0) { saa7110_write(client, 0x06, 0x83); if (status & 0x20) { - dprintk(1, - KERN_INFO - "%s: status=0x%02x (NTSC/no color)\n", - I2C_NAME(client), status); + v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status); //saa7110_write(client,0x2E,0x81); return VIDEO_MODE_NTSC; } - dprintk(1, KERN_INFO "%s: status=0x%02x (PAL/no color)\n", - I2C_NAME(client), status); + v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status); //saa7110_write(client,0x2E,0x9A); return VIDEO_MODE_PAL; } //saa7110_write(client,0x06,0x03); if (status & 0x20) { /* 60Hz */ - dprintk(1, KERN_INFO "%s: status=0x%02x (NTSC)\n", - I2C_NAME(client), status); + v4l_dbg(1, debug, client, "status=0x%02x (NTSC)\n", status); saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x50); saa7110_write(client, 0x11, 0x2C); @@ -255,13 +227,11 @@ determine_norm (struct i2c_client *client) status = saa7110_read(client); if ((status & 0x03) == 0x01) { - dprintk(1, KERN_INFO "%s: status=0x%02x (SECAM)\n", - I2C_NAME(client), status); + v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status); saa7110_write(client, 0x0D, 0x87); return VIDEO_MODE_SECAM; } - dprintk(1, KERN_INFO "%s: status=0x%02x (PAL)\n", I2C_NAME(client), - status); + v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status); return VIDEO_MODE_PAL; } @@ -287,8 +257,8 @@ saa7110_command (struct i2c_client *client, VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; dc->inputs = SAA7110_MAX_INPUT; dc->outputs = SAA7110_MAX_OUTPUT; - } break; + } case DECODER_GET_STATUS: { @@ -296,8 +266,8 @@ saa7110_command (struct i2c_client *client, int res = 0; status = saa7110_read(client); - dprintk(1, KERN_INFO "%s: status=0x%02x norm=%d\n", - I2C_NAME(client), status, decoder->norm); + v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n", + status, decoder->norm); if (!(status & 0x40)) res |= DECODER_STATUS_GOOD; if (status & 0x03) @@ -315,8 +285,8 @@ saa7110_command (struct i2c_client *client, break; } *(int *) arg = res; - } break; + } case DECODER_SET_NORM: v = *(int *) arg; @@ -329,34 +299,24 @@ saa7110_command (struct i2c_client *client, 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)); + v4l_dbg(1, debug, client, "switched to NTSC\n"); 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)); + v4l_dbg(1, debug, client, "switched to PAL\n"); 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)); + v4l_dbg(1, debug, client, "switched to SECAM\n"); break; case VIDEO_MODE_AUTO: - dprintk(1, - KERN_INFO - "%s: TV standard detection...\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "switched to AUTO\n"); decoder->norm = determine_norm(client); *(int *) arg = decoder->norm; break; @@ -369,15 +329,12 @@ saa7110_command (struct i2c_client *client, 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); + v4l_dbg(1, debug, client, "input=%d not available\n", 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); + v4l_dbg(1, debug, client, "switched to input=%d\n", v); } break; @@ -393,8 +350,7 @@ saa7110_command (struct i2c_client *client, 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"); + v4l_dbg(1, debug, client, "YUV %s\n", v ? "on" : "off"); } break; @@ -424,23 +380,23 @@ saa7110_command (struct i2c_client *client, saa7110_write(client, 0x07, (decoder->hue >> 8) - 128); } - } break; + } case DECODER_DUMP: + if (!debug) + break; for (v = 0; v < SAA7110_NR_REG; v += 16) { int j; - dprintk(1, KERN_DEBUG "%s: %02x:", I2C_NAME(client), - v); + v4l_dbg(1, debug, client, "%02x:", v); for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++) - dprintk(1, " %02x", decoder->reg[v + j]); - dprintk(1, "\n"); + printk(KERN_CONT " %02x", decoder->reg[v + j]); + printk(KERN_CONT "\n"); } break; default: - dprintk(1, KERN_INFO "unknown saa7110_command??(%d)\n", - cmd); + v4l_dbg(1, debug, client, "unknown command %08x\n", cmd); return -EINVAL; } return 0; @@ -452,55 +408,28 @@ saa7110_command (struct i2c_client *client, * 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 unsigned short normal_i2c[] = { 0x9c >> 1, 0x9e >> 1, I2C_CLIENT_END }; -static struct i2c_client_address_data addr_data = { - .normal_i2c = normal_i2c, - .probe = &ignore, - .ignore = &ignore, -}; +I2C_CLIENT_INSMOD; -static struct i2c_driver i2c_driver_saa7110; - -static int -saa7110_detect_client (struct i2c_adapter *adapter, - int address, - int kind) +static int saa7110_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - 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; + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) + return -ENODEV; - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) - return -ENOMEM; - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver_saa7110; - strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client))); + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL); - if (!decoder) { - kfree(client); + if (!decoder) return -ENOMEM; - } decoder->norm = VIDEO_MODE_PAL; decoder->input = 0; decoder->enable = 1; @@ -511,18 +440,10 @@ saa7110_detect_client (struct i2c_adapter *adapter, 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 { + if (rv < 0) { + v4l_dbg(1, debug, client, "init status %d\n", rv); + } else { int ver, status; saa7110_write(client, 0x21, 0x10); saa7110_write(client, 0x0e, 0x18); @@ -531,10 +452,8 @@ saa7110_detect_client (struct i2c_adapter *adapter, 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); + v4l_dbg(1, debug, client, "version %x, status=0x%02x\n", + ver, status); saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); @@ -548,58 +467,29 @@ saa7110_detect_client (struct i2c_adapter *adapter, return 0; } -static int -saa7110_attach_adapter (struct i2c_adapter *adapter) +static int saa7110_remove(struct i2c_client *client) { - 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 int -saa7110_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); - + kfree(i2c_get_clientdata(client)); return 0; } /* ----------------------------------------------------------------------- */ -static struct i2c_driver i2c_driver_saa7110 = { - .driver = { - .name = "saa7110", - }, - - .id = I2C_DRIVERID_SAA7110, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id saa7110_id[] = { + { "saa7110", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, saa7110_id); - .attach_adapter = saa7110_attach_adapter, - .detach_client = saa7110_detach_client, +#endif +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "saa7110", + .driverid = I2C_DRIVERID_SAA7110, .command = saa7110_command, + .probe = saa7110_probe, + .remove = saa7110_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = saa7110_id, +#endif }; - -static int __init -saa7110_init (void) -{ - return i2c_add_driver(&i2c_driver_saa7110); -} - -static void __exit -saa7110_exit (void) -{ - i2c_del_driver(&i2c_driver_saa7110); -} - -module_init(saa7110_init); -module_exit(saa7110_exit); -- cgit v1.2.3 From 8d4df3d15078f86d7f4e0c2089bcd51db5e9de58 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Sep 2008 13:00:49 +0200 Subject: saa7111: convert i2c driver for new i2c API From: Hans Verkuil - Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API - Cleanups - Use v4l_dbg/v4l_info to have uniform kernel messages Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7111.c | 228 ++++++++++-------------------------- 1 file changed, 62 insertions(+), 166 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7111.c b/linux/drivers/media/video/saa7111.c index 917fb2553..94e5d0b4e 100644 --- a/linux/drivers/media/video/saa7111.c +++ b/linux/drivers/media/video/saa7111.c @@ -28,44 +28,25 @@ */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include +#include #include - +#include +#include #include #include +#include +#include #include "compat.h" MODULE_DESCRIPTION("Philips SAA7111 video decoder driver"); MODULE_AUTHOR("Dave Perks"); MODULE_LICENSE("GPL"); - -#define I2C_NAME(s) (s)->name - - static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -#define dprintk(num, format, args...) \ - do { \ - if (debug >= num) \ - printk(format, ##args); \ - } while (0) - /* ----------------------------------------------------------------------- */ #define SAA7111_NR_REG 0x18 @@ -78,14 +59,9 @@ struct saa7111 { int enable; }; -#define I2C_SAA7111 0x48 - /* ----------------------------------------------------------------------- */ -static inline int -saa7111_write (struct i2c_client *client, - u8 reg, - u8 value) +static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value) { struct saa7111 *decoder = i2c_get_clientdata(client); @@ -93,8 +69,7 @@ saa7111_write (struct i2c_client *client, return i2c_smbus_write_byte_data(client, reg, value); } -static inline void -saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value) +static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value) { struct saa7111 *decoder = i2c_get_clientdata(client); @@ -104,10 +79,7 @@ saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value) } } -static int -saa7111_write_block (struct i2c_client *client, - const u8 *data, - unsigned int len) +static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len) { int ret = -1; u8 reg; @@ -128,18 +100,17 @@ saa7111_write_block (struct i2c_client *client, decoder->reg[reg++] = data[1]; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + } while (len >= 2 && data[0] == reg && block_len < 32); + ret = i2c_master_send(client, block_data, block_len); + if (ret < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - if ((ret = saa7111_write(client, reg, - *data++)) < 0) + ret = saa7111_write(client, reg, *data++); + if (ret < 0) break; len -= 2; } @@ -148,16 +119,13 @@ saa7111_write_block (struct i2c_client *client, return ret; } -static int -saa7111_init_decoder (struct i2c_client *client, - struct video_decoder_init *init) +static int saa7111_init_decoder(struct i2c_client *client, + struct video_decoder_init *init) { return saa7111_write_block(client, init->data, init->len); } -static inline int -saa7111_read (struct i2c_client *client, - u8 reg) +static inline int saa7111_read(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); } @@ -204,28 +172,23 @@ static const unsigned char saa7111_i2c_init[] = { 0x17, 0x00, /* 17 - VBI */ }; -static int -saa7111_command (struct i2c_client *client, - unsigned int cmd, - void *arg) +static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) { struct saa7111 *decoder = i2c_get_clientdata(client); switch (cmd) { - case 0: break; case DECODER_INIT: { struct video_decoder_init *init = arg; + struct video_decoder_init vdi; + if (NULL != init) return saa7111_init_decoder(client, init); - else { - struct video_decoder_init vdi; - vdi.data = saa7111_i2c_init; - vdi.len = sizeof(saa7111_i2c_init); - return saa7111_init_decoder(client, &vdi); - } + vdi.data = saa7111_i2c_init; + vdi.len = sizeof(saa7111_i2c_init); + return saa7111_init_decoder(client, &vdi); } case DECODER_DUMP: @@ -235,15 +198,15 @@ saa7111_command (struct i2c_client *client, for (i = 0; i < SAA7111_NR_REG; i += 16) { int j; - printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i); + v4l_info(client, "%03x", i); for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) { - printk(" %02x", + printk(KERN_CONT " %02x", saa7111_read(client, i + j)); } - printk("\n"); + printk(KERN_CONT "\n"); } - } break; + } case DECODER_GET_CAPABILITIES: { @@ -256,8 +219,8 @@ saa7111_command (struct i2c_client *client, VIDEO_DECODER_CCIR; cap->inputs = 8; cap->outputs = 1; - } break; + } case DECODER_GET_STATUS: { @@ -266,8 +229,7 @@ saa7111_command (struct i2c_client *client, int res; status = saa7111_read(client, 0x1f); - dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client), - status); + v4l_dbg(1, debug, client, "status: 0x%02x\n", status); res = 0; if ((status & (1 << 6)) == 0) { res |= DECODER_STATUS_GOOD; @@ -295,8 +257,8 @@ saa7111_command (struct i2c_client *client, res |= DECODER_STATUS_COLOR; } *iarg = res; - } break; + } case DECODER_SET_GPIO: { @@ -363,8 +325,8 @@ saa7111_command (struct i2c_client *client, } decoder->norm = *iarg; - } break; + } case DECODER_SET_INPUT: { @@ -388,8 +350,8 @@ saa7111_command (struct i2c_client *client, 3) ? 0x80 : 0)); } - } break; + } case DECODER_SET_OUTPUT: { @@ -399,8 +361,8 @@ saa7111_command (struct i2c_client *client, if (*iarg != 0) { return -EINVAL; } - } break; + } case DECODER_ENABLE_OUTPUT: { @@ -440,8 +402,8 @@ saa7111_command (struct i2c_client *client, (decoder->reg[0x11] & 0xf3)); } } - } break; + } case DECODER_SET_PICTURE: { @@ -455,8 +417,8 @@ saa7111_command (struct i2c_client *client, saa7111_write(client, 0x0c, pic->colour >> 9); /* We want -128 to 127 we get 0-65535 */ saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8); - } break; + } default: return -EINVAL; @@ -467,48 +429,23 @@ saa7111_command (struct i2c_client *client, /* ----------------------------------------------------------------------- */ -/* - * Generic i2c probe - * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' - */ -static unsigned short normal_i2c[] = { I2C_SAA7111 >> 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 unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END }; -static struct i2c_driver i2c_driver_saa7111; +I2C_CLIENT_INSMOD; -static int -saa7111_detect_client (struct i2c_adapter *adapter, - int address, - int kind) +static int saa7111_probe(struct i2c_client *client, + const struct i2c_device_id *id) { int i; - struct i2c_client *client; struct saa7111 *decoder; struct video_decoder_init vdi; - dprintk(1, - KERN_INFO - "saa7111.c: detecting saa7111 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; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) - return -ENOMEM; - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver_saa7111; - strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client))); + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL); if (decoder == NULL) { @@ -520,82 +457,41 @@ saa7111_detect_client (struct i2c_adapter *adapter, decoder->enable = 1; i2c_set_clientdata(client, decoder); - i = i2c_attach_client(client); - if (i) { - kfree(client); - kfree(decoder); - return i; - } - vdi.data = saa7111_i2c_init; vdi.len = sizeof(saa7111_i2c_init); i = saa7111_init_decoder(client, &vdi); if (i < 0) { - dprintk(1, KERN_ERR "%s_attach error: init status %d\n", - I2C_NAME(client), i); + v4l_dbg(1, debug, client, "init status %d\n", i); } else { - dprintk(1, - KERN_INFO - "%s_attach: chip version %x at address 0x%x\n", - I2C_NAME(client), saa7111_read(client, 0x00) >> 4, - client->addr << 1); + v4l_dbg(1, debug, client, "revision %x\n", + saa7111_read(client, 0x00) >> 4); } - return 0; } -static int -saa7111_attach_adapter (struct i2c_adapter *adapter) +static int saa7111_remove(struct i2c_client *client) { - dprintk(1, - KERN_INFO - "saa7111.c: starting probe for adapter %s (0x%x)\n", - I2C_NAME(adapter), adapter->id); - return i2c_probe(adapter, &addr_data, &saa7111_detect_client); -} - -static int -saa7111_detach_client (struct i2c_client *client) -{ - struct saa7111 *decoder = i2c_get_clientdata(client); - int err; - - err = i2c_detach_client(client); - if (err) { - return err; - } - - kfree(decoder); - kfree(client); - + kfree(i2c_get_clientdata(client)); return 0; } /* ----------------------------------------------------------------------- */ -static struct i2c_driver i2c_driver_saa7111 = { - .driver = { - .name = "saa7111", - }, - - .id = I2C_DRIVERID_SAA7111A, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id saa7111_id[] = { + { "saa7111_old", 0 }, /* "saa7111" maps to the saa7115 driver */ + { } +}; +MODULE_DEVICE_TABLE(i2c, saa7111_id); - .attach_adapter = saa7111_attach_adapter, - .detach_client = saa7111_detach_client, +#endif +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "saa7111", + .driverid = I2C_DRIVERID_SAA7111A, .command = saa7111_command, + .probe = saa7111_probe, + .remove = saa7111_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = saa7111_id, +#endif }; - -static int __init -saa7111_init (void) -{ - return i2c_add_driver(&i2c_driver_saa7111); -} - -static void __exit -saa7111_exit (void) -{ - i2c_del_driver(&i2c_driver_saa7111); -} - -module_init(saa7111_init); -module_exit(saa7111_exit); -- cgit v1.2.3 From a80d7a6db8d7216690007a8f2e06ba12a0ebdf15 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Sep 2008 13:01:05 +0200 Subject: saa7114: convert i2c driver for new i2c API From: Hans Verkuil - Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API - Cleanups - Use v4l_dbg/v4l_info to have uniform kernel messages Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7114.c | 368 +++++++++++------------------------- 1 file changed, 112 insertions(+), 256 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7114.c b/linux/drivers/media/video/saa7114.c index 158bd123c..6d380e255 100644 --- a/linux/drivers/media/video/saa7114.c +++ b/linux/drivers/media/video/saa7114.c @@ -29,44 +29,25 @@ */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include +#include #include - +#include +#include #include #include +#include +#include #include "compat.h" MODULE_DESCRIPTION("Philips SAA7114H video decoder driver"); MODULE_AUTHOR("Maxim Yevtyushkin"); MODULE_LICENSE("GPL"); - -#define I2C_NAME(x) (x)->name - - static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -#define dprintk(num, format, args...) \ - do { \ - if (debug >= num) \ - printk(format, ##args); \ - } while (0) - /* ----------------------------------------------------------------------- */ struct saa7114 { @@ -82,9 +63,6 @@ struct saa7114 { int playback; }; -#define I2C_SAA7114 0x42 -#define I2C_SAA7114A 0x40 - #define I2C_DELAY 10 @@ -130,18 +108,12 @@ struct saa7114 { /* ----------------------------------------------------------------------- */ -static inline int -saa7114_write (struct i2c_client *client, - u8 reg, - u8 value) +static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value) { return i2c_smbus_write_byte_data(client, reg, value); } -static int -saa7114_write_block (struct i2c_client *client, - const u8 *data, - unsigned int len) +static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len) { int ret = -1; u8 reg; @@ -161,18 +133,17 @@ saa7114_write_block (struct i2c_client *client, reg++; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + } while (len >= 2 && data[0] == reg && block_len < 32); + ret = i2c_master_send(client, block_data, block_len); + if (ret < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - if ((ret = saa7114_write(client, reg, - *data++)) < 0) + ret = saa7114_write(client, reg, *data++); + if (ret < 0) break; len -= 2; } @@ -181,9 +152,7 @@ saa7114_write_block (struct i2c_client *client, return ret; } -static inline int -saa7114_read (struct i2c_client *client, - u8 reg) +static inline int saa7114_read(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); } @@ -453,15 +422,11 @@ static const unsigned char init[] = { 0xef, 0x00 }; -static int -saa7114_command (struct i2c_client *client, - unsigned int cmd, - void *arg) +static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) { struct saa7114 *decoder = i2c_get_clientdata(client); switch (cmd) { - case 0: //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client)); //saa7114_write_block(client, init, sizeof(init)); @@ -471,27 +436,28 @@ saa7114_command (struct i2c_client *client, { int i; - dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client)); + if (!debug) + break; + v4l_info(client, "decoder dump\n"); for (i = 0; i < 32; i += 16) { int j; - printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i); + v4l_info(client, "%03x", i); for (j = 0; j < 16; ++j) { - printk(" %02x", + printk(KERN_CONT " %02x", saa7114_read(client, i + j)); } - printk("\n"); + printk(KERN_CONT "\n"); } - } break; + } case DECODER_GET_CAPABILITIES: { struct video_decoder_capability *cap = arg; - dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "get capabilities\n"); cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | @@ -499,8 +465,8 @@ saa7114_command (struct i2c_client *client, VIDEO_DECODER_CCIR; cap->inputs = 8; cap->outputs = 1; - } break; + } case DECODER_GET_STATUS: { @@ -510,8 +476,7 @@ saa7114_command (struct i2c_client *client, status = saa7114_read(client, 0x1f); - dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client), - status); + v4l_dbg(1, debug, client, "status: 0x%02x\n", status); res = 0; if ((status & (1 << 6)) == 0) { res |= DECODER_STATUS_GOOD; @@ -539,8 +504,8 @@ saa7114_command (struct i2c_client *client, res |= DECODER_STATUS_COLOR; } *iarg = res; - } break; + } case DECODER_SET_NORM: { @@ -548,12 +513,11 @@ saa7114_command (struct i2c_client *client, short int hoff = 0, voff = 0, w = 0, h = 0; - dprintk(1, KERN_DEBUG "%s: decoder set norm ", - I2C_NAME(client)); - switch (*iarg) { + v4l_dbg(1, debug, client, "set norm\n"); + switch (*iarg) { case VIDEO_MODE_NTSC: - dprintk(1, "NTSC\n"); + v4l_dbg(1, debug, client, "NTSC\n"); decoder->reg[REG_ADDR(0x06)] = SAA_7114_NTSC_HSYNC_START; decoder->reg[REG_ADDR(0x07)] = @@ -572,7 +536,7 @@ saa7114_command (struct i2c_client *client, break; case VIDEO_MODE_PAL: - dprintk(1, "PAL\n"); + v4l_dbg(1, debug, client, "PAL\n"); decoder->reg[REG_ADDR(0x06)] = SAA_7114_PAL_HSYNC_START; decoder->reg[REG_ADDR(0x07)] = @@ -591,9 +555,8 @@ saa7114_command (struct i2c_client *client, break; default: - dprintk(1, " Unknown video mode!!!\n"); + v4l_dbg(1, debug, client, "Unknown video mode\n"); return -EINVAL; - } @@ -645,22 +608,20 @@ saa7114_command (struct i2c_client *client, saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection decoder->norm = *iarg; - } break; + } case DECODER_SET_INPUT: { int *iarg = arg; - dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n", - I2C_NAME(client), *iarg); + v4l_dbg(1, debug, client, "set input (%d)\n", *iarg); if (*iarg < 0 || *iarg > 7) { return -EINVAL; } if (decoder->input != *iarg) { - dprintk(1, KERN_DEBUG "%s: now setting %s input\n", - I2C_NAME(client), + v4l_dbg(1, debug, client, "now setting %s input\n", *iarg >= 6 ? "S-Video" : "Composite"); decoder->input = *iarg; @@ -691,30 +652,29 @@ saa7114_command (struct i2c_client *client, saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]); } - } break; + } case DECODER_SET_OUTPUT: { int *iarg = arg; - dprintk(1, KERN_DEBUG "%s: decoder set output\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "set output\n"); /* not much choice of outputs */ if (*iarg != 0) { return -EINVAL; } - } break; + } case DECODER_ENABLE_OUTPUT: { int *iarg = arg; int enable = (*iarg != 0); - dprintk(1, KERN_DEBUG "%s: decoder %s output\n", - I2C_NAME(client), enable ? "enable" : "disable"); + v4l_dbg(1, debug, client, "%s output\n", + enable ? "enable" : "disable"); decoder->playback = !enable; @@ -755,18 +715,16 @@ saa7114_command (struct i2c_client *client, saa7114_write(client, 0x80, 0x36); } - } break; + } case DECODER_SET_PICTURE: { struct video_picture *pic = arg; - dprintk(1, - KERN_DEBUG - "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n", - I2C_NAME(client), pic->brightness, pic->contrast, - pic->colour, pic->hue); + v4l_dbg(1, debug, client, + "decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n", + pic->brightness, pic->contrast, pic->colour, pic->hue); if (decoder->bright != pic->brightness) { /* We want 0 to 255 we get 0-65535 */ @@ -790,8 +748,8 @@ saa7114_command (struct i2c_client *client, saa7114_write(client, 0x0d, (decoder->hue - 32768) >> 8); } - } break; + } default: return -EINVAL; @@ -802,58 +760,30 @@ saa7114_command (struct i2c_client *client, /* ----------------------------------------------------------------------- */ -/* - * Generic i2c probe - * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' - */ -static unsigned short normal_i2c[] = - { I2C_SAA7114 >> 1, I2C_SAA7114A >> 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 unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; -static struct i2c_driver i2c_driver_saa7114; +I2C_CLIENT_INSMOD; -static int -saa7114_detect_client (struct i2c_adapter *adapter, - int address, - int kind) +static int saa7114_probe(struct i2c_client *client, + const struct i2c_device_id *id) { 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; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) - return -ENOMEM; - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver_saa7114; - strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client))); + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL); - if (decoder == NULL) { - kfree(client); + if (decoder == NULL) return -ENOMEM; - } decoder->norm = VIDEO_MODE_NTSC; decoder->input = -1; decoder->enable = 1; @@ -938,8 +868,7 @@ saa7114_detect_client (struct i2c_adapter *adapter, decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on - dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "starting init\n"); err[0] = saa7114_write_block(client, decoder->reg + (0x20 << 1), @@ -963,28 +892,23 @@ saa7114_detect_client (struct i2c_adapter *adapter, 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]); + v4l_dbg(1, debug, client, + "init error %d at stage %d, leaving attach.\n", + i, err[i]); kfree(decoder); - kfree(client); - return 0; + return -EIO; } } 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), + v4l_dbg(1, debug, client, + "reg[0x%02x] = 0x%02x (0x%02x)\n", + i, saa7114_read(client, i), decoder->reg[REG_ADDR(i)]); } - dprintk(1, - KERN_DEBUG - "%s_attach: performing decoder reset sequence\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, + "performing decoder reset sequence\n"); 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 @@ -992,19 +916,15 @@ saa7114_detect_client (struct i2c_adapter *adapter, 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]); + v4l_dbg(1, debug, client, + "init error %d at stage %d, leaving attach.\n", + i, err[i]); kfree(decoder); - kfree(client); - return 0; + return -EIO; } } - dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n", - I2C_NAME(client)); - + v4l_dbg(1, debug, client, "performing the rest of init\n"); 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 @@ -1040,37 +960,32 @@ saa7114_detect_client (struct i2c_adapter *adapter, 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]); + v4l_dbg(1, debug, client, + "init error %d at stage %d, leaving attach.\n", + i, err[i]); kfree(decoder); - kfree(client); - return 0; + return -EIO; } } 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), + v4l_dbg(1, debug, client, + "reg[0x%02x] = 0x%02x (0x%02x)\n", + 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), + v4l_dbg(1, debug, client, + "reg[0x%02x] = 0x%02x (0x%02x)\n", + i, saa7114_read(client, i), decoder->reg[REG_ADDR(i)]); } - dprintk(1, KERN_DEBUG "%s_attach: setting video input\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "setting video input\n"); err[19] = saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]); @@ -1081,20 +996,15 @@ saa7114_detect_client (struct i2c_adapter *adapter, 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]); + v4l_dbg(1, debug, client, + "init error %d at stage %d, leaving attach.\n", + i, err[i]); kfree(decoder); - kfree(client); - return 0; + return -EIO; } } - dprintk(1, - KERN_DEBUG - "%s_attach: performing decoder reset sequence\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "performing decoder reset sequence\n"); err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release @@ -1103,13 +1013,11 @@ saa7114_detect_client (struct i2c_adapter *adapter, 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]); + v4l_dbg(1, debug, client, + "init error %d at stage %d, leaving attach.\n", + i, err[i]); kfree(decoder); - kfree(client); - return 0; + return -EIO; } } @@ -1117,101 +1025,49 @@ saa7114_detect_client (struct i2c_adapter *adapter, 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, + v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n", + 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), + v4l_dbg(1, debug, client, + "power save control: 0x%02x, scaler status: 0x%02x\n", + 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), + v4l_dbg(1, debug, client, + "reg[0x%02x] = 0x%02x (0x%02x)\n", + 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 int -saa7114_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 int -saa7114_detach_client (struct i2c_client *client) +static int saa7114_remove(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); - + kfree(i2c_get_clientdata(client)); return 0; } /* ----------------------------------------------------------------------- */ -static struct i2c_driver i2c_driver_saa7114 = { - .driver = { - .name = "saa7114", - }, - - .id = I2C_DRIVERID_SAA7114, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id saa7114_id[] = { + { "saa7114_old", 0 }, /* "saa7114" maps to the saa7115 driver */ + { } +}; +MODULE_DEVICE_TABLE(i2c, saa7114_id); - .attach_adapter = saa7114_attach_adapter, - .detach_client = saa7114_detach_client, +#endif +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "saa7114", + .driverid = I2C_DRIVERID_SAA7114, .command = saa7114_command, + .probe = saa7114_probe, + .remove = saa7114_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = saa7114_id, +#endif }; - -static int __init -saa7114_init (void) -{ - return i2c_add_driver(&i2c_driver_saa7114); -} - -static void __exit -saa7114_exit (void) -{ - i2c_del_driver(&i2c_driver_saa7114); -} - -module_init(saa7114_init); -module_exit(saa7114_exit); -- cgit v1.2.3 From 2399b144589f525f749347db788b584e0b8dace0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Sep 2008 13:01:20 +0200 Subject: saa7185: convert i2c driver for new i2c API From: Hans Verkuil - Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API - Cleanups - Use v4l_dbg/v4l_info to have uniform kernel messages Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7185.c | 214 +++++++++--------------------------- 1 file changed, 54 insertions(+), 160 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7185.c b/linux/drivers/media/video/saa7185.c index 7a6c9c1fb..195e2f415 100644 --- a/linux/drivers/media/video/saa7185.c +++ b/linux/drivers/media/video/saa7185.c @@ -25,24 +25,15 @@ */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include +#include #include - +#include +#include #include #include +#include +#include #include "compat.h" MODULE_DESCRIPTION("Philips SAA7185 video encoder driver"); @@ -50,19 +41,10 @@ MODULE_AUTHOR("Dave Perks"); MODULE_LICENSE("GPL"); -#define I2C_NAME(s) (s)->name - - static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -#define dprintk(num, format, args...) \ - do { \ - if (debug >= num) \ - printk(format, ##args); \ - } while (0) - /* ----------------------------------------------------------------------- */ struct saa7185 { @@ -76,32 +58,24 @@ struct saa7185 { int sat; }; -#define I2C_SAA7185 0x88 - /* ----------------------------------------------------------------------- */ -static inline int -saa7185_read (struct i2c_client *client) +static inline int saa7185_read(struct i2c_client *client) { return i2c_smbus_read_byte(client); } -static int -saa7185_write (struct i2c_client *client, - u8 reg, - u8 value) +static int saa7185_write(struct i2c_client *client, u8 reg, u8 value) { struct saa7185 *encoder = i2c_get_clientdata(client); - dprintk(1, KERN_DEBUG "SAA7185: %02x set to %02x\n", reg, value); + v4l_dbg(1, debug, client, "%02x set to %02x\n", reg, value); encoder->reg[reg] = value; return i2c_smbus_write_byte_data(client, reg, value); } -static int -saa7185_write_block (struct i2c_client *client, - const u8 *data, - unsigned int len) +static int saa7185_write_block(struct i2c_client *client, + const u8 *data, unsigned int len) { int ret = -1; u8 reg; @@ -122,18 +96,17 @@ saa7185_write_block (struct i2c_client *client, encoder->reg[reg++] = data[1]; len -= 2; data += 2; - } while (len >= 2 && data[0] == reg && - block_len < 32); - if ((ret = i2c_master_send(client, block_data, - block_len)) < 0) + } while (len >= 2 && data[0] == reg && block_len < 32); + ret = i2c_master_send(client, block_data, block_len); + if (ret < 0) break; } } else { /* do some slow I2C emulation kind of thing */ while (len >= 2) { reg = *data++; - if ((ret = saa7185_write(client, reg, - *data++)) < 0) + ret = saa7185_write(client, reg, *data++); + if (ret < 0) break; len -= 2; } @@ -241,15 +214,11 @@ static const unsigned char init_ntsc[] = { 0x66, 0x21, /* FSC3 */ }; -static int -saa7185_command (struct i2c_client *client, - unsigned int cmd, - void *arg) +static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) { struct saa7185 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: saa7185_write_block(client, init_common, sizeof(init_common)); @@ -265,7 +234,6 @@ saa7185_command (struct i2c_client *client, sizeof(init_pal)); break; } - break; case ENCODER_GET_CAPABILITIES: @@ -277,8 +245,8 @@ saa7185_command (struct i2c_client *client, VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR; cap->inputs = 1; cap->outputs = 1; - } break; + } case ENCODER_SET_NORM: { @@ -287,7 +255,6 @@ saa7185_command (struct i2c_client *client, //saa7185_write_block(client, init_common, sizeof(init_common)); switch (*iarg) { - case VIDEO_MODE_NTSC: saa7185_write_block(client, init_ntsc, sizeof(init_ntsc)); @@ -301,11 +268,10 @@ saa7185_command (struct i2c_client *client, case VIDEO_MODE_SECAM: default: return -EINVAL; - } encoder->norm = *iarg; - } break; + } case ENCODER_SET_INPUT: { @@ -315,7 +281,6 @@ saa7185_command (struct i2c_client *client, *iarg = 1: input is from ZR36060 */ switch (*iarg) { - case 0: /* Switch RTCE to 1 */ saa7185_write(client, 0x61, @@ -333,21 +298,19 @@ saa7185_command (struct i2c_client *client, default: return -EINVAL; - } - } break; + } case ENCODER_SET_OUTPUT: { int *iarg = arg; /* not much choice of outputs */ - if (*iarg != 0) { + if (*iarg != 0) return -EINVAL; - } - } break; + } case ENCODER_ENABLE_OUTPUT: { @@ -357,8 +320,8 @@ saa7185_command (struct i2c_client *client, saa7185_write(client, 0x61, (encoder->reg[0x61] & 0xbf) | (encoder->enable ? 0x00 : 0x40)); - } break; + } default: return -EINVAL; @@ -369,138 +332,69 @@ saa7185_command (struct i2c_client *client, /* ----------------------------------------------------------------------- */ -/* - * Generic i2c probe - * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' - */ -static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END }; +static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; -static unsigned short ignore = I2C_CLIENT_END; +I2C_CLIENT_INSMOD; -static struct i2c_client_address_data addr_data = { - .normal_i2c = normal_i2c, - .probe = &ignore, - .ignore = &ignore, -}; - -static struct i2c_driver i2c_driver_saa7185; - -static int -saa7185_detect_client (struct i2c_adapter *adapter, - int address, - int kind) +static int saa7185_probe(struct i2c_client *client, + const struct i2c_device_id *id) { int i; - struct i2c_client *client; struct saa7185 *encoder; - dprintk(1, - KERN_INFO - "saa7185.c: detecting saa7185 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; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) - return -ENOMEM; - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver_saa7185; - strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client))); + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL); - if (encoder == NULL) { - kfree(client); + if (encoder == NULL) return -ENOMEM; - } encoder->norm = VIDEO_MODE_NTSC; encoder->enable = 1; i2c_set_clientdata(client, encoder); - i = i2c_attach_client(client); - if (i) { - kfree(client); - kfree(encoder); - return i; - } - i = saa7185_write_block(client, init_common, sizeof(init_common)); - if (i >= 0) { - i = saa7185_write_block(client, init_ntsc, - sizeof(init_ntsc)); - } - if (i < 0) { - dprintk(1, KERN_ERR "%s_attach: init error %d\n", - I2C_NAME(client), i); - } else { - dprintk(1, - KERN_INFO - "%s_attach: chip version %d at address 0x%x\n", - I2C_NAME(client), saa7185_read(client) >> 5, - client->addr << 1); - } - + if (i >= 0) + i = saa7185_write_block(client, init_ntsc, sizeof(init_ntsc)); + if (i < 0) + v4l_dbg(1, debug, client, "init error %d\n", i); + else + v4l_dbg(1, debug, client, "revision 0x%x\n", + saa7185_read(client) >> 5); return 0; } -static int -saa7185_attach_adapter (struct i2c_adapter *adapter) -{ - dprintk(1, - KERN_INFO - "saa7185.c: starting probe for adapter %s (0x%x)\n", - I2C_NAME(adapter), adapter->id); - return i2c_probe(adapter, &addr_data, &saa7185_detect_client); -} - -static int -saa7185_detach_client (struct i2c_client *client) +static int saa7185_remove(struct i2c_client *client) { struct saa7185 *encoder = i2c_get_clientdata(client); - int err; - - err = i2c_detach_client(client); - if (err) { - return err; - } saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */ //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */ kfree(encoder); - kfree(client); - return 0; } /* ----------------------------------------------------------------------- */ -static struct i2c_driver i2c_driver_saa7185 = { - .driver = { - .name = "saa7185", /* name */ - }, - - .id = I2C_DRIVERID_SAA7185B, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id saa7185_id[] = { + { "saa7185", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, saa7185_id); +#endif - .attach_adapter = saa7185_attach_adapter, - .detach_client = saa7185_detach_client, +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "saa7185", + .driverid = I2C_DRIVERID_SAA7185B, .command = saa7185_command, + .probe = saa7185_probe, + .remove = saa7185_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = saa7185_id, +#endif }; - -static int __init -saa7185_init (void) -{ - return i2c_add_driver(&i2c_driver_saa7185); -} - -static void __exit -saa7185_exit (void) -{ - i2c_del_driver(&i2c_driver_saa7185); -} - -module_init(saa7185_init); -module_exit(saa7185_exit); -- cgit v1.2.3 From c48cf58021d869bbea55d4338a30ebbbf8ee5cdb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 7 Sep 2008 13:01:39 +0200 Subject: vpx3220: convert i2c driver for new i2c API From: Hans Verkuil - Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API - Cleanups - Use v4l_dbg/v4l_info to have uniform kernel messages Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vpx3220.c | 334 +++++++++++------------------------- 1 file changed, 96 insertions(+), 238 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/vpx3220.c b/linux/drivers/media/video/vpx3220.c index 896af1a12..5f368a1be 100644 --- a/linux/drivers/media/video/vpx3220.c +++ b/linux/drivers/media/video/vpx3220.c @@ -22,33 +22,22 @@ #include #include #include -#include - -#include #include - #include - -#define I2C_NAME(x) (x)->name - -#include "compat.h" -#include #include +#include +#include #include +#include "compat.h" -#define I2C_VPX3220 0x86 -#define VPX3220_DEBUG KERN_DEBUG "vpx3220: " +MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); +MODULE_AUTHOR("Laurent Pinchart"); +MODULE_LICENSE("GPL"); static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -#define dprintk(num, format, args...) \ - do { \ - if (debug >= num) \ - printk(format, ##args); \ - } while (0) - #define VPX_TIMEOUT_COUNT 10 /* ----------------------------------------------------------------------- */ @@ -68,10 +57,8 @@ struct vpx3220 { static char *inputs[] = { "internal", "composite", "svideo" }; /* ----------------------------------------------------------------------- */ -static inline int -vpx3220_write (struct i2c_client *client, - u8 reg, - u8 value) + +static inline int vpx3220_write(struct i2c_client *client, u8 reg, u8 value) { struct vpx3220 *decoder = i2c_get_clientdata(client); @@ -79,15 +66,12 @@ vpx3220_write (struct i2c_client *client, return i2c_smbus_write_byte_data(client, reg, value); } -static inline int -vpx3220_read (struct i2c_client *client, - u8 reg) +static inline int vpx3220_read(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); } -static int -vpx3220_fp_status (struct i2c_client *client) +static int vpx3220_fp_status(struct i2c_client *client) { unsigned char status; unsigned int i; @@ -107,14 +91,11 @@ vpx3220_fp_status (struct i2c_client *client) return -1; } -static int -vpx3220_fp_write (struct i2c_client *client, - u8 fpaddr, - u16 data) +static int vpx3220_fp_write(struct i2c_client *client, u8 fpaddr, u16 data) { /* Write the 16-bit address to the FPWR register */ if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) { - dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); + v4l_dbg(1, debug, client, "%s: failed\n", __func__); return -1; } @@ -123,22 +104,20 @@ vpx3220_fp_write (struct i2c_client *client, /* Write the 16-bit data to the FPDAT register */ if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) { - dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); + v4l_dbg(1, debug, client, "%s: failed\n", __func__); return -1; } return 0; } -static u16 -vpx3220_fp_read (struct i2c_client *client, - u16 fpaddr) +static u16 vpx3220_fp_read(struct i2c_client *client, u16 fpaddr) { s16 data; /* Write the 16-bit address to the FPRD register */ if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) { - dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); + v4l_dbg(1, debug, client, "%s: failed\n", __func__); return -1; } @@ -148,25 +127,22 @@ vpx3220_fp_read (struct i2c_client *client, /* Read the 16-bit data from the FPDAT register */ data = i2c_smbus_read_word_data(client, 0x28); if (data == -1) { - dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__); + v4l_dbg(1, debug, client, "%s: failed\n", __func__); return -1; } return swab16(data); } -static int -vpx3220_write_block (struct i2c_client *client, - const u8 *data, - unsigned int len) +static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsigned int len) { u8 reg; int ret = -1; while (len >= 2) { reg = *data++; - if ((ret = - vpx3220_write(client, reg, *data++)) < 0) + ret = vpx3220_write(client, reg, *data++); + if (ret < 0) break; len -= 2; } @@ -174,10 +150,8 @@ vpx3220_write_block (struct i2c_client *client, return ret; } -static int -vpx3220_write_fp_block (struct i2c_client *client, - const u16 *data, - unsigned int len) +static int vpx3220_write_fp_block(struct i2c_client *client, + const u16 *data, unsigned int len) { u8 reg; int ret = 0; @@ -286,25 +260,20 @@ static const unsigned short init_fp[] = { 0x4b, 0x298, /* PLL gain */ }; -static void -vpx3220_dump_i2c (struct i2c_client *client) +static void vpx3220_dump_i2c(struct i2c_client *client) { int len = sizeof(init_common); const unsigned char *data = init_common; while (len > 1) { - dprintk(1, - KERN_DEBUG "vpx3216b i2c reg 0x%02x data 0x%02x\n", + v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n", *data, vpx3220_read(client, *data)); data += 2; len -= 2; } } -static int -vpx3220_command (struct i2c_client *client, - unsigned int cmd, - void *arg) +static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) { struct vpx3220 *decoder = i2c_get_clientdata(client); @@ -316,7 +285,6 @@ vpx3220_command (struct i2c_client *client, vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1); switch (decoder->norm) { - case VIDEO_MODE_NTSC: vpx3220_write_fp_block(client, init_ntsc, sizeof(init_ntsc) >> 1); @@ -335,21 +303,20 @@ vpx3220_command (struct i2c_client *client, sizeof(init_pal) >> 1); break; } - } break; + } case DECODER_DUMP: { vpx3220_dump_i2c(client); - } break; + } case DECODER_GET_CAPABILITIES: { struct video_decoder_capability *cap = arg; - dprintk(1, KERN_DEBUG "%s: DECODER_GET_CAPABILITIES\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n"); cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | @@ -358,20 +325,18 @@ vpx3220_command (struct i2c_client *client, VIDEO_DECODER_CCIR; cap->inputs = 3; cap->outputs = 1; - } break; + } case DECODER_GET_STATUS: { int res = 0, status; - dprintk(1, KERN_INFO "%s: DECODER_GET_STATUS\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n"); status = vpx3220_fp_read(client, 0x0f3); - dprintk(1, KERN_INFO "%s: status: 0x%04x\n", I2C_NAME(client), - status); + v4l_dbg(1, debug, client, "status: 0x%04x\n", status); if (status < 0) return status; @@ -380,7 +345,6 @@ vpx3220_command (struct i2c_client *client, res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR; switch (status & 0x18) { - case 0x00: case 0x10: case 0x14: @@ -401,8 +365,8 @@ vpx3220_command (struct i2c_client *client, } *(int *) arg = res; - } break; + } case DECODER_SET_NORM: { @@ -414,50 +378,43 @@ vpx3220_command (struct i2c_client *client, choosen video norm */ temp_input = vpx3220_fp_read(client, 0xf2); - dprintk(1, KERN_DEBUG "%s: DECODER_SET_NORM %d\n", - I2C_NAME(client), *iarg); + v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg); switch (*iarg) { - case VIDEO_MODE_NTSC: vpx3220_write_fp_block(client, init_ntsc, sizeof(init_ntsc) >> 1); - dprintk(1, KERN_INFO "%s: norm switched to NTSC\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "norm switched to NTSC\n"); break; case VIDEO_MODE_PAL: vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1); - dprintk(1, KERN_INFO "%s: norm switched to PAL\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "norm switched to PAL\n"); break; case VIDEO_MODE_SECAM: vpx3220_write_fp_block(client, init_secam, sizeof(init_secam) >> 1); - dprintk(1, KERN_INFO "%s: norm switched to SECAM\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "norm switched to SECAM\n"); break; case VIDEO_MODE_AUTO: /* FIXME This is only preliminary support */ data = vpx3220_fp_read(client, 0xf2) & 0x20; vpx3220_fp_write(client, 0xf2, 0x00c0 | data); - dprintk(1, KERN_INFO "%s: norm switched to Auto\n", - I2C_NAME(client)); + v4l_dbg(1, debug, client, "norm switched to AUTO\n"); break; default: return -EINVAL; - } decoder->norm = *iarg; /* And here we set the backed up video input again */ vpx3220_fp_write(client, 0xf2, temp_input | 0x0010); udelay(10); - } break; + } case DECODER_SET_INPUT: { @@ -476,8 +433,7 @@ vpx3220_command (struct i2c_client *client, if (*iarg < 0 || *iarg > 2) return -EINVAL; - dprintk(1, KERN_INFO "%s: input switched to %s\n", - I2C_NAME(client), inputs[*iarg]); + v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]); vpx3220_write(client, 0x33, input[*iarg][0]); @@ -489,8 +445,8 @@ vpx3220_command (struct i2c_client *client, data | (input[*iarg][1] << 5) | 0x0010); udelay(10); - } break; + } case DECODER_SET_OUTPUT: { @@ -500,19 +456,18 @@ vpx3220_command (struct i2c_client *client, if (*iarg != 0) { return -EINVAL; } - } break; + } case DECODER_ENABLE_OUTPUT: { int *iarg = arg; - dprintk(1, KERN_DEBUG "%s: DECODER_ENABLE_OUTPUT %d\n", - I2C_NAME(client), *iarg); + v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg); vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00)); - } break; + } case DECODER_SET_PICTURE: { @@ -543,8 +498,8 @@ vpx3220_command (struct i2c_client *client, vpx3220_fp_write(client, 0x1c, ((decoder->hue - 32768) >> 6) & 0xFFF); } - } break; + } default: return -EINVAL; @@ -553,8 +508,7 @@ vpx3220_command (struct i2c_client *client, return 0; } -static int -vpx3220_init_client (struct i2c_client *client) +static int vpx3220_init_client(struct i2c_client *client) { vpx3220_write_block(client, init_common, sizeof(init_common)); vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1); @@ -568,115 +522,26 @@ vpx3220_init_client (struct i2c_client *client) * Client management code */ -/* - * Generic i2c probe - * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' - */ -static unsigned short normal_i2c[] = - { I2C_VPX3220 >> 1, (I2C_VPX3220 >> 1) + 4, - I2C_CLIENT_END -}; +static unsigned short normal_i2c[] = { 0x86 >> 1, 0x8e >> 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 vpx3220_i2c_driver; - -static int -vpx3220_detach_client (struct i2c_client *client) -{ - struct vpx3220 *decoder = i2c_get_clientdata(client); - int err; - - err = i2c_detach_client(client); - if (err) { - return err; - } - - kfree(decoder); - kfree(client); - - return 0; -} +I2C_CLIENT_INSMOD; -static int -vpx3220_detect_client (struct i2c_adapter *adapter, - int address, - int kind) +static int vpx3220_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - int err; - struct i2c_client *client; struct vpx3220 *decoder; - - dprintk(1, VPX3220_DEBUG "%s\n", __func__); + const char *name = NULL; + u8 ver; + u16 pn; /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality - (adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) - return 0; - - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == NULL) { - return -ENOMEM; - } - - client->addr = address; - client->adapter = adapter; - client->driver = &vpx3220_i2c_driver; - - /* Check for manufacture ID and part number */ - if (kind < 0) { - u8 id; - u16 pn; - - id = vpx3220_read(client, 0x00); - if (id != 0xec) { - dprintk(1, - KERN_INFO - "vpx3220_attach: Wrong manufacturer ID (0x%02x)\n", - id); - kfree(client); - return 0; - } - - pn = (vpx3220_read(client, 0x02) << 8) + - vpx3220_read(client, 0x01); - switch (pn) { - case 0x4680: - strlcpy(I2C_NAME(client), "vpx3220a", - sizeof(I2C_NAME(client))); - break; - case 0x4260: - strlcpy(I2C_NAME(client), "vpx3216b", - sizeof(I2C_NAME(client))); - break; - case 0x4280: - strlcpy(I2C_NAME(client), "vpx3214c", - sizeof(I2C_NAME(client))); - break; - default: - dprintk(1, - KERN_INFO - "%s: Wrong part number (0x%04x)\n", - __func__, pn); - kfree(client); - return 0; - } - } else { - strlcpy(I2C_NAME(client), "forced vpx32xx", - sizeof(I2C_NAME(client))); - } + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL); - if (decoder == NULL) { - kfree(client); + if (decoder == NULL) return -ENOMEM; - } decoder->norm = VIDEO_MODE_PAL; decoder->input = 0; decoder->enable = 1; @@ -686,63 +551,56 @@ vpx3220_detect_client (struct i2c_adapter *adapter, decoder->sat = 32768; i2c_set_clientdata(client, decoder); - err = i2c_attach_client(client); - if (err) { - kfree(client); - kfree(decoder); - return err; + ver = i2c_smbus_read_byte_data(client, 0x00); + pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) + + i2c_smbus_read_byte_data(client, 0x01); + if (ver == 0xec) { + switch (pn) { + case 0x4680: + name = "vpx3220a"; + break; + case 0x4260: + name = "vpx3216b"; + break; + case 0x4280: + name = "vpx3214c"; + break; + } } - - dprintk(1, KERN_INFO "%s: vpx32xx client found at address 0x%02x\n", - I2C_NAME(client), client->addr << 1); + if (name) + v4l_info(client, "%s found @ 0x%x (%s)\n", name, + client->addr << 1, client->adapter->name); + else + v4l_info(client, "chip (%02x:%04x) found @ 0x%x (%s)\n", + ver, pn, client->addr << 1, client->adapter->name); vpx3220_init_client(client); - return 0; } -static int -vpx3220_attach_adapter (struct i2c_adapter *adapter) +static int vpx3220_remove(struct i2c_client *client) { - int ret; - - ret = i2c_probe(adapter, &addr_data, &vpx3220_detect_client); - dprintk(1, VPX3220_DEBUG "%s: i2c_probe returned %d\n", - __func__, ret); - return ret; + kfree(i2c_get_clientdata(client)); + return 0; } -/* ----------------------------------------------------------------------- - * Driver initialization and cleanup code - */ - -static struct i2c_driver vpx3220_i2c_driver = { - .driver = { - .name = "vpx3220", - }, - - .id = I2C_DRIVERID_VPX3220, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +static const struct i2c_device_id vpx3220_id[] = { + { "vpx3220a", 0 }, + { "vpx3216b", 0 }, + { "vpx3214c", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, vpx3220_id); +#endif - .attach_adapter = vpx3220_attach_adapter, - .detach_client = vpx3220_detach_client, +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "vpx3220", + .driverid = I2C_DRIVERID_VPX3220, .command = vpx3220_command, + .probe = vpx3220_probe, + .remove = vpx3220_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + .id_table = vpx3220_id, +#endif }; - -static int __init -vpx3220_init (void) -{ - return i2c_add_driver(&vpx3220_i2c_driver); -} - -static void __exit -vpx3220_cleanup (void) -{ - i2c_del_driver(&vpx3220_i2c_driver); -} - -module_init(vpx3220_init); -module_exit(vpx3220_cleanup); - -MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); -MODULE_AUTHOR("Laurent Pinchart"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 84186d8dda12362e5c3bd4b59888cade5f860d2b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 13 Oct 2008 12:38:03 +0200 Subject: v4l2: add comment to the v4l2-i2c-drv headers. From: Hans Verkuil Looking at these headers as they appear in the kernel makes you wonder why it is done that way. Refer to the v4l-dvb repository where the full unstripped header can be found to understand the reasoning behind this. Priority: normal Signed-off-by: Hans Verkuil --- linux/include/media/v4l2-i2c-drv-legacy.h | 11 +++++++++++ linux/include/media/v4l2-i2c-drv.h | 11 +++++++++++ 2 files changed, 22 insertions(+) (limited to 'linux') diff --git a/linux/include/media/v4l2-i2c-drv-legacy.h b/linux/include/media/v4l2-i2c-drv-legacy.h index 299b1c344..333ab5d5b 100644 --- a/linux/include/media/v4l2-i2c-drv-legacy.h +++ b/linux/include/media/v4l2-i2c-drv-legacy.h @@ -21,6 +21,17 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* NOTE: the full version of this header is in the v4l-dvb repository + * and allows v4l i2c drivers to be compiled on older kernels as well. + * The version of this header as it appears in the kernel is a stripped + * version (without all the backwards compatibility stuff) and so it + * looks a bit odd. + * + * If you look at the full version then you will understand the reason + * for introducing this header since you really don't want to have all + * the tricky backwards compatibility code in each and every i2c driver. + */ + struct v4l2_i2c_driver_data { const char * const name; int driverid; diff --git a/linux/include/media/v4l2-i2c-drv.h b/linux/include/media/v4l2-i2c-drv.h index 1feadb6c1..8279d07e3 100644 --- a/linux/include/media/v4l2-i2c-drv.h +++ b/linux/include/media/v4l2-i2c-drv.h @@ -21,6 +21,17 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* NOTE: the full version of this header is in the v4l-dvb repository + * and allows v4l i2c drivers to be compiled on older kernels as well. + * The version of this header as it appears in the kernel is a stripped + * version (without all the backwards compatibility stuff) and so it + * looks a bit odd. + * + * If you look at the full version then you will understand the reason + * for introducing this header since you really don't want to have all + * the tricky backwards compatibility code in each and every i2c driver. + */ + #ifndef __V4L2_I2C_DRV_H__ #define __V4L2_I2C_DRV_H__ -- cgit v1.2.3