From: Bryan Wu Date: Tue, 15 Mar 2016 00:35:45 +0000 (-0700) Subject: media: soc_camera: add back ov5693_v4l2 driver X-Git-Tag: tegra-l4t-r24.1~31 X-Git-Url: http://rtime.felk.cvut.cz/gitweb/sojka/nv-tegra/linux-3.10.git/commitdiff_plain/3ab969a89c4c029c40fad4854ba2597c5b6de0c5 media: soc_camera: add back ov5693_v4l2 driver Bug 1740664 Change-Id: I6c9740d2f15b3c3923a97b2fa8bbd471ac624d36 Signed-off-by: Bryan Wu Reviewed-on: http://git-master/r/1031255 Reviewed-by: Bhanu Murthy V Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: David Wang (SW-TEGRA) Reviewed-by: Jihoon Bang --- diff --git a/drivers/media/i2c/soc_camera/ov5693_mode_tbls.h b/drivers/media/i2c/soc_camera/ov5693_mode_tbls.h new file mode 100644 index 00000000000..b3d150b5095 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov5693_mode_tbls.h @@ -0,0 +1,2345 @@ +/* + * ov5693_mode_tbls.h - ov5693 sensor mode tables + * + * Copyright (c) 2015-2016, NVIDIA CORPORATION, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __OV5693_TABLES__ +#define __OV5693_TABLES__ + +#include + +#define OV5693_TABLE_WAIT_MS 0 +#define OV5693_TABLE_END 1 +#define OV5693_MAX_RETRIES 3 + +#define ov5693_reg struct reg_8 + +static const ov5693_reg ov5693_start[] = { + {0x0100, 0x01}, /* mode select streaming on */ + {OV5693_TABLE_END, 0x00} +}; + +static const ov5693_reg ov5693_stop[] = { + {0x0100, 0x00}, /* mode select streaming on */ + {OV5693_TABLE_END, 0x00} +}; + +static const ov5693_reg tp_colorbars[] = { + {0x0600, 0x00}, + {0x0601, 0x02}, + + {OV5693_TABLE_END, 0x00} +}; + +static const ov5693_reg mode_2592x1944[] = { + {0x0100, 0x00},/* Including sw reset */ + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3090, 0x02}, + {0x3091, 0x0e}, + {0x3092, 0x00}, + {0x3093, 0x00}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x7b}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x02}, + {0x3508, 0x00}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x18}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x02}, + {0x3802, 0x00}, + {0x3803, 0x02}, + {0x3804, 0x0a}, + {0x3805, 0x41}, + {0x3806, 0x07}, + {0x3807, 0xa5}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x07}, + {0x380b, 0x98}, + {0x380c, 0x0a}, + {0x380d, 0x80}, + {0x380e, 0x07}, + {0x380f, 0xc0}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x1e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x06}, + {0x3a05, 0x14}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3d00, 0x00}, + {0x3d01, 0x00}, + {0x3d02, 0x00}, + {0x3d03, 0x00}, + {0x3d04, 0x00}, + {0x3d05, 0x00}, + {0x3d06, 0x00}, + {0x3d07, 0x00}, + {0x3d08, 0x00}, + {0x3d09, 0x00}, + {0x3d0a, 0x00}, + {0x3d0b, 0x00}, + {0x3d0c, 0x00}, + {0x3d0d, 0x00}, + {0x3d0e, 0x00}, + {0x3d0f, 0x00}, + {0x3d80, 0x00}, + {0x3d81, 0x00}, + {0x3d84, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_2592x1458[] = { + {0x0100, 0x00},/* Including sw reset */ + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3400, 0x04}, + {0x3401, 0x00}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x04}, + {0x3405, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x7b}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x02}, + {0x3508, 0x00}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3600, 0xbc}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x44}, + {0x3621, 0xb5}, + {0x3622, 0x0c}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0xf4}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x06}, + {0x3807, 0xb1}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x05}, + {0x380b, 0xb2}, + {0x380c, 0x0a}, + {0x380d, 0x80}, + {0x380e, 0x07}, + {0x380f, 0xc0}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x1e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x06}, + {0x3a05, 0x14}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0xfc}, + {0x5781, 0x13}, + {0x5782, 0x03}, + {0x5786, 0x20}, + {0x5787, 0x40}, + {0x5788, 0x08}, + {0x5789, 0x08}, + {0x578a, 0x02}, + {0x578b, 0x01}, + {0x578c, 0x01}, + {0x578d, 0x0c}, + {0x578e, 0x02}, + {0x578f, 0x01}, + {0x5790, 0x01}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_1296x972[] = { + {0x0100, 0x00},/* Including sw reset */ + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x7b}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x02}, + {0x3508, 0x00}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe6}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0xa3}, + {0x3808, 0x05}, + {0x3809, 0x10}, + {0x380a, 0x03}, + {0x380b, 0xcc}, + {0x380c, 0x0a}, + {0x380d, 0x80}, + {0x380e, 0x07}, + {0x380f, 0xc0}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3820, 0x01}, + {0x3821, 0x1f}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x06}, + {0x3a05, 0x14}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x00}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_1920x1080[] = { + {0x0100, 0x00},/*, 0xIncluding, 0xsw, 0xreset, 0x*/ + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x7b}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x02}, + {0x3508, 0x00}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0xf8}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x06}, + {0x3807, 0xab}, + {0x3808, 0x07}, + {0x3809, 0x80}, + {0x380a, 0x04}, + {0x380b, 0x38}, + {0x380c, 0x0a}, + {0x380d, 0x80}, + {0x380e, 0x07}, + {0x380f, 0xc0}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x1e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x06}, + {0x3a05, 0x14}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x80}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_1280x720_120fps[] = { + {0x0100, 0x00},/* Including sw reset */ + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x2e}, + {0x3502, 0x80}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x02}, + {0x3508, 0x00}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe6}, + {0x3709, 0xc7}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0xf4}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x06}, + {0x3807, 0xab}, + {0x3808, 0x05}, + {0x3809, 0x00}, + {0x380a, 0x02}, + {0x380b, 0xd0}, + {0x380c, 0x06}, + {0x380d, 0xd8}, + {0x380e, 0x02}, + {0x380f, 0xf8}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3820, 0x04}, + {0x3821, 0x1f}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x06}, + {0x3a05, 0x14}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x00}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_2592x1944_HDR_24fps[] = { + {0x0100, 0x00},/* Including sw reset */ + {0x0103, 0x01}, + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x02}, + {0x3099, 0x16}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30b2, 0x00}, + {0x30b3, 0x6e}, + {0x30b4, 0x03}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x7b}, + {0x3502, 0x80}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x01}, + {0x3508, 0x80}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x05}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xa8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x0c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x02}, + {0x3802, 0x00}, + {0x3803, 0x06}, + {0x3804, 0x0a}, + {0x3805, 0x41}, + {0x3806, 0x07}, + {0x3807, 0xa1}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x07}, + {0x380b, 0x98}, + {0x380c, 0x0e}, + {0x380d, 0x70}, + {0x380e, 0x07}, + {0x380f, 0xc0}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x9e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x09}, + {0x3a05, 0xa9}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_1920x1080_HDR_30fps[] = { + {0x0100, 0x00},/* Including sw reset */ + {0x0103, 0x01}, + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x72}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x01}, + {0x3508, 0x80}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x01}, + {0x3801, 0x70}, + {0x3802, 0x01}, + {0x3803, 0xbc}, + {0x3804, 0x09}, + {0x3805, 0x0f}, + {0x3806, 0x05}, + {0x3807, 0xff}, + {0x3808, 0x07}, + {0x3809, 0x80}, + {0x380a, 0x04}, + {0x380b, 0x38}, + {0x380c, 0x0b}, + {0x380d, 0x40}, + {0x380e, 0x07}, + {0x380f, 0x3a}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x9e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x09}, + {0x3a05, 0xa9}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_1296x972_HDR_30fps[] = { + {0x0100, 0x00},/* Including sw reset */ + {0x0103, 0x01}, + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x72}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x01}, + {0x3508, 0x80}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x02}, + {0x3801, 0xa0}, + {0x3802, 0x01}, + {0x3803, 0xe8}, + {0x3804, 0x07}, + {0x3805, 0xb7}, + {0x3806, 0x05}, + {0x3807, 0xb9}, + {0x3808, 0x05}, + {0x3809, 0x10}, + {0x380a, 0x03}, + {0x380b, 0xcc}, + {0x380c, 0x0b}, + {0x380d, 0x40}, + {0x380e, 0x07}, + {0x380f, 0x3a}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x9e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x09}, + {0x3a05, 0xa9}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_1280x720_HDR_60fps[] = { + {0x0100, 0x00},/* Including sw reset */ + {0x0103, 0x01}, + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x39}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x01}, + {0x3508, 0x80}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x02}, + {0x3801, 0xa8}, + {0x3802, 0x02}, + {0x3803, 0x68}, + {0x3804, 0x07}, + {0x3805, 0xb7}, + {0x3806, 0x05}, + {0x3807, 0x3b}, + {0x3808, 0x05}, + {0x3809, 0x00}, + {0x380a, 0x02}, + {0x380b, 0xd0}, + {0x380c, 0x0b}, + {0x380d, 0x40}, + {0x380e, 0x03}, + {0x380f, 0x9e}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x9e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x09}, + {0x3a05, 0xa9}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +enum { + OV5693_MODE_2592X1944, + OV5693_MODE_2592X1458, + OV5693_MODE_1920X1080, + OV5693_MODE_1296X972, + OV5693_MODE_1280X720_120FPS, + OV5693_MODE_2592X1944_HDR, + OV5693_MODE_1920X1080_HDR, + OV5693_MODE_1296X972_HDR, + + OV5693_MODE_START_STREAM, + OV5693_MODE_STOP_STREAM, + OV5693_MODE_TEST_PATTERN +}; + +static const ov5693_reg *mode_table[] = { + [OV5693_MODE_2592X1944] = mode_2592x1944, + [OV5693_MODE_2592X1458] = mode_2592x1458, + [OV5693_MODE_1920X1080] = mode_1920x1080, + [OV5693_MODE_1296X972] = mode_1296x972, + [OV5693_MODE_1280X720_120FPS] = mode_1280x720_120fps, + [OV5693_MODE_2592X1944_HDR] = mode_2592x1944_HDR_24fps, + [OV5693_MODE_1920X1080_HDR] = mode_1920x1080_HDR_30fps, + [OV5693_MODE_1296X972_HDR] = mode_1296x972_HDR_30fps, + + [OV5693_MODE_START_STREAM] = ov5693_start, + [OV5693_MODE_STOP_STREAM] = ov5693_stop, + [OV5693_MODE_TEST_PATTERN] = tp_colorbars, +}; + +static const struct camera_common_frmfmt ov5693_frmfmt[] = { + {{2592, 1944}, 0, OV5693_MODE_2592X1944}, + {{2592, 1458}, 0, OV5693_MODE_2592X1458}, + {{1920, 1080}, 0, OV5693_MODE_1920X1080}, + {{1296, 972}, 0, OV5693_MODE_1296X972}, + {{1280, 720}, 0, OV5693_MODE_1280X720_120FPS}, + {{2592, 1944}, 1, OV5693_MODE_2592X1944_HDR}, + {{1920, 1080}, 1, OV5693_MODE_1920X1080_HDR}, + {{1296, 972}, 1, OV5693_MODE_1296X972_HDR}, +}; +#endif /* __OV5693_TABLES__ */ + diff --git a/drivers/media/i2c/soc_camera/ov5693_v4l2.c b/drivers/media/i2c/soc_camera/ov5693_v4l2.c new file mode 100644 index 00000000000..bfae1880368 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov5693_v4l2.c @@ -0,0 +1,1335 @@ +/* + * ov5693_v4l2.c - ov5693 sensor driver + * + * Copyright (c) 2013-2016, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "cam_dev/camera_gpio.h" + +#include "ov5693_mode_tbls.h" + +#define OV5693_MAX_COARSE_DIFF 6 + +#define OV5693_GAIN_SHIFT 8 +#define OV5693_REAL_GAIN_SHIFT 4 +#define OV5693_MIN_GAIN (1 << OV5693_GAIN_SHIFT) +#define OV5693_MAX_GAIN (16 << OV5693_GAIN_SHIFT) +#define OV5693_MAX_UNREAL_GAIN (0x0F80) +#define OV5693_MIN_FRAME_LENGTH (0x0) +#define OV5693_MAX_FRAME_LENGTH (0x7fff) +#define OV5693_MIN_EXPOSURE_COARSE (0x0002) +#define OV5693_MAX_EXPOSURE_COARSE \ + (OV5693_MAX_FRAME_LENGTH-OV5693_MAX_COARSE_DIFF) + +#define OV5693_DEFAULT_GAIN OV5693_MIN_GAIN +#define OV5693_DEFAULT_FRAME_LENGTH (0x07C0) +#define OV5693_DEFAULT_EXPOSURE_COARSE \ + (OV5693_DEFAULT_FRAME_LENGTH-OV5693_MAX_COARSE_DIFF) + +#define OV5693_DEFAULT_MODE OV5693_MODE_2592X1944 +#define OV5693_DEFAULT_HDR_MODE OV5693_MODE_2592X1944_HDR +#define OV5693_DEFAULT_WIDTH 2592 +#define OV5693_DEFAULT_HEIGHT 1944 +#define OV5693_DEFAULT_DATAFMT V4L2_MBUS_FMT_SRGGB10_1X10 +#define OV5693_DEFAULT_CLK_FREQ 24000000 + +struct ov5693 { + struct camera_common_power_rail power; + int numctrls; + struct v4l2_ctrl_handler ctrl_handler; + struct camera_common_eeprom_data eeprom[OV5693_EEPROM_NUM_BLOCKS]; + u8 eeprom_buf[OV5693_EEPROM_SIZE]; + struct i2c_client *i2c_client; + struct v4l2_subdev *subdev; + + int reg_offset; + + s32 group_hold_prev; + bool group_hold_en; + struct regmap *regmap; + struct camera_common_data *s_data; + struct camera_common_pdata *pdata; + struct v4l2_ctrl *ctrls[]; +}; + +static struct regmap_config ov5693_regmap_config = { + .reg_bits = 16, + .val_bits = 8, +}; + +static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl); +static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl); + +static const struct v4l2_ctrl_ops ov5693_ctrl_ops = { + .g_volatile_ctrl = ov5693_g_volatile_ctrl, + .s_ctrl = ov5693_s_ctrl, +}; + +static struct v4l2_ctrl_config ctrl_config_list[] = { +/* Do not change the name field for the controls! */ + { + .ops = &ov5693_ctrl_ops, + .id = V4L2_CID_GAIN, + .name = "Gain", + .type = V4L2_CTRL_TYPE_INTEGER, + .flags = V4L2_CTRL_FLAG_SLIDER, + .min = OV5693_MIN_GAIN, + .max = OV5693_MAX_GAIN, + .def = OV5693_DEFAULT_GAIN, + .step = 1, + }, + { + .ops = &ov5693_ctrl_ops, + .id = V4L2_CID_FRAME_LENGTH, + .name = "Frame Length", + .type = V4L2_CTRL_TYPE_INTEGER, + .flags = V4L2_CTRL_FLAG_SLIDER, + .min = OV5693_MIN_FRAME_LENGTH, + .max = OV5693_MAX_FRAME_LENGTH, + .def = OV5693_DEFAULT_FRAME_LENGTH, + .step = 1, + }, + { + .ops = &ov5693_ctrl_ops, + .id = V4L2_CID_COARSE_TIME, + .name = "Coarse Time", + .type = V4L2_CTRL_TYPE_INTEGER, + .flags = V4L2_CTRL_FLAG_SLIDER, + .min = OV5693_MIN_EXPOSURE_COARSE, + .max = OV5693_MAX_EXPOSURE_COARSE, + .def = OV5693_DEFAULT_EXPOSURE_COARSE, + .step = 1, + }, + { + .ops = &ov5693_ctrl_ops, + .id = V4L2_CID_COARSE_TIME_SHORT, + .name = "Coarse Time Short", + .type = V4L2_CTRL_TYPE_INTEGER, + .flags = V4L2_CTRL_FLAG_SLIDER, + .min = OV5693_MIN_EXPOSURE_COARSE, + .max = OV5693_MAX_EXPOSURE_COARSE, + .def = OV5693_DEFAULT_EXPOSURE_COARSE, + .step = 1, + }, + { + .ops = &ov5693_ctrl_ops, + .id = V4L2_CID_GROUP_HOLD, + .name = "Group Hold", + .type = V4L2_CTRL_TYPE_INTEGER_MENU, + .min = 0, + .max = ARRAY_SIZE(switch_ctrl_qmenu) - 1, + .menu_skip_mask = 0, + .def = 0, + .qmenu_int = switch_ctrl_qmenu, + }, + { + .ops = &ov5693_ctrl_ops, + .id = V4L2_CID_HDR_EN, + .name = "HDR enable", + .type = V4L2_CTRL_TYPE_INTEGER_MENU, + .min = 0, + .max = ARRAY_SIZE(switch_ctrl_qmenu) - 1, + .menu_skip_mask = 0, + .def = 0, + .qmenu_int = switch_ctrl_qmenu, + }, + { + .ops = &ov5693_ctrl_ops, + .id = V4L2_CID_EEPROM_DATA, + .name = "EEPROM Data", + .type = V4L2_CTRL_TYPE_STRING, + .flags = V4L2_CTRL_FLAG_VOLATILE, + .min = 0, + .max = OV5693_EEPROM_STR_SIZE, + .step = 2, + }, + { + .ops = &ov5693_ctrl_ops, + .id = V4L2_CID_OTP_DATA, + .name = "OTP Data", + .type = V4L2_CTRL_TYPE_STRING, + .flags = V4L2_CTRL_FLAG_READ_ONLY, + .min = 0, + .max = OV5693_OTP_STR_SIZE, + .step = 2, + }, + { + .ops = &ov5693_ctrl_ops, + .id = V4L2_CID_FUSE_ID, + .name = "Fuse ID", + .type = V4L2_CTRL_TYPE_STRING, + .flags = V4L2_CTRL_FLAG_READ_ONLY, + .min = 0, + .max = OV5693_FUSE_ID_STR_SIZE, + .step = 2, + }, +}; + +static inline void ov5693_get_frame_length_regs(ov5693_reg *regs, + u32 frame_length) +{ + regs->addr = OV5693_FRAME_LENGTH_ADDR_MSB; + regs->val = (frame_length >> 8) & 0xff; + (regs + 1)->addr = OV5693_FRAME_LENGTH_ADDR_LSB; + (regs + 1)->val = (frame_length) & 0xff; +} + + +static inline void ov5693_get_coarse_time_regs(ov5693_reg *regs, + u32 coarse_time) +{ + regs->addr = OV5693_COARSE_TIME_ADDR_1; + regs->val = (coarse_time >> 12) & 0xff; + (regs + 1)->addr = OV5693_COARSE_TIME_ADDR_2; + (regs + 1)->val = (coarse_time >> 4) & 0xff; + (regs + 2)->addr = OV5693_COARSE_TIME_ADDR_3; + (regs + 2)->val = (coarse_time & 0xf) << 4; +} + +static inline void ov5693_get_coarse_time_short_regs(ov5693_reg *regs, + u32 coarse_time) +{ + regs->addr = OV5693_COARSE_TIME_SHORT_ADDR_1; + regs->val = (coarse_time >> 12) & 0xff; + (regs + 1)->addr = OV5693_COARSE_TIME_SHORT_ADDR_2; + (regs + 1)->val = (coarse_time >> 4) & 0xff; + (regs + 2)->addr = OV5693_COARSE_TIME_SHORT_ADDR_3; + (regs + 2)->val = (coarse_time & 0xf) << 4; +} + +static inline void ov5693_get_gain_regs(ov5693_reg *regs, + u16 gain) +{ + regs->addr = OV5693_GAIN_ADDR_MSB; + regs->val = (gain >> 8) & 0xff; + + (regs + 1)->addr = OV5693_GAIN_ADDR_LSB; + (regs + 1)->val = (gain) & 0xff; +} + +static int test_mode; +module_param(test_mode, int, 0644); + +static inline int ov5693_read_reg(struct camera_common_data *s_data, + u16 addr, u8 *val) +{ + struct ov5693 *priv = (struct ov5693 *)s_data->priv; + + return regmap_read(priv->regmap, addr, (unsigned int *) val); +} + +static int ov5693_write_reg(struct camera_common_data *s_data, u16 addr, u8 val) +{ + int err; + struct ov5693 *priv = (struct ov5693 *)s_data->priv; + + err = regmap_write(priv->regmap, addr, val); + if (err) + pr_err("%s:i2c write failed, %x = %x\n", + __func__, addr, val); + + return err; +} + +static int ov5693_write_table(struct ov5693 *priv, + const ov5693_reg table[]) +{ + return regmap_util_write_table_8(priv->regmap, + table, + NULL, 0, + OV5693_TABLE_WAIT_MS, + OV5693_TABLE_END); +} + +static void ov5693_gpio_set(struct ov5693 *priv, + unsigned int gpio, int val) +{ + if (priv->pdata->use_cam_gpio) + cam_gpio_ctrl(priv->i2c_client, gpio, val, 1); + else + gpio_set_value(gpio, val); +} + +static int ov5693_power_on(struct camera_common_data *s_data) +{ + int err = 0; + struct ov5693 *priv = (struct ov5693 *)s_data->priv; + struct camera_common_power_rail *pw = &priv->power; + + dev_dbg(&priv->i2c_client->dev, "%s: power on\n", __func__); + + if (priv->pdata && priv->pdata->power_on) { + err = priv->pdata->power_on(pw); + if (err) + pr_err("%s failed.\n", __func__); + else + pw->state = SWITCH_ON; + return err; + } + + /* sleeps calls in the sequence below are for internal device + * signal propagation as specified by sensor vendor */ + + if (pw->avdd) + err = regulator_enable(pw->avdd); + if (err) + goto ov5693_avdd_fail; + + if (pw->iovdd) + err = regulator_enable(pw->iovdd); + if (err) + goto ov5693_iovdd_fail; + + usleep_range(1, 2); + if (pw->pwdn_gpio) + ov5693_gpio_set(priv, pw->pwdn_gpio, 1); + + /* datasheet 2.9: reset requires ~2ms settling time + * a power on reset is generated after core power becomes stable */ + usleep_range(2000, 2010); + + if (pw->reset_gpio) + gpio_set_value(pw->reset_gpio, 1); + + /* datasheet fig 2-9: t3 */ + usleep_range(1350, 1360); + + pw->state = SWITCH_ON; + return 0; + +ov5693_iovdd_fail: + regulator_disable(pw->avdd); + +ov5693_avdd_fail: + pr_err("%s failed.\n", __func__); + return -ENODEV; +} + +static int ov5693_power_off(struct camera_common_data *s_data) +{ + int err = 0; + struct ov5693 *priv = (struct ov5693 *)s_data->priv; + struct camera_common_power_rail *pw = &priv->power; + + dev_dbg(&priv->i2c_client->dev, "%s: power off\n", __func__); + + if (priv->pdata && priv->pdata->power_on) { + err = priv->pdata->power_off(pw); + if (!err) { + goto power_off_done; + } else { + pr_err("%s failed.\n", __func__); + return err; + } + } + + /* sleeps calls in the sequence below are for internal device + * signal propagation as specified by sensor vendor */ + + usleep_range(21, 25); + if (pw->pwdn_gpio) + ov5693_gpio_set(priv, pw->pwdn_gpio, 0); + usleep_range(1, 2); + if (pw->reset_gpio) + gpio_set_value(pw->reset_gpio, 0); + + /* datasheet 2.9: reset requires ~2ms settling time*/ + usleep_range(2000, 2010); + + if (pw->iovdd) + regulator_disable(pw->iovdd); + if (pw->avdd) + regulator_disable(pw->avdd); + +power_off_done: + pw->state = SWITCH_OFF; + return 0; +} + +static int ov5693_power_put(struct ov5693 *priv) +{ + struct camera_common_power_rail *pw = &priv->power; + + if (unlikely(!pw)) + return -EFAULT; + + if (likely(pw->avdd)) + regulator_put(pw->avdd); + + if (likely(pw->iovdd)) + regulator_put(pw->iovdd); + + pw->avdd = NULL; + pw->iovdd = NULL; + + if (priv->pdata->use_cam_gpio) + cam_gpio_deregister(priv->i2c_client, pw->pwdn_gpio); + else + gpio_free(pw->pwdn_gpio); + + return 0; +} + +static int ov5693_power_get(struct ov5693 *priv) +{ + struct camera_common_power_rail *pw = &priv->power; + struct camera_common_pdata *pdata = priv->pdata; + const char *mclk_name; + int err = 0; + + mclk_name = priv->pdata->mclk_name ? + priv->pdata->mclk_name : "cam_mclk1"; + pw->mclk = devm_clk_get(&priv->i2c_client->dev, mclk_name); + if (IS_ERR(pw->mclk)) { + dev_err(&priv->i2c_client->dev, + "unable to get clock %s\n", mclk_name); + return PTR_ERR(pw->mclk); + } + + /* analog 2.8v */ + err |= camera_common_regulator_get(priv->i2c_client, + &pw->avdd, pdata->regulators.avdd); + /* IO 1.8v */ + err |= camera_common_regulator_get(priv->i2c_client, + &pw->iovdd, pdata->regulators.iovdd); + + if (!err) { + pw->reset_gpio = pdata->reset_gpio; + pw->pwdn_gpio = pdata->pwdn_gpio; + } + + if (priv->pdata->use_cam_gpio) { + err = cam_gpio_register(priv->i2c_client, pw->pwdn_gpio); + if (err) + dev_err(&priv->i2c_client->dev, + "%s ERR can't register cam gpio %u!\n", + __func__, pw->pwdn_gpio); + } else + gpio_request(pw->pwdn_gpio, "cam_pwdn_gpio"); + + pw->state = SWITCH_OFF; + return err; +} + +static int ov5693_set_gain(struct ov5693 *priv, s32 val); +static int ov5693_set_frame_length(struct ov5693 *priv, s32 val); +static int ov5693_set_coarse_time(struct ov5693 *priv, s32 val); +static int ov5693_set_coarse_time_short(struct ov5693 *priv, s32 val); + +static int ov5693_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct camera_common_data *s_data = to_camera_common_data(client); + struct ov5693 *priv = (struct ov5693 *)s_data->priv; + struct v4l2_control control; + int err; + + dev_dbg(&client->dev, "%s++\n", __func__); + + if (!enable) + return ov5693_write_table(priv, + mode_table[OV5693_MODE_STOP_STREAM]); + + err = ov5693_write_table(priv, mode_table[s_data->mode]); + if (err) + goto exit; + + /* write list of override regs for the asking frame length, + * coarse integration time, and gain. Failures to write + * overrides are non-fatal */ + control.id = V4L2_CID_GAIN; + err = v4l2_g_ctrl(&priv->ctrl_handler, &control); + err |= ov5693_set_gain(priv, control.value); + if (err) + dev_dbg(&client->dev, "%s: warning gain override failed\n", + __func__); + + control.id = V4L2_CID_FRAME_LENGTH; + err = v4l2_g_ctrl(&priv->ctrl_handler, &control); + err |= ov5693_set_frame_length(priv, control.value); + if (err) + dev_dbg(&client->dev, + "%s: warning frame length override failed\n", + __func__); + + control.id = V4L2_CID_COARSE_TIME; + err = v4l2_g_ctrl(&priv->ctrl_handler, &control); + err |= ov5693_set_coarse_time(priv, control.value); + if (err) + dev_dbg(&client->dev, + "%s: warning coarse time override failed\n", + __func__); + + control.id = V4L2_CID_COARSE_TIME_SHORT; + err = v4l2_g_ctrl(&priv->ctrl_handler, &control); + err |= ov5693_set_coarse_time_short(priv, control.value); + if (err) + dev_dbg(&client->dev, + "%s: warning coarse time short override failed\n", + __func__); + + err = ov5693_write_table(priv, mode_table[OV5693_MODE_START_STREAM]); + if (err) + goto exit; + + if (test_mode) + err = ov5693_write_table(priv, + mode_table[OV5693_MODE_TEST_PATTERN]); + + dev_dbg(&client->dev, "%s--\n", __func__); + return 0; +exit: + dev_dbg(&client->dev, "%s: error setting stream\n", __func__); + return err; +} + +static struct v4l2_subdev_video_ops ov5693_subdev_video_ops = { + .s_stream = ov5693_s_stream, + .s_mbus_fmt = camera_common_s_fmt, + .g_mbus_fmt = camera_common_g_fmt, + .try_mbus_fmt = camera_common_try_fmt, + .enum_mbus_fmt = camera_common_enum_fmt, + .g_mbus_config = camera_common_g_mbus_config, +}; + +static struct v4l2_subdev_core_ops ov5693_subdev_core_ops = { + .s_power = camera_common_s_power, +}; + +static struct v4l2_subdev_ops ov5693_subdev_ops = { + .core = &ov5693_subdev_core_ops, + .video = &ov5693_subdev_video_ops, +}; + +static struct of_device_id ov5693_of_match[] = { + { .compatible = "nvidia,ov5693", }, + { }, +}; + +static struct camera_common_sensor_ops ov5693_common_ops = { + .power_on = ov5693_power_on, + .power_off = ov5693_power_off, + .write_reg = ov5693_write_reg, + .read_reg = ov5693_read_reg, +}; + +static int ov5693_set_group_hold(struct ov5693 *priv) +{ + int err; + int gh_prev = switch_ctrl_qmenu[priv->group_hold_prev]; + + if (priv->group_hold_en == true && gh_prev == SWITCH_OFF) { + /* enter group hold */ + err = ov5693_write_reg(priv->s_data, + OV5693_GROUP_HOLD_ADDR, 0x01); + if (err) + goto fail; + + priv->group_hold_prev = 1; + + dev_dbg(&priv->i2c_client->dev, + "%s: enter group hold\n", __func__); + } else if (priv->group_hold_en == false && gh_prev == SWITCH_ON) { + /* leave group hold */ + err = ov5693_write_reg(priv->s_data, + OV5693_GROUP_HOLD_ADDR, 0x11); + if (err) + goto fail; + + err = ov5693_write_reg(priv->s_data, + OV5693_GROUP_HOLD_ADDR, 0x61); + if (err) + goto fail; + + priv->group_hold_prev = 0; + + dev_dbg(&priv->i2c_client->dev, + "%s: leave group hold\n", __func__); + } + + return 0; + +fail: + dev_dbg(&priv->i2c_client->dev, + "%s: Group hold control error\n", __func__); + return err; +} + +static u16 ov5693_to_real_gain(u32 rep, int shift) +{ + u16 gain; + int gain_int; + int gain_dec; + int min_int = (1 << shift); + + if (rep < OV5693_MIN_GAIN) + rep = OV5693_MIN_GAIN; + else if (rep > OV5693_MAX_GAIN) + rep = OV5693_MAX_GAIN; + + gain_int = (int)(rep >> shift); + gain_dec = (int)(rep & ~(0xffff << shift)); + + /* derived from formulat gain = (x * 16 + 0.5) */ + gain = ((gain_int * min_int + gain_dec) * 32 + min_int) / (2 * min_int); + + return gain; +} + +static int ov5693_set_gain(struct ov5693 *priv, s32 val) +{ + ov5693_reg reg_list[2]; + int err; + u16 gain; + int i; + + if (!priv->group_hold_prev) + ov5693_set_group_hold(priv); + + /* translate value */ + gain = ov5693_to_real_gain((u32)val, OV5693_GAIN_SHIFT); + + ov5693_get_gain_regs(reg_list, gain); + dev_dbg(&priv->i2c_client->dev, + "%s: gain %04x val: %04x\n", __func__, val, gain); + + for (i = 0; i < 2; i++) { + err = ov5693_write_reg(priv->s_data, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + return 0; + +fail: + dev_dbg(&priv->i2c_client->dev, + "%s: GAIN control error\n", __func__); + return err; +} + +static int ov5693_set_frame_length(struct ov5693 *priv, s32 val) +{ + ov5693_reg reg_list[2]; + int err; + u32 frame_length; + int i; + + if (!priv->group_hold_prev) + ov5693_set_group_hold(priv); + + frame_length = (u32)val; + + ov5693_get_frame_length_regs(reg_list, frame_length); + dev_dbg(&priv->i2c_client->dev, + "%s: val: %d\n", __func__, frame_length); + + for (i = 0; i < 2; i++) { + err = ov5693_write_reg(priv->s_data, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + return 0; + +fail: + dev_dbg(&priv->i2c_client->dev, + "%s: FRAME_LENGTH control error\n", __func__); + return err; +} + +static int ov5693_clamp_coarse_time(struct ov5693 *priv, s32 *val) +{ + struct v4l2_control fl_control; + int err; + + fl_control.id = V4L2_CID_FRAME_LENGTH; + + err = camera_common_g_ctrl(priv->s_data, &fl_control); + if (err < 0) { + dev_err(&priv->i2c_client->dev, + "could not find device ctrl.\n"); + return err; + } + + if (*val > (fl_control.value - OV5693_MAX_COARSE_DIFF)) { + dev_dbg(&priv->i2c_client->dev, + "%s: %d to %d\n", __func__, *val, + fl_control.value - OV5693_MAX_COARSE_DIFF); + *val = fl_control.value - OV5693_MAX_COARSE_DIFF; + } + + return 0; +} + +static int ov5693_set_coarse_time(struct ov5693 *priv, s32 val) +{ + ov5693_reg reg_list[3]; + int err; + u32 coarse_time; + int i; + + if (!priv->group_hold_prev) + ov5693_set_group_hold(priv); + + coarse_time = (u32)val; + + ov5693_get_coarse_time_regs(reg_list, coarse_time); + dev_dbg(&priv->i2c_client->dev, + "%s: val: %d\n", __func__, coarse_time); + + for (i = 0; i < 3; i++) { + err = ov5693_write_reg(priv->s_data, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + return 0; + +fail: + dev_dbg(&priv->i2c_client->dev, + "%s: COARSE_TIME control error\n", __func__); + return err; +} + +static int ov5693_set_coarse_time_short(struct ov5693 *priv, s32 val) +{ + ov5693_reg reg_list[3]; + int err; + struct v4l2_control hdr_control; + int hdr_en; + u32 coarse_time_short; + int i; + + if (!priv->group_hold_prev) + ov5693_set_group_hold(priv); + + /* check hdr enable ctrl */ + hdr_control.id = V4L2_CID_HDR_EN; + + err = camera_common_g_ctrl(priv->s_data, &hdr_control); + if (err < 0) { + dev_err(&priv->i2c_client->dev, + "could not find device ctrl.\n"); + return err; + } + + hdr_en = switch_ctrl_qmenu[hdr_control.value]; + if (hdr_en == SWITCH_OFF) + return 0; + + coarse_time_short = (u32)val; + + ov5693_get_coarse_time_short_regs(reg_list, coarse_time_short); + dev_dbg(&priv->i2c_client->dev, + "%s: val: %d\n", __func__, coarse_time_short); + + for (i = 0; i < 3; i++) { + err = ov5693_write_reg(priv->s_data, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + return 0; + +fail: + dev_dbg(&priv->i2c_client->dev, + "%s: COARSE_TIME_SHORT control error\n", __func__); + return err; +} + +static int ov5693_eeprom_device_release(struct ov5693 *priv) +{ + int i; + + for (i = 0; i < OV5693_EEPROM_NUM_BLOCKS; i++) { + if (priv->eeprom[i].i2c_client != NULL) { + i2c_unregister_device(priv->eeprom[i].i2c_client); + priv->eeprom[i].i2c_client = NULL; + } + } + + return 0; +} + +static int ov5693_eeprom_device_init(struct ov5693 *priv) +{ + char *dev_name = "eeprom_ov5693"; + static struct regmap_config eeprom_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + }; + int i; + int err; + struct v4l2_ctrl *ctrl; + + ctrl = v4l2_ctrl_find(&priv->ctrl_handler, V4L2_CID_EEPROM_DATA); + if (!ctrl) { + dev_err(&priv->i2c_client->dev, + "could not find device ctrl.\n"); + return -EINVAL; + } + + if (!priv->pdata->has_eeprom) { + ctrl->flags = V4L2_CTRL_FLAG_DISABLED; + return 0; + } + + for (i = 0; i < OV5693_EEPROM_NUM_BLOCKS; i++) { + priv->eeprom[i].adap = i2c_get_adapter( + priv->i2c_client->adapter->nr); + memset(&priv->eeprom[i].brd, 0, sizeof(priv->eeprom[i].brd)); + strncpy(priv->eeprom[i].brd.type, dev_name, + sizeof(priv->eeprom[i].brd.type)); + priv->eeprom[i].brd.addr = OV5693_EEPROM_ADDRESS + i; + priv->eeprom[i].i2c_client = i2c_new_device( + priv->eeprom[i].adap, &priv->eeprom[i].brd); + + priv->eeprom[i].regmap = devm_regmap_init_i2c( + priv->eeprom[i].i2c_client, &eeprom_regmap_config); + if (IS_ERR(priv->eeprom[i].regmap)) { + err = PTR_ERR(priv->eeprom[i].regmap); + ov5693_eeprom_device_release(priv); + ctrl->flags = V4L2_CTRL_FLAG_DISABLED; + return err; + } + } + + return 0; +} + +static int ov5693_read_eeprom(struct ov5693 *priv, + struct v4l2_ctrl *ctrl) +{ + int err, i; + + for (i = 0; i < OV5693_EEPROM_NUM_BLOCKS; i++) { + err = regmap_bulk_read(priv->eeprom[i].regmap, 0, + &priv->eeprom_buf[i * OV5693_EEPROM_BLOCK_SIZE], + OV5693_EEPROM_BLOCK_SIZE); + if (err) + return err; + } + + for (i = 0; i < OV5693_EEPROM_SIZE; i++) + sprintf(&ctrl->string[i*2], "%02x", + priv->eeprom_buf[i]); + return 0; +} + +static int ov5693_write_eeprom(struct ov5693 *priv, + char *string) +{ + int err; + int i; + u8 curr[3]; + unsigned long data; + + for (i = 0; i < OV5693_EEPROM_SIZE; i++) { + curr[0] = string[i*2]; + curr[1] = string[i*2+1]; + curr[2] = '\0'; + + err = kstrtol(curr, 16, &data); + if (err) { + dev_err(&priv->i2c_client->dev, + "invalid eeprom string\n"); + return -EINVAL; + } + + priv->eeprom_buf[i] = (u8)data; + err = regmap_write(priv->eeprom[i >> 8].regmap, + i & 0xFF, (u8)data); + if (err) + return err; + msleep(20); + } + return 0; +} + +static int ov5693_read_otp_bank(struct ov5693 *priv, + u8 *buf, int bank, u16 addr, int size) +{ + int err; + + /* sleeps calls in the sequence below are for internal device + * signal propagation as specified by sensor vendor */ + + usleep_range(10000, 11000); + err = ov5693_write_table(priv, mode_table[OV5693_MODE_START_STREAM]); + if (err) + return err; + + err = ov5693_write_reg(priv->s_data, OV5693_OTP_BANK_SELECT_ADDR, + 0xC0 | bank); + if (err) + return err; + + err = ov5693_write_reg(priv->s_data, OV5693_OTP_LOAD_CTRL_ADDR, 0x01); + if (err) + return err; + + usleep_range(10000, 11000); + err = regmap_bulk_read(priv->regmap, addr, buf, size); + if (err) + return err; + + err = ov5693_write_table(priv, + mode_table[OV5693_MODE_STOP_STREAM]); + if (err) + return err; + + return 0; +} + +static int ov5693_otp_setup(struct ov5693 *priv) +{ + int err; + int i; + struct v4l2_ctrl *ctrl; + u8 otp_buf[OV5693_OTP_SIZE]; + + err = camera_common_s_power(priv->subdev, true); + if (err) + return -ENODEV; + + for (i = 0; i < OV5693_OTP_NUM_BANKS; i++) { + ov5693_read_otp_bank(priv, + &otp_buf[i * OV5693_OTP_BANK_SIZE], + i, + OV5693_OTP_BANK_START_ADDR, + OV5693_OTP_BANK_SIZE); + } + + ctrl = v4l2_ctrl_find(&priv->ctrl_handler, V4L2_CID_OTP_DATA); + if (!ctrl) { + dev_err(&priv->i2c_client->dev, + "could not find device ctrl.\n"); + return -EINVAL; + } + + for (i = 0; i < OV5693_OTP_SIZE; i++) + sprintf(&ctrl->string[i*2], "%02x", + otp_buf[i]); + ctrl->cur.string = ctrl->string; + + err = camera_common_s_power(priv->subdev, false); + if (err) + return -ENODEV; + + return 0; +} + +static int ov5693_fuse_id_setup(struct ov5693 *priv) +{ + int err; + int i; + struct v4l2_ctrl *ctrl; + u8 fuse_id[OV5693_FUSE_ID_SIZE]; + + err = camera_common_s_power(priv->subdev, true); + if (err) + return -ENODEV; + + ov5693_read_otp_bank(priv, + &fuse_id[0], + OV5693_FUSE_ID_OTP_BANK, + OV5693_FUSE_ID_OTP_START_ADDR, + OV5693_FUSE_ID_SIZE); + + ctrl = v4l2_ctrl_find(&priv->ctrl_handler, V4L2_CID_FUSE_ID); + if (!ctrl) { + dev_err(&priv->i2c_client->dev, + "could not find device ctrl.\n"); + return -EINVAL; + } + + for (i = 0; i < OV5693_FUSE_ID_SIZE; i++) + sprintf(&ctrl->string[i*2], "%02x", + fuse_id[i]); + ctrl->cur.string = ctrl->string; + + err = camera_common_s_power(priv->subdev, false); + if (err) + return -ENODEV; + + return 0; +} + +static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl) +{ + struct ov5693 *priv = + container_of(ctrl->handler, struct ov5693, ctrl_handler); + int err = 0; + + if (priv->power.state == SWITCH_OFF) + return 0; + + switch (ctrl->id) { + case V4L2_CID_EEPROM_DATA: + err = ov5693_read_eeprom(priv, ctrl); + if (err) + return err; + break; + default: + pr_err("%s: unknown ctrl id.\n", __func__); + return -EINVAL; + } + + return err; +} + +static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct ov5693 *priv = + container_of(ctrl->handler, struct ov5693, ctrl_handler); + s32 clamp_val = ctrl->val; + int err = 0; + + if (priv->power.state == SWITCH_OFF) + return 0; + + switch (ctrl->id) { + case V4L2_CID_GAIN: + err = ov5693_set_gain(priv, ctrl->val); + break; + case V4L2_CID_FRAME_LENGTH: + err = ov5693_set_frame_length(priv, ctrl->val); + break; + case V4L2_CID_COARSE_TIME: + err = ov5693_clamp_coarse_time(priv, &clamp_val); + if (err) + return err; + + if (clamp_val != ctrl->cur.val) + err = ov5693_set_coarse_time(priv, clamp_val); + break; + case V4L2_CID_COARSE_TIME_SHORT: + err = ov5693_clamp_coarse_time(priv, &clamp_val); + if (err) + return err; + + if (clamp_val != ctrl->cur.val) + err = ov5693_set_coarse_time_short(priv, clamp_val); + break; + case V4L2_CID_GROUP_HOLD: + if (switch_ctrl_qmenu[ctrl->val] == SWITCH_ON) { + priv->group_hold_en = true; + } else { + priv->group_hold_en = false; + err = ov5693_set_group_hold(priv); + } + break; + case V4L2_CID_EEPROM_DATA: + if (!ctrl->string[0]) + break; + err = ov5693_write_eeprom(priv, ctrl->string); + if (err) + return err; + break; + case V4L2_CID_HDR_EN: + break; + default: + pr_err("%s: unknown ctrl id.\n", __func__); + return -EINVAL; + } + + if (clamp_val != ctrl->val) { + ctrl->val = clamp_val; + return -EINVAL; + } + + return err; +} + +static int ov5693_ctrls_init(struct ov5693 *priv) +{ + struct i2c_client *client = priv->i2c_client; + struct v4l2_ctrl *ctrl; + int numctrls; + int err; + int i; + + dev_dbg(&client->dev, "%s++\n", __func__); + + numctrls = ARRAY_SIZE(ctrl_config_list); + v4l2_ctrl_handler_init(&priv->ctrl_handler, numctrls); + + for (i = 0; i < numctrls; i++) { + ctrl = v4l2_ctrl_new_custom(&priv->ctrl_handler, + &ctrl_config_list[i], NULL); + if (ctrl == NULL) { + dev_err(&client->dev, "Failed to init %s ctrl\n", + ctrl_config_list[i].name); + continue; + } + + if (ctrl_config_list[i].type == V4L2_CTRL_TYPE_STRING && + ctrl_config_list[i].flags & V4L2_CTRL_FLAG_READ_ONLY) { + ctrl->string = devm_kzalloc(&client->dev, + ctrl_config_list[i].max + 1, GFP_KERNEL); + if (!ctrl->string) + return -ENOMEM; + } + priv->ctrls[i] = ctrl; + } + + priv->numctrls = numctrls; + priv->subdev->ctrl_handler = &priv->ctrl_handler; + if (priv->ctrl_handler.error) { + dev_err(&client->dev, "Error %d adding controls\n", + priv->ctrl_handler.error); + err = priv->ctrl_handler.error; + goto error; + } + + err = v4l2_ctrl_handler_setup(&priv->ctrl_handler); + if (err) { + dev_err(&client->dev, + "Error %d setting default controls\n", err); + goto error; + } + + err = ov5693_otp_setup(priv); + if (err) { + dev_err(&client->dev, + "Error %d reading otp data\n", err); + goto error; + } + + err = ov5693_fuse_id_setup(priv); + if (err) { + dev_err(&client->dev, + "Error %d reading fuse id data\n", err); + goto error; + } + + return 0; + +error: + v4l2_ctrl_handler_free(&priv->ctrl_handler); + return err; +} + +MODULE_DEVICE_TABLE(of, ov5693_of_match); + +static struct camera_common_pdata *ov5693_parse_dt(struct i2c_client *client) +{ + struct device_node *np = client->dev.of_node; + struct camera_common_pdata *board_priv_pdata; + const struct of_device_id *match; + int gpio; + int err; + + match = of_match_device(ov5693_of_match, &client->dev); + if (!match) { + dev_err(&client->dev, "Failed to find matching dt id\n"); + return NULL; + } + + board_priv_pdata = devm_kzalloc(&client->dev, + sizeof(*board_priv_pdata), GFP_KERNEL); + if (!board_priv_pdata) + return NULL; + + err = of_property_read_string(np, "mclk", + &board_priv_pdata->mclk_name); + if (err) { + dev_err(&client->dev, "mclk not in DT\n"); + goto error; + } + + gpio = of_get_named_gpio(np, "pwdn-gpios", 0); + if (gpio < 0) { + dev_err(&client->dev, "pwdn gpios not in DT\n"); + goto error; + } + board_priv_pdata->pwdn_gpio = (unsigned int)gpio; + + board_priv_pdata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); + + board_priv_pdata->use_cam_gpio = of_property_read_bool(np, + "cam,use-cam-gpio"); + + err = of_property_read_string(np, "avdd-reg", + &board_priv_pdata->regulators.avdd); + if (err) { + dev_err(&client->dev, "avdd-reg not in DT\n"); + goto error; + } + err = of_property_read_string(np, "iovdd-reg", + &board_priv_pdata->regulators.iovdd); + if (err) { + dev_err(&client->dev, "iovdd-reg not in DT\n"); + goto error; + } + + board_priv_pdata->has_eeprom = of_property_read_bool(np, "has-eeprom"); + + return board_priv_pdata; + +error: + devm_kfree(&client->dev, board_priv_pdata); + return NULL; +} + +static int ov5693_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct camera_common_data *common_data; + struct ov5693 *priv; + struct soc_camera_subdev_desc *ssdd; + struct tegra_camera_platform_data *ov5693_camera_data; + char node_name[10]; + int err; + + pr_info("[OV5693]: probing v4l2 sensor.\n"); + + common_data = devm_kzalloc(&client->dev, + sizeof(struct camera_common_data), GFP_KERNEL); + if (!common_data) + return -ENOMEM; + + priv = devm_kzalloc(&client->dev, + sizeof(struct ov5693) + sizeof(struct v4l2_ctrl *) * + ARRAY_SIZE(ctrl_config_list), + GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->regmap = devm_regmap_init_i2c(client, &ov5693_regmap_config); + if (IS_ERR(priv->regmap)) { + dev_err(&client->dev, + "regmap init failed: %ld\n", PTR_ERR(priv->regmap)); + return -ENODEV; + } + + ssdd = soc_camera_i2c_to_desc(client); + ov5693_camera_data = (struct tegra_camera_platform_data *) + ssdd->drv_priv; + if (!ov5693_camera_data) { + dev_err(&client->dev, "unable to find iclink module name\n"); + return -EFAULT; + } + + priv->pdata = ssdd->dev_priv; + if (!priv->pdata) { + dev_err(&client->dev, "unable to get platform data\n"); + return -EFAULT; + } + + common_data->ops = &ov5693_common_ops; + common_data->ctrl_handler = &priv->ctrl_handler; + common_data->i2c_client = client; + common_data->frmfmt = &ov5693_frmfmt[0]; + common_data->colorfmt = camera_common_find_datafmt( + OV5693_DEFAULT_DATAFMT); + common_data->power = &priv->power; + common_data->ctrls = priv->ctrls; + common_data->priv = (void *)priv; + common_data->numctrls = ARRAY_SIZE(ctrl_config_list); + common_data->numfmts = ARRAY_SIZE(ov5693_frmfmt); + common_data->def_mode = OV5693_DEFAULT_MODE; + common_data->def_width = OV5693_DEFAULT_WIDTH; + common_data->def_height = OV5693_DEFAULT_HEIGHT; + common_data->def_clk_freq = OV5693_DEFAULT_CLK_FREQ; + common_data->csi_port = (int)ov5693_camera_data->port; + common_data->numlanes = ov5693_camera_data->lanes; + + priv->i2c_client = client; + priv->s_data = common_data; + priv->subdev = &common_data->subdev; + + err = ov5693_power_get(priv); + if (err) + return err; + + camera_common_create_debugfs(common_data, node_name); + + v4l2_i2c_subdev_init(&common_data->subdev, client, &ov5693_subdev_ops); + + err = ov5693_ctrls_init(priv); + if (err) + return err; + + /* eeprom interface */ + err = ov5693_eeprom_device_init(priv); + if (err) { + dev_err(&client->dev, + "Failed to allocate eeprom reg map: %d\n", err); + } + + camera_common_s_power(priv->subdev, true); + return 0; +} + +static int +ov5693_remove(struct i2c_client *client) +{ + struct soc_camera_subdev_desc *ssdd; + struct camera_common_data *s_data = to_camera_common_data(client); + struct ov5693 *priv = (struct ov5693 *)s_data->priv; + + ssdd = soc_camera_i2c_to_desc(client); + if (ssdd->free_bus) + ssdd->free_bus(ssdd); + + v4l2_ctrl_handler_free(&priv->ctrl_handler); + ov5693_power_put(priv); + camera_common_remove_debugfs(s_data); + + return 0; +} + +static const struct i2c_device_id ov5693_id[] = { + { "ov5693_v4l2", 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, ov5693_id); + +static struct i2c_driver ov5693_i2c_driver = { + .driver = { + .name = "ov5693_v4l2", + .owner = THIS_MODULE, + }, + .probe = ov5693_probe, + .remove = ov5693_remove, + .id_table = ov5693_id, +}; + +module_i2c_driver(ov5693_i2c_driver); + +MODULE_DESCRIPTION("SoC Camera driver for Sony OV5693"); +MODULE_AUTHOR("David Wang "); +MODULE_LICENSE("GPL v2"); +