X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Fsaa7110.c;h=41d951db6ec0f34c731644d6dfa74b71dc8b8519;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=280f38b5183d56f6b07cb1593e12cf5ad279f284;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index 280f38b51..41d951db6 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,6 @@ MODULE_AUTHOR("Pauline Middelink"); MODULE_LICENSE("GPL"); #include -#include #define I2C_NAME(s) (s)->name @@ -46,7 +46,7 @@ MODULE_LICENSE("GPL"); #include static int debug = 0; -MODULE_PARM(debug, "i"); +module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define dprintk(num, format, args...) \ @@ -60,8 +60,10 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define I2C_SAA7110 0x9C /* or 0x9E */ +#define SAA7110_NR_REG 0x35 + struct saa7110 { - unsigned char reg[54]; + u8 reg[SAA7110_NR_REG]; int norm; int input; @@ -95,31 +97,23 @@ saa7110_write_block (struct i2c_client *client, unsigned int len) { int ret = -1; - u8 reg = *data++; + u8 reg = *data; /* first register to write to */ - len--; + /* Sanity check */ + if (reg + (len - 1) > SAA7110_NR_REG) + return ret; /* the saa7110 has an autoincrement function, use it if * the adapter understands raw I2C */ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { struct saa7110 *decoder = i2c_get_clientdata(client); - struct i2c_msg msg; - u8 block_data[54]; - - msg.len = 0; - msg.buf = (char *) block_data; - msg.addr = client->addr; - msg.flags = client->flags; - while (len >= 1) { - msg.len = 0; - block_data[msg.len++] = reg; - while (len-- >= 1 && msg.len < 54) - block_data[msg.len++] = - decoder->reg[reg++] = *data++; - ret = i2c_transfer(client->adapter, &msg, 1); - } + + ret = i2c_master_send(client, data, len); + + /* Cache the written data */ + memcpy(decoder->reg + reg, data + 1, len - 1); } else { - while (len-- >= 1) { + for (++data, --len; len; len--) { if ((ret = saa7110_write(client, reg++, *data++)) < 0) break; @@ -145,7 +139,7 @@ saa7110_read (struct i2c_client *client) static int saa7110_selmux (struct i2c_client *client, - int chan) + int chan) { static const unsigned char modes[9][8] = { /* mode 0 */ @@ -192,7 +186,7 @@ saa7110_selmux (struct i2c_client *client, return 0; } -static const unsigned char initseq[] = { +static const unsigned char initseq[1 + SAA7110_NR_REG] = { 0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF2, 0x03, 0x00, /* 0x08 */ 0xF8, 0xF8, 0x60, 0x60, 0x00, 0x86, 0x18, 0x90, /* 0x10 */ 0x00, 0x59, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA, @@ -205,13 +199,16 @@ static const unsigned char initseq[] = { static int determine_norm (struct i2c_client *client) { + DEFINE_WAIT(wait); struct saa7110 *decoder = i2c_get_clientdata(client); int status; /* mode changed, start automatic detection */ saa7110_write_block(client, initseq, sizeof(initseq)); saa7110_selmux(client, decoder->input); - sleep_on_timeout(&decoder->wq, HZ / 4); + prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/4); + finish_wait(&decoder->wq, &wait); status = saa7110_read(client); if (status & 0x40) { dprintk(1, KERN_INFO "%s: status=0x%02x (no signal)\n", @@ -250,7 +247,9 @@ determine_norm (struct i2c_client *client) saa7110_write(client, 0x11, 0x59); //saa7110_write(client,0x2E,0x9A); - sleep_on_timeout(&decoder->wq, HZ / 4); + prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/4); + finish_wait(&decoder->wq, &wait); status = saa7110_read(client); if ((status & 0x03) == 0x01) { @@ -427,15 +426,13 @@ saa7110_command (struct i2c_client *client, break; case DECODER_DUMP: - for (v = 0; v < 0x34; v += 16) { + for (v = 0; v < SAA7110_NR_REG; v += 16) { int j; - dprintk(1, KERN_INFO "%s: %03x\n", I2C_NAME(client), + dprintk(1, KERN_DEBUG "%s: %02x:", I2C_NAME(client), v); - for (j = 0; j < 16; j++) { - dprintk(1, KERN_INFO " %02x", - decoder->reg[v + j]); - } - dprintk(1, KERN_INFO "\n"); + for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++) + dprintk(1, " %02x", decoder->reg[v + j]); + dprintk(1, "\n"); } break; @@ -458,25 +455,15 @@ static unsigned short normal_i2c[] = { (I2C_SAA7110 >> 1) + 1, I2C_CLIENT_END }; -static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; - -static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; -static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; - + +static unsigned short ignore = I2C_CLIENT_END; + static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, - .normal_i2c_range = normal_i2c_range, - .probe = probe, - .probe_range = probe_range, - .ignore = ignore, - .ignore_range = ignore_range, - .force = force + .probe = &ignore, + .ignore = &ignore, }; -static int saa7110_i2c_id = 0; static struct i2c_driver i2c_driver_saa7110; static int @@ -499,24 +486,19 @@ saa7110_detect_client (struct i2c_adapter *adapter, I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) return 0; - client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); if (client == 0) return -ENOMEM; - memset(client, 0, sizeof(struct i2c_client)); client->addr = address; client->adapter = adapter; client->driver = &i2c_driver_saa7110; - client->flags = I2C_CLIENT_ALLOW_USE; - client->id = saa7110_i2c_id++; - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "saa7110[%d]", client->id); + strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client))); - decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL); + decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL); if (decoder == 0) { kfree(client); return -ENOMEM; } - memset(decoder, 0, sizeof(struct saa7110)); decoder->norm = VIDEO_MODE_PAL; decoder->input = 0; decoder->enable = 1; @@ -594,11 +576,11 @@ saa7110_detach_client (struct i2c_client *client) /* ----------------------------------------------------------------------- */ static struct i2c_driver i2c_driver_saa7110 = { - .owner = THIS_MODULE, - .name = "saa7110", + .driver = { + .name = "saa7110", + }, .id = I2C_DRIVERID_SAA7110, - .flags = I2C_DF_NOTIFY, .attach_adapter = saa7110_attach_adapter, .detach_client = saa7110_detach_client,