1fd9871f7SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2c52af799SJean-Francois Moine /* 38d64d4f6SJean-François Moine * ov534-ov9xxx gspca driver 4c52af799SJean-Francois Moine * 58d64d4f6SJean-François Moine * Copyright (C) 2009-2011 Jean-Francois Moine http://moinejf.free.fr 6c52af799SJean-Francois Moine * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 7c52af799SJean-Francois Moine * Copyright (C) 2008 Jim Paris <jim@jtan.com> 8c52af799SJean-Francois Moine * 9c52af799SJean-Francois Moine * Based on a prototype written by Mark Ferrell <majortrips@gmail.com> 10c52af799SJean-Francois Moine * USB protocol reverse engineered by Jim Paris <jim@jtan.com> 11c52af799SJean-Francois Moine * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ 12c52af799SJean-Francois Moine */ 13c52af799SJean-Francois Moine 14133a9fe9SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 15133a9fe9SJoe Perches 16c52af799SJean-Francois Moine #define MODULE_NAME "ov534_9" 17c52af799SJean-Francois Moine 18c52af799SJean-Francois Moine #include "gspca.h" 19c52af799SJean-Francois Moine 20c52af799SJean-Francois Moine #define OV534_REG_ADDRESS 0xf1 /* sensor address */ 21c52af799SJean-Francois Moine #define OV534_REG_SUBADDR 0xf2 22c52af799SJean-Francois Moine #define OV534_REG_WRITE 0xf3 23c52af799SJean-Francois Moine #define OV534_REG_READ 0xf4 24c52af799SJean-Francois Moine #define OV534_REG_OPERATION 0xf5 25c52af799SJean-Francois Moine #define OV534_REG_STATUS 0xf6 26c52af799SJean-Francois Moine 27c52af799SJean-Francois Moine #define OV534_OP_WRITE_3 0x37 28c52af799SJean-Francois Moine #define OV534_OP_WRITE_2 0x33 29c52af799SJean-Francois Moine #define OV534_OP_READ_2 0xf9 30c52af799SJean-Francois Moine 31c52af799SJean-Francois Moine #define CTRL_TIMEOUT 500 32c52af799SJean-Francois Moine 33c52af799SJean-Francois Moine MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>"); 34c52af799SJean-Francois Moine MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver"); 35c52af799SJean-Francois Moine MODULE_LICENSE("GPL"); 36c52af799SJean-Francois Moine 37c52af799SJean-Francois Moine /* specific webcam descriptor */ 38c52af799SJean-Francois Moine struct sd { 39c52af799SJean-Francois Moine struct gspca_dev gspca_dev; /* !! must be the first item */ 40c52af799SJean-Francois Moine __u32 last_pts; 41c52af799SJean-Francois Moine u8 last_fid; 428d64d4f6SJean-François Moine 438d64d4f6SJean-François Moine u8 sensor; 448d64d4f6SJean-François Moine }; 458d64d4f6SJean-François Moine enum sensors { 468d64d4f6SJean-François Moine SENSOR_OV965x, /* ov9657 */ 478d64d4f6SJean-François Moine SENSOR_OV971x, /* ov9712 */ 48965b37a4SJose Alberto Reguero SENSOR_OV562x, /* ov5621 */ 4915807765SVladik Aranov SENSOR_OV361x, /* ov3610 */ 508d64d4f6SJean-François Moine NSENSORS 51c52af799SJean-Francois Moine }; 52c52af799SJean-Francois Moine 53c52af799SJean-Francois Moine static const struct v4l2_pix_format ov965x_mode[] = { 54c52af799SJean-Francois Moine #define QVGA_MODE 0 55c52af799SJean-Francois Moine {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 56c52af799SJean-Francois Moine .bytesperline = 320, 57c52af799SJean-Francois Moine .sizeimage = 320 * 240 * 3 / 8 + 590, 58c52af799SJean-Francois Moine .colorspace = V4L2_COLORSPACE_JPEG}, 59c52af799SJean-Francois Moine #define VGA_MODE 1 60c52af799SJean-Francois Moine {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 61c52af799SJean-Francois Moine .bytesperline = 640, 62c52af799SJean-Francois Moine .sizeimage = 640 * 480 * 3 / 8 + 590, 63c52af799SJean-Francois Moine .colorspace = V4L2_COLORSPACE_JPEG}, 64c52af799SJean-Francois Moine #define SVGA_MODE 2 65c52af799SJean-Francois Moine {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 66c52af799SJean-Francois Moine .bytesperline = 800, 67c52af799SJean-Francois Moine .sizeimage = 800 * 600 * 3 / 8 + 590, 68c52af799SJean-Francois Moine .colorspace = V4L2_COLORSPACE_JPEG}, 69c52af799SJean-Francois Moine #define XGA_MODE 3 70c52af799SJean-Francois Moine {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 71c52af799SJean-Francois Moine .bytesperline = 1024, 72c52af799SJean-Francois Moine .sizeimage = 1024 * 768 * 3 / 8 + 590, 73c52af799SJean-Francois Moine .colorspace = V4L2_COLORSPACE_JPEG}, 74c52af799SJean-Francois Moine #define SXGA_MODE 4 75c52af799SJean-Francois Moine {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 76c52af799SJean-Francois Moine .bytesperline = 1280, 77c52af799SJean-Francois Moine .sizeimage = 1280 * 1024 * 3 / 8 + 590, 78c52af799SJean-Francois Moine .colorspace = V4L2_COLORSPACE_JPEG}, 79c52af799SJean-Francois Moine }; 80c52af799SJean-Francois Moine 818d64d4f6SJean-François Moine static const struct v4l2_pix_format ov971x_mode[] = { 828d64d4f6SJean-François Moine {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 838d64d4f6SJean-François Moine .bytesperline = 640, 848d64d4f6SJean-François Moine .sizeimage = 640 * 480, 858d64d4f6SJean-François Moine .colorspace = V4L2_COLORSPACE_SRGB 868d64d4f6SJean-François Moine } 878d64d4f6SJean-François Moine }; 888d64d4f6SJean-François Moine 89965b37a4SJose Alberto Reguero static const struct v4l2_pix_format ov562x_mode[] = { 90965b37a4SJose Alberto Reguero {2592, 1680, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 91965b37a4SJose Alberto Reguero .bytesperline = 2592, 92965b37a4SJose Alberto Reguero .sizeimage = 2592 * 1680, 93965b37a4SJose Alberto Reguero .colorspace = V4L2_COLORSPACE_SRGB 94965b37a4SJose Alberto Reguero } 95965b37a4SJose Alberto Reguero }; 96965b37a4SJose Alberto Reguero 9715807765SVladik Aranov enum ov361x { 9815807765SVladik Aranov ov361x_2048 = 0, 9915807765SVladik Aranov ov361x_1600, 10015807765SVladik Aranov ov361x_1024, 10115807765SVladik Aranov ov361x_640, 10215807765SVladik Aranov ov361x_320, 10315807765SVladik Aranov ov361x_160, 10415807765SVladik Aranov ov361x_last 10515807765SVladik Aranov }; 10615807765SVladik Aranov 10715807765SVladik Aranov static const struct v4l2_pix_format ov361x_mode[] = { 10815807765SVladik Aranov {0x800, 0x600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 10915807765SVladik Aranov .bytesperline = 0x800, 11015807765SVladik Aranov .sizeimage = 0x800 * 0x600, 11115807765SVladik Aranov .colorspace = V4L2_COLORSPACE_SRGB}, 11215807765SVladik Aranov {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 11315807765SVladik Aranov .bytesperline = 1600, 11415807765SVladik Aranov .sizeimage = 1600 * 1200, 11515807765SVladik Aranov .colorspace = V4L2_COLORSPACE_SRGB}, 11615807765SVladik Aranov {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 11715807765SVladik Aranov .bytesperline = 768, 11815807765SVladik Aranov .sizeimage = 1024 * 768, 11915807765SVladik Aranov .colorspace = V4L2_COLORSPACE_SRGB}, 12015807765SVladik Aranov {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 12115807765SVladik Aranov .bytesperline = 640, 12215807765SVladik Aranov .sizeimage = 640 * 480, 12315807765SVladik Aranov .colorspace = V4L2_COLORSPACE_SRGB}, 12415807765SVladik Aranov {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 12515807765SVladik Aranov .bytesperline = 320, 12615807765SVladik Aranov .sizeimage = 320 * 240, 12715807765SVladik Aranov .colorspace = V4L2_COLORSPACE_SRGB}, 12815807765SVladik Aranov {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 12915807765SVladik Aranov .bytesperline = 160, 13015807765SVladik Aranov .sizeimage = 160 * 120, 13115807765SVladik Aranov .colorspace = V4L2_COLORSPACE_SRGB} 13215807765SVladik Aranov }; 13315807765SVladik Aranov 13415807765SVladik Aranov static const u8 ov361x_start_2048[][2] = { 13515807765SVladik Aranov {0x12, 0x80}, 13615807765SVladik Aranov {0x13, 0xcf}, 13715807765SVladik Aranov {0x14, 0x40}, 13815807765SVladik Aranov {0x15, 0x00}, 13915807765SVladik Aranov {0x01, 0x80}, 14015807765SVladik Aranov {0x02, 0x80}, 14115807765SVladik Aranov {0x04, 0x70}, 14215807765SVladik Aranov {0x0d, 0x40}, 14315807765SVladik Aranov {0x0f, 0x47}, 14415807765SVladik Aranov {0x11, 0x81}, 14515807765SVladik Aranov {0x32, 0x36}, 14615807765SVladik Aranov {0x33, 0x0c}, 14715807765SVladik Aranov {0x34, 0x00}, 14815807765SVladik Aranov {0x35, 0x90}, 14915807765SVladik Aranov {0x12, 0x00}, 15015807765SVladik Aranov {0x17, 0x10}, 15115807765SVladik Aranov {0x18, 0x90}, 15215807765SVladik Aranov {0x19, 0x00}, 15315807765SVladik Aranov {0x1a, 0xc0}, 15415807765SVladik Aranov }; 15515807765SVladik Aranov static const u8 ov361x_bridge_start_2048[][2] = { 15615807765SVladik Aranov {0xf1, 0x60}, 15715807765SVladik Aranov {0x88, 0x00}, 15815807765SVladik Aranov {0x89, 0x08}, 15915807765SVladik Aranov {0x8a, 0x00}, 16015807765SVladik Aranov {0x8b, 0x06}, 16115807765SVladik Aranov {0x8c, 0x01}, 16215807765SVladik Aranov {0x8d, 0x10}, 16315807765SVladik Aranov {0x1c, 0x00}, 16415807765SVladik Aranov {0x1d, 0x48}, 16515807765SVladik Aranov {0x1d, 0x00}, 16615807765SVladik Aranov {0x1d, 0xff}, 16715807765SVladik Aranov {0x1c, 0x0a}, 16815807765SVladik Aranov {0x1d, 0x2e}, 16915807765SVladik Aranov {0x1d, 0x1e}, 17015807765SVladik Aranov }; 17115807765SVladik Aranov 17215807765SVladik Aranov static const u8 ov361x_start_1600[][2] = { 17315807765SVladik Aranov {0x12, 0x80}, 17415807765SVladik Aranov {0x13, 0xcf}, 17515807765SVladik Aranov {0x14, 0x40}, 17615807765SVladik Aranov {0x15, 0x00}, 17715807765SVladik Aranov {0x01, 0x80}, 17815807765SVladik Aranov {0x02, 0x80}, 17915807765SVladik Aranov {0x04, 0x70}, 18015807765SVladik Aranov {0x0d, 0x40}, 18115807765SVladik Aranov {0x0f, 0x47}, 18215807765SVladik Aranov {0x11, 0x81}, 18315807765SVladik Aranov {0x32, 0x36}, 18415807765SVladik Aranov {0x33, 0x0C}, 18515807765SVladik Aranov {0x34, 0x00}, 18615807765SVladik Aranov {0x35, 0x90}, 18715807765SVladik Aranov {0x12, 0x00}, 18815807765SVladik Aranov {0x17, 0x10}, 18915807765SVladik Aranov {0x18, 0x90}, 19015807765SVladik Aranov {0x19, 0x00}, 19115807765SVladik Aranov {0x1a, 0xc0}, 19215807765SVladik Aranov }; 19315807765SVladik Aranov static const u8 ov361x_bridge_start_1600[][2] = { 19415807765SVladik Aranov {0xf1, 0x60}, /* Hsize[7:0] */ 19515807765SVladik Aranov {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 19615807765SVladik Aranov {0x89, 0x08}, /* Vsize[7:0] */ 19715807765SVladik Aranov {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 19815807765SVladik Aranov {0x8b, 0x06}, /* for Iso */ 19915807765SVladik Aranov {0x8c, 0x01}, /* RAW input */ 20015807765SVladik Aranov {0x8d, 0x10}, 20115807765SVladik Aranov {0x1c, 0x00}, /* RAW output, Iso transfer */ 20215807765SVladik Aranov {0x1d, 0x48}, 20315807765SVladik Aranov {0x1d, 0x00}, 20415807765SVladik Aranov {0x1d, 0xff}, 20515807765SVladik Aranov {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 20615807765SVladik Aranov {0x1d, 0x2e}, /* for Iso */ 20715807765SVladik Aranov {0x1d, 0x1e}, 20815807765SVladik Aranov }; 20915807765SVladik Aranov 21015807765SVladik Aranov static const u8 ov361x_start_1024[][2] = { 21115807765SVladik Aranov {0x12, 0x80}, 21215807765SVladik Aranov {0x13, 0xcf}, 21315807765SVladik Aranov {0x14, 0x40}, 21415807765SVladik Aranov {0x15, 0x00}, 21515807765SVladik Aranov {0x01, 0x80}, 21615807765SVladik Aranov {0x02, 0x80}, 21715807765SVladik Aranov {0x04, 0x70}, 21815807765SVladik Aranov {0x0d, 0x40}, 21915807765SVladik Aranov {0x0f, 0x47}, 22015807765SVladik Aranov {0x11, 0x81}, 22115807765SVladik Aranov {0x32, 0x36}, 22215807765SVladik Aranov {0x33, 0x0C}, 22315807765SVladik Aranov {0x34, 0x00}, 22415807765SVladik Aranov {0x35, 0x90}, 22515807765SVladik Aranov {0x12, 0x40}, 22615807765SVladik Aranov {0x17, 0x1f}, 22715807765SVladik Aranov {0x18, 0x5f}, 22815807765SVladik Aranov {0x19, 0x00}, 22915807765SVladik Aranov {0x1a, 0x68}, 23015807765SVladik Aranov }; 23115807765SVladik Aranov static const u8 ov361x_bridge_start_1024[][2] = { 23215807765SVladik Aranov {0xf1, 0x60}, /* Hsize[7:0] */ 23315807765SVladik Aranov {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 23415807765SVladik Aranov {0x89, 0x04}, /* Vsize[7:0] */ 23515807765SVladik Aranov {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 23615807765SVladik Aranov {0x8b, 0x03}, /* for Iso */ 23715807765SVladik Aranov {0x8c, 0x01}, /* RAW input */ 23815807765SVladik Aranov {0x8d, 0x10}, 23915807765SVladik Aranov {0x1c, 0x00}, /* RAW output, Iso transfer */ 24015807765SVladik Aranov {0x1d, 0x48}, 24115807765SVladik Aranov {0x1d, 0x00}, 24215807765SVladik Aranov {0x1d, 0xff}, 24315807765SVladik Aranov {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 24415807765SVladik Aranov {0x1d, 0x2e}, /* for Iso */ 24515807765SVladik Aranov {0x1d, 0x1e}, 24615807765SVladik Aranov }; 24715807765SVladik Aranov 24815807765SVladik Aranov static const u8 ov361x_start_640[][2] = { 24915807765SVladik Aranov {0x12, 0x80}, 25015807765SVladik Aranov {0x13, 0xcf}, 25115807765SVladik Aranov {0x14, 0x40}, 25215807765SVladik Aranov {0x15, 0x00}, 25315807765SVladik Aranov {0x01, 0x80}, 25415807765SVladik Aranov {0x02, 0x80}, 25515807765SVladik Aranov {0x04, 0x70}, 25615807765SVladik Aranov {0x0d, 0x40}, 25715807765SVladik Aranov {0x0f, 0x47}, 25815807765SVladik Aranov {0x11, 0x81}, 25915807765SVladik Aranov {0x32, 0x36}, 26015807765SVladik Aranov {0x33, 0x0C}, 26115807765SVladik Aranov {0x34, 0x00}, 26215807765SVladik Aranov {0x35, 0x90}, 26315807765SVladik Aranov {0x12, 0x40}, 26415807765SVladik Aranov {0x17, 0x1f}, 26515807765SVladik Aranov {0x18, 0x5f}, 26615807765SVladik Aranov {0x19, 0x00}, 26715807765SVladik Aranov {0x1a, 0x68}, 26815807765SVladik Aranov }; 26915807765SVladik Aranov 27015807765SVladik Aranov static const u8 ov361x_bridge_start_640[][2] = { 27115807765SVladik Aranov {0xf1, 0x60}, /* Hsize[7:0]*/ 27215807765SVladik Aranov {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 27315807765SVladik Aranov {0x89, 0x04}, /* Vsize[7:0] */ 27415807765SVladik Aranov {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 27515807765SVladik Aranov {0x8b, 0x03}, /* for Iso */ 27615807765SVladik Aranov {0x8c, 0x01}, /* RAW input */ 27715807765SVladik Aranov {0x8d, 0x10}, 27815807765SVladik Aranov {0x1c, 0x00}, /* RAW output, Iso transfer */ 27915807765SVladik Aranov {0x1d, 0x48}, 28015807765SVladik Aranov {0x1d, 0x00}, 28115807765SVladik Aranov {0x1d, 0xff}, 28215807765SVladik Aranov {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 28315807765SVladik Aranov {0x1d, 0x2e}, /* for Iso */ 28415807765SVladik Aranov {0x1d, 0x1e}, 28515807765SVladik Aranov }; 28615807765SVladik Aranov 28715807765SVladik Aranov static const u8 ov361x_start_320[][2] = { 28815807765SVladik Aranov {0x12, 0x80}, 28915807765SVladik Aranov {0x13, 0xcf}, 29015807765SVladik Aranov {0x14, 0x40}, 29115807765SVladik Aranov {0x15, 0x00}, 29215807765SVladik Aranov {0x01, 0x80}, 29315807765SVladik Aranov {0x02, 0x80}, 29415807765SVladik Aranov {0x04, 0x70}, 29515807765SVladik Aranov {0x0d, 0x40}, 29615807765SVladik Aranov {0x0f, 0x47}, 29715807765SVladik Aranov {0x11, 0x81}, 29815807765SVladik Aranov {0x32, 0x36}, 29915807765SVladik Aranov {0x33, 0x0C}, 30015807765SVladik Aranov {0x34, 0x00}, 30115807765SVladik Aranov {0x35, 0x90}, 30215807765SVladik Aranov {0x12, 0x40}, 30315807765SVladik Aranov {0x17, 0x1f}, 30415807765SVladik Aranov {0x18, 0x5f}, 30515807765SVladik Aranov {0x19, 0x00}, 30615807765SVladik Aranov {0x1a, 0x68}, 30715807765SVladik Aranov }; 30815807765SVladik Aranov 30915807765SVladik Aranov static const u8 ov361x_bridge_start_320[][2] = { 31015807765SVladik Aranov {0xf1, 0x60}, /* Hsize[7:0] */ 31115807765SVladik Aranov {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 31215807765SVladik Aranov {0x89, 0x04}, /* Vsize[7:0] */ 31315807765SVladik Aranov {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 31415807765SVladik Aranov {0x8b, 0x03}, /* for Iso */ 31515807765SVladik Aranov {0x8c, 0x01}, /* RAW input */ 31615807765SVladik Aranov {0x8d, 0x10}, 31715807765SVladik Aranov {0x1c, 0x00}, /* RAW output, Iso transfer; */ 31815807765SVladik Aranov {0x1d, 0x48}, 31915807765SVladik Aranov {0x1d, 0x00}, 32015807765SVladik Aranov {0x1d, 0xff}, 32115807765SVladik Aranov {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 32215807765SVladik Aranov {0x1d, 0x2e}, /* for Iso */ 32315807765SVladik Aranov {0x1d, 0x1e}, 32415807765SVladik Aranov }; 32515807765SVladik Aranov 32615807765SVladik Aranov static const u8 ov361x_start_160[][2] = { 32715807765SVladik Aranov {0x12, 0x80}, 32815807765SVladik Aranov {0x13, 0xcf}, 32915807765SVladik Aranov {0x14, 0x40}, 33015807765SVladik Aranov {0x15, 0x00}, 33115807765SVladik Aranov {0x01, 0x80}, 33215807765SVladik Aranov {0x02, 0x80}, 33315807765SVladik Aranov {0x04, 0x70}, 33415807765SVladik Aranov {0x0d, 0x40}, 33515807765SVladik Aranov {0x0f, 0x47}, 33615807765SVladik Aranov {0x11, 0x81}, 33715807765SVladik Aranov {0x32, 0x36}, 33815807765SVladik Aranov {0x33, 0x0C}, 33915807765SVladik Aranov {0x34, 0x00}, 34015807765SVladik Aranov {0x35, 0x90}, 34115807765SVladik Aranov {0x12, 0x40}, 34215807765SVladik Aranov {0x17, 0x1f}, 34315807765SVladik Aranov {0x18, 0x5f}, 34415807765SVladik Aranov {0x19, 0x00}, 34515807765SVladik Aranov {0x1a, 0x68}, 34615807765SVladik Aranov }; 34715807765SVladik Aranov 34815807765SVladik Aranov static const u8 ov361x_bridge_start_160[][2] = { 34915807765SVladik Aranov {0xf1, 0x60}, /* Hsize[7:0] */ 35015807765SVladik Aranov {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 35115807765SVladik Aranov {0x89, 0x04}, /* Vsize[7:0] */ 35215807765SVladik Aranov {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 35315807765SVladik Aranov {0x8b, 0x03}, /* for Iso */ 35415807765SVladik Aranov {0x8c, 0x01}, /* RAW input */ 35515807765SVladik Aranov {0x8d, 0x10}, 35615807765SVladik Aranov {0x1c, 0x00}, /* RAW output, Iso transfer */ 35715807765SVladik Aranov {0x1d, 0x48}, 35815807765SVladik Aranov {0x1d, 0x00}, 35915807765SVladik Aranov {0x1d, 0xff}, 36015807765SVladik Aranov {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 36115807765SVladik Aranov {0x1d, 0x2e}, /* for Iso */ 36215807765SVladik Aranov {0x1d, 0x1e}, 36315807765SVladik Aranov }; 36415807765SVladik Aranov 365c52af799SJean-Francois Moine static const u8 bridge_init[][2] = { 366c52af799SJean-Francois Moine {0x88, 0xf8}, 367c52af799SJean-Francois Moine {0x89, 0xff}, 368c52af799SJean-Francois Moine {0x76, 0x03}, 369c52af799SJean-Francois Moine {0x92, 0x03}, 370c52af799SJean-Francois Moine {0x95, 0x10}, 371c52af799SJean-Francois Moine {0xe2, 0x00}, 372c52af799SJean-Francois Moine {0xe7, 0x3e}, 373c52af799SJean-Francois Moine {0x8d, 0x1c}, 374c52af799SJean-Francois Moine {0x8e, 0x00}, 375c52af799SJean-Francois Moine {0x8f, 0x00}, 376c52af799SJean-Francois Moine {0x1f, 0x00}, 377c52af799SJean-Francois Moine {0xc3, 0xf9}, 378c52af799SJean-Francois Moine {0x89, 0xff}, 379c52af799SJean-Francois Moine {0x88, 0xf8}, 380c52af799SJean-Francois Moine {0x76, 0x03}, 381c52af799SJean-Francois Moine {0x92, 0x01}, 382c52af799SJean-Francois Moine {0x93, 0x18}, 383c52af799SJean-Francois Moine {0x1c, 0x0a}, 384c52af799SJean-Francois Moine {0x1d, 0x48}, 385c52af799SJean-Francois Moine {0xc0, 0x50}, 386c52af799SJean-Francois Moine {0xc1, 0x3c}, 387c52af799SJean-Francois Moine {0x34, 0x05}, 388c52af799SJean-Francois Moine {0xc2, 0x0c}, 389c52af799SJean-Francois Moine {0xc3, 0xf9}, 390c52af799SJean-Francois Moine {0x34, 0x05}, 391c52af799SJean-Francois Moine {0xe7, 0x2e}, 392c52af799SJean-Francois Moine {0x31, 0xf9}, 393c52af799SJean-Francois Moine {0x35, 0x02}, 394c52af799SJean-Francois Moine {0xd9, 0x10}, 395c52af799SJean-Francois Moine {0x25, 0x42}, 396c52af799SJean-Francois Moine {0x94, 0x11}, 397c52af799SJean-Francois Moine }; 398c52af799SJean-Francois Moine 3998d64d4f6SJean-François Moine static const u8 ov965x_init[][2] = { 400c52af799SJean-Francois Moine {0x12, 0x80}, /* com7 - SSCB reset */ 401c52af799SJean-Francois Moine {0x00, 0x00}, /* gain */ 402c52af799SJean-Francois Moine {0x01, 0x80}, /* blue */ 403c52af799SJean-Francois Moine {0x02, 0x80}, /* red */ 404c52af799SJean-Francois Moine {0x03, 0x1b}, /* vref */ 405c52af799SJean-Francois Moine {0x04, 0x03}, /* com1 - exposure low bits */ 406c52af799SJean-Francois Moine {0x0b, 0x57}, /* ver */ 407c52af799SJean-Francois Moine {0x0e, 0x61}, /* com5 */ 408c52af799SJean-Francois Moine {0x0f, 0x42}, /* com6 */ 409c52af799SJean-Francois Moine {0x11, 0x00}, /* clkrc */ 410c52af799SJean-Francois Moine {0x12, 0x02}, /* com7 - 15fps VGA YUYV */ 411c52af799SJean-Francois Moine {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 412c52af799SJean-Francois Moine {0x14, 0x28}, /* com9 */ 413c52af799SJean-Francois Moine {0x16, 0x24}, /* reg16 */ 414c52af799SJean-Francois Moine {0x17, 0x1d}, /* hstart*/ 415c52af799SJean-Francois Moine {0x18, 0xbd}, /* hstop */ 416c52af799SJean-Francois Moine {0x19, 0x01}, /* vstrt */ 417c52af799SJean-Francois Moine {0x1a, 0x81}, /* vstop*/ 418c52af799SJean-Francois Moine {0x1e, 0x04}, /* mvfp */ 419c52af799SJean-Francois Moine {0x24, 0x3c}, /* aew */ 420c52af799SJean-Francois Moine {0x25, 0x36}, /* aeb */ 421c52af799SJean-Francois Moine {0x26, 0x71}, /* vpt */ 422c52af799SJean-Francois Moine {0x27, 0x08}, /* bbias */ 423c52af799SJean-Francois Moine {0x28, 0x08}, /* gbbias */ 424c52af799SJean-Francois Moine {0x29, 0x15}, /* gr com */ 425c52af799SJean-Francois Moine {0x2a, 0x00}, /* exhch */ 426c52af799SJean-Francois Moine {0x2b, 0x00}, /* exhcl */ 427c52af799SJean-Francois Moine {0x2c, 0x08}, /* rbias */ 428c52af799SJean-Francois Moine {0x32, 0xff}, /* href */ 429c52af799SJean-Francois Moine {0x33, 0x00}, /* chlf */ 430c52af799SJean-Francois Moine {0x34, 0x3f}, /* aref1 */ 431c52af799SJean-Francois Moine {0x35, 0x00}, /* aref2 */ 432c52af799SJean-Francois Moine {0x36, 0xf8}, /* aref3 */ 433c52af799SJean-Francois Moine {0x38, 0x72}, /* adc2 */ 434c52af799SJean-Francois Moine {0x39, 0x57}, /* aref4 */ 435c52af799SJean-Francois Moine {0x3a, 0x80}, /* tslb - yuyv */ 436c52af799SJean-Francois Moine {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 437c52af799SJean-Francois Moine {0x3d, 0x99}, /* com13 */ 438c52af799SJean-Francois Moine {0x3f, 0xc1}, /* edge */ 439c52af799SJean-Francois Moine {0x40, 0xc0}, /* com15 */ 440c52af799SJean-Francois Moine {0x41, 0x40}, /* com16 */ 441c52af799SJean-Francois Moine {0x42, 0xc0}, /* com17 */ 442c52af799SJean-Francois Moine {0x43, 0x0a}, /* rsvd */ 443c52af799SJean-Francois Moine {0x44, 0xf0}, 444c52af799SJean-Francois Moine {0x45, 0x46}, 445c52af799SJean-Francois Moine {0x46, 0x62}, 446c52af799SJean-Francois Moine {0x47, 0x2a}, 447c52af799SJean-Francois Moine {0x48, 0x3c}, 448c52af799SJean-Francois Moine {0x4a, 0xfc}, 449c52af799SJean-Francois Moine {0x4b, 0xfc}, 450c52af799SJean-Francois Moine {0x4c, 0x7f}, 451c52af799SJean-Francois Moine {0x4d, 0x7f}, 452c52af799SJean-Francois Moine {0x4e, 0x7f}, 453c52af799SJean-Francois Moine {0x4f, 0x98}, /* matrix */ 454c52af799SJean-Francois Moine {0x50, 0x98}, 455c52af799SJean-Francois Moine {0x51, 0x00}, 456c52af799SJean-Francois Moine {0x52, 0x28}, 457c52af799SJean-Francois Moine {0x53, 0x70}, 458c52af799SJean-Francois Moine {0x54, 0x98}, 459c52af799SJean-Francois Moine {0x58, 0x1a}, /* matrix coef sign */ 460c52af799SJean-Francois Moine {0x59, 0x85}, /* AWB control */ 461c52af799SJean-Francois Moine {0x5a, 0xa9}, 462c52af799SJean-Francois Moine {0x5b, 0x64}, 463c52af799SJean-Francois Moine {0x5c, 0x84}, 464c52af799SJean-Francois Moine {0x5d, 0x53}, 465c52af799SJean-Francois Moine {0x5e, 0x0e}, 466c52af799SJean-Francois Moine {0x5f, 0xf0}, /* AWB blue limit */ 467c52af799SJean-Francois Moine {0x60, 0xf0}, /* AWB red limit */ 468c52af799SJean-Francois Moine {0x61, 0xf0}, /* AWB green limit */ 469c52af799SJean-Francois Moine {0x62, 0x00}, /* lcc1 */ 470c52af799SJean-Francois Moine {0x63, 0x00}, /* lcc2 */ 471c52af799SJean-Francois Moine {0x64, 0x02}, /* lcc3 */ 472c52af799SJean-Francois Moine {0x65, 0x16}, /* lcc4 */ 473c52af799SJean-Francois Moine {0x66, 0x01}, /* lcc5 */ 474c52af799SJean-Francois Moine {0x69, 0x02}, /* hv */ 475c52af799SJean-Francois Moine {0x6b, 0x5a}, /* dbvl */ 476c52af799SJean-Francois Moine {0x6c, 0x04}, 477c52af799SJean-Francois Moine {0x6d, 0x55}, 478c52af799SJean-Francois Moine {0x6e, 0x00}, 479c52af799SJean-Francois Moine {0x6f, 0x9d}, 480c52af799SJean-Francois Moine {0x70, 0x21}, /* dnsth */ 481c52af799SJean-Francois Moine {0x71, 0x78}, 482c52af799SJean-Francois Moine {0x72, 0x00}, /* poidx */ 483c52af799SJean-Francois Moine {0x73, 0x01}, /* pckdv */ 484c52af799SJean-Francois Moine {0x74, 0x3a}, /* xindx */ 485c52af799SJean-Francois Moine {0x75, 0x35}, /* yindx */ 486c52af799SJean-Francois Moine {0x76, 0x01}, 487c52af799SJean-Francois Moine {0x77, 0x02}, 488c52af799SJean-Francois Moine {0x7a, 0x12}, /* gamma curve */ 489c52af799SJean-Francois Moine {0x7b, 0x08}, 490c52af799SJean-Francois Moine {0x7c, 0x16}, 491c52af799SJean-Francois Moine {0x7d, 0x30}, 492c52af799SJean-Francois Moine {0x7e, 0x5e}, 493c52af799SJean-Francois Moine {0x7f, 0x72}, 494c52af799SJean-Francois Moine {0x80, 0x82}, 495c52af799SJean-Francois Moine {0x81, 0x8e}, 496c52af799SJean-Francois Moine {0x82, 0x9a}, 497c52af799SJean-Francois Moine {0x83, 0xa4}, 498c52af799SJean-Francois Moine {0x84, 0xac}, 499c52af799SJean-Francois Moine {0x85, 0xb8}, 500c52af799SJean-Francois Moine {0x86, 0xc3}, 501c52af799SJean-Francois Moine {0x87, 0xd6}, 502c52af799SJean-Francois Moine {0x88, 0xe6}, 503c52af799SJean-Francois Moine {0x89, 0xf2}, 504c52af799SJean-Francois Moine {0x8a, 0x03}, 505c52af799SJean-Francois Moine {0x8c, 0x89}, /* com19 */ 506c52af799SJean-Francois Moine {0x14, 0x28}, /* com9 */ 507c52af799SJean-Francois Moine {0x90, 0x7d}, 508c52af799SJean-Francois Moine {0x91, 0x7b}, 509c52af799SJean-Francois Moine {0x9d, 0x03}, /* lcc6 */ 510c52af799SJean-Francois Moine {0x9e, 0x04}, /* lcc7 */ 511c52af799SJean-Francois Moine {0x9f, 0x7a}, 512c52af799SJean-Francois Moine {0xa0, 0x79}, 513c52af799SJean-Francois Moine {0xa1, 0x40}, /* aechm */ 514c52af799SJean-Francois Moine {0xa4, 0x50}, /* com21 */ 515c52af799SJean-Francois Moine {0xa5, 0x68}, /* com26 */ 516c52af799SJean-Francois Moine {0xa6, 0x4a}, /* AWB green */ 517c52af799SJean-Francois Moine {0xa8, 0xc1}, /* refa8 */ 518c52af799SJean-Francois Moine {0xa9, 0xef}, /* refa9 */ 519c52af799SJean-Francois Moine {0xaa, 0x92}, 520c52af799SJean-Francois Moine {0xab, 0x04}, 521c52af799SJean-Francois Moine {0xac, 0x80}, /* black level control */ 522c52af799SJean-Francois Moine {0xad, 0x80}, 523c52af799SJean-Francois Moine {0xae, 0x80}, 524c52af799SJean-Francois Moine {0xaf, 0x80}, 525c52af799SJean-Francois Moine {0xb2, 0xf2}, 526c52af799SJean-Francois Moine {0xb3, 0x20}, 527c52af799SJean-Francois Moine {0xb4, 0x20}, /* ctrlb4 */ 528c52af799SJean-Francois Moine {0xb5, 0x00}, 529c52af799SJean-Francois Moine {0xb6, 0xaf}, 530c52af799SJean-Francois Moine {0xbb, 0xae}, 531c52af799SJean-Francois Moine {0xbc, 0x7f}, /* ADC channel offsets */ 532c52af799SJean-Francois Moine {0xdb, 0x7f}, 533c52af799SJean-Francois Moine {0xbe, 0x7f}, 534c52af799SJean-Francois Moine {0xbf, 0x7f}, 535c52af799SJean-Francois Moine {0xc0, 0xe2}, 536c52af799SJean-Francois Moine {0xc1, 0xc0}, 537c52af799SJean-Francois Moine {0xc2, 0x01}, 538c52af799SJean-Francois Moine {0xc3, 0x4e}, 539c52af799SJean-Francois Moine {0xc6, 0x85}, 540c52af799SJean-Francois Moine {0xc7, 0x80}, /* com24 */ 541c52af799SJean-Francois Moine {0xc9, 0xe0}, 542c52af799SJean-Francois Moine {0xca, 0xe8}, 543c52af799SJean-Francois Moine {0xcb, 0xf0}, 544c52af799SJean-Francois Moine {0xcc, 0xd8}, 545c52af799SJean-Francois Moine {0xcd, 0xf1}, 546c52af799SJean-Francois Moine {0x4f, 0x98}, /* matrix */ 547c52af799SJean-Francois Moine {0x50, 0x98}, 548c52af799SJean-Francois Moine {0x51, 0x00}, 549c52af799SJean-Francois Moine {0x52, 0x28}, 550c52af799SJean-Francois Moine {0x53, 0x70}, 551c52af799SJean-Francois Moine {0x54, 0x98}, 552c52af799SJean-Francois Moine {0x58, 0x1a}, 553c52af799SJean-Francois Moine {0xff, 0x41}, /* read 41, write ff 00 */ 554c52af799SJean-Francois Moine {0x41, 0x40}, /* com16 */ 555c52af799SJean-Francois Moine 556c52af799SJean-Francois Moine {0xc5, 0x03}, /* 60 Hz banding filter */ 557c52af799SJean-Francois Moine {0x6a, 0x02}, /* 50 Hz banding filter */ 558c52af799SJean-Francois Moine 559c52af799SJean-Francois Moine {0x12, 0x62}, /* com7 - 30fps VGA YUV */ 560c52af799SJean-Francois Moine {0x36, 0xfa}, /* aref3 */ 561c52af799SJean-Francois Moine {0x69, 0x0a}, /* hv */ 562c52af799SJean-Francois Moine {0x8c, 0x89}, /* com22 */ 563c52af799SJean-Francois Moine {0x14, 0x28}, /* com9 */ 564c52af799SJean-Francois Moine {0x3e, 0x0c}, 565c52af799SJean-Francois Moine {0x41, 0x40}, /* com16 */ 566c52af799SJean-Francois Moine {0x72, 0x00}, 567c52af799SJean-Francois Moine {0x73, 0x00}, 568c52af799SJean-Francois Moine {0x74, 0x3a}, 569c52af799SJean-Francois Moine {0x75, 0x35}, 570c52af799SJean-Francois Moine {0x76, 0x01}, 571c52af799SJean-Francois Moine {0xc7, 0x80}, 572c52af799SJean-Francois Moine {0x03, 0x12}, /* vref */ 573c52af799SJean-Francois Moine {0x17, 0x16}, /* hstart */ 574c52af799SJean-Francois Moine {0x18, 0x02}, /* hstop */ 575c52af799SJean-Francois Moine {0x19, 0x01}, /* vstrt */ 576c52af799SJean-Francois Moine {0x1a, 0x3d}, /* vstop */ 577c52af799SJean-Francois Moine {0x32, 0xff}, /* href */ 578c52af799SJean-Francois Moine {0xc0, 0xaa}, 579c52af799SJean-Francois Moine }; 580c52af799SJean-Francois Moine 581c52af799SJean-Francois Moine static const u8 bridge_init_2[][2] = { 582c52af799SJean-Francois Moine {0x94, 0xaa}, 583c52af799SJean-Francois Moine {0xf1, 0x60}, 584c52af799SJean-Francois Moine {0xe5, 0x04}, 585c52af799SJean-Francois Moine {0xc0, 0x50}, 586c52af799SJean-Francois Moine {0xc1, 0x3c}, 587c52af799SJean-Francois Moine {0x8c, 0x00}, 588c52af799SJean-Francois Moine {0x8d, 0x1c}, 589c52af799SJean-Francois Moine {0x34, 0x05}, 590c52af799SJean-Francois Moine 591c52af799SJean-Francois Moine {0xc2, 0x0c}, 592c52af799SJean-Francois Moine {0xc3, 0xf9}, 593c52af799SJean-Francois Moine {0xda, 0x01}, 594c52af799SJean-Francois Moine {0x50, 0x00}, 595c52af799SJean-Francois Moine {0x51, 0xa0}, 596c52af799SJean-Francois Moine {0x52, 0x3c}, 597c52af799SJean-Francois Moine {0x53, 0x00}, 598c52af799SJean-Francois Moine {0x54, 0x00}, 599c52af799SJean-Francois Moine {0x55, 0x00}, 600c52af799SJean-Francois Moine {0x57, 0x00}, 601c52af799SJean-Francois Moine {0x5c, 0x00}, 602c52af799SJean-Francois Moine {0x5a, 0xa0}, 603c52af799SJean-Francois Moine {0x5b, 0x78}, 604c52af799SJean-Francois Moine {0x35, 0x02}, 605c52af799SJean-Francois Moine {0xd9, 0x10}, 606c52af799SJean-Francois Moine {0x94, 0x11}, 607c52af799SJean-Francois Moine }; 608c52af799SJean-Francois Moine 6098d64d4f6SJean-François Moine static const u8 ov965x_init_2[][2] = { 610c52af799SJean-Francois Moine {0x3b, 0xc4}, 611c52af799SJean-Francois Moine {0x1e, 0x04}, /* mvfp */ 612c52af799SJean-Francois Moine {0x13, 0xe0}, /* com8 */ 613c52af799SJean-Francois Moine {0x00, 0x00}, /* gain */ 614c52af799SJean-Francois Moine {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 615c52af799SJean-Francois Moine {0x11, 0x03}, /* clkrc */ 616c52af799SJean-Francois Moine {0x6b, 0x5a}, /* dblv */ 617c52af799SJean-Francois Moine {0x6a, 0x05}, 618c52af799SJean-Francois Moine {0xc5, 0x07}, 619c52af799SJean-Francois Moine {0xa2, 0x4b}, 620c52af799SJean-Francois Moine {0xa3, 0x3e}, 621c52af799SJean-Francois Moine {0x2d, 0x00}, 622c52af799SJean-Francois Moine {0xff, 0x42}, /* read 42, write ff 00 */ 623c52af799SJean-Francois Moine {0x42, 0xc0}, /* com17 */ 624c52af799SJean-Francois Moine {0x2d, 0x00}, 625c52af799SJean-Francois Moine {0xff, 0x42}, /* read 42, write ff 00 */ 626c52af799SJean-Francois Moine {0x42, 0xc1}, /* com17 */ 627c52af799SJean-Francois Moine /* sharpness */ 628c52af799SJean-Francois Moine {0x3f, 0x01}, 629c52af799SJean-Francois Moine {0xff, 0x42}, /* read 42, write ff 00 */ 630c52af799SJean-Francois Moine {0x42, 0xc1}, /* com17 */ 631c52af799SJean-Francois Moine /* saturation */ 632c52af799SJean-Francois Moine {0x4f, 0x98}, /* matrix */ 633c52af799SJean-Francois Moine {0x50, 0x98}, 634c52af799SJean-Francois Moine {0x51, 0x00}, 635c52af799SJean-Francois Moine {0x52, 0x28}, 636c52af799SJean-Francois Moine {0x53, 0x70}, 637c52af799SJean-Francois Moine {0x54, 0x98}, 638c52af799SJean-Francois Moine {0x58, 0x1a}, 639c52af799SJean-Francois Moine {0xff, 0x41}, /* read 41, write ff 00 */ 640c52af799SJean-Francois Moine {0x41, 0x40}, /* com16 */ 641c52af799SJean-Francois Moine /* contrast */ 642c52af799SJean-Francois Moine {0x56, 0x40}, 643c52af799SJean-Francois Moine /* brightness */ 644c52af799SJean-Francois Moine {0x55, 0x8f}, 645c52af799SJean-Francois Moine /* expo */ 646c52af799SJean-Francois Moine {0x10, 0x25}, /* aech - exposure high bits */ 647c52af799SJean-Francois Moine {0xff, 0x13}, /* read 13, write ff 00 */ 648c52af799SJean-Francois Moine {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 649c52af799SJean-Francois Moine }; 650c52af799SJean-Francois Moine 6518d64d4f6SJean-François Moine static const u8 ov971x_init[][2] = { 6528d64d4f6SJean-François Moine {0x12, 0x80}, 6538d64d4f6SJean-François Moine {0x09, 0x10}, 6548d64d4f6SJean-François Moine {0x1e, 0x07}, 6558d64d4f6SJean-François Moine {0x5f, 0x18}, 6568d64d4f6SJean-François Moine {0x69, 0x04}, 6578d64d4f6SJean-François Moine {0x65, 0x2a}, 6588d64d4f6SJean-François Moine {0x68, 0x0a}, 6598d64d4f6SJean-François Moine {0x39, 0x28}, 6608d64d4f6SJean-François Moine {0x4d, 0x90}, 6618d64d4f6SJean-François Moine {0xc1, 0x80}, 6628d64d4f6SJean-François Moine {0x0c, 0x30}, 6638d64d4f6SJean-François Moine {0x6d, 0x02}, 6648d64d4f6SJean-François Moine {0x96, 0xf1}, 6658d64d4f6SJean-François Moine {0xbc, 0x68}, 6668d64d4f6SJean-François Moine {0x12, 0x00}, 6678d64d4f6SJean-François Moine {0x3b, 0x00}, 6688d64d4f6SJean-François Moine {0x97, 0x80}, 6698d64d4f6SJean-François Moine {0x17, 0x25}, 6708d64d4f6SJean-François Moine {0x18, 0xa2}, 6718d64d4f6SJean-François Moine {0x19, 0x01}, 6728d64d4f6SJean-François Moine {0x1a, 0xca}, 6738d64d4f6SJean-François Moine {0x03, 0x0a}, 6748d64d4f6SJean-François Moine {0x32, 0x07}, 6758d64d4f6SJean-François Moine {0x98, 0x40}, /*{0x98, 0x00},*/ 6768d64d4f6SJean-François Moine {0x99, 0xA0}, /*{0x99, 0x00},*/ 6778d64d4f6SJean-François Moine {0x9a, 0x01}, /*{0x9a, 0x00},*/ 6788d64d4f6SJean-François Moine {0x57, 0x00}, 6798d64d4f6SJean-François Moine {0x58, 0x78}, /*{0x58, 0xc8},*/ 6808d64d4f6SJean-François Moine {0x59, 0x50}, /*{0x59, 0xa0},*/ 6818d64d4f6SJean-François Moine {0x4c, 0x13}, 6828d64d4f6SJean-François Moine {0x4b, 0x36}, 6838d64d4f6SJean-François Moine {0x3d, 0x3c}, 6848d64d4f6SJean-François Moine {0x3e, 0x03}, 6858d64d4f6SJean-François Moine {0xbd, 0x50}, /*{0xbd, 0xa0},*/ 6868d64d4f6SJean-François Moine {0xbe, 0x78}, /*{0xbe, 0xc8},*/ 6878d64d4f6SJean-François Moine {0x4e, 0x55}, 6888d64d4f6SJean-François Moine {0x4f, 0x55}, 6898d64d4f6SJean-François Moine {0x50, 0x55}, 6908d64d4f6SJean-François Moine {0x51, 0x55}, 6918d64d4f6SJean-François Moine {0x24, 0x55}, 6928d64d4f6SJean-François Moine {0x25, 0x40}, 6938d64d4f6SJean-François Moine {0x26, 0xa1}, 6948d64d4f6SJean-François Moine {0x5c, 0x59}, 6958d64d4f6SJean-François Moine {0x5d, 0x00}, 6968d64d4f6SJean-François Moine {0x11, 0x00}, 6978d64d4f6SJean-François Moine {0x2a, 0x98}, 6988d64d4f6SJean-François Moine {0x2b, 0x06}, 6998d64d4f6SJean-François Moine {0x2d, 0x00}, 7008d64d4f6SJean-François Moine {0x2e, 0x00}, 7018d64d4f6SJean-François Moine {0x13, 0xa5}, 7028d64d4f6SJean-François Moine {0x14, 0x40}, 7038d64d4f6SJean-François Moine {0x4a, 0x00}, 7048d64d4f6SJean-François Moine {0x49, 0xce}, 7058d64d4f6SJean-François Moine {0x22, 0x03}, 7068d64d4f6SJean-François Moine {0x09, 0x00} 7078d64d4f6SJean-François Moine }; 7088d64d4f6SJean-François Moine 7098d64d4f6SJean-François Moine static const u8 ov965x_start_1_vga[][2] = { /* same for qvga */ 710c52af799SJean-Francois Moine {0x12, 0x62}, /* com7 - 30fps VGA YUV */ 711c52af799SJean-Francois Moine {0x36, 0xfa}, /* aref3 */ 712c52af799SJean-Francois Moine {0x69, 0x0a}, /* hv */ 713c52af799SJean-Francois Moine {0x8c, 0x89}, /* com22 */ 714c52af799SJean-Francois Moine {0x14, 0x28}, /* com9 */ 715c52af799SJean-Francois Moine {0x3e, 0x0c}, /* com14 */ 716c52af799SJean-Francois Moine {0x41, 0x40}, /* com16 */ 717c52af799SJean-Francois Moine {0x72, 0x00}, 718c52af799SJean-Francois Moine {0x73, 0x00}, 719c52af799SJean-Francois Moine {0x74, 0x3a}, 720c52af799SJean-Francois Moine {0x75, 0x35}, 721c52af799SJean-Francois Moine {0x76, 0x01}, 722c52af799SJean-Francois Moine {0xc7, 0x80}, /* com24 */ 723c52af799SJean-Francois Moine {0x03, 0x12}, /* vref */ 724c52af799SJean-Francois Moine {0x17, 0x16}, /* hstart */ 725c52af799SJean-Francois Moine {0x18, 0x02}, /* hstop */ 726c52af799SJean-Francois Moine {0x19, 0x01}, /* vstrt */ 727c52af799SJean-Francois Moine {0x1a, 0x3d}, /* vstop */ 728c52af799SJean-Francois Moine {0x32, 0xff}, /* href */ 729c52af799SJean-Francois Moine {0xc0, 0xaa}, 730c52af799SJean-Francois Moine }; 731c52af799SJean-Francois Moine 7328d64d4f6SJean-François Moine static const u8 ov965x_start_1_svga[][2] = { 733c52af799SJean-Francois Moine {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */ 734c52af799SJean-Francois Moine {0x36, 0xf8}, /* aref3 */ 735c52af799SJean-Francois Moine {0x69, 0x02}, /* hv */ 736c52af799SJean-Francois Moine {0x8c, 0x0d}, /* com22 */ 737c52af799SJean-Francois Moine {0x3e, 0x0c}, /* com14 */ 738c52af799SJean-Francois Moine {0x41, 0x40}, /* com16 */ 739c52af799SJean-Francois Moine {0x72, 0x00}, 740c52af799SJean-Francois Moine {0x73, 0x01}, 741c52af799SJean-Francois Moine {0x74, 0x3a}, 742c52af799SJean-Francois Moine {0x75, 0x35}, 743c52af799SJean-Francois Moine {0x76, 0x01}, 744c52af799SJean-Francois Moine {0xc7, 0x80}, /* com24 */ 745c52af799SJean-Francois Moine {0x03, 0x1b}, /* vref */ 746c52af799SJean-Francois Moine {0x17, 0x1d}, /* hstart */ 747c52af799SJean-Francois Moine {0x18, 0xbd}, /* hstop */ 748c52af799SJean-Francois Moine {0x19, 0x01}, /* vstrt */ 749c52af799SJean-Francois Moine {0x1a, 0x81}, /* vstop */ 750c52af799SJean-Francois Moine {0x32, 0xff}, /* href */ 751c52af799SJean-Francois Moine {0xc0, 0xe2}, 752c52af799SJean-Francois Moine }; 753c52af799SJean-Francois Moine 7548d64d4f6SJean-François Moine static const u8 ov965x_start_1_xga[][2] = { 755c52af799SJean-Francois Moine {0x12, 0x02}, /* com7 */ 756c52af799SJean-Francois Moine {0x36, 0xf8}, /* aref3 */ 757c52af799SJean-Francois Moine {0x69, 0x02}, /* hv */ 758c52af799SJean-Francois Moine {0x8c, 0x89}, /* com22 */ 759c52af799SJean-Francois Moine {0x14, 0x28}, /* com9 */ 760c52af799SJean-Francois Moine {0x3e, 0x0c}, /* com14 */ 761c52af799SJean-Francois Moine {0x41, 0x40}, /* com16 */ 762c52af799SJean-Francois Moine {0x72, 0x00}, 763c52af799SJean-Francois Moine {0x73, 0x01}, 764c52af799SJean-Francois Moine {0x74, 0x3a}, 765c52af799SJean-Francois Moine {0x75, 0x35}, 766c52af799SJean-Francois Moine {0x76, 0x01}, 767c52af799SJean-Francois Moine {0xc7, 0x80}, /* com24 */ 768c52af799SJean-Francois Moine {0x03, 0x1b}, /* vref */ 769c52af799SJean-Francois Moine {0x17, 0x1d}, /* hstart */ 770c52af799SJean-Francois Moine {0x18, 0xbd}, /* hstop */ 771c52af799SJean-Francois Moine {0x19, 0x01}, /* vstrt */ 772c52af799SJean-Francois Moine {0x1a, 0x81}, /* vstop */ 773c52af799SJean-Francois Moine {0x32, 0xff}, /* href */ 774c52af799SJean-Francois Moine {0xc0, 0xe2}, 775c52af799SJean-Francois Moine }; 776c52af799SJean-Francois Moine 7778d64d4f6SJean-François Moine static const u8 ov965x_start_1_sxga[][2] = { 778c52af799SJean-Francois Moine {0x12, 0x02}, /* com7 */ 779c52af799SJean-Francois Moine {0x36, 0xf8}, /* aref3 */ 780c52af799SJean-Francois Moine {0x69, 0x02}, /* hv */ 781c52af799SJean-Francois Moine {0x8c, 0x89}, /* com22 */ 782c52af799SJean-Francois Moine {0x14, 0x28}, /* com9 */ 783c52af799SJean-Francois Moine {0x3e, 0x0c}, /* com14 */ 784c52af799SJean-Francois Moine {0x41, 0x40}, /* com16 */ 785c52af799SJean-Francois Moine {0x72, 0x00}, 786c52af799SJean-Francois Moine {0x73, 0x01}, 787c52af799SJean-Francois Moine {0x74, 0x3a}, 788c52af799SJean-Francois Moine {0x75, 0x35}, 789c52af799SJean-Francois Moine {0x76, 0x01}, 790c52af799SJean-Francois Moine {0xc7, 0x80}, /* com24 */ 791c52af799SJean-Francois Moine {0x03, 0x1b}, /* vref */ 792c52af799SJean-Francois Moine {0x17, 0x1d}, /* hstart */ 793c52af799SJean-Francois Moine {0x18, 0x02}, /* hstop */ 794c52af799SJean-Francois Moine {0x19, 0x01}, /* vstrt */ 795c52af799SJean-Francois Moine {0x1a, 0x81}, /* vstop */ 796c52af799SJean-Francois Moine {0x32, 0xff}, /* href */ 797c52af799SJean-Francois Moine {0xc0, 0xe2}, 798c52af799SJean-Francois Moine }; 799c52af799SJean-Francois Moine 800c52af799SJean-Francois Moine static const u8 bridge_start_qvga[][2] = { 801c52af799SJean-Francois Moine {0x94, 0xaa}, 802c52af799SJean-Francois Moine {0xf1, 0x60}, 803c52af799SJean-Francois Moine {0xe5, 0x04}, 804c52af799SJean-Francois Moine {0xc0, 0x50}, 805c52af799SJean-Francois Moine {0xc1, 0x3c}, 806c52af799SJean-Francois Moine {0x8c, 0x00}, 807c52af799SJean-Francois Moine {0x8d, 0x1c}, 808c52af799SJean-Francois Moine {0x34, 0x05}, 809c52af799SJean-Francois Moine 810c52af799SJean-Francois Moine {0xc2, 0x4c}, 811c52af799SJean-Francois Moine {0xc3, 0xf9}, 812c52af799SJean-Francois Moine {0xda, 0x00}, 813c52af799SJean-Francois Moine {0x50, 0x00}, 814c52af799SJean-Francois Moine {0x51, 0xa0}, 815c52af799SJean-Francois Moine {0x52, 0x78}, 816c52af799SJean-Francois Moine {0x53, 0x00}, 817c52af799SJean-Francois Moine {0x54, 0x00}, 818c52af799SJean-Francois Moine {0x55, 0x00}, 819c52af799SJean-Francois Moine {0x57, 0x00}, 820c52af799SJean-Francois Moine {0x5c, 0x00}, 821c52af799SJean-Francois Moine {0x5a, 0x50}, 822c52af799SJean-Francois Moine {0x5b, 0x3c}, 823c52af799SJean-Francois Moine {0x35, 0x02}, 824c52af799SJean-Francois Moine {0xd9, 0x10}, 825c52af799SJean-Francois Moine {0x94, 0x11}, 826c52af799SJean-Francois Moine }; 827c52af799SJean-Francois Moine 828c52af799SJean-Francois Moine static const u8 bridge_start_vga[][2] = { 829c52af799SJean-Francois Moine {0x94, 0xaa}, 830c52af799SJean-Francois Moine {0xf1, 0x60}, 831c52af799SJean-Francois Moine {0xe5, 0x04}, 832c52af799SJean-Francois Moine {0xc0, 0x50}, 833c52af799SJean-Francois Moine {0xc1, 0x3c}, 834c52af799SJean-Francois Moine {0x8c, 0x00}, 835c52af799SJean-Francois Moine {0x8d, 0x1c}, 836c52af799SJean-Francois Moine {0x34, 0x05}, 837c52af799SJean-Francois Moine {0xc2, 0x0c}, 838c52af799SJean-Francois Moine {0xc3, 0xf9}, 839c52af799SJean-Francois Moine {0xda, 0x01}, 840c52af799SJean-Francois Moine {0x50, 0x00}, 841c52af799SJean-Francois Moine {0x51, 0xa0}, 842c52af799SJean-Francois Moine {0x52, 0x3c}, 843c52af799SJean-Francois Moine {0x53, 0x00}, 844c52af799SJean-Francois Moine {0x54, 0x00}, 845c52af799SJean-Francois Moine {0x55, 0x00}, 846c52af799SJean-Francois Moine {0x57, 0x00}, 847c52af799SJean-Francois Moine {0x5c, 0x00}, 848c52af799SJean-Francois Moine {0x5a, 0xa0}, 849c52af799SJean-Francois Moine {0x5b, 0x78}, 850c52af799SJean-Francois Moine {0x35, 0x02}, 851c52af799SJean-Francois Moine {0xd9, 0x10}, 852c52af799SJean-Francois Moine {0x94, 0x11}, 853c52af799SJean-Francois Moine }; 854c52af799SJean-Francois Moine 855c52af799SJean-Francois Moine static const u8 bridge_start_svga[][2] = { 856c52af799SJean-Francois Moine {0x94, 0xaa}, 857c52af799SJean-Francois Moine {0xf1, 0x60}, 858c52af799SJean-Francois Moine {0xe5, 0x04}, 859c52af799SJean-Francois Moine {0xc0, 0xa0}, 860c52af799SJean-Francois Moine {0xc1, 0x80}, 861c52af799SJean-Francois Moine {0x8c, 0x00}, 862c52af799SJean-Francois Moine {0x8d, 0x1c}, 863c52af799SJean-Francois Moine {0x34, 0x05}, 864c52af799SJean-Francois Moine {0xc2, 0x4c}, 865c52af799SJean-Francois Moine {0xc3, 0xf9}, 866c52af799SJean-Francois Moine {0x50, 0x00}, 867c52af799SJean-Francois Moine {0x51, 0x40}, 868c52af799SJean-Francois Moine {0x52, 0x00}, 869c52af799SJean-Francois Moine {0x53, 0x00}, 870c52af799SJean-Francois Moine {0x54, 0x00}, 871c52af799SJean-Francois Moine {0x55, 0x88}, 872c52af799SJean-Francois Moine {0x57, 0x00}, 873c52af799SJean-Francois Moine {0x5c, 0x00}, 874c52af799SJean-Francois Moine {0x5a, 0xc8}, 875c52af799SJean-Francois Moine {0x5b, 0x96}, 876c52af799SJean-Francois Moine {0x35, 0x02}, 877c52af799SJean-Francois Moine {0xd9, 0x10}, 878c52af799SJean-Francois Moine {0xda, 0x00}, 879c52af799SJean-Francois Moine {0x94, 0x11}, 880c52af799SJean-Francois Moine }; 881c52af799SJean-Francois Moine 882c52af799SJean-Francois Moine static const u8 bridge_start_xga[][2] = { 883c52af799SJean-Francois Moine {0x94, 0xaa}, 884c52af799SJean-Francois Moine {0xf1, 0x60}, 885c52af799SJean-Francois Moine {0xe5, 0x04}, 886c52af799SJean-Francois Moine {0xc0, 0xa0}, 887c52af799SJean-Francois Moine {0xc1, 0x80}, 888c52af799SJean-Francois Moine {0x8c, 0x00}, 889c52af799SJean-Francois Moine {0x8d, 0x1c}, 890c52af799SJean-Francois Moine {0x34, 0x05}, 891c52af799SJean-Francois Moine {0xc2, 0x4c}, 892c52af799SJean-Francois Moine {0xc3, 0xf9}, 893c52af799SJean-Francois Moine {0x50, 0x00}, 894c52af799SJean-Francois Moine {0x51, 0x40}, 895c52af799SJean-Francois Moine {0x52, 0x00}, 896c52af799SJean-Francois Moine {0x53, 0x00}, 897c52af799SJean-Francois Moine {0x54, 0x00}, 898c52af799SJean-Francois Moine {0x55, 0x88}, 899c52af799SJean-Francois Moine {0x57, 0x00}, 900c52af799SJean-Francois Moine {0x5c, 0x01}, 901c52af799SJean-Francois Moine {0x5a, 0x00}, 902c52af799SJean-Francois Moine {0x5b, 0xc0}, 903c52af799SJean-Francois Moine {0x35, 0x02}, 904c52af799SJean-Francois Moine {0xd9, 0x10}, 905c52af799SJean-Francois Moine {0xda, 0x01}, 906c52af799SJean-Francois Moine {0x94, 0x11}, 907c52af799SJean-Francois Moine }; 908c52af799SJean-Francois Moine 909c52af799SJean-Francois Moine static const u8 bridge_start_sxga[][2] = { 910c52af799SJean-Francois Moine {0x94, 0xaa}, 911c52af799SJean-Francois Moine {0xf1, 0x60}, 912c52af799SJean-Francois Moine {0xe5, 0x04}, 913c52af799SJean-Francois Moine {0xc0, 0xa0}, 914c52af799SJean-Francois Moine {0xc1, 0x80}, 915c52af799SJean-Francois Moine {0x8c, 0x00}, 916c52af799SJean-Francois Moine {0x8d, 0x1c}, 917c52af799SJean-Francois Moine {0x34, 0x05}, 918c52af799SJean-Francois Moine {0xc2, 0x0c}, 919c52af799SJean-Francois Moine {0xc3, 0xf9}, 920c52af799SJean-Francois Moine {0xda, 0x00}, 921c52af799SJean-Francois Moine {0x35, 0x02}, 922c52af799SJean-Francois Moine {0xd9, 0x10}, 923c52af799SJean-Francois Moine {0x94, 0x11}, 924c52af799SJean-Francois Moine }; 925c52af799SJean-Francois Moine 9268d64d4f6SJean-François Moine static const u8 ov965x_start_2_qvga[][2] = { 927c52af799SJean-Francois Moine {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ 928c52af799SJean-Francois Moine {0x1e, 0x04}, /* mvfp */ 929c52af799SJean-Francois Moine {0x13, 0xe0}, /* com8 */ 930c52af799SJean-Francois Moine {0x00, 0x00}, 931c52af799SJean-Francois Moine {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 932c52af799SJean-Francois Moine {0x11, 0x01}, /* clkrc */ 933c52af799SJean-Francois Moine {0x6b, 0x5a}, /* dblv */ 934c52af799SJean-Francois Moine {0x6a, 0x02}, /* 50 Hz banding filter */ 935c52af799SJean-Francois Moine {0xc5, 0x03}, /* 60 Hz banding filter */ 936c52af799SJean-Francois Moine {0xa2, 0x96}, /* bd50 */ 937c52af799SJean-Francois Moine {0xa3, 0x7d}, /* bd60 */ 938c52af799SJean-Francois Moine 939c52af799SJean-Francois Moine {0xff, 0x13}, /* read 13, write ff 00 */ 940c52af799SJean-Francois Moine {0x13, 0xe7}, 941c52af799SJean-Francois Moine {0x3a, 0x80}, /* tslb - yuyv */ 942c52af799SJean-Francois Moine }; 943c52af799SJean-Francois Moine 9448d64d4f6SJean-François Moine static const u8 ov965x_start_2_vga[][2] = { 945c52af799SJean-Francois Moine {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 946c52af799SJean-Francois Moine {0x1e, 0x04}, /* mvfp */ 947c52af799SJean-Francois Moine {0x13, 0xe0}, /* com8 */ 948c52af799SJean-Francois Moine {0x00, 0x00}, 949c52af799SJean-Francois Moine {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 950c52af799SJean-Francois Moine {0x11, 0x03}, /* clkrc */ 951c52af799SJean-Francois Moine {0x6b, 0x5a}, /* dblv */ 952c52af799SJean-Francois Moine {0x6a, 0x05}, /* 50 Hz banding filter */ 953c52af799SJean-Francois Moine {0xc5, 0x07}, /* 60 Hz banding filter */ 954c52af799SJean-Francois Moine {0xa2, 0x4b}, /* bd50 */ 955c52af799SJean-Francois Moine {0xa3, 0x3e}, /* bd60 */ 956c52af799SJean-Francois Moine 957c52af799SJean-Francois Moine {0x2d, 0x00}, /* advfl */ 958c52af799SJean-Francois Moine }; 959c52af799SJean-Francois Moine 9608d64d4f6SJean-François Moine static const u8 ov965x_start_2_svga[][2] = { /* same for xga */ 961c52af799SJean-Francois Moine {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 962c52af799SJean-Francois Moine {0x1e, 0x04}, /* mvfp */ 963c52af799SJean-Francois Moine {0x13, 0xe0}, /* com8 */ 964c52af799SJean-Francois Moine {0x00, 0x00}, 965c52af799SJean-Francois Moine {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 966c52af799SJean-Francois Moine {0x11, 0x01}, /* clkrc */ 967c52af799SJean-Francois Moine {0x6b, 0x5a}, /* dblv */ 968c52af799SJean-Francois Moine {0x6a, 0x0c}, /* 50 Hz banding filter */ 969c52af799SJean-Francois Moine {0xc5, 0x0f}, /* 60 Hz banding filter */ 970c52af799SJean-Francois Moine {0xa2, 0x4e}, /* bd50 */ 971c52af799SJean-Francois Moine {0xa3, 0x41}, /* bd60 */ 972c52af799SJean-Francois Moine }; 973c52af799SJean-Francois Moine 9748d64d4f6SJean-François Moine static const u8 ov965x_start_2_sxga[][2] = { 975c52af799SJean-Francois Moine {0x13, 0xe0}, /* com8 */ 976c52af799SJean-Francois Moine {0x00, 0x00}, 977c52af799SJean-Francois Moine {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 978c52af799SJean-Francois Moine {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 979c52af799SJean-Francois Moine {0x1e, 0x04}, /* mvfp */ 980c52af799SJean-Francois Moine {0x11, 0x01}, /* clkrc */ 981c52af799SJean-Francois Moine {0x6b, 0x5a}, /* dblv */ 982c52af799SJean-Francois Moine {0x6a, 0x0c}, /* 50 Hz banding filter */ 983c52af799SJean-Francois Moine {0xc5, 0x0f}, /* 60 Hz banding filter */ 984c52af799SJean-Francois Moine {0xa2, 0x4e}, /* bd50 */ 985c52af799SJean-Francois Moine {0xa3, 0x41}, /* bd60 */ 986c52af799SJean-Francois Moine }; 987c52af799SJean-Francois Moine 988965b37a4SJose Alberto Reguero static const u8 ov562x_init[][2] = { 989965b37a4SJose Alberto Reguero {0x88, 0x20}, 990965b37a4SJose Alberto Reguero {0x89, 0x0a}, 991965b37a4SJose Alberto Reguero {0x8a, 0x90}, 992965b37a4SJose Alberto Reguero {0x8b, 0x06}, 993965b37a4SJose Alberto Reguero {0x8c, 0x01}, 994965b37a4SJose Alberto Reguero {0x8d, 0x10}, 995965b37a4SJose Alberto Reguero {0x1c, 0x00}, 996965b37a4SJose Alberto Reguero {0x1d, 0x48}, 997965b37a4SJose Alberto Reguero {0x1d, 0x00}, 998965b37a4SJose Alberto Reguero {0x1d, 0xff}, 999965b37a4SJose Alberto Reguero {0x1c, 0x0a}, 1000965b37a4SJose Alberto Reguero {0x1d, 0x2e}, 1001965b37a4SJose Alberto Reguero {0x1d, 0x1e}, 1002965b37a4SJose Alberto Reguero }; 1003965b37a4SJose Alberto Reguero 1004965b37a4SJose Alberto Reguero static const u8 ov562x_init_2[][2] = { 1005965b37a4SJose Alberto Reguero {0x12, 0x80}, 1006965b37a4SJose Alberto Reguero {0x11, 0x41}, 1007965b37a4SJose Alberto Reguero {0x13, 0x00}, 1008965b37a4SJose Alberto Reguero {0x10, 0x1e}, 1009965b37a4SJose Alberto Reguero {0x3b, 0x07}, 1010965b37a4SJose Alberto Reguero {0x5b, 0x40}, 1011965b37a4SJose Alberto Reguero {0x39, 0x07}, 1012965b37a4SJose Alberto Reguero {0x53, 0x02}, 1013965b37a4SJose Alberto Reguero {0x54, 0x60}, 1014965b37a4SJose Alberto Reguero {0x04, 0x20}, 1015965b37a4SJose Alberto Reguero {0x27, 0x04}, 1016965b37a4SJose Alberto Reguero {0x3d, 0x40}, 1017965b37a4SJose Alberto Reguero {0x36, 0x00}, 1018965b37a4SJose Alberto Reguero {0xc5, 0x04}, 1019965b37a4SJose Alberto Reguero {0x4e, 0x00}, 1020965b37a4SJose Alberto Reguero {0x4f, 0x93}, 1021965b37a4SJose Alberto Reguero {0x50, 0x7b}, 1022965b37a4SJose Alberto Reguero {0xca, 0x0c}, 1023965b37a4SJose Alberto Reguero {0xcb, 0x0f}, 1024965b37a4SJose Alberto Reguero {0x39, 0x07}, 1025965b37a4SJose Alberto Reguero {0x4a, 0x10}, 1026965b37a4SJose Alberto Reguero {0x3e, 0x0a}, 1027965b37a4SJose Alberto Reguero {0x3d, 0x00}, 1028965b37a4SJose Alberto Reguero {0x0c, 0x38}, 1029965b37a4SJose Alberto Reguero {0x38, 0x90}, 1030965b37a4SJose Alberto Reguero {0x46, 0x30}, 1031965b37a4SJose Alberto Reguero {0x4f, 0x93}, 1032965b37a4SJose Alberto Reguero {0x50, 0x7b}, 1033965b37a4SJose Alberto Reguero {0xab, 0x00}, 1034965b37a4SJose Alberto Reguero {0xca, 0x0c}, 1035965b37a4SJose Alberto Reguero {0xcb, 0x0f}, 1036965b37a4SJose Alberto Reguero {0x37, 0x02}, 1037965b37a4SJose Alberto Reguero {0x44, 0x48}, 1038965b37a4SJose Alberto Reguero {0x8d, 0x44}, 1039965b37a4SJose Alberto Reguero {0x2a, 0x00}, 1040965b37a4SJose Alberto Reguero {0x2b, 0x00}, 1041965b37a4SJose Alberto Reguero {0x32, 0x00}, 1042965b37a4SJose Alberto Reguero {0x38, 0x90}, 1043965b37a4SJose Alberto Reguero {0x53, 0x02}, 1044965b37a4SJose Alberto Reguero {0x54, 0x60}, 1045965b37a4SJose Alberto Reguero {0x12, 0x00}, 1046965b37a4SJose Alberto Reguero {0x17, 0x12}, 1047965b37a4SJose Alberto Reguero {0x18, 0xb4}, 1048965b37a4SJose Alberto Reguero {0x19, 0x0c}, 1049965b37a4SJose Alberto Reguero {0x1a, 0xf4}, 1050965b37a4SJose Alberto Reguero {0x03, 0x4a}, 1051965b37a4SJose Alberto Reguero {0x89, 0x20}, 1052965b37a4SJose Alberto Reguero {0x83, 0x80}, 1053965b37a4SJose Alberto Reguero {0xb7, 0x9d}, 1054965b37a4SJose Alberto Reguero {0xb6, 0x11}, 1055965b37a4SJose Alberto Reguero {0xb5, 0x55}, 1056965b37a4SJose Alberto Reguero {0xb4, 0x00}, 1057965b37a4SJose Alberto Reguero {0xa9, 0xf0}, 1058965b37a4SJose Alberto Reguero {0xa8, 0x0a}, 1059965b37a4SJose Alberto Reguero {0xb8, 0xf0}, 1060965b37a4SJose Alberto Reguero {0xb9, 0xf0}, 1061965b37a4SJose Alberto Reguero {0xba, 0xf0}, 1062965b37a4SJose Alberto Reguero {0x81, 0x07}, 1063965b37a4SJose Alberto Reguero {0x63, 0x44}, 1064965b37a4SJose Alberto Reguero {0x13, 0xc7}, 1065965b37a4SJose Alberto Reguero {0x14, 0x60}, 1066965b37a4SJose Alberto Reguero {0x33, 0x75}, 1067965b37a4SJose Alberto Reguero {0x2c, 0x00}, 1068965b37a4SJose Alberto Reguero {0x09, 0x00}, 1069965b37a4SJose Alberto Reguero {0x35, 0x30}, 1070965b37a4SJose Alberto Reguero {0x27, 0x04}, 1071965b37a4SJose Alberto Reguero {0x3c, 0x07}, 1072965b37a4SJose Alberto Reguero {0x3a, 0x0a}, 1073965b37a4SJose Alberto Reguero {0x3b, 0x07}, 1074965b37a4SJose Alberto Reguero {0x01, 0x40}, 1075965b37a4SJose Alberto Reguero {0x02, 0x40}, 1076965b37a4SJose Alberto Reguero {0x16, 0x40}, 1077965b37a4SJose Alberto Reguero {0x52, 0xb0}, 1078965b37a4SJose Alberto Reguero {0x51, 0x83}, 1079965b37a4SJose Alberto Reguero {0x21, 0xbb}, 1080965b37a4SJose Alberto Reguero {0x22, 0x10}, 1081965b37a4SJose Alberto Reguero {0x23, 0x03}, 1082965b37a4SJose Alberto Reguero {0x35, 0x38}, 1083965b37a4SJose Alberto Reguero {0x20, 0x90}, 1084965b37a4SJose Alberto Reguero {0x28, 0x30}, 1085965b37a4SJose Alberto Reguero {0x73, 0xe1}, 1086965b37a4SJose Alberto Reguero {0x6c, 0x00}, 1087965b37a4SJose Alberto Reguero {0x6d, 0x80}, 1088965b37a4SJose Alberto Reguero {0x6e, 0x00}, 1089965b37a4SJose Alberto Reguero {0x70, 0x04}, 1090965b37a4SJose Alberto Reguero {0x71, 0x00}, 1091965b37a4SJose Alberto Reguero {0x8d, 0x04}, 1092965b37a4SJose Alberto Reguero {0x64, 0x00}, 1093965b37a4SJose Alberto Reguero {0x65, 0x00}, 1094965b37a4SJose Alberto Reguero {0x66, 0x00}, 1095965b37a4SJose Alberto Reguero {0x67, 0x00}, 1096965b37a4SJose Alberto Reguero {0x68, 0x00}, 1097965b37a4SJose Alberto Reguero {0x69, 0x00}, 1098965b37a4SJose Alberto Reguero {0x6a, 0x00}, 1099965b37a4SJose Alberto Reguero {0x6b, 0x00}, 1100965b37a4SJose Alberto Reguero {0x71, 0x94}, 1101965b37a4SJose Alberto Reguero {0x74, 0x20}, 1102965b37a4SJose Alberto Reguero {0x80, 0x09}, 1103965b37a4SJose Alberto Reguero {0x85, 0xc0}, 1104965b37a4SJose Alberto Reguero }; 1105965b37a4SJose Alberto Reguero 1106c52af799SJean-Francois Moine static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val) 1107c52af799SJean-Francois Moine { 1108c52af799SJean-Francois Moine struct usb_device *udev = gspca_dev->dev; 1109c52af799SJean-Francois Moine int ret; 1110c52af799SJean-Francois Moine 1111c52af799SJean-Francois Moine if (gspca_dev->usb_err < 0) 1112c52af799SJean-Francois Moine return; 1113c52af799SJean-Francois Moine gspca_dev->usb_buf[0] = val; 1114c52af799SJean-Francois Moine ret = usb_control_msg(udev, 1115c52af799SJean-Francois Moine usb_sndctrlpipe(udev, 0), 1116c52af799SJean-Francois Moine 0x01, 1117c52af799SJean-Francois Moine USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1118c52af799SJean-Francois Moine 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); 1119c52af799SJean-Francois Moine if (ret < 0) { 1120133a9fe9SJoe Perches pr_err("reg_w failed %d\n", ret); 1121c52af799SJean-Francois Moine gspca_dev->usb_err = ret; 1122c52af799SJean-Francois Moine } 1123c52af799SJean-Francois Moine } 1124c52af799SJean-Francois Moine 1125c52af799SJean-Francois Moine static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val) 1126c52af799SJean-Francois Moine { 112737d5efb0SJoe Perches gspca_dbg(gspca_dev, D_USBO, "reg_w [%04x] = %02x\n", reg, val); 1128c52af799SJean-Francois Moine reg_w_i(gspca_dev, reg, val); 1129c52af799SJean-Francois Moine } 1130c52af799SJean-Francois Moine 1131c52af799SJean-Francois Moine static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg) 1132c52af799SJean-Francois Moine { 1133c52af799SJean-Francois Moine struct usb_device *udev = gspca_dev->dev; 1134c52af799SJean-Francois Moine int ret; 1135c52af799SJean-Francois Moine 1136c52af799SJean-Francois Moine if (gspca_dev->usb_err < 0) 1137c52af799SJean-Francois Moine return 0; 1138c52af799SJean-Francois Moine ret = usb_control_msg(udev, 1139c52af799SJean-Francois Moine usb_rcvctrlpipe(udev, 0), 1140c52af799SJean-Francois Moine 0x01, 1141c52af799SJean-Francois Moine USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1142c52af799SJean-Francois Moine 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); 114337d5efb0SJoe Perches gspca_dbg(gspca_dev, D_USBI, "reg_r [%04x] -> %02x\n", 114437d5efb0SJoe Perches reg, gspca_dev->usb_buf[0]); 1145c52af799SJean-Francois Moine if (ret < 0) { 1146133a9fe9SJoe Perches pr_err("reg_r err %d\n", ret); 1147c52af799SJean-Francois Moine gspca_dev->usb_err = ret; 1148*4843a543SHans Verkuil return 0; 1149c52af799SJean-Francois Moine } 1150c52af799SJean-Francois Moine return gspca_dev->usb_buf[0]; 1151c52af799SJean-Francois Moine } 1152c52af799SJean-Francois Moine 1153c52af799SJean-Francois Moine static int sccb_check_status(struct gspca_dev *gspca_dev) 1154c52af799SJean-Francois Moine { 1155c52af799SJean-Francois Moine u8 data; 1156c52af799SJean-Francois Moine int i; 1157c52af799SJean-Francois Moine 1158c52af799SJean-Francois Moine for (i = 0; i < 5; i++) { 115915807765SVladik Aranov msleep(20); 1160c52af799SJean-Francois Moine data = reg_r(gspca_dev, OV534_REG_STATUS); 1161c52af799SJean-Francois Moine 1162c52af799SJean-Francois Moine switch (data) { 1163c52af799SJean-Francois Moine case 0x00: 1164c52af799SJean-Francois Moine return 1; 1165c52af799SJean-Francois Moine case 0x04: 1166c52af799SJean-Francois Moine return 0; 1167c52af799SJean-Francois Moine case 0x03: 1168c52af799SJean-Francois Moine break; 1169c52af799SJean-Francois Moine default: 117037d5efb0SJoe Perches gspca_dbg(gspca_dev, D_USBI|D_USBO, 117137d5efb0SJoe Perches "sccb status 0x%02x, attempt %d/5\n", 1172c52af799SJean-Francois Moine data, i + 1); 1173c52af799SJean-Francois Moine } 1174c52af799SJean-Francois Moine } 1175c52af799SJean-Francois Moine return 0; 1176c52af799SJean-Francois Moine } 1177c52af799SJean-Francois Moine 1178c52af799SJean-Francois Moine static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val) 1179c52af799SJean-Francois Moine { 118037d5efb0SJoe Perches gspca_dbg(gspca_dev, D_USBO, "sccb_write [%02x] = %02x\n", reg, val); 1181c52af799SJean-Francois Moine reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg); 1182c52af799SJean-Francois Moine reg_w_i(gspca_dev, OV534_REG_WRITE, val); 1183c52af799SJean-Francois Moine reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); 1184c52af799SJean-Francois Moine 1185c52af799SJean-Francois Moine if (!sccb_check_status(gspca_dev)) 1186133a9fe9SJoe Perches pr_err("sccb_write failed\n"); 1187c52af799SJean-Francois Moine } 1188c52af799SJean-Francois Moine 1189c52af799SJean-Francois Moine static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg) 1190c52af799SJean-Francois Moine { 1191c52af799SJean-Francois Moine reg_w(gspca_dev, OV534_REG_SUBADDR, reg); 1192c52af799SJean-Francois Moine reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); 1193c52af799SJean-Francois Moine if (!sccb_check_status(gspca_dev)) 1194133a9fe9SJoe Perches pr_err("sccb_read failed 1\n"); 1195c52af799SJean-Francois Moine 1196c52af799SJean-Francois Moine reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); 1197c52af799SJean-Francois Moine if (!sccb_check_status(gspca_dev)) 1198133a9fe9SJoe Perches pr_err("sccb_read failed 2\n"); 1199c52af799SJean-Francois Moine 1200c52af799SJean-Francois Moine return reg_r(gspca_dev, OV534_REG_READ); 1201c52af799SJean-Francois Moine } 1202c52af799SJean-Francois Moine 1203c52af799SJean-Francois Moine /* output a bridge sequence (reg - val) */ 1204c52af799SJean-Francois Moine static void reg_w_array(struct gspca_dev *gspca_dev, 1205c52af799SJean-Francois Moine const u8 (*data)[2], int len) 1206c52af799SJean-Francois Moine { 1207c52af799SJean-Francois Moine while (--len >= 0) { 1208c52af799SJean-Francois Moine reg_w(gspca_dev, (*data)[0], (*data)[1]); 1209c52af799SJean-Francois Moine data++; 1210c52af799SJean-Francois Moine } 1211c52af799SJean-Francois Moine } 1212c52af799SJean-Francois Moine 1213c52af799SJean-Francois Moine /* output a sensor sequence (reg - val) */ 1214c52af799SJean-Francois Moine static void sccb_w_array(struct gspca_dev *gspca_dev, 1215c52af799SJean-Francois Moine const u8 (*data)[2], int len) 1216c52af799SJean-Francois Moine { 1217c52af799SJean-Francois Moine while (--len >= 0) { 1218c52af799SJean-Francois Moine if ((*data)[0] != 0xff) { 1219c52af799SJean-Francois Moine sccb_write(gspca_dev, (*data)[0], (*data)[1]); 1220c52af799SJean-Francois Moine } else { 1221c52af799SJean-Francois Moine sccb_read(gspca_dev, (*data)[1]); 1222c52af799SJean-Francois Moine sccb_write(gspca_dev, 0xff, 0x00); 1223c52af799SJean-Francois Moine } 1224c52af799SJean-Francois Moine data++; 1225c52af799SJean-Francois Moine } 1226c52af799SJean-Francois Moine } 1227c52af799SJean-Francois Moine 1228c52af799SJean-Francois Moine /* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. 1229c52af799SJean-Francois Moine * (direction and output)? */ 1230c52af799SJean-Francois Moine static void set_led(struct gspca_dev *gspca_dev, int status) 1231c52af799SJean-Francois Moine { 1232c52af799SJean-Francois Moine u8 data; 1233c52af799SJean-Francois Moine 123437d5efb0SJoe Perches gspca_dbg(gspca_dev, D_CONF, "led status: %d\n", status); 1235c52af799SJean-Francois Moine 1236c52af799SJean-Francois Moine data = reg_r(gspca_dev, 0x21); 1237c52af799SJean-Francois Moine data |= 0x80; 1238c52af799SJean-Francois Moine reg_w(gspca_dev, 0x21, data); 1239c52af799SJean-Francois Moine 1240c52af799SJean-Francois Moine data = reg_r(gspca_dev, 0x23); 1241c52af799SJean-Francois Moine if (status) 1242c52af799SJean-Francois Moine data |= 0x80; 1243c52af799SJean-Francois Moine else 1244c52af799SJean-Francois Moine data &= ~0x80; 1245c52af799SJean-Francois Moine 1246c52af799SJean-Francois Moine reg_w(gspca_dev, 0x23, data); 1247c52af799SJean-Francois Moine 1248c52af799SJean-Francois Moine if (!status) { 1249c52af799SJean-Francois Moine data = reg_r(gspca_dev, 0x21); 1250c52af799SJean-Francois Moine data &= ~0x80; 1251c52af799SJean-Francois Moine reg_w(gspca_dev, 0x21, data); 1252c52af799SJean-Francois Moine } 1253c52af799SJean-Francois Moine } 1254c52af799SJean-Francois Moine 1255f3920f0fSHans Verkuil static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) 1256c52af799SJean-Francois Moine { 1257c52af799SJean-Francois Moine struct sd *sd = (struct sd *) gspca_dev; 1258c52af799SJean-Francois Moine u8 val; 1259d9ef28a9SJose Alberto Reguero s8 sval; 1260c52af799SJean-Francois Moine 1261d9ef28a9SJose Alberto Reguero if (sd->sensor == SENSOR_OV562x) { 1262f3920f0fSHans Verkuil sval = brightness; 1263d9ef28a9SJose Alberto Reguero val = 0x76; 1264d9ef28a9SJose Alberto Reguero val += sval; 1265d9ef28a9SJose Alberto Reguero sccb_write(gspca_dev, 0x24, val); 1266d9ef28a9SJose Alberto Reguero val = 0x6a; 1267d9ef28a9SJose Alberto Reguero val += sval; 1268d9ef28a9SJose Alberto Reguero sccb_write(gspca_dev, 0x25, val); 1269d9ef28a9SJose Alberto Reguero if (sval < -40) 1270d9ef28a9SJose Alberto Reguero val = 0x71; 1271d9ef28a9SJose Alberto Reguero else if (sval < 20) 1272d9ef28a9SJose Alberto Reguero val = 0x94; 1273d9ef28a9SJose Alberto Reguero else 1274d9ef28a9SJose Alberto Reguero val = 0xe6; 1275d9ef28a9SJose Alberto Reguero sccb_write(gspca_dev, 0x26, val); 1276d9ef28a9SJose Alberto Reguero } else { 1277f3920f0fSHans Verkuil val = brightness; 1278c52af799SJean-Francois Moine if (val < 8) 1279c52af799SJean-Francois Moine val = 15 - val; /* f .. 8 */ 1280c52af799SJean-Francois Moine else 1281c52af799SJean-Francois Moine val = val - 8; /* 0 .. 7 */ 1282c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */ 1283c52af799SJean-Francois Moine 0x0f | (val << 4)); 1284c52af799SJean-Francois Moine } 1285d9ef28a9SJose Alberto Reguero } 1286c52af799SJean-Francois Moine 1287f3920f0fSHans Verkuil static void setcontrast(struct gspca_dev *gspca_dev, s32 val) 1288c52af799SJean-Francois Moine { 1289c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */ 1290f3920f0fSHans Verkuil val << 4); 1291c52af799SJean-Francois Moine } 1292c52af799SJean-Francois Moine 1293f3920f0fSHans Verkuil static void setautogain(struct gspca_dev *gspca_dev, s32 autogain) 1294c52af799SJean-Francois Moine { 1295c52af799SJean-Francois Moine u8 val; 1296c52af799SJean-Francois Moine 1297c52af799SJean-Francois Moine /*fixme: should adjust agc/awb/aec by different controls */ 1298c52af799SJean-Francois Moine val = sccb_read(gspca_dev, 0x13); /* com8 */ 1299c52af799SJean-Francois Moine sccb_write(gspca_dev, 0xff, 0x00); 1300f3920f0fSHans Verkuil if (autogain) 1301c52af799SJean-Francois Moine val |= 0x05; /* agc & aec */ 1302c52af799SJean-Francois Moine else 1303c52af799SJean-Francois Moine val &= 0xfa; 1304c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x13, val); 1305c52af799SJean-Francois Moine } 1306c52af799SJean-Francois Moine 1307f3920f0fSHans Verkuil static void setexposure(struct gspca_dev *gspca_dev, s32 exposure) 1308c52af799SJean-Francois Moine { 1309c52af799SJean-Francois Moine static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e}; 1310f3920f0fSHans Verkuil u8 val; 1311c52af799SJean-Francois Moine 1312f3920f0fSHans Verkuil sccb_write(gspca_dev, 0x10, expo[exposure]); /* aec[9:2] */ 1313c52af799SJean-Francois Moine 1314c52af799SJean-Francois Moine val = sccb_read(gspca_dev, 0x13); /* com8 */ 1315c52af799SJean-Francois Moine sccb_write(gspca_dev, 0xff, 0x00); 1316c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x13, val); 1317c52af799SJean-Francois Moine 1318c52af799SJean-Francois Moine val = sccb_read(gspca_dev, 0xa1); /* aech */ 1319c52af799SJean-Francois Moine sccb_write(gspca_dev, 0xff, 0x00); 1320c52af799SJean-Francois Moine sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */ 1321c52af799SJean-Francois Moine } 1322c52af799SJean-Francois Moine 1323f3920f0fSHans Verkuil static void setsharpness(struct gspca_dev *gspca_dev, s32 val) 1324c52af799SJean-Francois Moine { 1325c52af799SJean-Francois Moine if (val < 0) { /* auto */ 1326c52af799SJean-Francois Moine val = sccb_read(gspca_dev, 0x42); /* com17 */ 1327c52af799SJean-Francois Moine sccb_write(gspca_dev, 0xff, 0x00); 1328c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x42, val | 0x40); 1329c52af799SJean-Francois Moine /* Edge enhancement strength auto adjust */ 1330c52af799SJean-Francois Moine return; 1331c52af799SJean-Francois Moine } 1332c52af799SJean-Francois Moine if (val != 0) 1333c52af799SJean-Francois Moine val = 1 << (val - 1); 1334c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */ 1335c52af799SJean-Francois Moine val); 1336c52af799SJean-Francois Moine val = sccb_read(gspca_dev, 0x42); /* com17 */ 1337c52af799SJean-Francois Moine sccb_write(gspca_dev, 0xff, 0x00); 1338c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x42, val & 0xbf); 1339c52af799SJean-Francois Moine } 1340c52af799SJean-Francois Moine 1341f3920f0fSHans Verkuil static void setsatur(struct gspca_dev *gspca_dev, s32 val) 1342c52af799SJean-Francois Moine { 1343c52af799SJean-Francois Moine u8 val1, val2, val3; 1344c52af799SJean-Francois Moine static const u8 matrix[5][2] = { 1345c52af799SJean-Francois Moine {0x14, 0x38}, 1346c52af799SJean-Francois Moine {0x1e, 0x54}, 1347c52af799SJean-Francois Moine {0x28, 0x70}, 1348c52af799SJean-Francois Moine {0x32, 0x8c}, 1349c52af799SJean-Francois Moine {0x48, 0x90} 1350c52af799SJean-Francois Moine }; 1351c52af799SJean-Francois Moine 1352f3920f0fSHans Verkuil val1 = matrix[val][0]; 1353f3920f0fSHans Verkuil val2 = matrix[val][1]; 1354c52af799SJean-Francois Moine val3 = val1 + val2; 1355c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */ 1356c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x50, val3); 1357c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x51, 0x00); 1358c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x52, val1); 1359c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x53, val2); 1360c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x54, val3); 1361c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */ 1362c52af799SJean-Francois Moine 1363c52af799SJean-Francois Moine val1 = sccb_read(gspca_dev, 0x41); /* com16 */ 1364c52af799SJean-Francois Moine sccb_write(gspca_dev, 0xff, 0x00); 1365c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x41, val1); 1366c52af799SJean-Francois Moine } 1367c52af799SJean-Francois Moine 1368f3920f0fSHans Verkuil static void setlightfreq(struct gspca_dev *gspca_dev, s32 freq) 1369c52af799SJean-Francois Moine { 1370c52af799SJean-Francois Moine u8 val; 1371c52af799SJean-Francois Moine 1372c52af799SJean-Francois Moine val = sccb_read(gspca_dev, 0x13); /* com8 */ 1373c52af799SJean-Francois Moine sccb_write(gspca_dev, 0xff, 0x00); 1374f3920f0fSHans Verkuil if (freq == 0) { 1375c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x13, val & 0xdf); 1376c52af799SJean-Francois Moine return; 1377c52af799SJean-Francois Moine } 1378c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x13, val | 0x20); 1379c52af799SJean-Francois Moine 1380c52af799SJean-Francois Moine val = sccb_read(gspca_dev, 0x42); /* com17 */ 1381c52af799SJean-Francois Moine sccb_write(gspca_dev, 0xff, 0x00); 1382f3920f0fSHans Verkuil if (freq == 1) 1383c52af799SJean-Francois Moine val |= 0x01; 1384c52af799SJean-Francois Moine else 1385c52af799SJean-Francois Moine val &= 0xfe; 1386c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x42, val); 1387c52af799SJean-Francois Moine } 1388c52af799SJean-Francois Moine 1389c52af799SJean-Francois Moine /* this function is called at probe time */ 1390c52af799SJean-Francois Moine static int sd_config(struct gspca_dev *gspca_dev, 1391c52af799SJean-Francois Moine const struct usb_device_id *id) 1392c52af799SJean-Francois Moine { 1393c52af799SJean-Francois Moine return 0; 1394c52af799SJean-Francois Moine } 1395c52af799SJean-Francois Moine 1396c52af799SJean-Francois Moine /* this function is called at probe and resume time */ 1397c52af799SJean-Francois Moine static int sd_init(struct gspca_dev *gspca_dev) 1398c52af799SJean-Francois Moine { 13998d64d4f6SJean-François Moine struct sd *sd = (struct sd *) gspca_dev; 1400c52af799SJean-Francois Moine u16 sensor_id; 1401c52af799SJean-Francois Moine 1402c52af799SJean-Francois Moine /* reset bridge */ 1403c52af799SJean-Francois Moine reg_w(gspca_dev, 0xe7, 0x3a); 1404c52af799SJean-Francois Moine reg_w(gspca_dev, 0xe0, 0x08); 1405c52af799SJean-Francois Moine msleep(100); 1406c52af799SJean-Francois Moine 1407c52af799SJean-Francois Moine /* initialize the sensor address */ 1408c52af799SJean-Francois Moine reg_w(gspca_dev, OV534_REG_ADDRESS, 0x60); 1409c52af799SJean-Francois Moine 1410c52af799SJean-Francois Moine /* reset sensor */ 1411c52af799SJean-Francois Moine sccb_write(gspca_dev, 0x12, 0x80); 1412c52af799SJean-Francois Moine msleep(10); 1413c52af799SJean-Francois Moine 1414c52af799SJean-Francois Moine /* probe the sensor */ 1415c52af799SJean-Francois Moine sccb_read(gspca_dev, 0x0a); 1416c52af799SJean-Francois Moine sensor_id = sccb_read(gspca_dev, 0x0a) << 8; 1417c52af799SJean-Francois Moine sccb_read(gspca_dev, 0x0b); 1418c52af799SJean-Francois Moine sensor_id |= sccb_read(gspca_dev, 0x0b); 141937d5efb0SJoe Perches gspca_dbg(gspca_dev, D_PROBE, "Sensor ID: %04x\n", sensor_id); 1420c52af799SJean-Francois Moine 1421c52af799SJean-Francois Moine /* initialize */ 14228d64d4f6SJean-François Moine if ((sensor_id & 0xfff0) == 0x9650) { 14238d64d4f6SJean-François Moine sd->sensor = SENSOR_OV965x; 14248d64d4f6SJean-François Moine 14257592e037SJean-François Moine gspca_dev->cam.cam_mode = ov965x_mode; 14267592e037SJean-François Moine gspca_dev->cam.nmodes = ARRAY_SIZE(ov965x_mode); 14277592e037SJean-François Moine 1428c52af799SJean-Francois Moine reg_w_array(gspca_dev, bridge_init, 1429c52af799SJean-Francois Moine ARRAY_SIZE(bridge_init)); 14308d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_init, 14318d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_init)); 1432c52af799SJean-Francois Moine reg_w_array(gspca_dev, bridge_init_2, 1433c52af799SJean-Francois Moine ARRAY_SIZE(bridge_init_2)); 14348d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_init_2, 14358d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_init_2)); 1436c52af799SJean-Francois Moine reg_w(gspca_dev, 0xe0, 0x00); 1437c52af799SJean-Francois Moine reg_w(gspca_dev, 0xe0, 0x01); 1438c52af799SJean-Francois Moine set_led(gspca_dev, 0); 1439c52af799SJean-Francois Moine reg_w(gspca_dev, 0xe0, 0x00); 14408d64d4f6SJean-François Moine } else if ((sensor_id & 0xfff0) == 0x9710) { 14418d64d4f6SJean-François Moine const char *p; 14428d64d4f6SJean-François Moine int l; 14438d64d4f6SJean-François Moine 14448d64d4f6SJean-François Moine sd->sensor = SENSOR_OV971x; 14458d64d4f6SJean-François Moine 14468d64d4f6SJean-François Moine gspca_dev->cam.cam_mode = ov971x_mode; 14478d64d4f6SJean-François Moine gspca_dev->cam.nmodes = ARRAY_SIZE(ov971x_mode); 14488d64d4f6SJean-François Moine 14498d64d4f6SJean-François Moine gspca_dev->cam.bulk = 1; 14508d64d4f6SJean-François Moine gspca_dev->cam.bulk_size = 16384; 14518d64d4f6SJean-François Moine gspca_dev->cam.bulk_nurbs = 2; 14528d64d4f6SJean-François Moine 14538d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov971x_init, 14548d64d4f6SJean-François Moine ARRAY_SIZE(ov971x_init)); 14558d64d4f6SJean-François Moine 14568d64d4f6SJean-François Moine /* set video format on bridge processor */ 14578d64d4f6SJean-François Moine /* access bridge processor's video format registers at: 0x00 */ 14588d64d4f6SJean-François Moine reg_w(gspca_dev, 0x1c, 0x00); 14598d64d4f6SJean-François Moine /*set register: 0x00 is 'RAW8', 0x40 is 'YUV422' (YUYV?)*/ 14608d64d4f6SJean-François Moine reg_w(gspca_dev, 0x1d, 0x00); 14618d64d4f6SJean-François Moine 14628d64d4f6SJean-François Moine /* Will W. specific stuff 14638d64d4f6SJean-François Moine * set VSYNC to 14648d64d4f6SJean-François Moine * output (0x1f) if first webcam 14658d64d4f6SJean-François Moine * input (0x17) if 2nd or 3rd webcam */ 14668d64d4f6SJean-François Moine p = video_device_node_name(&gspca_dev->vdev); 14678d64d4f6SJean-François Moine l = strlen(p) - 1; 14688d64d4f6SJean-François Moine if (p[l] == '0') 14698d64d4f6SJean-François Moine reg_w(gspca_dev, 0x56, 0x1f); 14708d64d4f6SJean-François Moine else 14718d64d4f6SJean-François Moine reg_w(gspca_dev, 0x56, 0x17); 1472965b37a4SJose Alberto Reguero } else if ((sensor_id & 0xfff0) == 0x5620) { 1473965b37a4SJose Alberto Reguero sd->sensor = SENSOR_OV562x; 1474965b37a4SJose Alberto Reguero gspca_dev->cam.cam_mode = ov562x_mode; 1475965b37a4SJose Alberto Reguero gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); 1476965b37a4SJose Alberto Reguero 1477965b37a4SJose Alberto Reguero reg_w_array(gspca_dev, ov562x_init, 1478965b37a4SJose Alberto Reguero ARRAY_SIZE(ov562x_init)); 1479965b37a4SJose Alberto Reguero sccb_w_array(gspca_dev, ov562x_init_2, 1480965b37a4SJose Alberto Reguero ARRAY_SIZE(ov562x_init_2)); 1481965b37a4SJose Alberto Reguero reg_w(gspca_dev, 0xe0, 0x00); 148215807765SVladik Aranov } else if ((sensor_id & 0xfff0) == 0x3610) { 148315807765SVladik Aranov sd->sensor = SENSOR_OV361x; 148415807765SVladik Aranov gspca_dev->cam.cam_mode = ov361x_mode; 148515807765SVladik Aranov gspca_dev->cam.nmodes = ARRAY_SIZE(ov361x_mode); 148615807765SVladik Aranov reg_w(gspca_dev, 0xe7, 0x3a); 148715807765SVladik Aranov reg_w(gspca_dev, 0xf1, 0x60); 148815807765SVladik Aranov sccb_write(gspca_dev, 0x12, 0x80); 14898d64d4f6SJean-François Moine } else { 1490a581c72aSGreg Kroah-Hartman pr_err("Unknown sensor %04x", sensor_id); 14918d64d4f6SJean-François Moine return -EINVAL; 14928d64d4f6SJean-François Moine } 1493c52af799SJean-Francois Moine 14944b27d074SJean-Francois Moine return gspca_dev->usb_err; 1495c52af799SJean-Francois Moine } 1496c52af799SJean-Francois Moine 149715807765SVladik Aranov static int sd_start_ov361x(struct gspca_dev *gspca_dev) 149815807765SVladik Aranov { 149915807765SVladik Aranov sccb_write(gspca_dev, 0x12, 0x80); 150015807765SVladik Aranov msleep(20); 150115807765SVladik Aranov switch (gspca_dev->curr_mode % (ov361x_last)) { 150215807765SVladik Aranov case ov361x_2048: 150315807765SVladik Aranov reg_w_array(gspca_dev, ov361x_bridge_start_2048, 150415807765SVladik Aranov ARRAY_SIZE(ov361x_bridge_start_2048)); 150515807765SVladik Aranov sccb_w_array(gspca_dev, ov361x_start_2048, 150615807765SVladik Aranov ARRAY_SIZE(ov361x_start_2048)); 150715807765SVladik Aranov break; 150815807765SVladik Aranov case ov361x_1600: 150915807765SVladik Aranov reg_w_array(gspca_dev, ov361x_bridge_start_1600, 151015807765SVladik Aranov ARRAY_SIZE(ov361x_bridge_start_1600)); 151115807765SVladik Aranov sccb_w_array(gspca_dev, ov361x_start_1600, 151215807765SVladik Aranov ARRAY_SIZE(ov361x_start_1600)); 151315807765SVladik Aranov break; 151415807765SVladik Aranov case ov361x_1024: 151515807765SVladik Aranov reg_w_array(gspca_dev, ov361x_bridge_start_1024, 151615807765SVladik Aranov ARRAY_SIZE(ov361x_bridge_start_1024)); 151715807765SVladik Aranov sccb_w_array(gspca_dev, ov361x_start_1024, 151815807765SVladik Aranov ARRAY_SIZE(ov361x_start_1024)); 151915807765SVladik Aranov break; 152015807765SVladik Aranov case ov361x_640: 152115807765SVladik Aranov reg_w_array(gspca_dev, ov361x_bridge_start_640, 152215807765SVladik Aranov ARRAY_SIZE(ov361x_bridge_start_640)); 152315807765SVladik Aranov sccb_w_array(gspca_dev, ov361x_start_640, 152415807765SVladik Aranov ARRAY_SIZE(ov361x_start_640)); 152515807765SVladik Aranov break; 152615807765SVladik Aranov case ov361x_320: 152715807765SVladik Aranov reg_w_array(gspca_dev, ov361x_bridge_start_320, 152815807765SVladik Aranov ARRAY_SIZE(ov361x_bridge_start_320)); 152915807765SVladik Aranov sccb_w_array(gspca_dev, ov361x_start_320, 153015807765SVladik Aranov ARRAY_SIZE(ov361x_start_320)); 153115807765SVladik Aranov break; 153215807765SVladik Aranov case ov361x_160: 153315807765SVladik Aranov reg_w_array(gspca_dev, ov361x_bridge_start_160, 153415807765SVladik Aranov ARRAY_SIZE(ov361x_bridge_start_160)); 153515807765SVladik Aranov sccb_w_array(gspca_dev, ov361x_start_160, 153615807765SVladik Aranov ARRAY_SIZE(ov361x_start_160)); 153715807765SVladik Aranov break; 153815807765SVladik Aranov } 153915807765SVladik Aranov reg_w(gspca_dev, 0xe0, 0x00); /* start transfer */ 154015807765SVladik Aranov 154115807765SVladik Aranov return gspca_dev->usb_err; 154215807765SVladik Aranov } 154315807765SVladik Aranov 1544c52af799SJean-Francois Moine static int sd_start(struct gspca_dev *gspca_dev) 1545c52af799SJean-Francois Moine { 15468d64d4f6SJean-François Moine struct sd *sd = (struct sd *) gspca_dev; 15478d64d4f6SJean-François Moine 1548d9ef28a9SJose Alberto Reguero if (sd->sensor == SENSOR_OV971x) 15498d64d4f6SJean-François Moine return gspca_dev->usb_err; 155082b343b2SHans Verkuil if (sd->sensor == SENSOR_OV562x) 1551d9ef28a9SJose Alberto Reguero return gspca_dev->usb_err; 155215807765SVladik Aranov if (sd->sensor == SENSOR_OV361x) 155315807765SVladik Aranov return sd_start_ov361x(gspca_dev); 155482b343b2SHans Verkuil 1555c52af799SJean-Francois Moine switch (gspca_dev->curr_mode) { 1556c52af799SJean-Francois Moine case QVGA_MODE: /* 320x240 */ 15578d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_start_1_vga, 15588d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_start_1_vga)); 1559c52af799SJean-Francois Moine reg_w_array(gspca_dev, bridge_start_qvga, 1560c52af799SJean-Francois Moine ARRAY_SIZE(bridge_start_qvga)); 15618d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_start_2_qvga, 15628d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_start_2_qvga)); 1563c52af799SJean-Francois Moine break; 1564c52af799SJean-Francois Moine case VGA_MODE: /* 640x480 */ 15658d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_start_1_vga, 15668d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_start_1_vga)); 1567c52af799SJean-Francois Moine reg_w_array(gspca_dev, bridge_start_vga, 1568c52af799SJean-Francois Moine ARRAY_SIZE(bridge_start_vga)); 15698d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_start_2_vga, 15708d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_start_2_vga)); 1571c52af799SJean-Francois Moine break; 1572c52af799SJean-Francois Moine case SVGA_MODE: /* 800x600 */ 15738d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_start_1_svga, 15748d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_start_1_svga)); 1575c52af799SJean-Francois Moine reg_w_array(gspca_dev, bridge_start_svga, 1576c52af799SJean-Francois Moine ARRAY_SIZE(bridge_start_svga)); 15778d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_start_2_svga, 15788d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_start_2_svga)); 1579c52af799SJean-Francois Moine break; 1580c52af799SJean-Francois Moine case XGA_MODE: /* 1024x768 */ 15818d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_start_1_xga, 15828d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_start_1_xga)); 1583c52af799SJean-Francois Moine reg_w_array(gspca_dev, bridge_start_xga, 1584c52af799SJean-Francois Moine ARRAY_SIZE(bridge_start_xga)); 15858d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_start_2_svga, 15868d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_start_2_svga)); 1587c52af799SJean-Francois Moine break; 1588c52af799SJean-Francois Moine default: 1589c52af799SJean-Francois Moine /* case SXGA_MODE: * 1280x1024 */ 15908d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_start_1_sxga, 15918d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_start_1_sxga)); 1592c52af799SJean-Francois Moine reg_w_array(gspca_dev, bridge_start_sxga, 1593c52af799SJean-Francois Moine ARRAY_SIZE(bridge_start_sxga)); 15948d64d4f6SJean-François Moine sccb_w_array(gspca_dev, ov965x_start_2_sxga, 15958d64d4f6SJean-François Moine ARRAY_SIZE(ov965x_start_2_sxga)); 1596c52af799SJean-Francois Moine break; 1597c52af799SJean-Francois Moine } 1598c52af799SJean-Francois Moine 1599c52af799SJean-Francois Moine reg_w(gspca_dev, 0xe0, 0x00); 1600c52af799SJean-Francois Moine reg_w(gspca_dev, 0xe0, 0x00); 1601c52af799SJean-Francois Moine set_led(gspca_dev, 1); 16024b27d074SJean-Francois Moine return gspca_dev->usb_err; 1603c52af799SJean-Francois Moine } 1604c52af799SJean-Francois Moine 1605c52af799SJean-Francois Moine static void sd_stopN(struct gspca_dev *gspca_dev) 1606c52af799SJean-Francois Moine { 160715807765SVladik Aranov if (((struct sd *)gspca_dev)->sensor == SENSOR_OV361x) { 160815807765SVladik Aranov reg_w(gspca_dev, 0xe0, 0x01); /* stop transfer */ 160915807765SVladik Aranov /* reg_w(gspca_dev, 0x31, 0x09); */ 161015807765SVladik Aranov return; 161115807765SVladik Aranov } 1612c52af799SJean-Francois Moine reg_w(gspca_dev, 0xe0, 0x01); 1613c52af799SJean-Francois Moine set_led(gspca_dev, 0); 1614c52af799SJean-Francois Moine reg_w(gspca_dev, 0xe0, 0x00); 1615c52af799SJean-Francois Moine } 1616c52af799SJean-Francois Moine 1617c52af799SJean-Francois Moine /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 1618c52af799SJean-Francois Moine #define UVC_STREAM_EOH (1 << 7) 1619c52af799SJean-Francois Moine #define UVC_STREAM_ERR (1 << 6) 1620c52af799SJean-Francois Moine #define UVC_STREAM_STI (1 << 5) 1621c52af799SJean-Francois Moine #define UVC_STREAM_RES (1 << 4) 1622c52af799SJean-Francois Moine #define UVC_STREAM_SCR (1 << 3) 1623c52af799SJean-Francois Moine #define UVC_STREAM_PTS (1 << 2) 1624c52af799SJean-Francois Moine #define UVC_STREAM_EOF (1 << 1) 1625c52af799SJean-Francois Moine #define UVC_STREAM_FID (1 << 0) 1626c52af799SJean-Francois Moine 1627c52af799SJean-Francois Moine static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1628c52af799SJean-Francois Moine u8 *data, int len) 1629c52af799SJean-Francois Moine { 1630c52af799SJean-Francois Moine struct sd *sd = (struct sd *) gspca_dev; 1631c52af799SJean-Francois Moine __u32 this_pts; 1632c52af799SJean-Francois Moine u8 this_fid; 1633c52af799SJean-Francois Moine int remaining_len = len; 16348d64d4f6SJean-François Moine int payload_len; 1635c52af799SJean-Francois Moine 16368d64d4f6SJean-François Moine payload_len = gspca_dev->cam.bulk ? 2048 : 2040; 1637c52af799SJean-Francois Moine do { 16388d64d4f6SJean-François Moine len = min(remaining_len, payload_len); 1639c52af799SJean-Francois Moine 1640c52af799SJean-Francois Moine /* Payloads are prefixed with a UVC-style header. We 1641c52af799SJean-Francois Moine consider a frame to start when the FID toggles, or the PTS 1642c52af799SJean-Francois Moine changes. A frame ends when EOF is set, and we've received 1643c52af799SJean-Francois Moine the correct number of bytes. */ 1644c52af799SJean-Francois Moine 1645c52af799SJean-Francois Moine /* Verify UVC header. Header length is always 12 */ 1646c52af799SJean-Francois Moine if (data[0] != 12 || len < 12) { 164737d5efb0SJoe Perches gspca_dbg(gspca_dev, D_PACK, "bad header\n"); 1648c52af799SJean-Francois Moine goto discard; 1649c52af799SJean-Francois Moine } 1650c52af799SJean-Francois Moine 1651c52af799SJean-Francois Moine /* Check errors */ 1652c52af799SJean-Francois Moine if (data[1] & UVC_STREAM_ERR) { 165337d5efb0SJoe Perches gspca_dbg(gspca_dev, D_PACK, "payload error\n"); 1654c52af799SJean-Francois Moine goto discard; 1655c52af799SJean-Francois Moine } 1656c52af799SJean-Francois Moine 1657c52af799SJean-Francois Moine /* Extract PTS and FID */ 1658c52af799SJean-Francois Moine if (!(data[1] & UVC_STREAM_PTS)) { 165937d5efb0SJoe Perches gspca_dbg(gspca_dev, D_PACK, "PTS not present\n"); 1660c52af799SJean-Francois Moine goto discard; 1661c52af799SJean-Francois Moine } 1662c52af799SJean-Francois Moine this_pts = (data[5] << 24) | (data[4] << 16) 1663c52af799SJean-Francois Moine | (data[3] << 8) | data[2]; 1664c52af799SJean-Francois Moine this_fid = data[1] & UVC_STREAM_FID; 1665c52af799SJean-Francois Moine 1666c52af799SJean-Francois Moine /* If PTS or FID has changed, start a new frame. */ 1667c52af799SJean-Francois Moine if (this_pts != sd->last_pts || this_fid != sd->last_fid) { 1668c52af799SJean-Francois Moine if (gspca_dev->last_packet_type == INTER_PACKET) 1669c52af799SJean-Francois Moine gspca_frame_add(gspca_dev, LAST_PACKET, 1670c52af799SJean-Francois Moine NULL, 0); 1671c52af799SJean-Francois Moine sd->last_pts = this_pts; 1672c52af799SJean-Francois Moine sd->last_fid = this_fid; 1673c52af799SJean-Francois Moine gspca_frame_add(gspca_dev, FIRST_PACKET, 1674c52af799SJean-Francois Moine data + 12, len - 12); 1675c52af799SJean-Francois Moine /* If this packet is marked as EOF, end the frame */ 1676c52af799SJean-Francois Moine } else if (data[1] & UVC_STREAM_EOF) { 1677c52af799SJean-Francois Moine sd->last_pts = 0; 1678c52af799SJean-Francois Moine gspca_frame_add(gspca_dev, LAST_PACKET, 1679c52af799SJean-Francois Moine data + 12, len - 12); 1680c52af799SJean-Francois Moine } else { 1681c52af799SJean-Francois Moine 1682c52af799SJean-Francois Moine /* Add the data from this payload */ 1683c52af799SJean-Francois Moine gspca_frame_add(gspca_dev, INTER_PACKET, 1684c52af799SJean-Francois Moine data + 12, len - 12); 1685c52af799SJean-Francois Moine } 1686c52af799SJean-Francois Moine 1687c52af799SJean-Francois Moine /* Done this payload */ 1688c52af799SJean-Francois Moine goto scan_next; 1689c52af799SJean-Francois Moine 1690c52af799SJean-Francois Moine discard: 1691c52af799SJean-Francois Moine /* Discard data until a new frame starts. */ 1692c52af799SJean-Francois Moine gspca_dev->last_packet_type = DISCARD_PACKET; 1693c52af799SJean-Francois Moine 1694c52af799SJean-Francois Moine scan_next: 1695c52af799SJean-Francois Moine remaining_len -= len; 1696c52af799SJean-Francois Moine data += len; 1697c52af799SJean-Francois Moine } while (remaining_len > 0); 1698c52af799SJean-Francois Moine } 1699c52af799SJean-Francois Moine 1700f3920f0fSHans Verkuil static int sd_s_ctrl(struct v4l2_ctrl *ctrl) 1701c52af799SJean-Francois Moine { 1702f3920f0fSHans Verkuil struct gspca_dev *gspca_dev = 1703f3920f0fSHans Verkuil container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 1704f3920f0fSHans Verkuil 1705f3920f0fSHans Verkuil gspca_dev->usb_err = 0; 1706f3920f0fSHans Verkuil 1707f3920f0fSHans Verkuil if (!gspca_dev->streaming) 1708f3920f0fSHans Verkuil return 0; 1709f3920f0fSHans Verkuil 1710f3920f0fSHans Verkuil switch (ctrl->id) { 1711f3920f0fSHans Verkuil case V4L2_CID_BRIGHTNESS: 1712f3920f0fSHans Verkuil setbrightness(gspca_dev, ctrl->val); 1713f3920f0fSHans Verkuil break; 1714f3920f0fSHans Verkuil case V4L2_CID_CONTRAST: 1715f3920f0fSHans Verkuil setcontrast(gspca_dev, ctrl->val); 1716f3920f0fSHans Verkuil break; 1717f3920f0fSHans Verkuil case V4L2_CID_SATURATION: 1718f3920f0fSHans Verkuil setsatur(gspca_dev, ctrl->val); 1719f3920f0fSHans Verkuil break; 1720c52af799SJean-Francois Moine case V4L2_CID_POWER_LINE_FREQUENCY: 1721f3920f0fSHans Verkuil setlightfreq(gspca_dev, ctrl->val); 1722f3920f0fSHans Verkuil break; 1723f3920f0fSHans Verkuil case V4L2_CID_SHARPNESS: 1724f3920f0fSHans Verkuil setsharpness(gspca_dev, ctrl->val); 1725f3920f0fSHans Verkuil break; 1726f3920f0fSHans Verkuil case V4L2_CID_AUTOGAIN: 1727f3920f0fSHans Verkuil if (ctrl->is_new) 1728f3920f0fSHans Verkuil setautogain(gspca_dev, ctrl->val); 1729f3920f0fSHans Verkuil if (!ctrl->val && gspca_dev->exposure->is_new) 1730f3920f0fSHans Verkuil setexposure(gspca_dev, gspca_dev->exposure->val); 1731c52af799SJean-Francois Moine break; 1732c52af799SJean-Francois Moine } 1733f3920f0fSHans Verkuil return gspca_dev->usb_err; 1734f3920f0fSHans Verkuil } 1735f3920f0fSHans Verkuil 1736f3920f0fSHans Verkuil static const struct v4l2_ctrl_ops sd_ctrl_ops = { 1737f3920f0fSHans Verkuil .s_ctrl = sd_s_ctrl, 1738f3920f0fSHans Verkuil }; 1739f3920f0fSHans Verkuil 1740f3920f0fSHans Verkuil static int sd_init_controls(struct gspca_dev *gspca_dev) 1741f3920f0fSHans Verkuil { 1742f3920f0fSHans Verkuil struct sd *sd = (struct sd *)gspca_dev; 1743f3920f0fSHans Verkuil struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; 1744f3920f0fSHans Verkuil 1745f3920f0fSHans Verkuil if (sd->sensor == SENSOR_OV971x) 1746f3920f0fSHans Verkuil return 0; 174715807765SVladik Aranov if (sd->sensor == SENSOR_OV361x) 174815807765SVladik Aranov return 0; 1749f3920f0fSHans Verkuil gspca_dev->vdev.ctrl_handler = hdl; 1750f3920f0fSHans Verkuil v4l2_ctrl_handler_init(hdl, 7); 1751f3920f0fSHans Verkuil if (sd->sensor == SENSOR_OV562x) { 1752f3920f0fSHans Verkuil v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1753f3920f0fSHans Verkuil V4L2_CID_BRIGHTNESS, -90, 90, 1, 0); 1754f3920f0fSHans Verkuil } else { 1755f3920f0fSHans Verkuil v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1756f3920f0fSHans Verkuil V4L2_CID_BRIGHTNESS, 0, 15, 1, 7); 1757f3920f0fSHans Verkuil v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1758f3920f0fSHans Verkuil V4L2_CID_CONTRAST, 0, 15, 1, 3); 1759f3920f0fSHans Verkuil v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1760f3920f0fSHans Verkuil V4L2_CID_SATURATION, 0, 4, 1, 2); 1761f3920f0fSHans Verkuil /* -1 = auto */ 1762f3920f0fSHans Verkuil v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1763f3920f0fSHans Verkuil V4L2_CID_SHARPNESS, -1, 4, 1, -1); 1764f3920f0fSHans Verkuil gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1765f3920f0fSHans Verkuil V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 1766f3920f0fSHans Verkuil gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1767f3920f0fSHans Verkuil V4L2_CID_EXPOSURE, 0, 3, 1, 0); 1768f3920f0fSHans Verkuil v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, 1769f3920f0fSHans Verkuil V4L2_CID_POWER_LINE_FREQUENCY, 1770f3920f0fSHans Verkuil V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); 1771f3920f0fSHans Verkuil v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); 1772f3920f0fSHans Verkuil } 1773f3920f0fSHans Verkuil 1774f3920f0fSHans Verkuil if (hdl->error) { 1775f3920f0fSHans Verkuil pr_err("Could not initialize controls\n"); 1776f3920f0fSHans Verkuil return hdl->error; 1777f3920f0fSHans Verkuil } 1778f3920f0fSHans Verkuil return 0; 1779c52af799SJean-Francois Moine } 1780c52af799SJean-Francois Moine 1781c52af799SJean-Francois Moine /* sub-driver description */ 1782c52af799SJean-Francois Moine static const struct sd_desc sd_desc = { 1783c52af799SJean-Francois Moine .name = MODULE_NAME, 1784c52af799SJean-Francois Moine .config = sd_config, 1785c52af799SJean-Francois Moine .init = sd_init, 1786f3920f0fSHans Verkuil .init_controls = sd_init_controls, 1787c52af799SJean-Francois Moine .start = sd_start, 1788c52af799SJean-Francois Moine .stopN = sd_stopN, 1789c52af799SJean-Francois Moine .pkt_scan = sd_pkt_scan, 1790c52af799SJean-Francois Moine }; 1791c52af799SJean-Francois Moine 1792c52af799SJean-Francois Moine /* -- module initialisation -- */ 179395c967c1SJean-François Moine static const struct usb_device_id device_table[] = { 17948d64d4f6SJean-François Moine {USB_DEVICE(0x05a9, 0x8065)}, 1795c52af799SJean-Francois Moine {USB_DEVICE(0x06f8, 0x3003)}, 1796965b37a4SJose Alberto Reguero {USB_DEVICE(0x05a9, 0x1550)}, 1797c52af799SJean-Francois Moine {} 1798c52af799SJean-Francois Moine }; 1799c52af799SJean-Francois Moine 1800c52af799SJean-Francois Moine MODULE_DEVICE_TABLE(usb, device_table); 1801c52af799SJean-Francois Moine 1802c52af799SJean-Francois Moine /* -- device connect -- */ 1803c52af799SJean-Francois Moine static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 1804c52af799SJean-Francois Moine { 1805c52af799SJean-Francois Moine return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 1806c52af799SJean-Francois Moine THIS_MODULE); 1807c52af799SJean-Francois Moine } 1808c52af799SJean-Francois Moine 1809c52af799SJean-Francois Moine static struct usb_driver sd_driver = { 1810c52af799SJean-Francois Moine .name = MODULE_NAME, 1811c52af799SJean-Francois Moine .id_table = device_table, 1812c52af799SJean-Francois Moine .probe = sd_probe, 1813c52af799SJean-Francois Moine .disconnect = gspca_disconnect, 1814c52af799SJean-Francois Moine #ifdef CONFIG_PM 1815c52af799SJean-Francois Moine .suspend = gspca_suspend, 1816c52af799SJean-Francois Moine .resume = gspca_resume, 18178bb58964SHans de Goede .reset_resume = gspca_resume, 1818c52af799SJean-Francois Moine #endif 1819c52af799SJean-Francois Moine }; 1820c52af799SJean-Francois Moine 1821ecb3b2b3SGreg Kroah-Hartman module_usb_driver(sd_driver); 1822