From 780dd9c63fd7a2a60e09f01b8891bc599aa2ac5f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 16 Oct 2009 07:42:53 -0300 Subject: [PATCH] --- yaml --- r: 173973 b: refs/heads/master c: fb1f9020609ead93fcec4b0dd02511a46294c147 h: refs/heads/master i: 173971: e3b26dcc2cad574c1abdd2e23f9cd73047e1f5eb v: v3 --- [refs] | 2 +- trunk/drivers/media/video/gspca/ov519.c | 53 ++++++++++++++++++++----- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index 229880918951..7ed3b013d33a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a511ba947600ae263f8c29c86020ba66a901d3e5 +refs/heads/master: fb1f9020609ead93fcec4b0dd02511a46294c147 diff --git a/trunk/drivers/media/video/gspca/ov519.c b/trunk/drivers/media/video/gspca/ov519.c index 994a5e927d2d..91e9b23a3a01 100644 --- a/trunk/drivers/media/video/gspca/ov519.c +++ b/trunk/drivers/media/video/gspca/ov519.c @@ -103,6 +103,7 @@ struct sd { u8 sensor_addr; int sensor_width; int sensor_height; + int sensor_reg_cache[256]; }; /* Note this is a bit of a hack, but the w9968cf driver needs the code for all @@ -2210,38 +2211,70 @@ static int ovfx2_i2c_r(struct sd *sd, __u8 reg) static int i2c_w(struct sd *sd, __u8 reg, __u8 value) { + int ret = -1; + + if (sd->sensor_reg_cache[reg] == value) + return 0; + switch (sd->bridge) { case BRIDGE_OV511: case BRIDGE_OV511PLUS: - return ov511_i2c_w(sd, reg, value); + ret = ov511_i2c_w(sd, reg, value); + break; case BRIDGE_OV518: case BRIDGE_OV518PLUS: case BRIDGE_OV519: - return ov518_i2c_w(sd, reg, value); + ret = ov518_i2c_w(sd, reg, value); + break; case BRIDGE_OVFX2: - return ovfx2_i2c_w(sd, reg, value); + ret = ovfx2_i2c_w(sd, reg, value); + break; case BRIDGE_W9968CF: - return w9968cf_i2c_w(sd, reg, value); + ret = w9968cf_i2c_w(sd, reg, value); + break; + } + + if (ret >= 0) { + /* Up on sensor reset empty the register cache */ + if (reg == 0x12 && (value & 0x80)) + memset(sd->sensor_reg_cache, -1, + sizeof(sd->sensor_reg_cache)); + else + sd->sensor_reg_cache[reg] = value; } - return -1; /* Should never happen */ + + return ret; } static int i2c_r(struct sd *sd, __u8 reg) { + int ret; + + if (sd->sensor_reg_cache[reg] != -1) + return sd->sensor_reg_cache[reg]; + switch (sd->bridge) { case BRIDGE_OV511: case BRIDGE_OV511PLUS: - return ov511_i2c_r(sd, reg); + ret = ov511_i2c_r(sd, reg); + break; case BRIDGE_OV518: case BRIDGE_OV518PLUS: case BRIDGE_OV519: - return ov518_i2c_r(sd, reg); + ret = ov518_i2c_r(sd, reg); + break; case BRIDGE_OVFX2: - return ovfx2_i2c_r(sd, reg); + ret = ovfx2_i2c_r(sd, reg); + break; case BRIDGE_W9968CF: - return w9968cf_i2c_r(sd, reg); + ret = w9968cf_i2c_r(sd, reg); + break; } - return -1; /* Should never happen */ + + if (ret >= 0) + sd->sensor_reg_cache[reg] = ret; + + return ret; } /* Writes bits at positions specified by mask to an I2C reg. Bits that are in