diff --git a/drivers/media/i2c/gc4c33.c b/drivers/media/i2c/gc4c33.c index 80cc5df63f5c..7ef179345495 100644 --- a/drivers/media/i2c/gc4c33.c +++ b/drivers/media/i2c/gc4c33.c @@ -8,6 +8,7 @@ * V0.0X01.0X02 fix mclk issue when probe multiple camera. * V0.0X01.0X03 fix gain range. * V0.0X01.0X04 add enum_frame_interval function. + * V0.0X01.0X05 fix gain reg, add otp and dpc. */ #include @@ -29,7 +30,7 @@ #include #include -#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x04) +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x05) #ifndef V4L2_CID_DIGITAL_GAIN #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN @@ -49,9 +50,9 @@ #define GC4C33_REG_CHIP_ID_H 0x03f0 #define GC4C33_REG_CHIP_ID_L 0x03f1 -#define GC4C33_REG_CTRL_MODE 0x00 +#define GC4C33_REG_CTRL_MODE 0x0100 #define GC4C33_MODE_SW_STANDBY 0x00 -#define GC4C33_MODE_STREAMING 0x01 +#define GC4C33_MODE_STREAMING 0x09 #define GC4C33_REG_EXPOSURE_H 0x0202 #define GC4C33_REG_EXPOSURE_L 0x0203 @@ -82,6 +83,8 @@ #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode" #define GC4C33_NAME "gc4c33" +//#define GC4C33_ENABLE_HIGHLIGHT + static const char * const gc4c33_supply_names[] = { "dovdd", /* Digital I/O power */ "dvdd", /* Digital core power */ @@ -155,93 +158,50 @@ static const struct regval gc4c33_global_regs[] = { {REG_NULL, 0x00}, }; -static const u32 reg_val_table[43][17] = { - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x00, - 0x00, 0x01, 0x00, 0x20, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x08, - 0x00, 0x01, 0x0B, 0x20, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x01, - 0x00, 0x01, 0x1B, 0x1e, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x09, - 0x00, 0x01, 0x2A, 0x1c, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x10, - 0x00, 0x01, 0x3E, 0x1a, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x18, - 0x00, 0x02, 0x13, 0x18, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x11, - 0x00, 0x02, 0x33, 0x18, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x19, - 0x00, 0x03, 0x11, 0x16, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x30, - 0x00, 0x03, 0x3B, 0x16, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x38, - 0x00, 0x04, 0x26, 0x14, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x31, - 0x00, 0x05, 0x24, 0x14, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x39, - 0x00, 0x06, 0x21, 0x12, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x32, - 0x00, 0x07, 0x28, 0x12, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x3a, - 0x00, 0x08, 0x3C, 0x12, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x33, - 0x00, 0x0A, 0x3F, 0x10, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x3b, - 0x00, 0x0C, 0x38, 0x10, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x34, - 0x00, 0x0F, 0x17, 0x0e, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x3c, - 0x00, 0x11, 0x3F, 0x0c, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0xb4, - 0x00, 0x15, 0x34, 0x0a, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0xbc, - 0x00, 0x19, 0x22, 0x08, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x34, - 0x01, 0x1E, 0x09, 0x06, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x3c, - 0x01, 0x1A, 0x31, 0x04, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0xb4, - 0x01, 0x20, 0x12, 0x02, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0xbc, - 0x01, 0x25, 0x28, 0x02, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x80, 0x80, 0x80, 0x80, 0x34, - 0x02, 0x2D, 0x28, 0x02, 0x01, 0x01, 0x01, 0x01}, - {0x00, 0x3b, 0x00, 0x3b, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0x35, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x34, 0x00, 0x34, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0x3F, 0x22, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x3c, 0x00, 0x3c, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0x4A, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0xb4, 0x00, 0xb4, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0x5A, 0x36, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0xbc, 0x00, 0xbc, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0x69, 0x37, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x01, 0x34, 0x10, 0x34, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0x7E, 0x13, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x01, 0x3c, 0x10, 0x3c, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0x93, 0x0B, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x01, 0xb4, 0x10, 0xb4, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0xB4, 0x19, 0x04, 0x00, 0x00, 0x00, 0x00}, - {0x01, 0xbc, 0x10, 0xbc, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0xD2, 0x0E, 0x02, 0x00, 0x00, 0x00, 0x00}, - {0x02, 0x34, 0x20, 0x34, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0xFC, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x00}, - {0x02, 0x3c, 0x20, 0x3c, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00}, - {0x01, 0xf4, 0x10, 0xf4, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00}, - {0x01, 0xfc, 0x10, 0xfc, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00}, - {0x02, 0x74, 0x20, 0x74, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00}, - {0x02, 0x7c, 0x20, 0x7c, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00}, - {0x02, 0x75, 0x20, 0x75, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00}, - {0x02, 0x7d, 0x20, 0x7d, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00}, - {0x02, 0xf5, 0x20, 0xf5, 0x5a, 0x5a, 0x5a, 0x5a, 0x34, - 0x12, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00}, +static const u32 reg_val_table[43][9] = { + {0x00, 0x39, 0x00, 0x39, 0x00, 0x00, 0x01, 0x00, 0x20}, + {0x00, 0x39, 0x00, 0x39, 0x08, 0x00, 0x01, 0x0B, 0x20}, + {0x00, 0x39, 0x00, 0x39, 0x01, 0x00, 0x01, 0x1B, 0x1e}, + {0x00, 0x39, 0x00, 0x39, 0x09, 0x00, 0x01, 0x2A, 0x1c}, + {0x00, 0x39, 0x00, 0x39, 0x10, 0x00, 0x01, 0x3E, 0x1a}, + {0x00, 0x39, 0x00, 0x39, 0x18, 0x00, 0x02, 0x13, 0x18}, + {0x00, 0x39, 0x00, 0x39, 0x11, 0x00, 0x02, 0x33, 0x18}, + {0x00, 0x39, 0x00, 0x39, 0x19, 0x00, 0x03, 0x11, 0x16}, + {0x00, 0x39, 0x00, 0x39, 0x30, 0x00, 0x03, 0x3B, 0x16}, + {0x00, 0x39, 0x00, 0x39, 0x38, 0x00, 0x04, 0x26, 0x14}, + {0x00, 0x39, 0x00, 0x39, 0x31, 0x00, 0x05, 0x24, 0x14}, + {0x00, 0x39, 0x00, 0x39, 0x39, 0x00, 0x06, 0x21, 0x12}, + {0x00, 0x39, 0x00, 0x39, 0x32, 0x00, 0x07, 0x28, 0x12}, + {0x00, 0x39, 0x00, 0x39, 0x3a, 0x00, 0x08, 0x3C, 0x12}, + {0x00, 0x39, 0x00, 0x39, 0x33, 0x00, 0x0A, 0x3F, 0x10}, + {0x00, 0x39, 0x00, 0x39, 0x3b, 0x00, 0x0C, 0x38, 0x10}, + {0x00, 0x39, 0x00, 0x39, 0x34, 0x00, 0x0F, 0x17, 0x0e}, + {0x00, 0x39, 0x00, 0x39, 0x3c, 0x00, 0x11, 0x3F, 0x0c}, + {0x00, 0x39, 0x00, 0x39, 0xb4, 0x00, 0x15, 0x34, 0x0a}, + {0x00, 0x39, 0x00, 0x39, 0xbc, 0x00, 0x19, 0x22, 0x08}, + {0x00, 0x39, 0x00, 0x39, 0x34, 0x01, 0x1E, 0x09, 0x06}, + {0x00, 0x39, 0x00, 0x39, 0x3c, 0x11, 0x1A, 0x31, 0x14}, + {0x00, 0x32, 0x00, 0x32, 0x3c, 0x11, 0x20, 0x12, 0x13}, + {0x00, 0x3a, 0x00, 0x3a, 0x3c, 0x11, 0x25, 0x28, 0x12}, + {0x00, 0x33, 0x00, 0x33, 0x3c, 0x11, 0x2D, 0x28, 0x11}, + {0x00, 0x3b, 0x00, 0x3b, 0x3c, 0x11, 0x35, 0x0A, 0x10}, + {0x00, 0x34, 0x00, 0x34, 0x3c, 0x11, 0x3F, 0x22, 0x0e}, + {0x00, 0x3c, 0x00, 0x3c, 0x3c, 0x11, 0x4A, 0x02, 0x0c}, + {0x00, 0xb4, 0x00, 0xb4, 0x3c, 0x11, 0x5A, 0x36, 0x0a}, + {0x00, 0xbc, 0x00, 0xbc, 0x3c, 0x11, 0x69, 0x37, 0x0a}, + {0x01, 0x34, 0x10, 0x34, 0x3c, 0x11, 0x7E, 0x13, 0x08}, + {0x01, 0x3c, 0x10, 0x3c, 0x3c, 0x11, 0x93, 0x0B, 0x06}, + {0x01, 0xb4, 0x10, 0xb4, 0x3c, 0x11, 0xB4, 0x19, 0x04}, + {0x01, 0xbc, 0x10, 0xbc, 0x3c, 0x11, 0xD2, 0x0E, 0x02}, + {0x02, 0x34, 0x20, 0x34, 0x3c, 0x11, 0xFC, 0x0B, 0x02}, + {0x02, 0x3c, 0x20, 0x3c, 0x3c, 0x11, 0xff, 0xff, 0x02}, + {0x01, 0xf4, 0x10, 0xf4, 0x3c, 0x11, 0xff, 0xff, 0x02}, + {0x01, 0xfc, 0x10, 0xfc, 0x3c, 0x11, 0xff, 0xff, 0x02}, + {0x02, 0x74, 0x20, 0x74, 0x3c, 0x11, 0xff, 0xff, 0x02}, + {0x02, 0x7c, 0x20, 0x7c, 0x3c, 0x11, 0xff, 0xff, 0x02}, + {0x02, 0x75, 0x20, 0x75, 0x3c, 0x11, 0xff, 0xff, 0x02}, + {0x02, 0x7d, 0x20, 0x7d, 0x3c, 0x11, 0xff, 0xff, 0x02}, + {0x02, 0xf5, 0x20, 0xf5, 0x3c, 0x11, 0xff, 0xff, 0x02}, }; static const u32 gain_level_table[44] = { @@ -266,10 +226,10 @@ static const u32 gain_level_table[44] = { 1396, 1634, 1929, - 2259, - 2736, - 3204, - 3844, + 1702, + 2066, + 2377, + 2957, 3402, 4096, 4738, @@ -291,6 +251,76 @@ static const u32 gain_level_table[44] = { 0xffffffff }; +static const u32 reg_Val_Table_720P[32][5] = { + {0x00, 0x00, 0x01, 0x00, 0x20}, + {0x08, 0x00, 0x01, 0x0A, 0x20}, + {0x01, 0x00, 0x01, 0x19, 0x1E}, + {0x09, 0x00, 0x01, 0x26, 0x1C}, + {0x10, 0x00, 0x01, 0x3F, 0x1A}, + {0x18, 0x00, 0x02, 0x13, 0x18}, + {0x11, 0x00, 0x02, 0x31, 0x18}, + {0x19, 0x00, 0x03, 0x0B, 0x16}, + {0x30, 0x00, 0x04, 0x04, 0x16}, + {0x38, 0x00, 0x04, 0x2C, 0x14}, + {0x31, 0x00, 0x05, 0x29, 0x13}, + {0x39, 0x00, 0x06, 0x1F, 0x12}, + {0x32, 0x00, 0x07, 0x38, 0x12}, + {0x3a, 0x00, 0x09, 0x05, 0x12}, + {0x33, 0x00, 0x0B, 0x12, 0x10}, + {0x3b, 0x00, 0x0D, 0x00, 0x10}, + {0x34, 0x00, 0x10, 0x03, 0x0e}, + {0x3c, 0x00, 0x12, 0x1E, 0x0c}, + {0xb4, 0x00, 0x16, 0x00, 0x0a}, + {0xbc, 0x00, 0x19, 0x15, 0x08}, + {0x34, 0x01, 0x1F, 0x06, 0x06}, + {0x3c, 0x01, 0x23, 0x33, 0x04}, + {0xb4, 0x01, 0x2C, 0x22, 0x02}, + {0xbc, 0x01, 0x33, 0x12, 0x02}, + {0x34, 0x02, 0x3F, 0x10, 0x02}, + {0x3c, 0x02, 0x48, 0x34, 0x02}, + {0xf4, 0x01, 0x5F, 0x06, 0x02}, + {0xfc, 0x01, 0x6D, 0x1E, 0x02}, + {0x74, 0x02, 0x87, 0x00, 0x02}, + {0x7c, 0x02, 0x9B, 0x19, 0x02}, + {0x75, 0x02, 0xC7, 0x07, 0x02}, + {0x7d, 0x02, 0xE5, 0x0B, 0x02}, +}; + +static const u32 gain_Level_Table_720P[32] = { + 64, + 74, + 89, + 102, + 127, + 147, + 177, + 203, + 260, + 300, + 361, + 415, + 504, + 581, + 722, + 832, + 1027, + 1182, + 1408, + 1621, + 1990, + 2291, + 2850, + 3282, + 4048, + 4660, + 6086, + 7006, + 8640, + 9945, + 12743, + 14667, +}; + /* * Xclk 27Mhz * max_framerate 30fps @@ -496,14 +526,14 @@ static const struct regval gc4c33_linear10bit_2560x1440_regs[] = { {0x02fd, 0x00}, {0x0263, 0x00}, {0x0267, 0x00}, - {0x0451, 0x00}, - {0x0455, 0x04}, - {0x0452, 0x00}, + {0x0451, 0x21}, + {0x0455, 0x05}, + {0x0452, 0xE6}, {0x0456, 0x04}, - {0x0450, 0x00}, - {0x0454, 0x04}, - {0x0453, 0x00}, - {0x0457, 0x04}, + {0x0450, 0xAB}, + {0x0454, 0x02}, + {0x0453, 0xAB}, + {0x0457, 0x02}, {0x0226, 0x30}, {0x0042, 0x20}, {0x0458, 0x01}, @@ -550,7 +580,11 @@ static const struct regval gc4c33_linear10bit_2560x1440_regs[] = { {0x0115, 0x12}, {0x0103, 0x00}, {0x0104, 0x20}, - {0x0100, 0x09}, + {0x00aa, 0x3a}, + {0x00a7, 0x18}, + {0x00a8, 0x10}, + {0x00a1, 0xE0}, + {0x00a2, 0xE0}, {REG_NULL, 0x00}, }; @@ -713,14 +747,14 @@ static const struct regval gc4c33_linear10bit_1280x720_regs[] = { {0x02b1, 0xf2}, {0x02b3, 0x00}, {0x02b4, 0x00}, - {0x0451, 0x00}, - {0x0455, 0x04}, - {0x0452, 0x00}, + {0x0451, 0x21}, + {0x0455, 0x05}, + {0x0452, 0xE6}, {0x0456, 0x04}, - {0x0450, 0x00}, - {0x0454, 0x04}, - {0x0453, 0x00}, - {0x0457, 0x04}, + {0x0450, 0xAB}, + {0x0454, 0x02}, + {0x0453, 0xAB}, + {0x0457, 0x02}, {0x0226, 0x30}, {0x0042, 0x20}, {0x0458, 0x01}, @@ -756,7 +790,11 @@ static const struct regval gc4c33_linear10bit_1280x720_regs[] = { {0x0115, 0x12}, {0x0103, 0x00}, {0x0104, 0x20}, - {0x0100, 0x09}, + {0x00aa, 0x3a}, + {0x00a7, 0x18}, + {0x00a8, 0x10}, + {0x00a1, 0xE0}, + {0x00a2, 0xE0}, {REG_NULL, 0x00}, }; @@ -1022,7 +1060,11 @@ static const struct regval gc4c33_linear10bit_1920x1080_regs[] = { {0x0115, 0x12}, {0x0103, 0x00}, {0x0104, 0x20}, - {0x0100, 0x09}, + {0x00aa, 0x3a}, + {0x00a7, 0x18}, + {0x00a8, 0x10}, + {0x00a1, 0xE0}, + {0x00a2, 0xE0}, {REG_NULL, 0x00}, }; @@ -1302,6 +1344,8 @@ static int gc4c33_set_gain_reg(struct gc4c33 *gc4c33, u32 gain) int total; u32 tol_dig_gain = 0; + if (gain < 64) + gain = 64; total = sizeof(gain_level_table) / sizeof(u32) - 1; for (i = 0; i < total; i++) { if (gain_level_table[i] <= gain && @@ -1311,18 +1355,7 @@ static int gc4c33_set_gain_reg(struct gc4c33 *gc4c33, u32 gain) tol_dig_gain = gain * 64 / gain_level_table[i]; if (i >= total) i = total - 1; - gc4c33_write_reg(gc4c33->client, 0x31d, GC4C33_REG_VALUE_08BIT, 0x29); - gc4c33_write_reg(gc4c33->client, 0x458, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][13]); - gc4c33_write_reg(gc4c33->client, 0x459, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][14]); - gc4c33_write_reg(gc4c33->client, 0x45a, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][15]); - gc4c33_write_reg(gc4c33->client, 0x45b, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][16]); - - gc4c33_write_reg(gc4c33->client, 0x31d, - GC4C33_REG_VALUE_08BIT, 0x2a); + gc4c33_write_reg(gc4c33->client, 0x31d, GC4C33_REG_VALUE_08BIT, 0x2a); gc4c33_write_reg(gc4c33->client, 0x2fd, GC4C33_REG_VALUE_08BIT, reg_val_table[i][0]); gc4c33_write_reg(gc4c33->client, 0x2fc, @@ -1331,27 +1364,19 @@ static int gc4c33_set_gain_reg(struct gc4c33 *gc4c33, u32 gain) GC4C33_REG_VALUE_08BIT, reg_val_table[i][2]); gc4c33_write_reg(gc4c33->client, 0x267, GC4C33_REG_VALUE_08BIT, reg_val_table[i][3]); - gc4c33_write_reg(gc4c33->client, 0x44c, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][4]); - gc4c33_write_reg(gc4c33->client, 0x44d, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][5]); - gc4c33_write_reg(gc4c33->client, 0x44e, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][6]); - gc4c33_write_reg(gc4c33->client, 0x44f, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][7]); - gc4c33_write_reg(gc4c33->client, 0x31d, - GC4C33_REG_VALUE_08BIT, 0x28); + + gc4c33_write_reg(gc4c33->client, 0x31d, GC4C33_REG_VALUE_08BIT, 0x28); gc4c33_write_reg(gc4c33->client, 0x2b3, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][8]); + GC4C33_REG_VALUE_08BIT, reg_val_table[i][4]); gc4c33_write_reg(gc4c33->client, 0x2b4, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][9]); + GC4C33_REG_VALUE_08BIT, reg_val_table[i][5]); gc4c33_write_reg(gc4c33->client, 0x2b8, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][10]); + GC4C33_REG_VALUE_08BIT, reg_val_table[i][6]); gc4c33_write_reg(gc4c33->client, 0x2b9, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][11]); + GC4C33_REG_VALUE_08BIT, reg_val_table[i][7]); gc4c33_write_reg(gc4c33->client, 0x515, - GC4C33_REG_VALUE_08BIT, reg_val_table[i][12]); + GC4C33_REG_VALUE_08BIT, reg_val_table[i][8]); gc4c33_write_reg(gc4c33->client, 0x20e, GC4C33_REG_VALUE_08BIT, (tol_dig_gain >> 6)); @@ -1360,6 +1385,38 @@ static int gc4c33_set_gain_reg(struct gc4c33 *gc4c33, u32 gain) return 0; } +static int gc4c33_set_gain_reg_720P(struct gc4c33 *gc4c33, u32 gain) +{ + int i; + int total; + u32 tol_dig_gain = 0; + + total = sizeof(gain_Level_Table_720P) / sizeof(u32) - 1; + for (i = 0; i < total; i++) { + if (gain_Level_Table_720P[i] <= gain && + gain < gain_Level_Table_720P[i + 1]) + break; + } + if (gain == gain_Level_Table_720P[total]) + i = total; + tol_dig_gain = gain * 64 / gain_Level_Table_720P[i]; + gc4c33_write_reg(gc4c33->client, 0x2b3, + GC4C33_REG_VALUE_08BIT, reg_Val_Table_720P[i][0]); + gc4c33_write_reg(gc4c33->client, 0x2b4, + GC4C33_REG_VALUE_08BIT, reg_Val_Table_720P[i][1]); + gc4c33_write_reg(gc4c33->client, 0x2b8, + GC4C33_REG_VALUE_08BIT, reg_Val_Table_720P[i][2]); + gc4c33_write_reg(gc4c33->client, 0x2b9, + GC4C33_REG_VALUE_08BIT, reg_Val_Table_720P[i][3]); + gc4c33_write_reg(gc4c33->client, 0x515, + GC4C33_REG_VALUE_08BIT, reg_Val_Table_720P[i][4]); + gc4c33_write_reg(gc4c33->client, 0x20e, + GC4C33_REG_VALUE_08BIT, (tol_dig_gain >> 6)); + gc4c33_write_reg(gc4c33->client, 0x20f, + GC4C33_REG_VALUE_08BIT, ((tol_dig_gain & 0x3f) << 2)); + return 0; +} + static int gc4c33_g_frame_interval(struct v4l2_subdev *sd, struct v4l2_subdev_frame_interval *fi) { @@ -1539,6 +1596,109 @@ static long gc4c33_compat_ioctl32(struct v4l2_subdev *sd, } #endif +static int gc4c33_sensor_dpc_otp_dd(struct gc4c33 *gc4c33) +{ + u32 num = 0; + int ret; + + ret = gc4c33_write_reg(gc4c33->client, 0x0a70, + GC4C33_REG_VALUE_08BIT, 0x00); + ret |= gc4c33_write_reg(gc4c33->client, 0x0317, + GC4C33_REG_VALUE_08BIT, 0x2c); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a67, + GC4C33_REG_VALUE_08BIT, 0x80); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a4f, + GC4C33_REG_VALUE_08BIT, 0x00); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a54, + GC4C33_REG_VALUE_08BIT, 0x80); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a66, + GC4C33_REG_VALUE_08BIT, 0x03); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a69, + GC4C33_REG_VALUE_08BIT, 0x00); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a6a, + GC4C33_REG_VALUE_08BIT, 0x70); + ret |= gc4c33_write_reg(gc4c33->client, 0x0313, + GC4C33_REG_VALUE_08BIT, 0x20); + ret |= gc4c33_read_reg(gc4c33->client, 0x0a6c, + GC4C33_REG_VALUE_08BIT, &num); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a69, + GC4C33_REG_VALUE_08BIT, 0x00); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a6a, + GC4C33_REG_VALUE_08BIT, 0x10); + ret |= gc4c33_write_reg(gc4c33->client, 0x0313, + GC4C33_REG_VALUE_08BIT, 0x20); + + if (num != 0) { + ret |= gc4c33_write_reg(gc4c33->client, 0x0317, + GC4C33_REG_VALUE_08BIT, 0x2c); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a67, + GC4C33_REG_VALUE_08BIT, 0x80); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a66, + GC4C33_REG_VALUE_08BIT, 0x03); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a70, + GC4C33_REG_VALUE_08BIT, 0x05); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a71, + GC4C33_REG_VALUE_08BIT, 0x00); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a72, + GC4C33_REG_VALUE_08BIT, 0x08); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a73, + GC4C33_REG_VALUE_08BIT, num); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a74, + GC4C33_REG_VALUE_08BIT, 0x00); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a75, + GC4C33_REG_VALUE_08BIT, 0x80); + ret |= gc4c33_write_reg(gc4c33->client, 0x05be, + GC4C33_REG_VALUE_08BIT, 0x00); + ret |= gc4c33_write_reg(gc4c33->client, 0x05a9, + GC4C33_REG_VALUE_08BIT, 0x01); + usleep_range(30 * 1000, 30 * 1000 * 2); + ret |= gc4c33_write_reg(gc4c33->client, 0x0313, + GC4C33_REG_VALUE_08BIT, 0x80); + usleep_range(120 * 1000, 120 * 1000 * 2); + + ret |= gc4c33_write_reg(gc4c33->client, 0x0080, + GC4C33_REG_VALUE_08BIT, 0x06); + ret |= gc4c33_write_reg(gc4c33->client, 0x05be, + GC4C33_REG_VALUE_08BIT, 0x01); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a70, + GC4C33_REG_VALUE_08BIT, 0x00); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a69, + GC4C33_REG_VALUE_08BIT, 0x00); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a6a, + GC4C33_REG_VALUE_08BIT, 0x10); + ret |= gc4c33_write_reg(gc4c33->client, 0x0313, + GC4C33_REG_VALUE_08BIT, 0x20); + } else { + ret |= gc4c33_write_reg(gc4c33->client, 0x0317, + GC4C33_REG_VALUE_08BIT, 0x2c); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a67, + GC4C33_REG_VALUE_08BIT, 0x80); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a4f, + GC4C33_REG_VALUE_08BIT, 0x00); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a54, + GC4C33_REG_VALUE_08BIT, 0x80); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a66, + GC4C33_REG_VALUE_08BIT, 0x03); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a69, + GC4C33_REG_VALUE_08BIT, 0x00); + ret |= gc4c33_write_reg(gc4c33->client, 0x0a6a, + GC4C33_REG_VALUE_08BIT, 0x10); + ret |= gc4c33_write_reg(gc4c33->client, 0x0313, + GC4C33_REG_VALUE_08BIT, 0x20); + } + +#ifdef GC4C33_ENABLE_HIGHLIGHT + ret |= gc4c33_write_reg(gc4c33->client, 0x0080, + GC4C33_REG_VALUE_08BIT, 0x04); + ret |= gc4c33_write_reg(gc4c33->client, 0x0090, + GC4C33_REG_VALUE_08BIT, 0x49); + ret |= gc4c33_write_reg(gc4c33->client, 0x05be, + GC4C33_REG_VALUE_08BIT, 0x01); +#endif + + return ret; +} + static int __gc4c33_start_stream(struct gc4c33 *gc4c33) { int ret; @@ -1547,6 +1707,10 @@ static int __gc4c33_start_stream(struct gc4c33 *gc4c33) if (ret) return ret; + ret = gc4c33_sensor_dpc_otp_dd(gc4c33); + if (ret) + return ret; + /* In case these controls are set before streaming */ mutex_unlock(&gc4c33->mutex); ret = v4l2_ctrl_handler_setup(&gc4c33->ctrl_handler); @@ -1856,7 +2020,10 @@ static int gc4c33_set_ctrl(struct v4l2_ctrl *ctrl) ctrl->val & 0xfe); break; case V4L2_CID_ANALOGUE_GAIN: - ret = gc4c33_set_gain_reg(gc4c33, ctrl->val); + if (gc4c33->cur_mode->height == 720) + ret = gc4c33_set_gain_reg_720P(gc4c33, ctrl->val); + else + ret = gc4c33_set_gain_reg(gc4c33, ctrl->val); break; case V4L2_CID_VBLANK: ret = gc4c33_write_reg(gc4c33->client, GC4C33_REG_VTS_H,