diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/tegra/ov9726.c | 117 |
1 files changed, 115 insertions, 2 deletions
diff --git a/drivers/media/video/tegra/ov9726.c b/drivers/media/video/tegra/ov9726.c index 501292d9e034..655d07c736a8 100644 --- a/drivers/media/video/tegra/ov9726.c +++ b/drivers/media/video/tegra/ov9726.c @@ -20,7 +20,7 @@ #include <linux/io.h> #include <linux/uaccess.h> #include <mach/iomap.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <mach/gpio.h> #include <linux/regulator/consumer.h> @@ -154,6 +154,107 @@ static struct ov9726_reg mode_1280x720[] = { {OV9726_TABLE_END, 0x0000} }; +static struct ov9726_reg mode_1280x800[] = { + {0x0103, 0x01}, + + {OV9726_TABLE_WAIT_MS, 10}, + + {0x3026, 0x00}, + {0x3027, 0x00}, + {0x3705, 0x45}, + {0x3603, 0xaa}, + {0x3632, 0x2f}, + {0x3620, 0x66}, + {0x3621, 0xc0}, + {0x0202, 0x03}, + {0x0203, 0x13}, + {0x3833, 0x04}, + {0x3835, 0x02}, + {0x4702, 0x04}, + {0x4704, 0x00}, + {0x4706, 0x08}, + {0x5052, 0x01}, + {0x3819, 0x6c}, + {0x3817, 0x94}, + {0x404e, 0x7e}, + {0x3601, 0x40}, + {0x3610, 0xa0}, + + {0x0344, 0x00}, + {0x0345, 0x00}, + {0x0346, 0x00}, + {0x0347, 0x00}, + {0x034c, 0x05}, + {0x034d, 0x10}, + {0x034e, 0x03}, + {0x034f, 0x28}, + + {0x3002, 0x00}, + {0x3004, 0x00}, + {0x3005, 0x00}, + {0x4800, 0x44}, + {0x4801, 0x0f}, + {0x4803, 0x05}, + {0x4601, 0x16}, + {0x3014, 0x05}, + {0x0101, 0x01}, + {0x3707, 0x14}, + {0x3622, 0x9f}, + {0x4002, 0x45}, + {0x5001, 0x00}, + {0x3406, 0x01}, + {0x3503, 0x17}, + {0x0205, 0x3f}, + {0x0100, 0x01}, + {0x0112, 0x0a}, + {0x0113, 0x0a}, + {0x3013, 0x20}, + {0x4837, 0x2f}, + {0x3615, 0xf0}, + {0x0340, 0x03}, + {0x0341, 0x48}, + {0x0342, 0x06}, + {0x0343, 0x80}, + {0x3702, 0x1e}, + {0x3703, 0x3c}, + {0x3704, 0x0e}, + + {0x3104, 0x20}, + {0x0305, 0x04}, + {0x0307, 0x46}, + {0x0303, 0x01}, + {0x0301, 0x0a}, + {0x3010, 0x01}, + {0x460e, 0x00}, + + {0x5000, 0x00}, + {0x5002, 0x00}, + {0x3017, 0xd2}, + {0x3018, 0x69}, + {0x3019, 0x96}, + {0x5047, 0x61}, + {0x3604, 0x1c}, + {0x3602, 0x10}, + {0x3612, 0x21}, + {0x3630, 0x0a}, + {0x3631, 0x53}, + {0x3633, 0x70}, + {0x4005, 0x1a}, + {0x4009, 0x10}, + + {OV9726_TABLE_END, 0x0000} +}; + +enum { + OV9726_MODE_1280x720, + OV9726_MODE_1280x800, +}; + +static struct ov9726_reg *mode_table[] = { + [OV9726_MODE_1280x720] = mode_1280x720, + [OV9726_MODE_1280x800] = mode_1280x800, +}; + static inline void msleep_range(unsigned int delay_base) { @@ -519,9 +620,21 @@ ov9726_set_mode( struct i2c_client *i2c_client = dev->i2c_client; struct ov9726_reg reg_override[6]; int err = 0; + int sensor_mode; dev_info(&i2c_client->dev, "%s.\n", __func__); + if (mode->xres == 1280 && mode->yres == 800) + sensor_mode = OV9726_MODE_1280x800; + else if (mode->xres == 1280 && mode->yres == 720) + sensor_mode = OV9726_MODE_1280x720; + else { + dev_err(&i2c_client->dev, + "%s: invalid resolution supplied to set mode %d %d\n", + __func__, mode->xres, mode->yres); + return -EINVAL; + } + ov9726_get_frame_length_regs(reg_override, mode->frame_length); ov9726_get_coarse_time_regs(reg_override + 2, mode->coarse_time); ov9726_get_gain_reg(reg_override + 4, mode->gain); @@ -533,7 +646,7 @@ ov9726_set_mode( mode->coarse_time, mode->gain); err = ov9726_write_table(i2c_client, - mode_1280x720, reg_override, + mode_table[sensor_mode], reg_override, sizeof(reg_override) / sizeof(reg_override[0])); if (err) goto ov9726_set_mode_exit; |