diff --git a/drivers/media/i2c/ov5695.c b/drivers/media/i2c/ov5695.c index 1bb396f2a418..ecd4e253e15d 100644 --- a/drivers/media/i2c/ov5695.c +++ b/drivers/media/i2c/ov5695.c @@ -69,6 +69,10 @@ #define OV5695_LANES 2 #define OV5695_BITS_PER_SAMPLE 10 +#define I2C_M_WR 0 +#define I2C_MSG_MAX 300 +#define I2C_DATA_MAX (I2C_MSG_MAX * 3) + static const char * const ov5695_supply_names[] = { "avdd", /* Analog power */ "dovdd", /* Digital I/O power */ @@ -385,175 +389,18 @@ static const struct regval ov5695_1920x1080_regs[] = { * mipi_datarate per lane 840Mbps */ static const struct regval ov5695_1296x972_regs[] = { - {0x0103, 0x01}, - {0x0100, 0x00}, - {0x0300, 0x04}, - {0x0301, 0x00}, - {0x0302, 0x69}, - {0x0303, 0x00}, - {0x0304, 0x00}, - {0x0305, 0x01}, - {0x0307, 0x00}, - {0x030b, 0x00}, - {0x030c, 0x00}, - {0x030d, 0x1e}, - {0x030e, 0x04}, - {0x030f, 0x03}, - {0x0312, 0x01}, - {0x3000, 0x00}, - {0x3002, 0xa1}, - {0x3008, 0x00}, - {0x3010, 0x00}, - {0x3016, 0x32}, - {0x3022, 0x51}, - {0x3106, 0x15}, - {0x3107, 0x01}, - {0x3108, 0x05}, - {0x3500, 0x00}, {0x3501, 0x3e}, - {0x3502, 0x00}, - {0x3503, 0x08}, - {0x3504, 0x03}, - {0x3505, 0x8c}, - {0x3507, 0x03}, - {0x3508, 0x00}, - {0x3509, 0x10}, - {0x350c, 0x00}, - {0x350d, 0x80}, - {0x3510, 0x00}, - {0x3511, 0x02}, - {0x3512, 0x00}, - {0x3601, 0x55}, - {0x3602, 0x58}, {0x3611, 0x58}, - {0x3614, 0x30}, - {0x3615, 0x77}, - {0x3621, 0x08}, - {0x3624, 0x40}, - {0x3633, 0x0c}, - {0x3634, 0x0c}, - {0x3635, 0x0c}, - {0x3636, 0x0c}, - {0x3638, 0x00}, - {0x3639, 0x00}, - {0x363a, 0x00}, - {0x363b, 0x00}, - {0x363c, 0xff}, - {0x363d, 0xfa}, - {0x3650, 0x44}, - {0x3651, 0x44}, - {0x3652, 0x44}, - {0x3653, 0x44}, - {0x3654, 0x44}, - {0x3655, 0x44}, - {0x3656, 0x44}, - {0x3657, 0x44}, - {0x3660, 0x00}, - {0x3661, 0x00}, - {0x3662, 0x00}, - {0x366a, 0x00}, - {0x366e, 0x0c}, - {0x3673, 0x04}, - {0x3700, 0x14}, - {0x3703, 0x0c}, {0x3706, 0x24}, {0x3714, 0x27}, - {0x3715, 0x01}, {0x3716, 0x00}, {0x3717, 0x02}, - {0x3733, 0x10}, - {0x3734, 0x40}, - {0x373f, 0xa0}, - {0x3765, 0x20}, - {0x37a1, 0x1d}, - {0x37a8, 0x26}, - {0x37ab, 0x14}, - {0x37c2, 0x04}, {0x37c3, 0xf0}, - {0x37cb, 0x09}, - {0x37cc, 0x13}, - {0x37cd, 0x1f}, - {0x37ce, 0x1f}, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, - {0x3803, 0x00}, - {0x3804, 0x0a}, - {0x3805, 0x3f}, - {0x3806, 0x07}, - {0x3807, 0xaf}, - {0x3808, 0x05}, - {0x3809, 0x10}, - {0x380a, 0x03}, - {0x380b, 0xcc}, - {0x380c, 0x02}, {0x380d, 0xe4}, {0x380e, 0x03}, {0x380f, 0xf4}, - {0x3810, 0x00}, {0x3811, 0x00}, - {0x3812, 0x00}, - {0x3813, 0x06}, - {0x3814, 0x03}, - {0x3815, 0x01}, - {0x3816, 0x03}, - {0x3817, 0x01}, - {0x3818, 0x00}, - {0x3819, 0x00}, - {0x381a, 0x00}, - {0x381b, 0x01}, - {0x3820, 0x8b}, - {0x3821, 0x01}, - {0x3c80, 0x08}, - {0x3c82, 0x00}, - {0x3c83, 0x00}, - {0x3c88, 0x00}, - {0x3d85, 0x14}, - {0x3f02, 0x08}, - {0x3f03, 0x10}, - {0x4008, 0x02}, - {0x4009, 0x09}, - {0x404e, 0x20}, - {0x4501, 0x00}, - {0x4502, 0x10}, - {0x4800, 0x00}, - {0x481f, 0x2a}, - {0x4837, 0x13}, {0x5000, 0x13}, - {0x5780, 0x3e}, - {0x5781, 0x0f}, - {0x5782, 0x44}, - {0x5783, 0x02}, - {0x5784, 0x01}, - {0x5785, 0x01}, - {0x5786, 0x00}, - {0x5787, 0x04}, - {0x5788, 0x02}, - {0x5789, 0x0f}, - {0x578a, 0xfd}, - {0x578b, 0xf5}, - {0x578c, 0xf5}, - {0x578d, 0x03}, - {0x578e, 0x08}, - {0x578f, 0x0c}, - {0x5790, 0x08}, - {0x5791, 0x06}, - {0x5792, 0x00}, - {0x5793, 0x52}, - {0x5794, 0xa3}, - {0x5b00, 0x00}, - {0x5b01, 0x1c}, - {0x5b02, 0x00}, - {0x5b03, 0x7f}, - {0x5b05, 0x6c}, - {0x5e10, 0xfc}, - {0x4010, 0xf1}, - {0x3503, 0x08}, - {0x3505, 0x8c}, - {0x3507, 0x03}, - {0x3508, 0x00}, - {0x3509, 0xf8}, - {0x0100, 0x01}, {REG_NULL, 0x00} }; @@ -734,14 +581,58 @@ static int ov5695_write_reg(struct i2c_client *client, u16 reg, static int ov5695_write_array(struct i2c_client *client, const struct regval *regs) { - u32 i; + u8 *data; + u32 i, j = 0, k = 0; int ret = 0; + struct i2c_msg *msg; - for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) - ret = ov5695_write_reg(client, regs[i].addr, - OV5695_REG_VALUE_08BIT, regs[i].val); + msg = kmalloc((sizeof(struct i2c_msg) * I2C_MSG_MAX), + GFP_KERNEL); + if (!msg) + return -ENOMEM; - return ret; + data = kmalloc((sizeof(unsigned char) * I2C_DATA_MAX), + GFP_KERNEL); + if (!data) { + kfree(msg); + return -ENOMEM; + } + + for (i = 0; regs[i].addr != REG_NULL; i++) { + (msg + j)->addr = client->addr; + (msg + j)->flags = I2C_M_WR; + (msg + j)->buf = (data + k); + + data[k + 0] = (u8)(regs[i].addr >> 8); + data[k + 1] = (u8)(regs[i].addr & 0xFF); + data[k + 2] = (u8)(regs[i].val & 0xFF); + k = k + 3; + (msg + j)->len = 3; + + if (j++ == (I2C_MSG_MAX - 1)) { + ret = i2c_transfer(client->adapter, msg, j); + if (ret < 0) { + kfree(msg); + kfree(data); + return ret; + } + j = 0; + k = 0; + } + } + + if (j != 0) { + ret = i2c_transfer(client->adapter, msg, j); + if (ret < 0) { + kfree(msg); + kfree(data); + return ret; + } + } + kfree(msg); + kfree(data); + + return 0; } /* Read registers up to 4 at a time */