18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * ov534-ov9xxx gspca driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2009-2011 Jean-Francois Moine http://moinejf.free.fr 68c2ecf20Sopenharmony_ci * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 78c2ecf20Sopenharmony_ci * Copyright (C) 2008 Jim Paris <jim@jtan.com> 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Based on a prototype written by Mark Ferrell <majortrips@gmail.com> 108c2ecf20Sopenharmony_ci * USB protocol reverse engineered by Jim Paris <jim@jtan.com> 118c2ecf20Sopenharmony_ci * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define MODULE_NAME "ov534_9" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include "gspca.h" 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define OV534_REG_ADDRESS 0xf1 /* sensor address */ 218c2ecf20Sopenharmony_ci#define OV534_REG_SUBADDR 0xf2 228c2ecf20Sopenharmony_ci#define OV534_REG_WRITE 0xf3 238c2ecf20Sopenharmony_ci#define OV534_REG_READ 0xf4 248c2ecf20Sopenharmony_ci#define OV534_REG_OPERATION 0xf5 258c2ecf20Sopenharmony_ci#define OV534_REG_STATUS 0xf6 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define OV534_OP_WRITE_3 0x37 288c2ecf20Sopenharmony_ci#define OV534_OP_WRITE_2 0x33 298c2ecf20Sopenharmony_ci#define OV534_OP_READ_2 0xf9 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define CTRL_TIMEOUT 500 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ciMODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>"); 348c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver"); 358c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* specific webcam descriptor */ 388c2ecf20Sopenharmony_cistruct sd { 398c2ecf20Sopenharmony_ci struct gspca_dev gspca_dev; /* !! must be the first item */ 408c2ecf20Sopenharmony_ci __u32 last_pts; 418c2ecf20Sopenharmony_ci u8 last_fid; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci u8 sensor; 448c2ecf20Sopenharmony_ci}; 458c2ecf20Sopenharmony_cienum sensors { 468c2ecf20Sopenharmony_ci SENSOR_OV965x, /* ov9657 */ 478c2ecf20Sopenharmony_ci SENSOR_OV971x, /* ov9712 */ 488c2ecf20Sopenharmony_ci SENSOR_OV562x, /* ov5621 */ 498c2ecf20Sopenharmony_ci SENSOR_OV361x, /* ov3610 */ 508c2ecf20Sopenharmony_ci NSENSORS 518c2ecf20Sopenharmony_ci}; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistatic const struct v4l2_pix_format ov965x_mode[] = { 548c2ecf20Sopenharmony_ci#define QVGA_MODE 0 558c2ecf20Sopenharmony_ci {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 568c2ecf20Sopenharmony_ci .bytesperline = 320, 578c2ecf20Sopenharmony_ci .sizeimage = 320 * 240 * 3 / 8 + 590, 588c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_JPEG}, 598c2ecf20Sopenharmony_ci#define VGA_MODE 1 608c2ecf20Sopenharmony_ci {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 618c2ecf20Sopenharmony_ci .bytesperline = 640, 628c2ecf20Sopenharmony_ci .sizeimage = 640 * 480 * 3 / 8 + 590, 638c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_JPEG}, 648c2ecf20Sopenharmony_ci#define SVGA_MODE 2 658c2ecf20Sopenharmony_ci {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 668c2ecf20Sopenharmony_ci .bytesperline = 800, 678c2ecf20Sopenharmony_ci .sizeimage = 800 * 600 * 3 / 8 + 590, 688c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_JPEG}, 698c2ecf20Sopenharmony_ci#define XGA_MODE 3 708c2ecf20Sopenharmony_ci {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 718c2ecf20Sopenharmony_ci .bytesperline = 1024, 728c2ecf20Sopenharmony_ci .sizeimage = 1024 * 768 * 3 / 8 + 590, 738c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_JPEG}, 748c2ecf20Sopenharmony_ci#define SXGA_MODE 4 758c2ecf20Sopenharmony_ci {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 768c2ecf20Sopenharmony_ci .bytesperline = 1280, 778c2ecf20Sopenharmony_ci .sizeimage = 1280 * 1024 * 3 / 8 + 590, 788c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_JPEG}, 798c2ecf20Sopenharmony_ci}; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic const struct v4l2_pix_format ov971x_mode[] = { 828c2ecf20Sopenharmony_ci {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 838c2ecf20Sopenharmony_ci .bytesperline = 640, 848c2ecf20Sopenharmony_ci .sizeimage = 640 * 480, 858c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB 868c2ecf20Sopenharmony_ci } 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic const struct v4l2_pix_format ov562x_mode[] = { 908c2ecf20Sopenharmony_ci {2592, 1680, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 918c2ecf20Sopenharmony_ci .bytesperline = 2592, 928c2ecf20Sopenharmony_ci .sizeimage = 2592 * 1680, 938c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB 948c2ecf20Sopenharmony_ci } 958c2ecf20Sopenharmony_ci}; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_cienum ov361x { 988c2ecf20Sopenharmony_ci ov361x_2048 = 0, 998c2ecf20Sopenharmony_ci ov361x_1600, 1008c2ecf20Sopenharmony_ci ov361x_1024, 1018c2ecf20Sopenharmony_ci ov361x_640, 1028c2ecf20Sopenharmony_ci ov361x_320, 1038c2ecf20Sopenharmony_ci ov361x_160, 1048c2ecf20Sopenharmony_ci ov361x_last 1058c2ecf20Sopenharmony_ci}; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_cistatic const struct v4l2_pix_format ov361x_mode[] = { 1088c2ecf20Sopenharmony_ci {0x800, 0x600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 1098c2ecf20Sopenharmony_ci .bytesperline = 0x800, 1108c2ecf20Sopenharmony_ci .sizeimage = 0x800 * 0x600, 1118c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB}, 1128c2ecf20Sopenharmony_ci {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 1138c2ecf20Sopenharmony_ci .bytesperline = 1600, 1148c2ecf20Sopenharmony_ci .sizeimage = 1600 * 1200, 1158c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB}, 1168c2ecf20Sopenharmony_ci {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 1178c2ecf20Sopenharmony_ci .bytesperline = 768, 1188c2ecf20Sopenharmony_ci .sizeimage = 1024 * 768, 1198c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB}, 1208c2ecf20Sopenharmony_ci {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 1218c2ecf20Sopenharmony_ci .bytesperline = 640, 1228c2ecf20Sopenharmony_ci .sizeimage = 640 * 480, 1238c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB}, 1248c2ecf20Sopenharmony_ci {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 1258c2ecf20Sopenharmony_ci .bytesperline = 320, 1268c2ecf20Sopenharmony_ci .sizeimage = 320 * 240, 1278c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB}, 1288c2ecf20Sopenharmony_ci {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 1298c2ecf20Sopenharmony_ci .bytesperline = 160, 1308c2ecf20Sopenharmony_ci .sizeimage = 160 * 120, 1318c2ecf20Sopenharmony_ci .colorspace = V4L2_COLORSPACE_SRGB} 1328c2ecf20Sopenharmony_ci}; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic const u8 ov361x_start_2048[][2] = { 1358c2ecf20Sopenharmony_ci {0x12, 0x80}, 1368c2ecf20Sopenharmony_ci {0x13, 0xcf}, 1378c2ecf20Sopenharmony_ci {0x14, 0x40}, 1388c2ecf20Sopenharmony_ci {0x15, 0x00}, 1398c2ecf20Sopenharmony_ci {0x01, 0x80}, 1408c2ecf20Sopenharmony_ci {0x02, 0x80}, 1418c2ecf20Sopenharmony_ci {0x04, 0x70}, 1428c2ecf20Sopenharmony_ci {0x0d, 0x40}, 1438c2ecf20Sopenharmony_ci {0x0f, 0x47}, 1448c2ecf20Sopenharmony_ci {0x11, 0x81}, 1458c2ecf20Sopenharmony_ci {0x32, 0x36}, 1468c2ecf20Sopenharmony_ci {0x33, 0x0c}, 1478c2ecf20Sopenharmony_ci {0x34, 0x00}, 1488c2ecf20Sopenharmony_ci {0x35, 0x90}, 1498c2ecf20Sopenharmony_ci {0x12, 0x00}, 1508c2ecf20Sopenharmony_ci {0x17, 0x10}, 1518c2ecf20Sopenharmony_ci {0x18, 0x90}, 1528c2ecf20Sopenharmony_ci {0x19, 0x00}, 1538c2ecf20Sopenharmony_ci {0x1a, 0xc0}, 1548c2ecf20Sopenharmony_ci}; 1558c2ecf20Sopenharmony_cistatic const u8 ov361x_bridge_start_2048[][2] = { 1568c2ecf20Sopenharmony_ci {0xf1, 0x60}, 1578c2ecf20Sopenharmony_ci {0x88, 0x00}, 1588c2ecf20Sopenharmony_ci {0x89, 0x08}, 1598c2ecf20Sopenharmony_ci {0x8a, 0x00}, 1608c2ecf20Sopenharmony_ci {0x8b, 0x06}, 1618c2ecf20Sopenharmony_ci {0x8c, 0x01}, 1628c2ecf20Sopenharmony_ci {0x8d, 0x10}, 1638c2ecf20Sopenharmony_ci {0x1c, 0x00}, 1648c2ecf20Sopenharmony_ci {0x1d, 0x48}, 1658c2ecf20Sopenharmony_ci {0x1d, 0x00}, 1668c2ecf20Sopenharmony_ci {0x1d, 0xff}, 1678c2ecf20Sopenharmony_ci {0x1c, 0x0a}, 1688c2ecf20Sopenharmony_ci {0x1d, 0x2e}, 1698c2ecf20Sopenharmony_ci {0x1d, 0x1e}, 1708c2ecf20Sopenharmony_ci}; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_cistatic const u8 ov361x_start_1600[][2] = { 1738c2ecf20Sopenharmony_ci {0x12, 0x80}, 1748c2ecf20Sopenharmony_ci {0x13, 0xcf}, 1758c2ecf20Sopenharmony_ci {0x14, 0x40}, 1768c2ecf20Sopenharmony_ci {0x15, 0x00}, 1778c2ecf20Sopenharmony_ci {0x01, 0x80}, 1788c2ecf20Sopenharmony_ci {0x02, 0x80}, 1798c2ecf20Sopenharmony_ci {0x04, 0x70}, 1808c2ecf20Sopenharmony_ci {0x0d, 0x40}, 1818c2ecf20Sopenharmony_ci {0x0f, 0x47}, 1828c2ecf20Sopenharmony_ci {0x11, 0x81}, 1838c2ecf20Sopenharmony_ci {0x32, 0x36}, 1848c2ecf20Sopenharmony_ci {0x33, 0x0C}, 1858c2ecf20Sopenharmony_ci {0x34, 0x00}, 1868c2ecf20Sopenharmony_ci {0x35, 0x90}, 1878c2ecf20Sopenharmony_ci {0x12, 0x00}, 1888c2ecf20Sopenharmony_ci {0x17, 0x10}, 1898c2ecf20Sopenharmony_ci {0x18, 0x90}, 1908c2ecf20Sopenharmony_ci {0x19, 0x00}, 1918c2ecf20Sopenharmony_ci {0x1a, 0xc0}, 1928c2ecf20Sopenharmony_ci}; 1938c2ecf20Sopenharmony_cistatic const u8 ov361x_bridge_start_1600[][2] = { 1948c2ecf20Sopenharmony_ci {0xf1, 0x60}, /* Hsize[7:0] */ 1958c2ecf20Sopenharmony_ci {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 1968c2ecf20Sopenharmony_ci {0x89, 0x08}, /* Vsize[7:0] */ 1978c2ecf20Sopenharmony_ci {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 1988c2ecf20Sopenharmony_ci {0x8b, 0x06}, /* for Iso */ 1998c2ecf20Sopenharmony_ci {0x8c, 0x01}, /* RAW input */ 2008c2ecf20Sopenharmony_ci {0x8d, 0x10}, 2018c2ecf20Sopenharmony_ci {0x1c, 0x00}, /* RAW output, Iso transfer */ 2028c2ecf20Sopenharmony_ci {0x1d, 0x48}, 2038c2ecf20Sopenharmony_ci {0x1d, 0x00}, 2048c2ecf20Sopenharmony_ci {0x1d, 0xff}, 2058c2ecf20Sopenharmony_ci {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 2068c2ecf20Sopenharmony_ci {0x1d, 0x2e}, /* for Iso */ 2078c2ecf20Sopenharmony_ci {0x1d, 0x1e}, 2088c2ecf20Sopenharmony_ci}; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_cistatic const u8 ov361x_start_1024[][2] = { 2118c2ecf20Sopenharmony_ci {0x12, 0x80}, 2128c2ecf20Sopenharmony_ci {0x13, 0xcf}, 2138c2ecf20Sopenharmony_ci {0x14, 0x40}, 2148c2ecf20Sopenharmony_ci {0x15, 0x00}, 2158c2ecf20Sopenharmony_ci {0x01, 0x80}, 2168c2ecf20Sopenharmony_ci {0x02, 0x80}, 2178c2ecf20Sopenharmony_ci {0x04, 0x70}, 2188c2ecf20Sopenharmony_ci {0x0d, 0x40}, 2198c2ecf20Sopenharmony_ci {0x0f, 0x47}, 2208c2ecf20Sopenharmony_ci {0x11, 0x81}, 2218c2ecf20Sopenharmony_ci {0x32, 0x36}, 2228c2ecf20Sopenharmony_ci {0x33, 0x0C}, 2238c2ecf20Sopenharmony_ci {0x34, 0x00}, 2248c2ecf20Sopenharmony_ci {0x35, 0x90}, 2258c2ecf20Sopenharmony_ci {0x12, 0x40}, 2268c2ecf20Sopenharmony_ci {0x17, 0x1f}, 2278c2ecf20Sopenharmony_ci {0x18, 0x5f}, 2288c2ecf20Sopenharmony_ci {0x19, 0x00}, 2298c2ecf20Sopenharmony_ci {0x1a, 0x68}, 2308c2ecf20Sopenharmony_ci}; 2318c2ecf20Sopenharmony_cistatic const u8 ov361x_bridge_start_1024[][2] = { 2328c2ecf20Sopenharmony_ci {0xf1, 0x60}, /* Hsize[7:0] */ 2338c2ecf20Sopenharmony_ci {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 2348c2ecf20Sopenharmony_ci {0x89, 0x04}, /* Vsize[7:0] */ 2358c2ecf20Sopenharmony_ci {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 2368c2ecf20Sopenharmony_ci {0x8b, 0x03}, /* for Iso */ 2378c2ecf20Sopenharmony_ci {0x8c, 0x01}, /* RAW input */ 2388c2ecf20Sopenharmony_ci {0x8d, 0x10}, 2398c2ecf20Sopenharmony_ci {0x1c, 0x00}, /* RAW output, Iso transfer */ 2408c2ecf20Sopenharmony_ci {0x1d, 0x48}, 2418c2ecf20Sopenharmony_ci {0x1d, 0x00}, 2428c2ecf20Sopenharmony_ci {0x1d, 0xff}, 2438c2ecf20Sopenharmony_ci {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 2448c2ecf20Sopenharmony_ci {0x1d, 0x2e}, /* for Iso */ 2458c2ecf20Sopenharmony_ci {0x1d, 0x1e}, 2468c2ecf20Sopenharmony_ci}; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_cistatic const u8 ov361x_start_640[][2] = { 2498c2ecf20Sopenharmony_ci {0x12, 0x80}, 2508c2ecf20Sopenharmony_ci {0x13, 0xcf}, 2518c2ecf20Sopenharmony_ci {0x14, 0x40}, 2528c2ecf20Sopenharmony_ci {0x15, 0x00}, 2538c2ecf20Sopenharmony_ci {0x01, 0x80}, 2548c2ecf20Sopenharmony_ci {0x02, 0x80}, 2558c2ecf20Sopenharmony_ci {0x04, 0x70}, 2568c2ecf20Sopenharmony_ci {0x0d, 0x40}, 2578c2ecf20Sopenharmony_ci {0x0f, 0x47}, 2588c2ecf20Sopenharmony_ci {0x11, 0x81}, 2598c2ecf20Sopenharmony_ci {0x32, 0x36}, 2608c2ecf20Sopenharmony_ci {0x33, 0x0C}, 2618c2ecf20Sopenharmony_ci {0x34, 0x00}, 2628c2ecf20Sopenharmony_ci {0x35, 0x90}, 2638c2ecf20Sopenharmony_ci {0x12, 0x40}, 2648c2ecf20Sopenharmony_ci {0x17, 0x1f}, 2658c2ecf20Sopenharmony_ci {0x18, 0x5f}, 2668c2ecf20Sopenharmony_ci {0x19, 0x00}, 2678c2ecf20Sopenharmony_ci {0x1a, 0x68}, 2688c2ecf20Sopenharmony_ci}; 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_cistatic const u8 ov361x_bridge_start_640[][2] = { 2718c2ecf20Sopenharmony_ci {0xf1, 0x60}, /* Hsize[7:0]*/ 2728c2ecf20Sopenharmony_ci {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 2738c2ecf20Sopenharmony_ci {0x89, 0x04}, /* Vsize[7:0] */ 2748c2ecf20Sopenharmony_ci {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 2758c2ecf20Sopenharmony_ci {0x8b, 0x03}, /* for Iso */ 2768c2ecf20Sopenharmony_ci {0x8c, 0x01}, /* RAW input */ 2778c2ecf20Sopenharmony_ci {0x8d, 0x10}, 2788c2ecf20Sopenharmony_ci {0x1c, 0x00}, /* RAW output, Iso transfer */ 2798c2ecf20Sopenharmony_ci {0x1d, 0x48}, 2808c2ecf20Sopenharmony_ci {0x1d, 0x00}, 2818c2ecf20Sopenharmony_ci {0x1d, 0xff}, 2828c2ecf20Sopenharmony_ci {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 2838c2ecf20Sopenharmony_ci {0x1d, 0x2e}, /* for Iso */ 2848c2ecf20Sopenharmony_ci {0x1d, 0x1e}, 2858c2ecf20Sopenharmony_ci}; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_cistatic const u8 ov361x_start_320[][2] = { 2888c2ecf20Sopenharmony_ci {0x12, 0x80}, 2898c2ecf20Sopenharmony_ci {0x13, 0xcf}, 2908c2ecf20Sopenharmony_ci {0x14, 0x40}, 2918c2ecf20Sopenharmony_ci {0x15, 0x00}, 2928c2ecf20Sopenharmony_ci {0x01, 0x80}, 2938c2ecf20Sopenharmony_ci {0x02, 0x80}, 2948c2ecf20Sopenharmony_ci {0x04, 0x70}, 2958c2ecf20Sopenharmony_ci {0x0d, 0x40}, 2968c2ecf20Sopenharmony_ci {0x0f, 0x47}, 2978c2ecf20Sopenharmony_ci {0x11, 0x81}, 2988c2ecf20Sopenharmony_ci {0x32, 0x36}, 2998c2ecf20Sopenharmony_ci {0x33, 0x0C}, 3008c2ecf20Sopenharmony_ci {0x34, 0x00}, 3018c2ecf20Sopenharmony_ci {0x35, 0x90}, 3028c2ecf20Sopenharmony_ci {0x12, 0x40}, 3038c2ecf20Sopenharmony_ci {0x17, 0x1f}, 3048c2ecf20Sopenharmony_ci {0x18, 0x5f}, 3058c2ecf20Sopenharmony_ci {0x19, 0x00}, 3068c2ecf20Sopenharmony_ci {0x1a, 0x68}, 3078c2ecf20Sopenharmony_ci}; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_cistatic const u8 ov361x_bridge_start_320[][2] = { 3108c2ecf20Sopenharmony_ci {0xf1, 0x60}, /* Hsize[7:0] */ 3118c2ecf20Sopenharmony_ci {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 3128c2ecf20Sopenharmony_ci {0x89, 0x04}, /* Vsize[7:0] */ 3138c2ecf20Sopenharmony_ci {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 3148c2ecf20Sopenharmony_ci {0x8b, 0x03}, /* for Iso */ 3158c2ecf20Sopenharmony_ci {0x8c, 0x01}, /* RAW input */ 3168c2ecf20Sopenharmony_ci {0x8d, 0x10}, 3178c2ecf20Sopenharmony_ci {0x1c, 0x00}, /* RAW output, Iso transfer; */ 3188c2ecf20Sopenharmony_ci {0x1d, 0x48}, 3198c2ecf20Sopenharmony_ci {0x1d, 0x00}, 3208c2ecf20Sopenharmony_ci {0x1d, 0xff}, 3218c2ecf20Sopenharmony_ci {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 3228c2ecf20Sopenharmony_ci {0x1d, 0x2e}, /* for Iso */ 3238c2ecf20Sopenharmony_ci {0x1d, 0x1e}, 3248c2ecf20Sopenharmony_ci}; 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_cistatic const u8 ov361x_start_160[][2] = { 3278c2ecf20Sopenharmony_ci {0x12, 0x80}, 3288c2ecf20Sopenharmony_ci {0x13, 0xcf}, 3298c2ecf20Sopenharmony_ci {0x14, 0x40}, 3308c2ecf20Sopenharmony_ci {0x15, 0x00}, 3318c2ecf20Sopenharmony_ci {0x01, 0x80}, 3328c2ecf20Sopenharmony_ci {0x02, 0x80}, 3338c2ecf20Sopenharmony_ci {0x04, 0x70}, 3348c2ecf20Sopenharmony_ci {0x0d, 0x40}, 3358c2ecf20Sopenharmony_ci {0x0f, 0x47}, 3368c2ecf20Sopenharmony_ci {0x11, 0x81}, 3378c2ecf20Sopenharmony_ci {0x32, 0x36}, 3388c2ecf20Sopenharmony_ci {0x33, 0x0C}, 3398c2ecf20Sopenharmony_ci {0x34, 0x00}, 3408c2ecf20Sopenharmony_ci {0x35, 0x90}, 3418c2ecf20Sopenharmony_ci {0x12, 0x40}, 3428c2ecf20Sopenharmony_ci {0x17, 0x1f}, 3438c2ecf20Sopenharmony_ci {0x18, 0x5f}, 3448c2ecf20Sopenharmony_ci {0x19, 0x00}, 3458c2ecf20Sopenharmony_ci {0x1a, 0x68}, 3468c2ecf20Sopenharmony_ci}; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_cistatic const u8 ov361x_bridge_start_160[][2] = { 3498c2ecf20Sopenharmony_ci {0xf1, 0x60}, /* Hsize[7:0] */ 3508c2ecf20Sopenharmony_ci {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 3518c2ecf20Sopenharmony_ci {0x89, 0x04}, /* Vsize[7:0] */ 3528c2ecf20Sopenharmony_ci {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 3538c2ecf20Sopenharmony_ci {0x8b, 0x03}, /* for Iso */ 3548c2ecf20Sopenharmony_ci {0x8c, 0x01}, /* RAW input */ 3558c2ecf20Sopenharmony_ci {0x8d, 0x10}, 3568c2ecf20Sopenharmony_ci {0x1c, 0x00}, /* RAW output, Iso transfer */ 3578c2ecf20Sopenharmony_ci {0x1d, 0x48}, 3588c2ecf20Sopenharmony_ci {0x1d, 0x00}, 3598c2ecf20Sopenharmony_ci {0x1d, 0xff}, 3608c2ecf20Sopenharmony_ci {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 3618c2ecf20Sopenharmony_ci {0x1d, 0x2e}, /* for Iso */ 3628c2ecf20Sopenharmony_ci {0x1d, 0x1e}, 3638c2ecf20Sopenharmony_ci}; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_cistatic const u8 bridge_init[][2] = { 3668c2ecf20Sopenharmony_ci {0x88, 0xf8}, 3678c2ecf20Sopenharmony_ci {0x89, 0xff}, 3688c2ecf20Sopenharmony_ci {0x76, 0x03}, 3698c2ecf20Sopenharmony_ci {0x92, 0x03}, 3708c2ecf20Sopenharmony_ci {0x95, 0x10}, 3718c2ecf20Sopenharmony_ci {0xe2, 0x00}, 3728c2ecf20Sopenharmony_ci {0xe7, 0x3e}, 3738c2ecf20Sopenharmony_ci {0x8d, 0x1c}, 3748c2ecf20Sopenharmony_ci {0x8e, 0x00}, 3758c2ecf20Sopenharmony_ci {0x8f, 0x00}, 3768c2ecf20Sopenharmony_ci {0x1f, 0x00}, 3778c2ecf20Sopenharmony_ci {0xc3, 0xf9}, 3788c2ecf20Sopenharmony_ci {0x89, 0xff}, 3798c2ecf20Sopenharmony_ci {0x88, 0xf8}, 3808c2ecf20Sopenharmony_ci {0x76, 0x03}, 3818c2ecf20Sopenharmony_ci {0x92, 0x01}, 3828c2ecf20Sopenharmony_ci {0x93, 0x18}, 3838c2ecf20Sopenharmony_ci {0x1c, 0x0a}, 3848c2ecf20Sopenharmony_ci {0x1d, 0x48}, 3858c2ecf20Sopenharmony_ci {0xc0, 0x50}, 3868c2ecf20Sopenharmony_ci {0xc1, 0x3c}, 3878c2ecf20Sopenharmony_ci {0x34, 0x05}, 3888c2ecf20Sopenharmony_ci {0xc2, 0x0c}, 3898c2ecf20Sopenharmony_ci {0xc3, 0xf9}, 3908c2ecf20Sopenharmony_ci {0x34, 0x05}, 3918c2ecf20Sopenharmony_ci {0xe7, 0x2e}, 3928c2ecf20Sopenharmony_ci {0x31, 0xf9}, 3938c2ecf20Sopenharmony_ci {0x35, 0x02}, 3948c2ecf20Sopenharmony_ci {0xd9, 0x10}, 3958c2ecf20Sopenharmony_ci {0x25, 0x42}, 3968c2ecf20Sopenharmony_ci {0x94, 0x11}, 3978c2ecf20Sopenharmony_ci}; 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_cistatic const u8 ov965x_init[][2] = { 4008c2ecf20Sopenharmony_ci {0x12, 0x80}, /* com7 - SSCB reset */ 4018c2ecf20Sopenharmony_ci {0x00, 0x00}, /* gain */ 4028c2ecf20Sopenharmony_ci {0x01, 0x80}, /* blue */ 4038c2ecf20Sopenharmony_ci {0x02, 0x80}, /* red */ 4048c2ecf20Sopenharmony_ci {0x03, 0x1b}, /* vref */ 4058c2ecf20Sopenharmony_ci {0x04, 0x03}, /* com1 - exposure low bits */ 4068c2ecf20Sopenharmony_ci {0x0b, 0x57}, /* ver */ 4078c2ecf20Sopenharmony_ci {0x0e, 0x61}, /* com5 */ 4088c2ecf20Sopenharmony_ci {0x0f, 0x42}, /* com6 */ 4098c2ecf20Sopenharmony_ci {0x11, 0x00}, /* clkrc */ 4108c2ecf20Sopenharmony_ci {0x12, 0x02}, /* com7 - 15fps VGA YUYV */ 4118c2ecf20Sopenharmony_ci {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 4128c2ecf20Sopenharmony_ci {0x14, 0x28}, /* com9 */ 4138c2ecf20Sopenharmony_ci {0x16, 0x24}, /* reg16 */ 4148c2ecf20Sopenharmony_ci {0x17, 0x1d}, /* hstart*/ 4158c2ecf20Sopenharmony_ci {0x18, 0xbd}, /* hstop */ 4168c2ecf20Sopenharmony_ci {0x19, 0x01}, /* vstrt */ 4178c2ecf20Sopenharmony_ci {0x1a, 0x81}, /* vstop*/ 4188c2ecf20Sopenharmony_ci {0x1e, 0x04}, /* mvfp */ 4198c2ecf20Sopenharmony_ci {0x24, 0x3c}, /* aew */ 4208c2ecf20Sopenharmony_ci {0x25, 0x36}, /* aeb */ 4218c2ecf20Sopenharmony_ci {0x26, 0x71}, /* vpt */ 4228c2ecf20Sopenharmony_ci {0x27, 0x08}, /* bbias */ 4238c2ecf20Sopenharmony_ci {0x28, 0x08}, /* gbbias */ 4248c2ecf20Sopenharmony_ci {0x29, 0x15}, /* gr com */ 4258c2ecf20Sopenharmony_ci {0x2a, 0x00}, /* exhch */ 4268c2ecf20Sopenharmony_ci {0x2b, 0x00}, /* exhcl */ 4278c2ecf20Sopenharmony_ci {0x2c, 0x08}, /* rbias */ 4288c2ecf20Sopenharmony_ci {0x32, 0xff}, /* href */ 4298c2ecf20Sopenharmony_ci {0x33, 0x00}, /* chlf */ 4308c2ecf20Sopenharmony_ci {0x34, 0x3f}, /* aref1 */ 4318c2ecf20Sopenharmony_ci {0x35, 0x00}, /* aref2 */ 4328c2ecf20Sopenharmony_ci {0x36, 0xf8}, /* aref3 */ 4338c2ecf20Sopenharmony_ci {0x38, 0x72}, /* adc2 */ 4348c2ecf20Sopenharmony_ci {0x39, 0x57}, /* aref4 */ 4358c2ecf20Sopenharmony_ci {0x3a, 0x80}, /* tslb - yuyv */ 4368c2ecf20Sopenharmony_ci {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 4378c2ecf20Sopenharmony_ci {0x3d, 0x99}, /* com13 */ 4388c2ecf20Sopenharmony_ci {0x3f, 0xc1}, /* edge */ 4398c2ecf20Sopenharmony_ci {0x40, 0xc0}, /* com15 */ 4408c2ecf20Sopenharmony_ci {0x41, 0x40}, /* com16 */ 4418c2ecf20Sopenharmony_ci {0x42, 0xc0}, /* com17 */ 4428c2ecf20Sopenharmony_ci {0x43, 0x0a}, /* rsvd */ 4438c2ecf20Sopenharmony_ci {0x44, 0xf0}, 4448c2ecf20Sopenharmony_ci {0x45, 0x46}, 4458c2ecf20Sopenharmony_ci {0x46, 0x62}, 4468c2ecf20Sopenharmony_ci {0x47, 0x2a}, 4478c2ecf20Sopenharmony_ci {0x48, 0x3c}, 4488c2ecf20Sopenharmony_ci {0x4a, 0xfc}, 4498c2ecf20Sopenharmony_ci {0x4b, 0xfc}, 4508c2ecf20Sopenharmony_ci {0x4c, 0x7f}, 4518c2ecf20Sopenharmony_ci {0x4d, 0x7f}, 4528c2ecf20Sopenharmony_ci {0x4e, 0x7f}, 4538c2ecf20Sopenharmony_ci {0x4f, 0x98}, /* matrix */ 4548c2ecf20Sopenharmony_ci {0x50, 0x98}, 4558c2ecf20Sopenharmony_ci {0x51, 0x00}, 4568c2ecf20Sopenharmony_ci {0x52, 0x28}, 4578c2ecf20Sopenharmony_ci {0x53, 0x70}, 4588c2ecf20Sopenharmony_ci {0x54, 0x98}, 4598c2ecf20Sopenharmony_ci {0x58, 0x1a}, /* matrix coef sign */ 4608c2ecf20Sopenharmony_ci {0x59, 0x85}, /* AWB control */ 4618c2ecf20Sopenharmony_ci {0x5a, 0xa9}, 4628c2ecf20Sopenharmony_ci {0x5b, 0x64}, 4638c2ecf20Sopenharmony_ci {0x5c, 0x84}, 4648c2ecf20Sopenharmony_ci {0x5d, 0x53}, 4658c2ecf20Sopenharmony_ci {0x5e, 0x0e}, 4668c2ecf20Sopenharmony_ci {0x5f, 0xf0}, /* AWB blue limit */ 4678c2ecf20Sopenharmony_ci {0x60, 0xf0}, /* AWB red limit */ 4688c2ecf20Sopenharmony_ci {0x61, 0xf0}, /* AWB green limit */ 4698c2ecf20Sopenharmony_ci {0x62, 0x00}, /* lcc1 */ 4708c2ecf20Sopenharmony_ci {0x63, 0x00}, /* lcc2 */ 4718c2ecf20Sopenharmony_ci {0x64, 0x02}, /* lcc3 */ 4728c2ecf20Sopenharmony_ci {0x65, 0x16}, /* lcc4 */ 4738c2ecf20Sopenharmony_ci {0x66, 0x01}, /* lcc5 */ 4748c2ecf20Sopenharmony_ci {0x69, 0x02}, /* hv */ 4758c2ecf20Sopenharmony_ci {0x6b, 0x5a}, /* dbvl */ 4768c2ecf20Sopenharmony_ci {0x6c, 0x04}, 4778c2ecf20Sopenharmony_ci {0x6d, 0x55}, 4788c2ecf20Sopenharmony_ci {0x6e, 0x00}, 4798c2ecf20Sopenharmony_ci {0x6f, 0x9d}, 4808c2ecf20Sopenharmony_ci {0x70, 0x21}, /* dnsth */ 4818c2ecf20Sopenharmony_ci {0x71, 0x78}, 4828c2ecf20Sopenharmony_ci {0x72, 0x00}, /* poidx */ 4838c2ecf20Sopenharmony_ci {0x73, 0x01}, /* pckdv */ 4848c2ecf20Sopenharmony_ci {0x74, 0x3a}, /* xindx */ 4858c2ecf20Sopenharmony_ci {0x75, 0x35}, /* yindx */ 4868c2ecf20Sopenharmony_ci {0x76, 0x01}, 4878c2ecf20Sopenharmony_ci {0x77, 0x02}, 4888c2ecf20Sopenharmony_ci {0x7a, 0x12}, /* gamma curve */ 4898c2ecf20Sopenharmony_ci {0x7b, 0x08}, 4908c2ecf20Sopenharmony_ci {0x7c, 0x16}, 4918c2ecf20Sopenharmony_ci {0x7d, 0x30}, 4928c2ecf20Sopenharmony_ci {0x7e, 0x5e}, 4938c2ecf20Sopenharmony_ci {0x7f, 0x72}, 4948c2ecf20Sopenharmony_ci {0x80, 0x82}, 4958c2ecf20Sopenharmony_ci {0x81, 0x8e}, 4968c2ecf20Sopenharmony_ci {0x82, 0x9a}, 4978c2ecf20Sopenharmony_ci {0x83, 0xa4}, 4988c2ecf20Sopenharmony_ci {0x84, 0xac}, 4998c2ecf20Sopenharmony_ci {0x85, 0xb8}, 5008c2ecf20Sopenharmony_ci {0x86, 0xc3}, 5018c2ecf20Sopenharmony_ci {0x87, 0xd6}, 5028c2ecf20Sopenharmony_ci {0x88, 0xe6}, 5038c2ecf20Sopenharmony_ci {0x89, 0xf2}, 5048c2ecf20Sopenharmony_ci {0x8a, 0x03}, 5058c2ecf20Sopenharmony_ci {0x8c, 0x89}, /* com19 */ 5068c2ecf20Sopenharmony_ci {0x14, 0x28}, /* com9 */ 5078c2ecf20Sopenharmony_ci {0x90, 0x7d}, 5088c2ecf20Sopenharmony_ci {0x91, 0x7b}, 5098c2ecf20Sopenharmony_ci {0x9d, 0x03}, /* lcc6 */ 5108c2ecf20Sopenharmony_ci {0x9e, 0x04}, /* lcc7 */ 5118c2ecf20Sopenharmony_ci {0x9f, 0x7a}, 5128c2ecf20Sopenharmony_ci {0xa0, 0x79}, 5138c2ecf20Sopenharmony_ci {0xa1, 0x40}, /* aechm */ 5148c2ecf20Sopenharmony_ci {0xa4, 0x50}, /* com21 */ 5158c2ecf20Sopenharmony_ci {0xa5, 0x68}, /* com26 */ 5168c2ecf20Sopenharmony_ci {0xa6, 0x4a}, /* AWB green */ 5178c2ecf20Sopenharmony_ci {0xa8, 0xc1}, /* refa8 */ 5188c2ecf20Sopenharmony_ci {0xa9, 0xef}, /* refa9 */ 5198c2ecf20Sopenharmony_ci {0xaa, 0x92}, 5208c2ecf20Sopenharmony_ci {0xab, 0x04}, 5218c2ecf20Sopenharmony_ci {0xac, 0x80}, /* black level control */ 5228c2ecf20Sopenharmony_ci {0xad, 0x80}, 5238c2ecf20Sopenharmony_ci {0xae, 0x80}, 5248c2ecf20Sopenharmony_ci {0xaf, 0x80}, 5258c2ecf20Sopenharmony_ci {0xb2, 0xf2}, 5268c2ecf20Sopenharmony_ci {0xb3, 0x20}, 5278c2ecf20Sopenharmony_ci {0xb4, 0x20}, /* ctrlb4 */ 5288c2ecf20Sopenharmony_ci {0xb5, 0x00}, 5298c2ecf20Sopenharmony_ci {0xb6, 0xaf}, 5308c2ecf20Sopenharmony_ci {0xbb, 0xae}, 5318c2ecf20Sopenharmony_ci {0xbc, 0x7f}, /* ADC channel offsets */ 5328c2ecf20Sopenharmony_ci {0xdb, 0x7f}, 5338c2ecf20Sopenharmony_ci {0xbe, 0x7f}, 5348c2ecf20Sopenharmony_ci {0xbf, 0x7f}, 5358c2ecf20Sopenharmony_ci {0xc0, 0xe2}, 5368c2ecf20Sopenharmony_ci {0xc1, 0xc0}, 5378c2ecf20Sopenharmony_ci {0xc2, 0x01}, 5388c2ecf20Sopenharmony_ci {0xc3, 0x4e}, 5398c2ecf20Sopenharmony_ci {0xc6, 0x85}, 5408c2ecf20Sopenharmony_ci {0xc7, 0x80}, /* com24 */ 5418c2ecf20Sopenharmony_ci {0xc9, 0xe0}, 5428c2ecf20Sopenharmony_ci {0xca, 0xe8}, 5438c2ecf20Sopenharmony_ci {0xcb, 0xf0}, 5448c2ecf20Sopenharmony_ci {0xcc, 0xd8}, 5458c2ecf20Sopenharmony_ci {0xcd, 0xf1}, 5468c2ecf20Sopenharmony_ci {0x4f, 0x98}, /* matrix */ 5478c2ecf20Sopenharmony_ci {0x50, 0x98}, 5488c2ecf20Sopenharmony_ci {0x51, 0x00}, 5498c2ecf20Sopenharmony_ci {0x52, 0x28}, 5508c2ecf20Sopenharmony_ci {0x53, 0x70}, 5518c2ecf20Sopenharmony_ci {0x54, 0x98}, 5528c2ecf20Sopenharmony_ci {0x58, 0x1a}, 5538c2ecf20Sopenharmony_ci {0xff, 0x41}, /* read 41, write ff 00 */ 5548c2ecf20Sopenharmony_ci {0x41, 0x40}, /* com16 */ 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci {0xc5, 0x03}, /* 60 Hz banding filter */ 5578c2ecf20Sopenharmony_ci {0x6a, 0x02}, /* 50 Hz banding filter */ 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_ci {0x12, 0x62}, /* com7 - 30fps VGA YUV */ 5608c2ecf20Sopenharmony_ci {0x36, 0xfa}, /* aref3 */ 5618c2ecf20Sopenharmony_ci {0x69, 0x0a}, /* hv */ 5628c2ecf20Sopenharmony_ci {0x8c, 0x89}, /* com22 */ 5638c2ecf20Sopenharmony_ci {0x14, 0x28}, /* com9 */ 5648c2ecf20Sopenharmony_ci {0x3e, 0x0c}, 5658c2ecf20Sopenharmony_ci {0x41, 0x40}, /* com16 */ 5668c2ecf20Sopenharmony_ci {0x72, 0x00}, 5678c2ecf20Sopenharmony_ci {0x73, 0x00}, 5688c2ecf20Sopenharmony_ci {0x74, 0x3a}, 5698c2ecf20Sopenharmony_ci {0x75, 0x35}, 5708c2ecf20Sopenharmony_ci {0x76, 0x01}, 5718c2ecf20Sopenharmony_ci {0xc7, 0x80}, 5728c2ecf20Sopenharmony_ci {0x03, 0x12}, /* vref */ 5738c2ecf20Sopenharmony_ci {0x17, 0x16}, /* hstart */ 5748c2ecf20Sopenharmony_ci {0x18, 0x02}, /* hstop */ 5758c2ecf20Sopenharmony_ci {0x19, 0x01}, /* vstrt */ 5768c2ecf20Sopenharmony_ci {0x1a, 0x3d}, /* vstop */ 5778c2ecf20Sopenharmony_ci {0x32, 0xff}, /* href */ 5788c2ecf20Sopenharmony_ci {0xc0, 0xaa}, 5798c2ecf20Sopenharmony_ci}; 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_cistatic const u8 bridge_init_2[][2] = { 5828c2ecf20Sopenharmony_ci {0x94, 0xaa}, 5838c2ecf20Sopenharmony_ci {0xf1, 0x60}, 5848c2ecf20Sopenharmony_ci {0xe5, 0x04}, 5858c2ecf20Sopenharmony_ci {0xc0, 0x50}, 5868c2ecf20Sopenharmony_ci {0xc1, 0x3c}, 5878c2ecf20Sopenharmony_ci {0x8c, 0x00}, 5888c2ecf20Sopenharmony_ci {0x8d, 0x1c}, 5898c2ecf20Sopenharmony_ci {0x34, 0x05}, 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci {0xc2, 0x0c}, 5928c2ecf20Sopenharmony_ci {0xc3, 0xf9}, 5938c2ecf20Sopenharmony_ci {0xda, 0x01}, 5948c2ecf20Sopenharmony_ci {0x50, 0x00}, 5958c2ecf20Sopenharmony_ci {0x51, 0xa0}, 5968c2ecf20Sopenharmony_ci {0x52, 0x3c}, 5978c2ecf20Sopenharmony_ci {0x53, 0x00}, 5988c2ecf20Sopenharmony_ci {0x54, 0x00}, 5998c2ecf20Sopenharmony_ci {0x55, 0x00}, 6008c2ecf20Sopenharmony_ci {0x57, 0x00}, 6018c2ecf20Sopenharmony_ci {0x5c, 0x00}, 6028c2ecf20Sopenharmony_ci {0x5a, 0xa0}, 6038c2ecf20Sopenharmony_ci {0x5b, 0x78}, 6048c2ecf20Sopenharmony_ci {0x35, 0x02}, 6058c2ecf20Sopenharmony_ci {0xd9, 0x10}, 6068c2ecf20Sopenharmony_ci {0x94, 0x11}, 6078c2ecf20Sopenharmony_ci}; 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_cistatic const u8 ov965x_init_2[][2] = { 6108c2ecf20Sopenharmony_ci {0x3b, 0xc4}, 6118c2ecf20Sopenharmony_ci {0x1e, 0x04}, /* mvfp */ 6128c2ecf20Sopenharmony_ci {0x13, 0xe0}, /* com8 */ 6138c2ecf20Sopenharmony_ci {0x00, 0x00}, /* gain */ 6148c2ecf20Sopenharmony_ci {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 6158c2ecf20Sopenharmony_ci {0x11, 0x03}, /* clkrc */ 6168c2ecf20Sopenharmony_ci {0x6b, 0x5a}, /* dblv */ 6178c2ecf20Sopenharmony_ci {0x6a, 0x05}, 6188c2ecf20Sopenharmony_ci {0xc5, 0x07}, 6198c2ecf20Sopenharmony_ci {0xa2, 0x4b}, 6208c2ecf20Sopenharmony_ci {0xa3, 0x3e}, 6218c2ecf20Sopenharmony_ci {0x2d, 0x00}, 6228c2ecf20Sopenharmony_ci {0xff, 0x42}, /* read 42, write ff 00 */ 6238c2ecf20Sopenharmony_ci {0x42, 0xc0}, /* com17 */ 6248c2ecf20Sopenharmony_ci {0x2d, 0x00}, 6258c2ecf20Sopenharmony_ci {0xff, 0x42}, /* read 42, write ff 00 */ 6268c2ecf20Sopenharmony_ci {0x42, 0xc1}, /* com17 */ 6278c2ecf20Sopenharmony_ci/* sharpness */ 6288c2ecf20Sopenharmony_ci {0x3f, 0x01}, 6298c2ecf20Sopenharmony_ci {0xff, 0x42}, /* read 42, write ff 00 */ 6308c2ecf20Sopenharmony_ci {0x42, 0xc1}, /* com17 */ 6318c2ecf20Sopenharmony_ci/* saturation */ 6328c2ecf20Sopenharmony_ci {0x4f, 0x98}, /* matrix */ 6338c2ecf20Sopenharmony_ci {0x50, 0x98}, 6348c2ecf20Sopenharmony_ci {0x51, 0x00}, 6358c2ecf20Sopenharmony_ci {0x52, 0x28}, 6368c2ecf20Sopenharmony_ci {0x53, 0x70}, 6378c2ecf20Sopenharmony_ci {0x54, 0x98}, 6388c2ecf20Sopenharmony_ci {0x58, 0x1a}, 6398c2ecf20Sopenharmony_ci {0xff, 0x41}, /* read 41, write ff 00 */ 6408c2ecf20Sopenharmony_ci {0x41, 0x40}, /* com16 */ 6418c2ecf20Sopenharmony_ci/* contrast */ 6428c2ecf20Sopenharmony_ci {0x56, 0x40}, 6438c2ecf20Sopenharmony_ci/* brightness */ 6448c2ecf20Sopenharmony_ci {0x55, 0x8f}, 6458c2ecf20Sopenharmony_ci/* expo */ 6468c2ecf20Sopenharmony_ci {0x10, 0x25}, /* aech - exposure high bits */ 6478c2ecf20Sopenharmony_ci {0xff, 0x13}, /* read 13, write ff 00 */ 6488c2ecf20Sopenharmony_ci {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 6498c2ecf20Sopenharmony_ci}; 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_cistatic const u8 ov971x_init[][2] = { 6528c2ecf20Sopenharmony_ci {0x12, 0x80}, 6538c2ecf20Sopenharmony_ci {0x09, 0x10}, 6548c2ecf20Sopenharmony_ci {0x1e, 0x07}, 6558c2ecf20Sopenharmony_ci {0x5f, 0x18}, 6568c2ecf20Sopenharmony_ci {0x69, 0x04}, 6578c2ecf20Sopenharmony_ci {0x65, 0x2a}, 6588c2ecf20Sopenharmony_ci {0x68, 0x0a}, 6598c2ecf20Sopenharmony_ci {0x39, 0x28}, 6608c2ecf20Sopenharmony_ci {0x4d, 0x90}, 6618c2ecf20Sopenharmony_ci {0xc1, 0x80}, 6628c2ecf20Sopenharmony_ci {0x0c, 0x30}, 6638c2ecf20Sopenharmony_ci {0x6d, 0x02}, 6648c2ecf20Sopenharmony_ci {0x96, 0xf1}, 6658c2ecf20Sopenharmony_ci {0xbc, 0x68}, 6668c2ecf20Sopenharmony_ci {0x12, 0x00}, 6678c2ecf20Sopenharmony_ci {0x3b, 0x00}, 6688c2ecf20Sopenharmony_ci {0x97, 0x80}, 6698c2ecf20Sopenharmony_ci {0x17, 0x25}, 6708c2ecf20Sopenharmony_ci {0x18, 0xa2}, 6718c2ecf20Sopenharmony_ci {0x19, 0x01}, 6728c2ecf20Sopenharmony_ci {0x1a, 0xca}, 6738c2ecf20Sopenharmony_ci {0x03, 0x0a}, 6748c2ecf20Sopenharmony_ci {0x32, 0x07}, 6758c2ecf20Sopenharmony_ci {0x98, 0x40}, /*{0x98, 0x00},*/ 6768c2ecf20Sopenharmony_ci {0x99, 0xA0}, /*{0x99, 0x00},*/ 6778c2ecf20Sopenharmony_ci {0x9a, 0x01}, /*{0x9a, 0x00},*/ 6788c2ecf20Sopenharmony_ci {0x57, 0x00}, 6798c2ecf20Sopenharmony_ci {0x58, 0x78}, /*{0x58, 0xc8},*/ 6808c2ecf20Sopenharmony_ci {0x59, 0x50}, /*{0x59, 0xa0},*/ 6818c2ecf20Sopenharmony_ci {0x4c, 0x13}, 6828c2ecf20Sopenharmony_ci {0x4b, 0x36}, 6838c2ecf20Sopenharmony_ci {0x3d, 0x3c}, 6848c2ecf20Sopenharmony_ci {0x3e, 0x03}, 6858c2ecf20Sopenharmony_ci {0xbd, 0x50}, /*{0xbd, 0xa0},*/ 6868c2ecf20Sopenharmony_ci {0xbe, 0x78}, /*{0xbe, 0xc8},*/ 6878c2ecf20Sopenharmony_ci {0x4e, 0x55}, 6888c2ecf20Sopenharmony_ci {0x4f, 0x55}, 6898c2ecf20Sopenharmony_ci {0x50, 0x55}, 6908c2ecf20Sopenharmony_ci {0x51, 0x55}, 6918c2ecf20Sopenharmony_ci {0x24, 0x55}, 6928c2ecf20Sopenharmony_ci {0x25, 0x40}, 6938c2ecf20Sopenharmony_ci {0x26, 0xa1}, 6948c2ecf20Sopenharmony_ci {0x5c, 0x59}, 6958c2ecf20Sopenharmony_ci {0x5d, 0x00}, 6968c2ecf20Sopenharmony_ci {0x11, 0x00}, 6978c2ecf20Sopenharmony_ci {0x2a, 0x98}, 6988c2ecf20Sopenharmony_ci {0x2b, 0x06}, 6998c2ecf20Sopenharmony_ci {0x2d, 0x00}, 7008c2ecf20Sopenharmony_ci {0x2e, 0x00}, 7018c2ecf20Sopenharmony_ci {0x13, 0xa5}, 7028c2ecf20Sopenharmony_ci {0x14, 0x40}, 7038c2ecf20Sopenharmony_ci {0x4a, 0x00}, 7048c2ecf20Sopenharmony_ci {0x49, 0xce}, 7058c2ecf20Sopenharmony_ci {0x22, 0x03}, 7068c2ecf20Sopenharmony_ci {0x09, 0x00} 7078c2ecf20Sopenharmony_ci}; 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_cistatic const u8 ov965x_start_1_vga[][2] = { /* same for qvga */ 7108c2ecf20Sopenharmony_ci {0x12, 0x62}, /* com7 - 30fps VGA YUV */ 7118c2ecf20Sopenharmony_ci {0x36, 0xfa}, /* aref3 */ 7128c2ecf20Sopenharmony_ci {0x69, 0x0a}, /* hv */ 7138c2ecf20Sopenharmony_ci {0x8c, 0x89}, /* com22 */ 7148c2ecf20Sopenharmony_ci {0x14, 0x28}, /* com9 */ 7158c2ecf20Sopenharmony_ci {0x3e, 0x0c}, /* com14 */ 7168c2ecf20Sopenharmony_ci {0x41, 0x40}, /* com16 */ 7178c2ecf20Sopenharmony_ci {0x72, 0x00}, 7188c2ecf20Sopenharmony_ci {0x73, 0x00}, 7198c2ecf20Sopenharmony_ci {0x74, 0x3a}, 7208c2ecf20Sopenharmony_ci {0x75, 0x35}, 7218c2ecf20Sopenharmony_ci {0x76, 0x01}, 7228c2ecf20Sopenharmony_ci {0xc7, 0x80}, /* com24 */ 7238c2ecf20Sopenharmony_ci {0x03, 0x12}, /* vref */ 7248c2ecf20Sopenharmony_ci {0x17, 0x16}, /* hstart */ 7258c2ecf20Sopenharmony_ci {0x18, 0x02}, /* hstop */ 7268c2ecf20Sopenharmony_ci {0x19, 0x01}, /* vstrt */ 7278c2ecf20Sopenharmony_ci {0x1a, 0x3d}, /* vstop */ 7288c2ecf20Sopenharmony_ci {0x32, 0xff}, /* href */ 7298c2ecf20Sopenharmony_ci {0xc0, 0xaa}, 7308c2ecf20Sopenharmony_ci}; 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_cistatic const u8 ov965x_start_1_svga[][2] = { 7338c2ecf20Sopenharmony_ci {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */ 7348c2ecf20Sopenharmony_ci {0x36, 0xf8}, /* aref3 */ 7358c2ecf20Sopenharmony_ci {0x69, 0x02}, /* hv */ 7368c2ecf20Sopenharmony_ci {0x8c, 0x0d}, /* com22 */ 7378c2ecf20Sopenharmony_ci {0x3e, 0x0c}, /* com14 */ 7388c2ecf20Sopenharmony_ci {0x41, 0x40}, /* com16 */ 7398c2ecf20Sopenharmony_ci {0x72, 0x00}, 7408c2ecf20Sopenharmony_ci {0x73, 0x01}, 7418c2ecf20Sopenharmony_ci {0x74, 0x3a}, 7428c2ecf20Sopenharmony_ci {0x75, 0x35}, 7438c2ecf20Sopenharmony_ci {0x76, 0x01}, 7448c2ecf20Sopenharmony_ci {0xc7, 0x80}, /* com24 */ 7458c2ecf20Sopenharmony_ci {0x03, 0x1b}, /* vref */ 7468c2ecf20Sopenharmony_ci {0x17, 0x1d}, /* hstart */ 7478c2ecf20Sopenharmony_ci {0x18, 0xbd}, /* hstop */ 7488c2ecf20Sopenharmony_ci {0x19, 0x01}, /* vstrt */ 7498c2ecf20Sopenharmony_ci {0x1a, 0x81}, /* vstop */ 7508c2ecf20Sopenharmony_ci {0x32, 0xff}, /* href */ 7518c2ecf20Sopenharmony_ci {0xc0, 0xe2}, 7528c2ecf20Sopenharmony_ci}; 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_cistatic const u8 ov965x_start_1_xga[][2] = { 7558c2ecf20Sopenharmony_ci {0x12, 0x02}, /* com7 */ 7568c2ecf20Sopenharmony_ci {0x36, 0xf8}, /* aref3 */ 7578c2ecf20Sopenharmony_ci {0x69, 0x02}, /* hv */ 7588c2ecf20Sopenharmony_ci {0x8c, 0x89}, /* com22 */ 7598c2ecf20Sopenharmony_ci {0x14, 0x28}, /* com9 */ 7608c2ecf20Sopenharmony_ci {0x3e, 0x0c}, /* com14 */ 7618c2ecf20Sopenharmony_ci {0x41, 0x40}, /* com16 */ 7628c2ecf20Sopenharmony_ci {0x72, 0x00}, 7638c2ecf20Sopenharmony_ci {0x73, 0x01}, 7648c2ecf20Sopenharmony_ci {0x74, 0x3a}, 7658c2ecf20Sopenharmony_ci {0x75, 0x35}, 7668c2ecf20Sopenharmony_ci {0x76, 0x01}, 7678c2ecf20Sopenharmony_ci {0xc7, 0x80}, /* com24 */ 7688c2ecf20Sopenharmony_ci {0x03, 0x1b}, /* vref */ 7698c2ecf20Sopenharmony_ci {0x17, 0x1d}, /* hstart */ 7708c2ecf20Sopenharmony_ci {0x18, 0xbd}, /* hstop */ 7718c2ecf20Sopenharmony_ci {0x19, 0x01}, /* vstrt */ 7728c2ecf20Sopenharmony_ci {0x1a, 0x81}, /* vstop */ 7738c2ecf20Sopenharmony_ci {0x32, 0xff}, /* href */ 7748c2ecf20Sopenharmony_ci {0xc0, 0xe2}, 7758c2ecf20Sopenharmony_ci}; 7768c2ecf20Sopenharmony_ci 7778c2ecf20Sopenharmony_cistatic const u8 ov965x_start_1_sxga[][2] = { 7788c2ecf20Sopenharmony_ci {0x12, 0x02}, /* com7 */ 7798c2ecf20Sopenharmony_ci {0x36, 0xf8}, /* aref3 */ 7808c2ecf20Sopenharmony_ci {0x69, 0x02}, /* hv */ 7818c2ecf20Sopenharmony_ci {0x8c, 0x89}, /* com22 */ 7828c2ecf20Sopenharmony_ci {0x14, 0x28}, /* com9 */ 7838c2ecf20Sopenharmony_ci {0x3e, 0x0c}, /* com14 */ 7848c2ecf20Sopenharmony_ci {0x41, 0x40}, /* com16 */ 7858c2ecf20Sopenharmony_ci {0x72, 0x00}, 7868c2ecf20Sopenharmony_ci {0x73, 0x01}, 7878c2ecf20Sopenharmony_ci {0x74, 0x3a}, 7888c2ecf20Sopenharmony_ci {0x75, 0x35}, 7898c2ecf20Sopenharmony_ci {0x76, 0x01}, 7908c2ecf20Sopenharmony_ci {0xc7, 0x80}, /* com24 */ 7918c2ecf20Sopenharmony_ci {0x03, 0x1b}, /* vref */ 7928c2ecf20Sopenharmony_ci {0x17, 0x1d}, /* hstart */ 7938c2ecf20Sopenharmony_ci {0x18, 0x02}, /* hstop */ 7948c2ecf20Sopenharmony_ci {0x19, 0x01}, /* vstrt */ 7958c2ecf20Sopenharmony_ci {0x1a, 0x81}, /* vstop */ 7968c2ecf20Sopenharmony_ci {0x32, 0xff}, /* href */ 7978c2ecf20Sopenharmony_ci {0xc0, 0xe2}, 7988c2ecf20Sopenharmony_ci}; 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_cistatic const u8 bridge_start_qvga[][2] = { 8018c2ecf20Sopenharmony_ci {0x94, 0xaa}, 8028c2ecf20Sopenharmony_ci {0xf1, 0x60}, 8038c2ecf20Sopenharmony_ci {0xe5, 0x04}, 8048c2ecf20Sopenharmony_ci {0xc0, 0x50}, 8058c2ecf20Sopenharmony_ci {0xc1, 0x3c}, 8068c2ecf20Sopenharmony_ci {0x8c, 0x00}, 8078c2ecf20Sopenharmony_ci {0x8d, 0x1c}, 8088c2ecf20Sopenharmony_ci {0x34, 0x05}, 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci {0xc2, 0x4c}, 8118c2ecf20Sopenharmony_ci {0xc3, 0xf9}, 8128c2ecf20Sopenharmony_ci {0xda, 0x00}, 8138c2ecf20Sopenharmony_ci {0x50, 0x00}, 8148c2ecf20Sopenharmony_ci {0x51, 0xa0}, 8158c2ecf20Sopenharmony_ci {0x52, 0x78}, 8168c2ecf20Sopenharmony_ci {0x53, 0x00}, 8178c2ecf20Sopenharmony_ci {0x54, 0x00}, 8188c2ecf20Sopenharmony_ci {0x55, 0x00}, 8198c2ecf20Sopenharmony_ci {0x57, 0x00}, 8208c2ecf20Sopenharmony_ci {0x5c, 0x00}, 8218c2ecf20Sopenharmony_ci {0x5a, 0x50}, 8228c2ecf20Sopenharmony_ci {0x5b, 0x3c}, 8238c2ecf20Sopenharmony_ci {0x35, 0x02}, 8248c2ecf20Sopenharmony_ci {0xd9, 0x10}, 8258c2ecf20Sopenharmony_ci {0x94, 0x11}, 8268c2ecf20Sopenharmony_ci}; 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_cistatic const u8 bridge_start_vga[][2] = { 8298c2ecf20Sopenharmony_ci {0x94, 0xaa}, 8308c2ecf20Sopenharmony_ci {0xf1, 0x60}, 8318c2ecf20Sopenharmony_ci {0xe5, 0x04}, 8328c2ecf20Sopenharmony_ci {0xc0, 0x50}, 8338c2ecf20Sopenharmony_ci {0xc1, 0x3c}, 8348c2ecf20Sopenharmony_ci {0x8c, 0x00}, 8358c2ecf20Sopenharmony_ci {0x8d, 0x1c}, 8368c2ecf20Sopenharmony_ci {0x34, 0x05}, 8378c2ecf20Sopenharmony_ci {0xc2, 0x0c}, 8388c2ecf20Sopenharmony_ci {0xc3, 0xf9}, 8398c2ecf20Sopenharmony_ci {0xda, 0x01}, 8408c2ecf20Sopenharmony_ci {0x50, 0x00}, 8418c2ecf20Sopenharmony_ci {0x51, 0xa0}, 8428c2ecf20Sopenharmony_ci {0x52, 0x3c}, 8438c2ecf20Sopenharmony_ci {0x53, 0x00}, 8448c2ecf20Sopenharmony_ci {0x54, 0x00}, 8458c2ecf20Sopenharmony_ci {0x55, 0x00}, 8468c2ecf20Sopenharmony_ci {0x57, 0x00}, 8478c2ecf20Sopenharmony_ci {0x5c, 0x00}, 8488c2ecf20Sopenharmony_ci {0x5a, 0xa0}, 8498c2ecf20Sopenharmony_ci {0x5b, 0x78}, 8508c2ecf20Sopenharmony_ci {0x35, 0x02}, 8518c2ecf20Sopenharmony_ci {0xd9, 0x10}, 8528c2ecf20Sopenharmony_ci {0x94, 0x11}, 8538c2ecf20Sopenharmony_ci}; 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_cistatic const u8 bridge_start_svga[][2] = { 8568c2ecf20Sopenharmony_ci {0x94, 0xaa}, 8578c2ecf20Sopenharmony_ci {0xf1, 0x60}, 8588c2ecf20Sopenharmony_ci {0xe5, 0x04}, 8598c2ecf20Sopenharmony_ci {0xc0, 0xa0}, 8608c2ecf20Sopenharmony_ci {0xc1, 0x80}, 8618c2ecf20Sopenharmony_ci {0x8c, 0x00}, 8628c2ecf20Sopenharmony_ci {0x8d, 0x1c}, 8638c2ecf20Sopenharmony_ci {0x34, 0x05}, 8648c2ecf20Sopenharmony_ci {0xc2, 0x4c}, 8658c2ecf20Sopenharmony_ci {0xc3, 0xf9}, 8668c2ecf20Sopenharmony_ci {0x50, 0x00}, 8678c2ecf20Sopenharmony_ci {0x51, 0x40}, 8688c2ecf20Sopenharmony_ci {0x52, 0x00}, 8698c2ecf20Sopenharmony_ci {0x53, 0x00}, 8708c2ecf20Sopenharmony_ci {0x54, 0x00}, 8718c2ecf20Sopenharmony_ci {0x55, 0x88}, 8728c2ecf20Sopenharmony_ci {0x57, 0x00}, 8738c2ecf20Sopenharmony_ci {0x5c, 0x00}, 8748c2ecf20Sopenharmony_ci {0x5a, 0xc8}, 8758c2ecf20Sopenharmony_ci {0x5b, 0x96}, 8768c2ecf20Sopenharmony_ci {0x35, 0x02}, 8778c2ecf20Sopenharmony_ci {0xd9, 0x10}, 8788c2ecf20Sopenharmony_ci {0xda, 0x00}, 8798c2ecf20Sopenharmony_ci {0x94, 0x11}, 8808c2ecf20Sopenharmony_ci}; 8818c2ecf20Sopenharmony_ci 8828c2ecf20Sopenharmony_cistatic const u8 bridge_start_xga[][2] = { 8838c2ecf20Sopenharmony_ci {0x94, 0xaa}, 8848c2ecf20Sopenharmony_ci {0xf1, 0x60}, 8858c2ecf20Sopenharmony_ci {0xe5, 0x04}, 8868c2ecf20Sopenharmony_ci {0xc0, 0xa0}, 8878c2ecf20Sopenharmony_ci {0xc1, 0x80}, 8888c2ecf20Sopenharmony_ci {0x8c, 0x00}, 8898c2ecf20Sopenharmony_ci {0x8d, 0x1c}, 8908c2ecf20Sopenharmony_ci {0x34, 0x05}, 8918c2ecf20Sopenharmony_ci {0xc2, 0x4c}, 8928c2ecf20Sopenharmony_ci {0xc3, 0xf9}, 8938c2ecf20Sopenharmony_ci {0x50, 0x00}, 8948c2ecf20Sopenharmony_ci {0x51, 0x40}, 8958c2ecf20Sopenharmony_ci {0x52, 0x00}, 8968c2ecf20Sopenharmony_ci {0x53, 0x00}, 8978c2ecf20Sopenharmony_ci {0x54, 0x00}, 8988c2ecf20Sopenharmony_ci {0x55, 0x88}, 8998c2ecf20Sopenharmony_ci {0x57, 0x00}, 9008c2ecf20Sopenharmony_ci {0x5c, 0x01}, 9018c2ecf20Sopenharmony_ci {0x5a, 0x00}, 9028c2ecf20Sopenharmony_ci {0x5b, 0xc0}, 9038c2ecf20Sopenharmony_ci {0x35, 0x02}, 9048c2ecf20Sopenharmony_ci {0xd9, 0x10}, 9058c2ecf20Sopenharmony_ci {0xda, 0x01}, 9068c2ecf20Sopenharmony_ci {0x94, 0x11}, 9078c2ecf20Sopenharmony_ci}; 9088c2ecf20Sopenharmony_ci 9098c2ecf20Sopenharmony_cistatic const u8 bridge_start_sxga[][2] = { 9108c2ecf20Sopenharmony_ci {0x94, 0xaa}, 9118c2ecf20Sopenharmony_ci {0xf1, 0x60}, 9128c2ecf20Sopenharmony_ci {0xe5, 0x04}, 9138c2ecf20Sopenharmony_ci {0xc0, 0xa0}, 9148c2ecf20Sopenharmony_ci {0xc1, 0x80}, 9158c2ecf20Sopenharmony_ci {0x8c, 0x00}, 9168c2ecf20Sopenharmony_ci {0x8d, 0x1c}, 9178c2ecf20Sopenharmony_ci {0x34, 0x05}, 9188c2ecf20Sopenharmony_ci {0xc2, 0x0c}, 9198c2ecf20Sopenharmony_ci {0xc3, 0xf9}, 9208c2ecf20Sopenharmony_ci {0xda, 0x00}, 9218c2ecf20Sopenharmony_ci {0x35, 0x02}, 9228c2ecf20Sopenharmony_ci {0xd9, 0x10}, 9238c2ecf20Sopenharmony_ci {0x94, 0x11}, 9248c2ecf20Sopenharmony_ci}; 9258c2ecf20Sopenharmony_ci 9268c2ecf20Sopenharmony_cistatic const u8 ov965x_start_2_qvga[][2] = { 9278c2ecf20Sopenharmony_ci {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ 9288c2ecf20Sopenharmony_ci {0x1e, 0x04}, /* mvfp */ 9298c2ecf20Sopenharmony_ci {0x13, 0xe0}, /* com8 */ 9308c2ecf20Sopenharmony_ci {0x00, 0x00}, 9318c2ecf20Sopenharmony_ci {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 9328c2ecf20Sopenharmony_ci {0x11, 0x01}, /* clkrc */ 9338c2ecf20Sopenharmony_ci {0x6b, 0x5a}, /* dblv */ 9348c2ecf20Sopenharmony_ci {0x6a, 0x02}, /* 50 Hz banding filter */ 9358c2ecf20Sopenharmony_ci {0xc5, 0x03}, /* 60 Hz banding filter */ 9368c2ecf20Sopenharmony_ci {0xa2, 0x96}, /* bd50 */ 9378c2ecf20Sopenharmony_ci {0xa3, 0x7d}, /* bd60 */ 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_ci {0xff, 0x13}, /* read 13, write ff 00 */ 9408c2ecf20Sopenharmony_ci {0x13, 0xe7}, 9418c2ecf20Sopenharmony_ci {0x3a, 0x80}, /* tslb - yuyv */ 9428c2ecf20Sopenharmony_ci}; 9438c2ecf20Sopenharmony_ci 9448c2ecf20Sopenharmony_cistatic const u8 ov965x_start_2_vga[][2] = { 9458c2ecf20Sopenharmony_ci {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 9468c2ecf20Sopenharmony_ci {0x1e, 0x04}, /* mvfp */ 9478c2ecf20Sopenharmony_ci {0x13, 0xe0}, /* com8 */ 9488c2ecf20Sopenharmony_ci {0x00, 0x00}, 9498c2ecf20Sopenharmony_ci {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 9508c2ecf20Sopenharmony_ci {0x11, 0x03}, /* clkrc */ 9518c2ecf20Sopenharmony_ci {0x6b, 0x5a}, /* dblv */ 9528c2ecf20Sopenharmony_ci {0x6a, 0x05}, /* 50 Hz banding filter */ 9538c2ecf20Sopenharmony_ci {0xc5, 0x07}, /* 60 Hz banding filter */ 9548c2ecf20Sopenharmony_ci {0xa2, 0x4b}, /* bd50 */ 9558c2ecf20Sopenharmony_ci {0xa3, 0x3e}, /* bd60 */ 9568c2ecf20Sopenharmony_ci 9578c2ecf20Sopenharmony_ci {0x2d, 0x00}, /* advfl */ 9588c2ecf20Sopenharmony_ci}; 9598c2ecf20Sopenharmony_ci 9608c2ecf20Sopenharmony_cistatic const u8 ov965x_start_2_svga[][2] = { /* same for xga */ 9618c2ecf20Sopenharmony_ci {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 9628c2ecf20Sopenharmony_ci {0x1e, 0x04}, /* mvfp */ 9638c2ecf20Sopenharmony_ci {0x13, 0xe0}, /* com8 */ 9648c2ecf20Sopenharmony_ci {0x00, 0x00}, 9658c2ecf20Sopenharmony_ci {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 9668c2ecf20Sopenharmony_ci {0x11, 0x01}, /* clkrc */ 9678c2ecf20Sopenharmony_ci {0x6b, 0x5a}, /* dblv */ 9688c2ecf20Sopenharmony_ci {0x6a, 0x0c}, /* 50 Hz banding filter */ 9698c2ecf20Sopenharmony_ci {0xc5, 0x0f}, /* 60 Hz banding filter */ 9708c2ecf20Sopenharmony_ci {0xa2, 0x4e}, /* bd50 */ 9718c2ecf20Sopenharmony_ci {0xa3, 0x41}, /* bd60 */ 9728c2ecf20Sopenharmony_ci}; 9738c2ecf20Sopenharmony_ci 9748c2ecf20Sopenharmony_cistatic const u8 ov965x_start_2_sxga[][2] = { 9758c2ecf20Sopenharmony_ci {0x13, 0xe0}, /* com8 */ 9768c2ecf20Sopenharmony_ci {0x00, 0x00}, 9778c2ecf20Sopenharmony_ci {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 9788c2ecf20Sopenharmony_ci {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 9798c2ecf20Sopenharmony_ci {0x1e, 0x04}, /* mvfp */ 9808c2ecf20Sopenharmony_ci {0x11, 0x01}, /* clkrc */ 9818c2ecf20Sopenharmony_ci {0x6b, 0x5a}, /* dblv */ 9828c2ecf20Sopenharmony_ci {0x6a, 0x0c}, /* 50 Hz banding filter */ 9838c2ecf20Sopenharmony_ci {0xc5, 0x0f}, /* 60 Hz banding filter */ 9848c2ecf20Sopenharmony_ci {0xa2, 0x4e}, /* bd50 */ 9858c2ecf20Sopenharmony_ci {0xa3, 0x41}, /* bd60 */ 9868c2ecf20Sopenharmony_ci}; 9878c2ecf20Sopenharmony_ci 9888c2ecf20Sopenharmony_cistatic const u8 ov562x_init[][2] = { 9898c2ecf20Sopenharmony_ci {0x88, 0x20}, 9908c2ecf20Sopenharmony_ci {0x89, 0x0a}, 9918c2ecf20Sopenharmony_ci {0x8a, 0x90}, 9928c2ecf20Sopenharmony_ci {0x8b, 0x06}, 9938c2ecf20Sopenharmony_ci {0x8c, 0x01}, 9948c2ecf20Sopenharmony_ci {0x8d, 0x10}, 9958c2ecf20Sopenharmony_ci {0x1c, 0x00}, 9968c2ecf20Sopenharmony_ci {0x1d, 0x48}, 9978c2ecf20Sopenharmony_ci {0x1d, 0x00}, 9988c2ecf20Sopenharmony_ci {0x1d, 0xff}, 9998c2ecf20Sopenharmony_ci {0x1c, 0x0a}, 10008c2ecf20Sopenharmony_ci {0x1d, 0x2e}, 10018c2ecf20Sopenharmony_ci {0x1d, 0x1e}, 10028c2ecf20Sopenharmony_ci}; 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_cistatic const u8 ov562x_init_2[][2] = { 10058c2ecf20Sopenharmony_ci {0x12, 0x80}, 10068c2ecf20Sopenharmony_ci {0x11, 0x41}, 10078c2ecf20Sopenharmony_ci {0x13, 0x00}, 10088c2ecf20Sopenharmony_ci {0x10, 0x1e}, 10098c2ecf20Sopenharmony_ci {0x3b, 0x07}, 10108c2ecf20Sopenharmony_ci {0x5b, 0x40}, 10118c2ecf20Sopenharmony_ci {0x39, 0x07}, 10128c2ecf20Sopenharmony_ci {0x53, 0x02}, 10138c2ecf20Sopenharmony_ci {0x54, 0x60}, 10148c2ecf20Sopenharmony_ci {0x04, 0x20}, 10158c2ecf20Sopenharmony_ci {0x27, 0x04}, 10168c2ecf20Sopenharmony_ci {0x3d, 0x40}, 10178c2ecf20Sopenharmony_ci {0x36, 0x00}, 10188c2ecf20Sopenharmony_ci {0xc5, 0x04}, 10198c2ecf20Sopenharmony_ci {0x4e, 0x00}, 10208c2ecf20Sopenharmony_ci {0x4f, 0x93}, 10218c2ecf20Sopenharmony_ci {0x50, 0x7b}, 10228c2ecf20Sopenharmony_ci {0xca, 0x0c}, 10238c2ecf20Sopenharmony_ci {0xcb, 0x0f}, 10248c2ecf20Sopenharmony_ci {0x39, 0x07}, 10258c2ecf20Sopenharmony_ci {0x4a, 0x10}, 10268c2ecf20Sopenharmony_ci {0x3e, 0x0a}, 10278c2ecf20Sopenharmony_ci {0x3d, 0x00}, 10288c2ecf20Sopenharmony_ci {0x0c, 0x38}, 10298c2ecf20Sopenharmony_ci {0x38, 0x90}, 10308c2ecf20Sopenharmony_ci {0x46, 0x30}, 10318c2ecf20Sopenharmony_ci {0x4f, 0x93}, 10328c2ecf20Sopenharmony_ci {0x50, 0x7b}, 10338c2ecf20Sopenharmony_ci {0xab, 0x00}, 10348c2ecf20Sopenharmony_ci {0xca, 0x0c}, 10358c2ecf20Sopenharmony_ci {0xcb, 0x0f}, 10368c2ecf20Sopenharmony_ci {0x37, 0x02}, 10378c2ecf20Sopenharmony_ci {0x44, 0x48}, 10388c2ecf20Sopenharmony_ci {0x8d, 0x44}, 10398c2ecf20Sopenharmony_ci {0x2a, 0x00}, 10408c2ecf20Sopenharmony_ci {0x2b, 0x00}, 10418c2ecf20Sopenharmony_ci {0x32, 0x00}, 10428c2ecf20Sopenharmony_ci {0x38, 0x90}, 10438c2ecf20Sopenharmony_ci {0x53, 0x02}, 10448c2ecf20Sopenharmony_ci {0x54, 0x60}, 10458c2ecf20Sopenharmony_ci {0x12, 0x00}, 10468c2ecf20Sopenharmony_ci {0x17, 0x12}, 10478c2ecf20Sopenharmony_ci {0x18, 0xb4}, 10488c2ecf20Sopenharmony_ci {0x19, 0x0c}, 10498c2ecf20Sopenharmony_ci {0x1a, 0xf4}, 10508c2ecf20Sopenharmony_ci {0x03, 0x4a}, 10518c2ecf20Sopenharmony_ci {0x89, 0x20}, 10528c2ecf20Sopenharmony_ci {0x83, 0x80}, 10538c2ecf20Sopenharmony_ci {0xb7, 0x9d}, 10548c2ecf20Sopenharmony_ci {0xb6, 0x11}, 10558c2ecf20Sopenharmony_ci {0xb5, 0x55}, 10568c2ecf20Sopenharmony_ci {0xb4, 0x00}, 10578c2ecf20Sopenharmony_ci {0xa9, 0xf0}, 10588c2ecf20Sopenharmony_ci {0xa8, 0x0a}, 10598c2ecf20Sopenharmony_ci {0xb8, 0xf0}, 10608c2ecf20Sopenharmony_ci {0xb9, 0xf0}, 10618c2ecf20Sopenharmony_ci {0xba, 0xf0}, 10628c2ecf20Sopenharmony_ci {0x81, 0x07}, 10638c2ecf20Sopenharmony_ci {0x63, 0x44}, 10648c2ecf20Sopenharmony_ci {0x13, 0xc7}, 10658c2ecf20Sopenharmony_ci {0x14, 0x60}, 10668c2ecf20Sopenharmony_ci {0x33, 0x75}, 10678c2ecf20Sopenharmony_ci {0x2c, 0x00}, 10688c2ecf20Sopenharmony_ci {0x09, 0x00}, 10698c2ecf20Sopenharmony_ci {0x35, 0x30}, 10708c2ecf20Sopenharmony_ci {0x27, 0x04}, 10718c2ecf20Sopenharmony_ci {0x3c, 0x07}, 10728c2ecf20Sopenharmony_ci {0x3a, 0x0a}, 10738c2ecf20Sopenharmony_ci {0x3b, 0x07}, 10748c2ecf20Sopenharmony_ci {0x01, 0x40}, 10758c2ecf20Sopenharmony_ci {0x02, 0x40}, 10768c2ecf20Sopenharmony_ci {0x16, 0x40}, 10778c2ecf20Sopenharmony_ci {0x52, 0xb0}, 10788c2ecf20Sopenharmony_ci {0x51, 0x83}, 10798c2ecf20Sopenharmony_ci {0x21, 0xbb}, 10808c2ecf20Sopenharmony_ci {0x22, 0x10}, 10818c2ecf20Sopenharmony_ci {0x23, 0x03}, 10828c2ecf20Sopenharmony_ci {0x35, 0x38}, 10838c2ecf20Sopenharmony_ci {0x20, 0x90}, 10848c2ecf20Sopenharmony_ci {0x28, 0x30}, 10858c2ecf20Sopenharmony_ci {0x73, 0xe1}, 10868c2ecf20Sopenharmony_ci {0x6c, 0x00}, 10878c2ecf20Sopenharmony_ci {0x6d, 0x80}, 10888c2ecf20Sopenharmony_ci {0x6e, 0x00}, 10898c2ecf20Sopenharmony_ci {0x70, 0x04}, 10908c2ecf20Sopenharmony_ci {0x71, 0x00}, 10918c2ecf20Sopenharmony_ci {0x8d, 0x04}, 10928c2ecf20Sopenharmony_ci {0x64, 0x00}, 10938c2ecf20Sopenharmony_ci {0x65, 0x00}, 10948c2ecf20Sopenharmony_ci {0x66, 0x00}, 10958c2ecf20Sopenharmony_ci {0x67, 0x00}, 10968c2ecf20Sopenharmony_ci {0x68, 0x00}, 10978c2ecf20Sopenharmony_ci {0x69, 0x00}, 10988c2ecf20Sopenharmony_ci {0x6a, 0x00}, 10998c2ecf20Sopenharmony_ci {0x6b, 0x00}, 11008c2ecf20Sopenharmony_ci {0x71, 0x94}, 11018c2ecf20Sopenharmony_ci {0x74, 0x20}, 11028c2ecf20Sopenharmony_ci {0x80, 0x09}, 11038c2ecf20Sopenharmony_ci {0x85, 0xc0}, 11048c2ecf20Sopenharmony_ci}; 11058c2ecf20Sopenharmony_ci 11068c2ecf20Sopenharmony_cistatic void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val) 11078c2ecf20Sopenharmony_ci{ 11088c2ecf20Sopenharmony_ci struct usb_device *udev = gspca_dev->dev; 11098c2ecf20Sopenharmony_ci int ret; 11108c2ecf20Sopenharmony_ci 11118c2ecf20Sopenharmony_ci if (gspca_dev->usb_err < 0) 11128c2ecf20Sopenharmony_ci return; 11138c2ecf20Sopenharmony_ci gspca_dev->usb_buf[0] = val; 11148c2ecf20Sopenharmony_ci ret = usb_control_msg(udev, 11158c2ecf20Sopenharmony_ci usb_sndctrlpipe(udev, 0), 11168c2ecf20Sopenharmony_ci 0x01, 11178c2ecf20Sopenharmony_ci USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 11188c2ecf20Sopenharmony_ci 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); 11198c2ecf20Sopenharmony_ci if (ret < 0) { 11208c2ecf20Sopenharmony_ci pr_err("reg_w failed %d\n", ret); 11218c2ecf20Sopenharmony_ci gspca_dev->usb_err = ret; 11228c2ecf20Sopenharmony_ci } 11238c2ecf20Sopenharmony_ci} 11248c2ecf20Sopenharmony_ci 11258c2ecf20Sopenharmony_cistatic void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val) 11268c2ecf20Sopenharmony_ci{ 11278c2ecf20Sopenharmony_ci gspca_dbg(gspca_dev, D_USBO, "reg_w [%04x] = %02x\n", reg, val); 11288c2ecf20Sopenharmony_ci reg_w_i(gspca_dev, reg, val); 11298c2ecf20Sopenharmony_ci} 11308c2ecf20Sopenharmony_ci 11318c2ecf20Sopenharmony_cistatic u8 reg_r(struct gspca_dev *gspca_dev, u16 reg) 11328c2ecf20Sopenharmony_ci{ 11338c2ecf20Sopenharmony_ci struct usb_device *udev = gspca_dev->dev; 11348c2ecf20Sopenharmony_ci int ret; 11358c2ecf20Sopenharmony_ci 11368c2ecf20Sopenharmony_ci if (gspca_dev->usb_err < 0) 11378c2ecf20Sopenharmony_ci return 0; 11388c2ecf20Sopenharmony_ci ret = usb_control_msg(udev, 11398c2ecf20Sopenharmony_ci usb_rcvctrlpipe(udev, 0), 11408c2ecf20Sopenharmony_ci 0x01, 11418c2ecf20Sopenharmony_ci USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 11428c2ecf20Sopenharmony_ci 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); 11438c2ecf20Sopenharmony_ci gspca_dbg(gspca_dev, D_USBI, "reg_r [%04x] -> %02x\n", 11448c2ecf20Sopenharmony_ci reg, gspca_dev->usb_buf[0]); 11458c2ecf20Sopenharmony_ci if (ret < 0) { 11468c2ecf20Sopenharmony_ci pr_err("reg_r err %d\n", ret); 11478c2ecf20Sopenharmony_ci gspca_dev->usb_err = ret; 11488c2ecf20Sopenharmony_ci return 0; 11498c2ecf20Sopenharmony_ci } 11508c2ecf20Sopenharmony_ci return gspca_dev->usb_buf[0]; 11518c2ecf20Sopenharmony_ci} 11528c2ecf20Sopenharmony_ci 11538c2ecf20Sopenharmony_cistatic int sccb_check_status(struct gspca_dev *gspca_dev) 11548c2ecf20Sopenharmony_ci{ 11558c2ecf20Sopenharmony_ci u8 data; 11568c2ecf20Sopenharmony_ci int i; 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_ci for (i = 0; i < 5; i++) { 11598c2ecf20Sopenharmony_ci msleep(20); 11608c2ecf20Sopenharmony_ci data = reg_r(gspca_dev, OV534_REG_STATUS); 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci switch (data) { 11638c2ecf20Sopenharmony_ci case 0x00: 11648c2ecf20Sopenharmony_ci return 1; 11658c2ecf20Sopenharmony_ci case 0x04: 11668c2ecf20Sopenharmony_ci return 0; 11678c2ecf20Sopenharmony_ci case 0x03: 11688c2ecf20Sopenharmony_ci break; 11698c2ecf20Sopenharmony_ci default: 11708c2ecf20Sopenharmony_ci gspca_dbg(gspca_dev, D_USBI|D_USBO, 11718c2ecf20Sopenharmony_ci "sccb status 0x%02x, attempt %d/5\n", 11728c2ecf20Sopenharmony_ci data, i + 1); 11738c2ecf20Sopenharmony_ci } 11748c2ecf20Sopenharmony_ci } 11758c2ecf20Sopenharmony_ci return 0; 11768c2ecf20Sopenharmony_ci} 11778c2ecf20Sopenharmony_ci 11788c2ecf20Sopenharmony_cistatic void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val) 11798c2ecf20Sopenharmony_ci{ 11808c2ecf20Sopenharmony_ci gspca_dbg(gspca_dev, D_USBO, "sccb_write [%02x] = %02x\n", reg, val); 11818c2ecf20Sopenharmony_ci reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg); 11828c2ecf20Sopenharmony_ci reg_w_i(gspca_dev, OV534_REG_WRITE, val); 11838c2ecf20Sopenharmony_ci reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); 11848c2ecf20Sopenharmony_ci 11858c2ecf20Sopenharmony_ci if (!sccb_check_status(gspca_dev)) 11868c2ecf20Sopenharmony_ci pr_err("sccb_write failed\n"); 11878c2ecf20Sopenharmony_ci} 11888c2ecf20Sopenharmony_ci 11898c2ecf20Sopenharmony_cistatic u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg) 11908c2ecf20Sopenharmony_ci{ 11918c2ecf20Sopenharmony_ci reg_w(gspca_dev, OV534_REG_SUBADDR, reg); 11928c2ecf20Sopenharmony_ci reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); 11938c2ecf20Sopenharmony_ci if (!sccb_check_status(gspca_dev)) 11948c2ecf20Sopenharmony_ci pr_err("sccb_read failed 1\n"); 11958c2ecf20Sopenharmony_ci 11968c2ecf20Sopenharmony_ci reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); 11978c2ecf20Sopenharmony_ci if (!sccb_check_status(gspca_dev)) 11988c2ecf20Sopenharmony_ci pr_err("sccb_read failed 2\n"); 11998c2ecf20Sopenharmony_ci 12008c2ecf20Sopenharmony_ci return reg_r(gspca_dev, OV534_REG_READ); 12018c2ecf20Sopenharmony_ci} 12028c2ecf20Sopenharmony_ci 12038c2ecf20Sopenharmony_ci/* output a bridge sequence (reg - val) */ 12048c2ecf20Sopenharmony_cistatic void reg_w_array(struct gspca_dev *gspca_dev, 12058c2ecf20Sopenharmony_ci const u8 (*data)[2], int len) 12068c2ecf20Sopenharmony_ci{ 12078c2ecf20Sopenharmony_ci while (--len >= 0) { 12088c2ecf20Sopenharmony_ci reg_w(gspca_dev, (*data)[0], (*data)[1]); 12098c2ecf20Sopenharmony_ci data++; 12108c2ecf20Sopenharmony_ci } 12118c2ecf20Sopenharmony_ci} 12128c2ecf20Sopenharmony_ci 12138c2ecf20Sopenharmony_ci/* output a sensor sequence (reg - val) */ 12148c2ecf20Sopenharmony_cistatic void sccb_w_array(struct gspca_dev *gspca_dev, 12158c2ecf20Sopenharmony_ci const u8 (*data)[2], int len) 12168c2ecf20Sopenharmony_ci{ 12178c2ecf20Sopenharmony_ci while (--len >= 0) { 12188c2ecf20Sopenharmony_ci if ((*data)[0] != 0xff) { 12198c2ecf20Sopenharmony_ci sccb_write(gspca_dev, (*data)[0], (*data)[1]); 12208c2ecf20Sopenharmony_ci } else { 12218c2ecf20Sopenharmony_ci sccb_read(gspca_dev, (*data)[1]); 12228c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0xff, 0x00); 12238c2ecf20Sopenharmony_ci } 12248c2ecf20Sopenharmony_ci data++; 12258c2ecf20Sopenharmony_ci } 12268c2ecf20Sopenharmony_ci} 12278c2ecf20Sopenharmony_ci 12288c2ecf20Sopenharmony_ci/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. 12298c2ecf20Sopenharmony_ci * (direction and output)? */ 12308c2ecf20Sopenharmony_cistatic void set_led(struct gspca_dev *gspca_dev, int status) 12318c2ecf20Sopenharmony_ci{ 12328c2ecf20Sopenharmony_ci u8 data; 12338c2ecf20Sopenharmony_ci 12348c2ecf20Sopenharmony_ci gspca_dbg(gspca_dev, D_CONF, "led status: %d\n", status); 12358c2ecf20Sopenharmony_ci 12368c2ecf20Sopenharmony_ci data = reg_r(gspca_dev, 0x21); 12378c2ecf20Sopenharmony_ci data |= 0x80; 12388c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0x21, data); 12398c2ecf20Sopenharmony_ci 12408c2ecf20Sopenharmony_ci data = reg_r(gspca_dev, 0x23); 12418c2ecf20Sopenharmony_ci if (status) 12428c2ecf20Sopenharmony_ci data |= 0x80; 12438c2ecf20Sopenharmony_ci else 12448c2ecf20Sopenharmony_ci data &= ~0x80; 12458c2ecf20Sopenharmony_ci 12468c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0x23, data); 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_ci if (!status) { 12498c2ecf20Sopenharmony_ci data = reg_r(gspca_dev, 0x21); 12508c2ecf20Sopenharmony_ci data &= ~0x80; 12518c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0x21, data); 12528c2ecf20Sopenharmony_ci } 12538c2ecf20Sopenharmony_ci} 12548c2ecf20Sopenharmony_ci 12558c2ecf20Sopenharmony_cistatic void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) 12568c2ecf20Sopenharmony_ci{ 12578c2ecf20Sopenharmony_ci struct sd *sd = (struct sd *) gspca_dev; 12588c2ecf20Sopenharmony_ci u8 val; 12598c2ecf20Sopenharmony_ci s8 sval; 12608c2ecf20Sopenharmony_ci 12618c2ecf20Sopenharmony_ci if (sd->sensor == SENSOR_OV562x) { 12628c2ecf20Sopenharmony_ci sval = brightness; 12638c2ecf20Sopenharmony_ci val = 0x76; 12648c2ecf20Sopenharmony_ci val += sval; 12658c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x24, val); 12668c2ecf20Sopenharmony_ci val = 0x6a; 12678c2ecf20Sopenharmony_ci val += sval; 12688c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x25, val); 12698c2ecf20Sopenharmony_ci if (sval < -40) 12708c2ecf20Sopenharmony_ci val = 0x71; 12718c2ecf20Sopenharmony_ci else if (sval < 20) 12728c2ecf20Sopenharmony_ci val = 0x94; 12738c2ecf20Sopenharmony_ci else 12748c2ecf20Sopenharmony_ci val = 0xe6; 12758c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x26, val); 12768c2ecf20Sopenharmony_ci } else { 12778c2ecf20Sopenharmony_ci val = brightness; 12788c2ecf20Sopenharmony_ci if (val < 8) 12798c2ecf20Sopenharmony_ci val = 15 - val; /* f .. 8 */ 12808c2ecf20Sopenharmony_ci else 12818c2ecf20Sopenharmony_ci val = val - 8; /* 0 .. 7 */ 12828c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */ 12838c2ecf20Sopenharmony_ci 0x0f | (val << 4)); 12848c2ecf20Sopenharmony_ci } 12858c2ecf20Sopenharmony_ci} 12868c2ecf20Sopenharmony_ci 12878c2ecf20Sopenharmony_cistatic void setcontrast(struct gspca_dev *gspca_dev, s32 val) 12888c2ecf20Sopenharmony_ci{ 12898c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */ 12908c2ecf20Sopenharmony_ci val << 4); 12918c2ecf20Sopenharmony_ci} 12928c2ecf20Sopenharmony_ci 12938c2ecf20Sopenharmony_cistatic void setautogain(struct gspca_dev *gspca_dev, s32 autogain) 12948c2ecf20Sopenharmony_ci{ 12958c2ecf20Sopenharmony_ci u8 val; 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_ci/*fixme: should adjust agc/awb/aec by different controls */ 12988c2ecf20Sopenharmony_ci val = sccb_read(gspca_dev, 0x13); /* com8 */ 12998c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0xff, 0x00); 13008c2ecf20Sopenharmony_ci if (autogain) 13018c2ecf20Sopenharmony_ci val |= 0x05; /* agc & aec */ 13028c2ecf20Sopenharmony_ci else 13038c2ecf20Sopenharmony_ci val &= 0xfa; 13048c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x13, val); 13058c2ecf20Sopenharmony_ci} 13068c2ecf20Sopenharmony_ci 13078c2ecf20Sopenharmony_cistatic void setexposure(struct gspca_dev *gspca_dev, s32 exposure) 13088c2ecf20Sopenharmony_ci{ 13098c2ecf20Sopenharmony_ci static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e}; 13108c2ecf20Sopenharmony_ci u8 val; 13118c2ecf20Sopenharmony_ci 13128c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x10, expo[exposure]); /* aec[9:2] */ 13138c2ecf20Sopenharmony_ci 13148c2ecf20Sopenharmony_ci val = sccb_read(gspca_dev, 0x13); /* com8 */ 13158c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0xff, 0x00); 13168c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x13, val); 13178c2ecf20Sopenharmony_ci 13188c2ecf20Sopenharmony_ci val = sccb_read(gspca_dev, 0xa1); /* aech */ 13198c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0xff, 0x00); 13208c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */ 13218c2ecf20Sopenharmony_ci} 13228c2ecf20Sopenharmony_ci 13238c2ecf20Sopenharmony_cistatic void setsharpness(struct gspca_dev *gspca_dev, s32 val) 13248c2ecf20Sopenharmony_ci{ 13258c2ecf20Sopenharmony_ci if (val < 0) { /* auto */ 13268c2ecf20Sopenharmony_ci val = sccb_read(gspca_dev, 0x42); /* com17 */ 13278c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0xff, 0x00); 13288c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x42, val | 0x40); 13298c2ecf20Sopenharmony_ci /* Edge enhancement strength auto adjust */ 13308c2ecf20Sopenharmony_ci return; 13318c2ecf20Sopenharmony_ci } 13328c2ecf20Sopenharmony_ci if (val != 0) 13338c2ecf20Sopenharmony_ci val = 1 << (val - 1); 13348c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */ 13358c2ecf20Sopenharmony_ci val); 13368c2ecf20Sopenharmony_ci val = sccb_read(gspca_dev, 0x42); /* com17 */ 13378c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0xff, 0x00); 13388c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x42, val & 0xbf); 13398c2ecf20Sopenharmony_ci} 13408c2ecf20Sopenharmony_ci 13418c2ecf20Sopenharmony_cistatic void setsatur(struct gspca_dev *gspca_dev, s32 val) 13428c2ecf20Sopenharmony_ci{ 13438c2ecf20Sopenharmony_ci u8 val1, val2, val3; 13448c2ecf20Sopenharmony_ci static const u8 matrix[5][2] = { 13458c2ecf20Sopenharmony_ci {0x14, 0x38}, 13468c2ecf20Sopenharmony_ci {0x1e, 0x54}, 13478c2ecf20Sopenharmony_ci {0x28, 0x70}, 13488c2ecf20Sopenharmony_ci {0x32, 0x8c}, 13498c2ecf20Sopenharmony_ci {0x48, 0x90} 13508c2ecf20Sopenharmony_ci }; 13518c2ecf20Sopenharmony_ci 13528c2ecf20Sopenharmony_ci val1 = matrix[val][0]; 13538c2ecf20Sopenharmony_ci val2 = matrix[val][1]; 13548c2ecf20Sopenharmony_ci val3 = val1 + val2; 13558c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */ 13568c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x50, val3); 13578c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x51, 0x00); 13588c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x52, val1); 13598c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x53, val2); 13608c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x54, val3); 13618c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */ 13628c2ecf20Sopenharmony_ci 13638c2ecf20Sopenharmony_ci val1 = sccb_read(gspca_dev, 0x41); /* com16 */ 13648c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0xff, 0x00); 13658c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x41, val1); 13668c2ecf20Sopenharmony_ci} 13678c2ecf20Sopenharmony_ci 13688c2ecf20Sopenharmony_cistatic void setlightfreq(struct gspca_dev *gspca_dev, s32 freq) 13698c2ecf20Sopenharmony_ci{ 13708c2ecf20Sopenharmony_ci u8 val; 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_ci val = sccb_read(gspca_dev, 0x13); /* com8 */ 13738c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0xff, 0x00); 13748c2ecf20Sopenharmony_ci if (freq == 0) { 13758c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x13, val & 0xdf); 13768c2ecf20Sopenharmony_ci return; 13778c2ecf20Sopenharmony_ci } 13788c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x13, val | 0x20); 13798c2ecf20Sopenharmony_ci 13808c2ecf20Sopenharmony_ci val = sccb_read(gspca_dev, 0x42); /* com17 */ 13818c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0xff, 0x00); 13828c2ecf20Sopenharmony_ci if (freq == 1) 13838c2ecf20Sopenharmony_ci val |= 0x01; 13848c2ecf20Sopenharmony_ci else 13858c2ecf20Sopenharmony_ci val &= 0xfe; 13868c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x42, val); 13878c2ecf20Sopenharmony_ci} 13888c2ecf20Sopenharmony_ci 13898c2ecf20Sopenharmony_ci/* this function is called at probe time */ 13908c2ecf20Sopenharmony_cistatic int sd_config(struct gspca_dev *gspca_dev, 13918c2ecf20Sopenharmony_ci const struct usb_device_id *id) 13928c2ecf20Sopenharmony_ci{ 13938c2ecf20Sopenharmony_ci return 0; 13948c2ecf20Sopenharmony_ci} 13958c2ecf20Sopenharmony_ci 13968c2ecf20Sopenharmony_ci/* this function is called at probe and resume time */ 13978c2ecf20Sopenharmony_cistatic int sd_init(struct gspca_dev *gspca_dev) 13988c2ecf20Sopenharmony_ci{ 13998c2ecf20Sopenharmony_ci struct sd *sd = (struct sd *) gspca_dev; 14008c2ecf20Sopenharmony_ci u16 sensor_id; 14018c2ecf20Sopenharmony_ci 14028c2ecf20Sopenharmony_ci /* reset bridge */ 14038c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe7, 0x3a); 14048c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe0, 0x08); 14058c2ecf20Sopenharmony_ci msleep(100); 14068c2ecf20Sopenharmony_ci 14078c2ecf20Sopenharmony_ci /* initialize the sensor address */ 14088c2ecf20Sopenharmony_ci reg_w(gspca_dev, OV534_REG_ADDRESS, 0x60); 14098c2ecf20Sopenharmony_ci 14108c2ecf20Sopenharmony_ci /* reset sensor */ 14118c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x12, 0x80); 14128c2ecf20Sopenharmony_ci msleep(10); 14138c2ecf20Sopenharmony_ci 14148c2ecf20Sopenharmony_ci /* probe the sensor */ 14158c2ecf20Sopenharmony_ci sccb_read(gspca_dev, 0x0a); 14168c2ecf20Sopenharmony_ci sensor_id = sccb_read(gspca_dev, 0x0a) << 8; 14178c2ecf20Sopenharmony_ci sccb_read(gspca_dev, 0x0b); 14188c2ecf20Sopenharmony_ci sensor_id |= sccb_read(gspca_dev, 0x0b); 14198c2ecf20Sopenharmony_ci gspca_dbg(gspca_dev, D_PROBE, "Sensor ID: %04x\n", sensor_id); 14208c2ecf20Sopenharmony_ci 14218c2ecf20Sopenharmony_ci /* initialize */ 14228c2ecf20Sopenharmony_ci if ((sensor_id & 0xfff0) == 0x9650) { 14238c2ecf20Sopenharmony_ci sd->sensor = SENSOR_OV965x; 14248c2ecf20Sopenharmony_ci 14258c2ecf20Sopenharmony_ci gspca_dev->cam.cam_mode = ov965x_mode; 14268c2ecf20Sopenharmony_ci gspca_dev->cam.nmodes = ARRAY_SIZE(ov965x_mode); 14278c2ecf20Sopenharmony_ci 14288c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, bridge_init, 14298c2ecf20Sopenharmony_ci ARRAY_SIZE(bridge_init)); 14308c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_init, 14318c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_init)); 14328c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, bridge_init_2, 14338c2ecf20Sopenharmony_ci ARRAY_SIZE(bridge_init_2)); 14348c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_init_2, 14358c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_init_2)); 14368c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe0, 0x00); 14378c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe0, 0x01); 14388c2ecf20Sopenharmony_ci set_led(gspca_dev, 0); 14398c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe0, 0x00); 14408c2ecf20Sopenharmony_ci } else if ((sensor_id & 0xfff0) == 0x9710) { 14418c2ecf20Sopenharmony_ci const char *p; 14428c2ecf20Sopenharmony_ci int l; 14438c2ecf20Sopenharmony_ci 14448c2ecf20Sopenharmony_ci sd->sensor = SENSOR_OV971x; 14458c2ecf20Sopenharmony_ci 14468c2ecf20Sopenharmony_ci gspca_dev->cam.cam_mode = ov971x_mode; 14478c2ecf20Sopenharmony_ci gspca_dev->cam.nmodes = ARRAY_SIZE(ov971x_mode); 14488c2ecf20Sopenharmony_ci 14498c2ecf20Sopenharmony_ci gspca_dev->cam.bulk = 1; 14508c2ecf20Sopenharmony_ci gspca_dev->cam.bulk_size = 16384; 14518c2ecf20Sopenharmony_ci gspca_dev->cam.bulk_nurbs = 2; 14528c2ecf20Sopenharmony_ci 14538c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov971x_init, 14548c2ecf20Sopenharmony_ci ARRAY_SIZE(ov971x_init)); 14558c2ecf20Sopenharmony_ci 14568c2ecf20Sopenharmony_ci /* set video format on bridge processor */ 14578c2ecf20Sopenharmony_ci /* access bridge processor's video format registers at: 0x00 */ 14588c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0x1c, 0x00); 14598c2ecf20Sopenharmony_ci /*set register: 0x00 is 'RAW8', 0x40 is 'YUV422' (YUYV?)*/ 14608c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0x1d, 0x00); 14618c2ecf20Sopenharmony_ci 14628c2ecf20Sopenharmony_ci /* Will W. specific stuff 14638c2ecf20Sopenharmony_ci * set VSYNC to 14648c2ecf20Sopenharmony_ci * output (0x1f) if first webcam 14658c2ecf20Sopenharmony_ci * input (0x17) if 2nd or 3rd webcam */ 14668c2ecf20Sopenharmony_ci p = video_device_node_name(&gspca_dev->vdev); 14678c2ecf20Sopenharmony_ci l = strlen(p) - 1; 14688c2ecf20Sopenharmony_ci if (p[l] == '0') 14698c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0x56, 0x1f); 14708c2ecf20Sopenharmony_ci else 14718c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0x56, 0x17); 14728c2ecf20Sopenharmony_ci } else if ((sensor_id & 0xfff0) == 0x5620) { 14738c2ecf20Sopenharmony_ci sd->sensor = SENSOR_OV562x; 14748c2ecf20Sopenharmony_ci gspca_dev->cam.cam_mode = ov562x_mode; 14758c2ecf20Sopenharmony_ci gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); 14768c2ecf20Sopenharmony_ci 14778c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, ov562x_init, 14788c2ecf20Sopenharmony_ci ARRAY_SIZE(ov562x_init)); 14798c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov562x_init_2, 14808c2ecf20Sopenharmony_ci ARRAY_SIZE(ov562x_init_2)); 14818c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe0, 0x00); 14828c2ecf20Sopenharmony_ci } else if ((sensor_id & 0xfff0) == 0x3610) { 14838c2ecf20Sopenharmony_ci sd->sensor = SENSOR_OV361x; 14848c2ecf20Sopenharmony_ci gspca_dev->cam.cam_mode = ov361x_mode; 14858c2ecf20Sopenharmony_ci gspca_dev->cam.nmodes = ARRAY_SIZE(ov361x_mode); 14868c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe7, 0x3a); 14878c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xf1, 0x60); 14888c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x12, 0x80); 14898c2ecf20Sopenharmony_ci } else { 14908c2ecf20Sopenharmony_ci pr_err("Unknown sensor %04x", sensor_id); 14918c2ecf20Sopenharmony_ci return -EINVAL; 14928c2ecf20Sopenharmony_ci } 14938c2ecf20Sopenharmony_ci 14948c2ecf20Sopenharmony_ci return gspca_dev->usb_err; 14958c2ecf20Sopenharmony_ci} 14968c2ecf20Sopenharmony_ci 14978c2ecf20Sopenharmony_cistatic int sd_start_ov361x(struct gspca_dev *gspca_dev) 14988c2ecf20Sopenharmony_ci{ 14998c2ecf20Sopenharmony_ci sccb_write(gspca_dev, 0x12, 0x80); 15008c2ecf20Sopenharmony_ci msleep(20); 15018c2ecf20Sopenharmony_ci switch (gspca_dev->curr_mode % (ov361x_last)) { 15028c2ecf20Sopenharmony_ci case ov361x_2048: 15038c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, ov361x_bridge_start_2048, 15048c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_bridge_start_2048)); 15058c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov361x_start_2048, 15068c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_start_2048)); 15078c2ecf20Sopenharmony_ci break; 15088c2ecf20Sopenharmony_ci case ov361x_1600: 15098c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, ov361x_bridge_start_1600, 15108c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_bridge_start_1600)); 15118c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov361x_start_1600, 15128c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_start_1600)); 15138c2ecf20Sopenharmony_ci break; 15148c2ecf20Sopenharmony_ci case ov361x_1024: 15158c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, ov361x_bridge_start_1024, 15168c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_bridge_start_1024)); 15178c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov361x_start_1024, 15188c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_start_1024)); 15198c2ecf20Sopenharmony_ci break; 15208c2ecf20Sopenharmony_ci case ov361x_640: 15218c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, ov361x_bridge_start_640, 15228c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_bridge_start_640)); 15238c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov361x_start_640, 15248c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_start_640)); 15258c2ecf20Sopenharmony_ci break; 15268c2ecf20Sopenharmony_ci case ov361x_320: 15278c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, ov361x_bridge_start_320, 15288c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_bridge_start_320)); 15298c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov361x_start_320, 15308c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_start_320)); 15318c2ecf20Sopenharmony_ci break; 15328c2ecf20Sopenharmony_ci case ov361x_160: 15338c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, ov361x_bridge_start_160, 15348c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_bridge_start_160)); 15358c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov361x_start_160, 15368c2ecf20Sopenharmony_ci ARRAY_SIZE(ov361x_start_160)); 15378c2ecf20Sopenharmony_ci break; 15388c2ecf20Sopenharmony_ci } 15398c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe0, 0x00); /* start transfer */ 15408c2ecf20Sopenharmony_ci 15418c2ecf20Sopenharmony_ci return gspca_dev->usb_err; 15428c2ecf20Sopenharmony_ci} 15438c2ecf20Sopenharmony_ci 15448c2ecf20Sopenharmony_cistatic int sd_start(struct gspca_dev *gspca_dev) 15458c2ecf20Sopenharmony_ci{ 15468c2ecf20Sopenharmony_ci struct sd *sd = (struct sd *) gspca_dev; 15478c2ecf20Sopenharmony_ci 15488c2ecf20Sopenharmony_ci if (sd->sensor == SENSOR_OV971x) 15498c2ecf20Sopenharmony_ci return gspca_dev->usb_err; 15508c2ecf20Sopenharmony_ci if (sd->sensor == SENSOR_OV562x) 15518c2ecf20Sopenharmony_ci return gspca_dev->usb_err; 15528c2ecf20Sopenharmony_ci if (sd->sensor == SENSOR_OV361x) 15538c2ecf20Sopenharmony_ci return sd_start_ov361x(gspca_dev); 15548c2ecf20Sopenharmony_ci 15558c2ecf20Sopenharmony_ci switch (gspca_dev->curr_mode) { 15568c2ecf20Sopenharmony_ci case QVGA_MODE: /* 320x240 */ 15578c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_start_1_vga, 15588c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_start_1_vga)); 15598c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, bridge_start_qvga, 15608c2ecf20Sopenharmony_ci ARRAY_SIZE(bridge_start_qvga)); 15618c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_start_2_qvga, 15628c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_start_2_qvga)); 15638c2ecf20Sopenharmony_ci break; 15648c2ecf20Sopenharmony_ci case VGA_MODE: /* 640x480 */ 15658c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_start_1_vga, 15668c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_start_1_vga)); 15678c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, bridge_start_vga, 15688c2ecf20Sopenharmony_ci ARRAY_SIZE(bridge_start_vga)); 15698c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_start_2_vga, 15708c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_start_2_vga)); 15718c2ecf20Sopenharmony_ci break; 15728c2ecf20Sopenharmony_ci case SVGA_MODE: /* 800x600 */ 15738c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_start_1_svga, 15748c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_start_1_svga)); 15758c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, bridge_start_svga, 15768c2ecf20Sopenharmony_ci ARRAY_SIZE(bridge_start_svga)); 15778c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_start_2_svga, 15788c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_start_2_svga)); 15798c2ecf20Sopenharmony_ci break; 15808c2ecf20Sopenharmony_ci case XGA_MODE: /* 1024x768 */ 15818c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_start_1_xga, 15828c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_start_1_xga)); 15838c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, bridge_start_xga, 15848c2ecf20Sopenharmony_ci ARRAY_SIZE(bridge_start_xga)); 15858c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_start_2_svga, 15868c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_start_2_svga)); 15878c2ecf20Sopenharmony_ci break; 15888c2ecf20Sopenharmony_ci default: 15898c2ecf20Sopenharmony_ci/* case SXGA_MODE: * 1280x1024 */ 15908c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_start_1_sxga, 15918c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_start_1_sxga)); 15928c2ecf20Sopenharmony_ci reg_w_array(gspca_dev, bridge_start_sxga, 15938c2ecf20Sopenharmony_ci ARRAY_SIZE(bridge_start_sxga)); 15948c2ecf20Sopenharmony_ci sccb_w_array(gspca_dev, ov965x_start_2_sxga, 15958c2ecf20Sopenharmony_ci ARRAY_SIZE(ov965x_start_2_sxga)); 15968c2ecf20Sopenharmony_ci break; 15978c2ecf20Sopenharmony_ci } 15988c2ecf20Sopenharmony_ci 15998c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe0, 0x00); 16008c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe0, 0x00); 16018c2ecf20Sopenharmony_ci set_led(gspca_dev, 1); 16028c2ecf20Sopenharmony_ci return gspca_dev->usb_err; 16038c2ecf20Sopenharmony_ci} 16048c2ecf20Sopenharmony_ci 16058c2ecf20Sopenharmony_cistatic void sd_stopN(struct gspca_dev *gspca_dev) 16068c2ecf20Sopenharmony_ci{ 16078c2ecf20Sopenharmony_ci if (((struct sd *)gspca_dev)->sensor == SENSOR_OV361x) { 16088c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe0, 0x01); /* stop transfer */ 16098c2ecf20Sopenharmony_ci /* reg_w(gspca_dev, 0x31, 0x09); */ 16108c2ecf20Sopenharmony_ci return; 16118c2ecf20Sopenharmony_ci } 16128c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe0, 0x01); 16138c2ecf20Sopenharmony_ci set_led(gspca_dev, 0); 16148c2ecf20Sopenharmony_ci reg_w(gspca_dev, 0xe0, 0x00); 16158c2ecf20Sopenharmony_ci} 16168c2ecf20Sopenharmony_ci 16178c2ecf20Sopenharmony_ci/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 16188c2ecf20Sopenharmony_ci#define UVC_STREAM_EOH (1 << 7) 16198c2ecf20Sopenharmony_ci#define UVC_STREAM_ERR (1 << 6) 16208c2ecf20Sopenharmony_ci#define UVC_STREAM_STI (1 << 5) 16218c2ecf20Sopenharmony_ci#define UVC_STREAM_RES (1 << 4) 16228c2ecf20Sopenharmony_ci#define UVC_STREAM_SCR (1 << 3) 16238c2ecf20Sopenharmony_ci#define UVC_STREAM_PTS (1 << 2) 16248c2ecf20Sopenharmony_ci#define UVC_STREAM_EOF (1 << 1) 16258c2ecf20Sopenharmony_ci#define UVC_STREAM_FID (1 << 0) 16268c2ecf20Sopenharmony_ci 16278c2ecf20Sopenharmony_cistatic void sd_pkt_scan(struct gspca_dev *gspca_dev, 16288c2ecf20Sopenharmony_ci u8 *data, int len) 16298c2ecf20Sopenharmony_ci{ 16308c2ecf20Sopenharmony_ci struct sd *sd = (struct sd *) gspca_dev; 16318c2ecf20Sopenharmony_ci __u32 this_pts; 16328c2ecf20Sopenharmony_ci u8 this_fid; 16338c2ecf20Sopenharmony_ci int remaining_len = len; 16348c2ecf20Sopenharmony_ci int payload_len; 16358c2ecf20Sopenharmony_ci 16368c2ecf20Sopenharmony_ci payload_len = gspca_dev->cam.bulk ? 2048 : 2040; 16378c2ecf20Sopenharmony_ci do { 16388c2ecf20Sopenharmony_ci len = min(remaining_len, payload_len); 16398c2ecf20Sopenharmony_ci 16408c2ecf20Sopenharmony_ci /* Payloads are prefixed with a UVC-style header. We 16418c2ecf20Sopenharmony_ci consider a frame to start when the FID toggles, or the PTS 16428c2ecf20Sopenharmony_ci changes. A frame ends when EOF is set, and we've received 16438c2ecf20Sopenharmony_ci the correct number of bytes. */ 16448c2ecf20Sopenharmony_ci 16458c2ecf20Sopenharmony_ci /* Verify UVC header. Header length is always 12 */ 16468c2ecf20Sopenharmony_ci if (data[0] != 12 || len < 12) { 16478c2ecf20Sopenharmony_ci gspca_dbg(gspca_dev, D_PACK, "bad header\n"); 16488c2ecf20Sopenharmony_ci goto discard; 16498c2ecf20Sopenharmony_ci } 16508c2ecf20Sopenharmony_ci 16518c2ecf20Sopenharmony_ci /* Check errors */ 16528c2ecf20Sopenharmony_ci if (data[1] & UVC_STREAM_ERR) { 16538c2ecf20Sopenharmony_ci gspca_dbg(gspca_dev, D_PACK, "payload error\n"); 16548c2ecf20Sopenharmony_ci goto discard; 16558c2ecf20Sopenharmony_ci } 16568c2ecf20Sopenharmony_ci 16578c2ecf20Sopenharmony_ci /* Extract PTS and FID */ 16588c2ecf20Sopenharmony_ci if (!(data[1] & UVC_STREAM_PTS)) { 16598c2ecf20Sopenharmony_ci gspca_dbg(gspca_dev, D_PACK, "PTS not present\n"); 16608c2ecf20Sopenharmony_ci goto discard; 16618c2ecf20Sopenharmony_ci } 16628c2ecf20Sopenharmony_ci this_pts = (data[5] << 24) | (data[4] << 16) 16638c2ecf20Sopenharmony_ci | (data[3] << 8) | data[2]; 16648c2ecf20Sopenharmony_ci this_fid = data[1] & UVC_STREAM_FID; 16658c2ecf20Sopenharmony_ci 16668c2ecf20Sopenharmony_ci /* If PTS or FID has changed, start a new frame. */ 16678c2ecf20Sopenharmony_ci if (this_pts != sd->last_pts || this_fid != sd->last_fid) { 16688c2ecf20Sopenharmony_ci if (gspca_dev->last_packet_type == INTER_PACKET) 16698c2ecf20Sopenharmony_ci gspca_frame_add(gspca_dev, LAST_PACKET, 16708c2ecf20Sopenharmony_ci NULL, 0); 16718c2ecf20Sopenharmony_ci sd->last_pts = this_pts; 16728c2ecf20Sopenharmony_ci sd->last_fid = this_fid; 16738c2ecf20Sopenharmony_ci gspca_frame_add(gspca_dev, FIRST_PACKET, 16748c2ecf20Sopenharmony_ci data + 12, len - 12); 16758c2ecf20Sopenharmony_ci /* If this packet is marked as EOF, end the frame */ 16768c2ecf20Sopenharmony_ci } else if (data[1] & UVC_STREAM_EOF) { 16778c2ecf20Sopenharmony_ci sd->last_pts = 0; 16788c2ecf20Sopenharmony_ci gspca_frame_add(gspca_dev, LAST_PACKET, 16798c2ecf20Sopenharmony_ci data + 12, len - 12); 16808c2ecf20Sopenharmony_ci } else { 16818c2ecf20Sopenharmony_ci 16828c2ecf20Sopenharmony_ci /* Add the data from this payload */ 16838c2ecf20Sopenharmony_ci gspca_frame_add(gspca_dev, INTER_PACKET, 16848c2ecf20Sopenharmony_ci data + 12, len - 12); 16858c2ecf20Sopenharmony_ci } 16868c2ecf20Sopenharmony_ci 16878c2ecf20Sopenharmony_ci /* Done this payload */ 16888c2ecf20Sopenharmony_ci goto scan_next; 16898c2ecf20Sopenharmony_ci 16908c2ecf20Sopenharmony_cidiscard: 16918c2ecf20Sopenharmony_ci /* Discard data until a new frame starts. */ 16928c2ecf20Sopenharmony_ci gspca_dev->last_packet_type = DISCARD_PACKET; 16938c2ecf20Sopenharmony_ci 16948c2ecf20Sopenharmony_ciscan_next: 16958c2ecf20Sopenharmony_ci remaining_len -= len; 16968c2ecf20Sopenharmony_ci data += len; 16978c2ecf20Sopenharmony_ci } while (remaining_len > 0); 16988c2ecf20Sopenharmony_ci} 16998c2ecf20Sopenharmony_ci 17008c2ecf20Sopenharmony_cistatic int sd_s_ctrl(struct v4l2_ctrl *ctrl) 17018c2ecf20Sopenharmony_ci{ 17028c2ecf20Sopenharmony_ci struct gspca_dev *gspca_dev = 17038c2ecf20Sopenharmony_ci container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 17048c2ecf20Sopenharmony_ci 17058c2ecf20Sopenharmony_ci gspca_dev->usb_err = 0; 17068c2ecf20Sopenharmony_ci 17078c2ecf20Sopenharmony_ci if (!gspca_dev->streaming) 17088c2ecf20Sopenharmony_ci return 0; 17098c2ecf20Sopenharmony_ci 17108c2ecf20Sopenharmony_ci switch (ctrl->id) { 17118c2ecf20Sopenharmony_ci case V4L2_CID_BRIGHTNESS: 17128c2ecf20Sopenharmony_ci setbrightness(gspca_dev, ctrl->val); 17138c2ecf20Sopenharmony_ci break; 17148c2ecf20Sopenharmony_ci case V4L2_CID_CONTRAST: 17158c2ecf20Sopenharmony_ci setcontrast(gspca_dev, ctrl->val); 17168c2ecf20Sopenharmony_ci break; 17178c2ecf20Sopenharmony_ci case V4L2_CID_SATURATION: 17188c2ecf20Sopenharmony_ci setsatur(gspca_dev, ctrl->val); 17198c2ecf20Sopenharmony_ci break; 17208c2ecf20Sopenharmony_ci case V4L2_CID_POWER_LINE_FREQUENCY: 17218c2ecf20Sopenharmony_ci setlightfreq(gspca_dev, ctrl->val); 17228c2ecf20Sopenharmony_ci break; 17238c2ecf20Sopenharmony_ci case V4L2_CID_SHARPNESS: 17248c2ecf20Sopenharmony_ci setsharpness(gspca_dev, ctrl->val); 17258c2ecf20Sopenharmony_ci break; 17268c2ecf20Sopenharmony_ci case V4L2_CID_AUTOGAIN: 17278c2ecf20Sopenharmony_ci if (ctrl->is_new) 17288c2ecf20Sopenharmony_ci setautogain(gspca_dev, ctrl->val); 17298c2ecf20Sopenharmony_ci if (!ctrl->val && gspca_dev->exposure->is_new) 17308c2ecf20Sopenharmony_ci setexposure(gspca_dev, gspca_dev->exposure->val); 17318c2ecf20Sopenharmony_ci break; 17328c2ecf20Sopenharmony_ci } 17338c2ecf20Sopenharmony_ci return gspca_dev->usb_err; 17348c2ecf20Sopenharmony_ci} 17358c2ecf20Sopenharmony_ci 17368c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops sd_ctrl_ops = { 17378c2ecf20Sopenharmony_ci .s_ctrl = sd_s_ctrl, 17388c2ecf20Sopenharmony_ci}; 17398c2ecf20Sopenharmony_ci 17408c2ecf20Sopenharmony_cistatic int sd_init_controls(struct gspca_dev *gspca_dev) 17418c2ecf20Sopenharmony_ci{ 17428c2ecf20Sopenharmony_ci struct sd *sd = (struct sd *)gspca_dev; 17438c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; 17448c2ecf20Sopenharmony_ci 17458c2ecf20Sopenharmony_ci if (sd->sensor == SENSOR_OV971x) 17468c2ecf20Sopenharmony_ci return 0; 17478c2ecf20Sopenharmony_ci if (sd->sensor == SENSOR_OV361x) 17488c2ecf20Sopenharmony_ci return 0; 17498c2ecf20Sopenharmony_ci gspca_dev->vdev.ctrl_handler = hdl; 17508c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl, 7); 17518c2ecf20Sopenharmony_ci if (sd->sensor == SENSOR_OV562x) { 17528c2ecf20Sopenharmony_ci v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 17538c2ecf20Sopenharmony_ci V4L2_CID_BRIGHTNESS, -90, 90, 1, 0); 17548c2ecf20Sopenharmony_ci } else { 17558c2ecf20Sopenharmony_ci v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 17568c2ecf20Sopenharmony_ci V4L2_CID_BRIGHTNESS, 0, 15, 1, 7); 17578c2ecf20Sopenharmony_ci v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 17588c2ecf20Sopenharmony_ci V4L2_CID_CONTRAST, 0, 15, 1, 3); 17598c2ecf20Sopenharmony_ci v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 17608c2ecf20Sopenharmony_ci V4L2_CID_SATURATION, 0, 4, 1, 2); 17618c2ecf20Sopenharmony_ci /* -1 = auto */ 17628c2ecf20Sopenharmony_ci v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 17638c2ecf20Sopenharmony_ci V4L2_CID_SHARPNESS, -1, 4, 1, -1); 17648c2ecf20Sopenharmony_ci gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 17658c2ecf20Sopenharmony_ci V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 17668c2ecf20Sopenharmony_ci gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 17678c2ecf20Sopenharmony_ci V4L2_CID_EXPOSURE, 0, 3, 1, 0); 17688c2ecf20Sopenharmony_ci v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, 17698c2ecf20Sopenharmony_ci V4L2_CID_POWER_LINE_FREQUENCY, 17708c2ecf20Sopenharmony_ci V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); 17718c2ecf20Sopenharmony_ci v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); 17728c2ecf20Sopenharmony_ci } 17738c2ecf20Sopenharmony_ci 17748c2ecf20Sopenharmony_ci if (hdl->error) { 17758c2ecf20Sopenharmony_ci pr_err("Could not initialize controls\n"); 17768c2ecf20Sopenharmony_ci return hdl->error; 17778c2ecf20Sopenharmony_ci } 17788c2ecf20Sopenharmony_ci return 0; 17798c2ecf20Sopenharmony_ci} 17808c2ecf20Sopenharmony_ci 17818c2ecf20Sopenharmony_ci/* sub-driver description */ 17828c2ecf20Sopenharmony_cistatic const struct sd_desc sd_desc = { 17838c2ecf20Sopenharmony_ci .name = MODULE_NAME, 17848c2ecf20Sopenharmony_ci .config = sd_config, 17858c2ecf20Sopenharmony_ci .init = sd_init, 17868c2ecf20Sopenharmony_ci .init_controls = sd_init_controls, 17878c2ecf20Sopenharmony_ci .start = sd_start, 17888c2ecf20Sopenharmony_ci .stopN = sd_stopN, 17898c2ecf20Sopenharmony_ci .pkt_scan = sd_pkt_scan, 17908c2ecf20Sopenharmony_ci}; 17918c2ecf20Sopenharmony_ci 17928c2ecf20Sopenharmony_ci/* -- module initialisation -- */ 17938c2ecf20Sopenharmony_cistatic const struct usb_device_id device_table[] = { 17948c2ecf20Sopenharmony_ci {USB_DEVICE(0x05a9, 0x8065)}, 17958c2ecf20Sopenharmony_ci {USB_DEVICE(0x06f8, 0x3003)}, 17968c2ecf20Sopenharmony_ci {USB_DEVICE(0x05a9, 0x1550)}, 17978c2ecf20Sopenharmony_ci {} 17988c2ecf20Sopenharmony_ci}; 17998c2ecf20Sopenharmony_ci 18008c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(usb, device_table); 18018c2ecf20Sopenharmony_ci 18028c2ecf20Sopenharmony_ci/* -- device connect -- */ 18038c2ecf20Sopenharmony_cistatic int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 18048c2ecf20Sopenharmony_ci{ 18058c2ecf20Sopenharmony_ci return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 18068c2ecf20Sopenharmony_ci THIS_MODULE); 18078c2ecf20Sopenharmony_ci} 18088c2ecf20Sopenharmony_ci 18098c2ecf20Sopenharmony_cistatic struct usb_driver sd_driver = { 18108c2ecf20Sopenharmony_ci .name = MODULE_NAME, 18118c2ecf20Sopenharmony_ci .id_table = device_table, 18128c2ecf20Sopenharmony_ci .probe = sd_probe, 18138c2ecf20Sopenharmony_ci .disconnect = gspca_disconnect, 18148c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 18158c2ecf20Sopenharmony_ci .suspend = gspca_suspend, 18168c2ecf20Sopenharmony_ci .resume = gspca_resume, 18178c2ecf20Sopenharmony_ci .reset_resume = gspca_resume, 18188c2ecf20Sopenharmony_ci#endif 18198c2ecf20Sopenharmony_ci}; 18208c2ecf20Sopenharmony_ci 18218c2ecf20Sopenharmony_cimodule_usb_driver(sd_driver); 1822