16a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* 26a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * Sunplus spca561 subdriver 36a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * 46a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr 56a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * 66a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 76a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * 86a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * This program is free software; you can redistribute it and/or modify 96a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * it under the terms of the GNU General Public License as published by 106a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * the Free Software Foundation; either version 2 of the License, or 116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * any later version. 126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * 136a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * This program is distributed in the hope that it will be useful, 146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * but WITHOUT ANY WARRANTY; without even the implied warranty of 156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 166a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * GNU General Public License for more details. 176a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * 186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * You should have received a copy of the GNU General Public License 196a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * along with this program; if not, write to the Free Software 206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine */ 226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 23133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 24133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches 256a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define MODULE_NAME "spca561" 266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 27436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede#include <linux/input.h> 286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#include "gspca.h" 296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois MoineMODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 316a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois MoineMODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); 326a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois MoineMODULE_LICENSE("GPL"); 336a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 343fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil#define EXPOSURE_MAX (2047 + 325) 353fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil 366a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* specific webcam descriptor */ 376a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestruct sd { 386a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine struct gspca_dev gspca_dev; /* !! must be the first item */ 396a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 403fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil struct { /* hue/contrast control cluster */ 413fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil struct v4l2_ctrl *contrast; 423fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil struct v4l2_ctrl *hue; 433fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil }; 443fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil struct v4l2_ctrl *autogain; 456a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 46d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine#define EXPO12A_DEF 3 47d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine __u8 expo12a; /* expo/gain? for rev 12a */ 48d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine 496a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine __u8 chip_revision; 507879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define Rev012A 0 517879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine#define Rev072A 1 527879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine 536a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine signed char ag_cnt; 546a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define AG_CNT_START 13 556a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}; 566a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 57cc611b8aef7a8a9a2e614f1bdf3e2b8f066c8c8dJean-Francois Moinestatic const struct v4l2_pix_format sif_012a_mode[] = { 58c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 59c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .bytesperline = 160, 60c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .sizeimage = 160 * 120, 61c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .colorspace = V4L2_COLORSPACE_SRGB, 62c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .priv = 3}, 63c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 64c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .bytesperline = 176, 65c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .sizeimage = 176 * 144, 66c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .colorspace = V4L2_COLORSPACE_SRGB, 67c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .priv = 2}, 68c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE, 69c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .bytesperline = 320, 70c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .sizeimage = 320 * 240 * 4 / 8, 71c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .colorspace = V4L2_COLORSPACE_SRGB, 72c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .priv = 1}, 73c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE, 74c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .bytesperline = 352, 75c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .sizeimage = 352 * 288 * 4 / 8, 76c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .colorspace = V4L2_COLORSPACE_SRGB, 77c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine .priv = 0}, 786a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}; 796a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 80cc611b8aef7a8a9a2e614f1bdf3e2b8f066c8c8dJean-Francois Moinestatic const struct v4l2_pix_format sif_072a_mode[] = { 81b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 82b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .bytesperline = 160, 83b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .sizeimage = 160 * 120, 84b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .colorspace = V4L2_COLORSPACE_SRGB, 85b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .priv = 3}, 86b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 87b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .bytesperline = 176, 88b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .sizeimage = 176 * 144, 89b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .colorspace = V4L2_COLORSPACE_SRGB, 90b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .priv = 2}, 91b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 92b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .bytesperline = 320, 93b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .sizeimage = 320 * 240, 94b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .colorspace = V4L2_COLORSPACE_SRGB, 95b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .priv = 1}, 96b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 97b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .bytesperline = 352, 98b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .sizeimage = 352 * 288, 99b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .colorspace = V4L2_COLORSPACE_SRGB, 100b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine .priv = 0}, 101b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine}; 102b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine 1036a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* 1046a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * Initialization data 1056a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * I'm not very sure how to split initialization from open data 1066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * chunks. For now, we'll consider everything as initialization 1076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine */ 1086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* Frame packet header offsets for the spca561 */ 1096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_SNAP 1 1106a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_TYPE 2 1116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_COMPRESS 3 1126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_FRAMSEQ 4 1136a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_GPIO 5 1146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_USBBUFF 6 1156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN2GRAVE 7 1166a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN2RAVE 8 1176a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN2BAVE 9 1186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN2GBAVE 10 1196a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN1GRAVE 11 1206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN1RAVE 12 1216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN1BAVE 13 1226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_WIN1GBAVE 14 1236a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_FREQ 15 1246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_OFFSET_VSYNC 16 1256a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_INDEX_I2C_BASE 0x8800 1266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_SNAPBIT 0x20 1276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine#define SPCA561_SNAPCTRL 0x40 1286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 1290dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moinestatic const u16 rev72a_reset[][2] = { 1306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0000, 0x8114}, /* Software GPIO output data */ 1316a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0001, 0x8114}, /* Software GPIO output data */ 1326a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0000, 0x8112}, /* Some kind of reset */ 1330dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {} 1340dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine}; 1350dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moinestatic const __u16 rev72a_init_data1[][2] = { 1366a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0003, 0x8701}, /* PCLK clock delay adjustment */ 1376a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0001, 0x8703}, /* HSYNC from cmos inverted */ 1386a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0011, 0x8118}, /* Enable and conf sensor */ 1396a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0001, 0x8118}, /* Conf sensor */ 1406a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0092, 0x8804}, /* I know nothing about these */ 1416a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ 142f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine {} 143f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine}; 1440dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moinestatic const u16 rev72a_init_sensor1[][2] = { 1450dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0001, 0x000d}, 1460dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0002, 0x0018}, 1470dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0004, 0x0165}, 1480dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0005, 0x0021}, 1490dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0007, 0x00aa}, 1500dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0020, 0x1504}, 1510dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0039, 0x0002}, 1520dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0035, 0x0010}, 1530dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0009, 0x1049}, 1540dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0028, 0x000b}, 1550dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x003b, 0x000f}, 1560dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x003c, 0x0000}, 157f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine {} 158f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine}; 159f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moinestatic const __u16 rev72a_init_data2[][2] = { 1606a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0018, 0x8601}, /* Pixel/line selection for color separation */ 1616a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0000, 0x8602}, /* Optical black level for user setting */ 1626a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0060, 0x8604}, /* Optical black horizontal offset */ 1636a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0002, 0x8605}, /* Optical black vertical offset */ 1646a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0000, 0x8603}, /* Non-automatic optical black level */ 1656a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ 1666a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0000, 0x865f}, /* Vertical valid pixels window (x2) */ 1676a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x00b0, 0x865d}, /* Horizontal valid pixels window (x2) */ 1686a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0090, 0x865e}, /* Vertical valid lines window (x2) */ 1696a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x00e0, 0x8406}, /* Memory buffer threshold */ 1706a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0000, 0x8660}, /* Compensation memory stuff */ 1716a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */ 1726a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ 1736a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0001, 0x8200}, /* OprMode to be executed by hardware */ 1740dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine/* from ms-win */ 1750dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0000, 0x8611}, /* R offset for white balance */ 1760dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x00fd, 0x8612}, /* Gr offset for white balance */ 1770dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0003, 0x8613}, /* B offset for white balance */ 1786a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0000, 0x8614}, /* Gb offset for white balance */ 1795b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine/* from ms-win */ 1805b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine {0x0035, 0x8651}, /* R gain for white balance */ 1815b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine {0x0040, 0x8652}, /* Gr gain for white balance */ 1825b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine {0x005f, 0x8653}, /* B gain for white balance */ 1835b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine {0x0040, 0x8654}, /* Gb gain for white balance */ 1846a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0002, 0x8502}, /* Maximum average bit rate stuff */ 1856a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0011, 0x8802}, 1860dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine 1876a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0087, 0x8700}, /* Set master clock (96Mhz????) */ 1886a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0081, 0x8702}, /* Master clock output enable */ 1896a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 1906a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0000, 0x8500}, /* Set image type (352x288 no compression) */ 1916a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* Originally was 0x0010 (352x288 compression) */ 1926a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 1936a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ 1946a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0003, 0x865c}, /* Vertical offset for valid lines */ 195f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine {} 196f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine}; 1970dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moinestatic const u16 rev72a_init_sensor2[][2] = { 1980dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0003, 0x0121}, 1990dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0004, 0x0165}, 2000dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0005, 0x002f}, /* blanking control column */ 2010dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0006, 0x0000}, /* blanking mode row*/ 2020dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x000a, 0x0002}, 2030dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0009, 0x1061}, /* setexposure times && pixel clock 2046a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * 0001 0 | 000 0110 0001 */ 2050dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine {0x0035, 0x0014}, 2066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {} 2076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}; 2086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 2096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/******************** QC Express etch2 stuff ********************/ 210a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moinestatic const __u16 Pb100_1map8300[][2] = { 2116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* reg, value */ 2126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x8320, 0x3304}, 2136a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 2146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x8303, 0x0125}, /* image area */ 2156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x8304, 0x0169}, 2166a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x8328, 0x000b}, 2177879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine {0x833c, 0x0001}, /*fixme: win:07*/ 2186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 2197879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine {0x832f, 0x1904}, /*fixme: was 0419*/ 2206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x8307, 0x00aa}, 2216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x8301, 0x0003}, 2226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x8302, 0x000e}, 2236a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {} 2246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}; 225a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moinestatic const __u16 Pb100_2map8300[][2] = { 2266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* reg, value */ 2276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x8339, 0x0000}, 2286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x8307, 0x00aa}, 2296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {} 2306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}; 2316a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 232a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moinestatic const __u16 spca561_161rev12A_data1[][2] = { 2336b33e5e7fe03c6577ccbaeeb028ab4ec1f26f2b0Hans de Goede {0x29, 0x8118}, /* Control register (various enable bits) */ 2346b33e5e7fe03c6577ccbaeeb028ab4ec1f26f2b0Hans de Goede {0x08, 0x8114}, /* GPIO: Led off */ 2356b33e5e7fe03c6577ccbaeeb028ab4ec1f26f2b0Hans de Goede {0x0e, 0x8112}, /* 0x0e stream off 0x3e stream on */ 2366c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine {0x00, 0x8102}, /* white balance - new */ 2376a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x92, 0x8804}, 2386a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x04, 0x8802}, /* windows uses 08 */ 2396a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {} 2406a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}; 241a5ae2062252e697d38e53dbbeb91460252208914Jean-Francois Moinestatic const __u16 spca561_161rev12A_data2[][2] = { 2426a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x21, 0x8118}, 2436a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x10, 0x8500}, 2446a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x07, 0x8601}, 2456a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x07, 0x8602}, 2466a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x04, 0x8501}, 2476a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 2486a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x07, 0x8201}, /* windows uses 02 */ 2496a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x08, 0x8200}, 2506a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x01, 0x8200}, 2516a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 2526a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x90, 0x8604}, 2536a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x00, 0x8605}, 2546a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0xb0, 0x8603}, 2556a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 2566a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* sensor gains */ 2576c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine {0x07, 0x8601}, /* white balance - new */ 2586c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine {0x07, 0x8602}, /* white balance - new */ 2596a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x00, 0x8610}, /* *red */ 2606a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x00, 0x8611}, /* 3f *green */ 2616a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x00, 0x8612}, /* green *blue */ 2626a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x00, 0x8613}, /* blue *green */ 2636c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine {0x43, 0x8614}, /* green *red - white balance - was 0x35 */ 2646c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine {0x40, 0x8615}, /* 40 *green - white balance - was 0x35 */ 2656c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine {0x71, 0x8616}, /* 7a *blue - white balance - was 0x35 */ 2666c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine {0x40, 0x8617}, /* 40 *green - white balance - was 0x35 */ 2676a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 2686a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x0c, 0x8620}, /* 0c */ 2696a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0xc8, 0x8631}, /* c8 */ 2706a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0xc8, 0x8634}, /* c8 */ 2716a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x23, 0x8635}, /* 23 */ 2726a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x1f, 0x8636}, /* 1f */ 2736a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0xdd, 0x8637}, /* dd */ 2746a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0xe1, 0x8638}, /* e1 */ 2756a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x1d, 0x8639}, /* 1d */ 2766a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x21, 0x863a}, /* 21 */ 2776a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0xe3, 0x863b}, /* e3 */ 2786a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0xdf, 0x863c}, /* df */ 2796a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0xf0, 0x8505}, 2806a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {0x32, 0x850a}, 2817879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* {0x99, 0x8700}, * - white balance - new (removed) */ 2826b33e5e7fe03c6577ccbaeeb028ab4ec1f26f2b0Hans de Goede /* HDG we used to do this in stop0, making the init state and the state 2836b33e5e7fe03c6577ccbaeeb028ab4ec1f26f2b0Hans de Goede after a start / stop different, so do this here instead. */ 2846b33e5e7fe03c6577ccbaeeb028ab4ec1f26f2b0Hans de Goede {0x29, 0x8118}, 2856a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {} 2866a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}; 2876a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 288c93396e13576928a073154b5715761ff8a998368Theodore Kilgorestatic void reg_w_val(struct gspca_dev *gspca_dev, __u16 index, __u8 value) 28935dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine{ 29035dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine int ret; 291c93396e13576928a073154b5715761ff8a998368Theodore Kilgore struct usb_device *dev = gspca_dev->dev; 29235dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 29335dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 29435dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 0, /* request */ 29535dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 29635dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine value, index, NULL, 0, 500); 29735dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value); 29835dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine if (ret < 0) 299133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches pr_err("reg write: error %d\n", ret); 30035dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine} 30135dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 30235dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moinestatic void write_vector(struct gspca_dev *gspca_dev, 30335dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine const __u16 data[][2]) 3046a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{ 30535dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine int i; 3066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 30735dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine i = 0; 30835dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine while (data[i][1] != 0) { 309c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, data[i][1], data[i][0]); 3106a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine i++; 3116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine } 3126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine} 31335dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 31435dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine/* read 'len' bytes to gspca_dev->usb_buf */ 31535dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moinestatic void reg_r(struct gspca_dev *gspca_dev, 31635dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine __u16 index, __u16 length) 31735dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine{ 31835dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine usb_control_msg(gspca_dev->dev, 31935dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine usb_rcvctrlpipe(gspca_dev->dev, 0), 32035dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 0, /* request */ 32135dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 32235dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 0, /* value */ 32335dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine index, gspca_dev->usb_buf, length, 500); 32435dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine} 32535dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 32635dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine/* write 'len' bytes from gspca_dev->usb_buf */ 32735dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moinestatic void reg_w_buf(struct gspca_dev *gspca_dev, 32835dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine __u16 index, __u16 len) 32935dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine{ 33035dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine usb_control_msg(gspca_dev->dev, 33135dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine usb_sndctrlpipe(gspca_dev->dev, 0), 33235dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 0, /* request */ 33335dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 33435dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 0, /* value */ 33535dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine index, gspca_dev->usb_buf, len, 500); 33635dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine} 33735dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 33835dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moinestatic void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg) 33935dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine{ 34035dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine int retry = 60; 34135dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 342c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8801, reg); 343c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8805, value); 344c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8800, value >> 8); 34535dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine do { 34635dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine reg_r(gspca_dev, 0x8803, 1); 34735dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine if (!gspca_dev->usb_buf[0]) 34835dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine return; 3490dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine msleep(10); 35035dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine } while (--retry); 35135dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine} 35235dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 35335dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moinestatic int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) 35435dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine{ 35535dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine int retry = 60; 35635dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine __u8 value; 35735dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 358c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8804, 0x92); 359c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8801, reg); 360c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8802, mode | 0x01); 36135dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine do { 36235dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine reg_r(gspca_dev, 0x8803, 1); 36335dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine if (!gspca_dev->usb_buf[0]) { 36435dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine reg_r(gspca_dev, 0x8800, 1); 36535dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine value = gspca_dev->usb_buf[0]; 36635dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine reg_r(gspca_dev, 0x8805, 1); 36735dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine return ((int) value << 8) | gspca_dev->usb_buf[0]; 36835dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine } 3690dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine msleep(10); 37035dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine } while (--retry); 37135dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine return -1; 37235dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine} 37335dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 37435dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moinestatic void sensor_mapwrite(struct gspca_dev *gspca_dev, 37535dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine const __u16 (*sensormap)[2]) 37635dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine{ 37735dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine while ((*sensormap)[0]) { 37835dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine gspca_dev->usb_buf[0] = (*sensormap)[1]; 37935dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8; 38035dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine reg_w_buf(gspca_dev, (*sensormap)[0], 2); 38135dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine sensormap++; 38235dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine } 38335dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine} 38435dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 385f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moinestatic void write_sensor_72a(struct gspca_dev *gspca_dev, 386f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine const __u16 (*sensor)[2]) 387f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine{ 388f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine while ((*sensor)[0]) { 389f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]); 390f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine sensor++; 391f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine } 392f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine} 393f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine 3946a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void init_161rev12A(struct gspca_dev *gspca_dev) 3956a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{ 3966a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine write_vector(gspca_dev, spca561_161rev12A_data1); 3976a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine sensor_mapwrite(gspca_dev, Pb100_1map8300); 3987879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/*fixme: should be in sd_start*/ 3996a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine write_vector(gspca_dev, spca561_161rev12A_data2); 4006a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine sensor_mapwrite(gspca_dev, Pb100_2map8300); 4016a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine} 4026a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 4036a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* this function is called at probe time */ 4046a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int sd_config(struct gspca_dev *gspca_dev, 4056a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine const struct usb_device_id *id) 4066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{ 4076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine struct sd *sd = (struct sd *) gspca_dev; 4086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine struct cam *cam; 4096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine __u16 vendor, product; 4106a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine __u8 data1, data2; 4116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 4126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* Read frm global register the USB product and vendor IDs, just to 4136a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * prove that we can communicate with the device. This works, which 4146a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * confirms at we are communicating properly and that the device 4156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine * is a 561. */ 416739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine reg_r(gspca_dev, 0x8104, 1); 417739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine data1 = gspca_dev->usb_buf[0]; 418739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine reg_r(gspca_dev, 0x8105, 1); 419739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine data2 = gspca_dev->usb_buf[0]; 4206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine vendor = (data2 << 8) | data1; 421739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine reg_r(gspca_dev, 0x8106, 1); 422739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine data1 = gspca_dev->usb_buf[0]; 423739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine reg_r(gspca_dev, 0x8107, 1); 424739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine data2 = gspca_dev->usb_buf[0]; 4256a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine product = (data2 << 8) | data1; 4266a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine if (vendor != id->idVendor || product != id->idProduct) { 4276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine PDEBUG(D_PROBE, "Bad vendor / product from device"); 4286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine return -EINVAL; 4296a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine } 4309d64fdb15b1b9ce9144cfde4001e9194ccde42d1Jean-Francois Moine 4316a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine cam = &gspca_dev->cam; 432eb3fb7c9633f79077c7c650efe0edec1840926daHans de Goede cam->needs_full_bandwidth = 1; 4339d64fdb15b1b9ce9144cfde4001e9194ccde42d1Jean-Francois Moine 4349d64fdb15b1b9ce9144cfde4001e9194ccde42d1Jean-Francois Moine sd->chip_revision = id->driver_info; 435b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine if (sd->chip_revision == Rev012A) { 436b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine cam->cam_mode = sif_012a_mode; 437b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine cam->nmodes = ARRAY_SIZE(sif_012a_mode); 438b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine } else { 439b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine cam->cam_mode = sif_072a_mode; 440b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine cam->nmodes = ARRAY_SIZE(sif_072a_mode); 441b77c0046a63e7aa87152f9978cf7c46e7bead7fcJean-Francois Moine } 442d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine sd->expo12a = EXPO12A_DEF; 4436a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine return 0; 4446a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine} 4456a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 446012d6b029ec17f45374303bbdccd0bc206725751Jean-Francois Moine/* this function is called at probe and resume time */ 447012d6b029ec17f45374303bbdccd0bc206725751Jean-Francois Moinestatic int sd_init_12a(struct gspca_dev *gspca_dev) 4486a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{ 4497879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine PDEBUG(D_STREAM, "Chip revision: 012a"); 4507879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine init_161rev12A(gspca_dev); 4517879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine return 0; 4527879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine} 453012d6b029ec17f45374303bbdccd0bc206725751Jean-Francois Moinestatic int sd_init_72a(struct gspca_dev *gspca_dev) 4547879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{ 4557879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine PDEBUG(D_STREAM, "Chip revision: 072a"); 4560dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine write_vector(gspca_dev, rev72a_reset); 4570dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine msleep(200); 458f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine write_vector(gspca_dev, rev72a_init_data1); 459f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine write_sensor_72a(gspca_dev, rev72a_init_sensor1); 460f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine write_vector(gspca_dev, rev72a_init_data2); 461f8a04a6fc4373001a7f311540dba5e4f4d86300fJean-Francois Moine write_sensor_72a(gspca_dev, rev72a_init_sensor2); 462c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8112, 0x30); 4636a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine return 0; 4646a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine} 4656a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 4663fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuilstatic void setbrightness(struct gspca_dev *gspca_dev, s32 val) 4676a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{ 468a8931d5948cdd55f899f107c61f375d34a580304Hans de Goede struct sd *sd = (struct sd *) gspca_dev; 469a8931d5948cdd55f899f107c61f375d34a580304Hans de Goede __u16 reg; 4705b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine 471a8931d5948cdd55f899f107c61f375d34a580304Hans de Goede if (sd->chip_revision == Rev012A) 472a8931d5948cdd55f899f107c61f375d34a580304Hans de Goede reg = 0x8610; 473a8931d5948cdd55f899f107c61f375d34a580304Hans de Goede else 474a8931d5948cdd55f899f107c61f375d34a580304Hans de Goede reg = 0x8611; 475a8931d5948cdd55f899f107c61f375d34a580304Hans de Goede 476c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, reg + 0, val); /* R */ 477c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, reg + 1, val); /* Gr */ 478c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, reg + 2, val); /* B */ 479c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, reg + 3, val); /* Gb */ 4806a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine} 4816a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 4823fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuilstatic void setwhite(struct gspca_dev *gspca_dev, s32 white, s32 contrast) 4836c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine{ 4846c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine struct sd *sd = (struct sd *) gspca_dev; 4855b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine __u8 blue, red; 4865b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine __u16 reg; 4876c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine 4887879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine /* try to emulate MS-win as possible */ 4895b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine red = 0x20 + white * 3 / 8; 4905b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine blue = 0x90 - white * 5 / 8; 4915b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine if (sd->chip_revision == Rev012A) { 4925b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine reg = 0x8614; 4935b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine } else { 4945b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine reg = 0x8651; 4953fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil red += contrast - 0x20; 4963fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil blue += contrast - 0x20; 497c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8652, contrast + 0x20); /* Gr */ 498c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8654, contrast + 0x20); /* Gb */ 4995b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine } 500c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, reg, red); 501c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, reg + 2, blue); 5027879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine} 5037879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine 5047879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev 12a only */ 5053fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuilstatic void setexposure(struct gspca_dev *gspca_dev, s32 val) 5067879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{ 507d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede int i, expo = 0; 5087879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine 5090fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede /* Register 0x8309 controls exposure for the spca561, 5100fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede the basic exposure setting goes from 1-2047, where 1 is completely 5110fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede dark and 2047 is very bright. It not only influences exposure but 5120fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede also the framerate (to allow for longer exposure) from 1 - 300 it 5130fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede only raises the exposure time then from 300 - 600 it halves the 5140fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede framerate to be able to further raise the exposure time and for every 5150fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede 300 more it halves the framerate again. This allows for a maximum 5160fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps). 5170fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12 5180fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede configure a divider for the base framerate which us used at the 5190fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede exposure setting of 1-300. These bits configure the base framerate 5200fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede according to the following formula: fps = 60 / (value + 2) */ 521d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede 522d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede /* We choose to use the high bits setting the fixed framerate divisor 523d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede asap, as setting high basic exposure setting without the fixed 524d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede divider in combination with high gains makes the cam stop */ 525d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede int table[] = { 0, 450, 550, 625, EXPOSURE_MAX }; 526d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede 527d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede for (i = 0; i < ARRAY_SIZE(table) - 1; i++) { 5283fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil if (val <= table[i + 1]) { 5293fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil expo = val - table[i]; 530d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede if (i) 531d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede expo += 300; 532d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede expo |= i << 11; 533d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede break; 534d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede } 5350fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede } 536d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede 53735dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine gspca_dev->usb_buf[0] = expo; 53835dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine gspca_dev->usb_buf[1] = expo >> 8; 53935dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine reg_w_buf(gspca_dev, 0x8309, 2); 5407879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine} 5417879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine 5427879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine/* rev 12a only */ 5433fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuilstatic void setgain(struct gspca_dev *gspca_dev, s32 val) 5447879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{ 545d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede /* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the 546d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede sensitivity when set, so 31 + one of them set == 63, and 15 547d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede with both of them set == 63 */ 5483fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil if (val < 64) 5493fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil gspca_dev->usb_buf[0] = val; 5503fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil else if (val < 128) 5513fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil gspca_dev->usb_buf[0] = (val / 2) | 0x40; 552d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede else 5533fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil gspca_dev->usb_buf[0] = (val / 4) | 0xc0; 554d0848eb2864c0f1ef52d586cd33c68a103b0a2acHans de Goede 55535dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine gspca_dev->usb_buf[1] = 0; 55635dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine reg_w_buf(gspca_dev, 0x8335, 2); 5576c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine} 5586c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine 5593fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuilstatic void setautogain(struct gspca_dev *gspca_dev, s32 val) 560cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine{ 561cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine struct sd *sd = (struct sd *) gspca_dev; 562cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine 5633fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil if (val) 564d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine sd->ag_cnt = AG_CNT_START; 565d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine else 566d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine sd->ag_cnt = -1; 567cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine} 568cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine 56972ab97cecb7225a4c9f74cdd80268b50b74697bbJean-Francois Moinestatic int sd_start_12a(struct gspca_dev *gspca_dev) 5706a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{ 5716a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine int mode; 5725b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine static const __u8 Reg8391[8] = 5735b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine {0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00}; 5746a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 575c2446b3eba97243acbe2ad0939a28b5edb97eae7Jean-Francois Moine mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 5767879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine if (mode <= 1) { 5777879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine /* Use compression on 320x240 and above */ 578c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8500, 0x10 | mode); 5797879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine } else { 5807879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine /* I couldn't get the compression to work below 320x240 5817879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine * Fortunately at these resolutions the bandwidth 5827879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine * is sufficient to push raw frames at ~20fps */ 583c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8500, mode); 5847879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine } /* -- qq@kuku.eu.org */ 58535dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine 5865b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine gspca_dev->usb_buf[0] = 0xaa; 5875b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine gspca_dev->usb_buf[1] = 0x00; 5885b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine reg_w_buf(gspca_dev, 0x8307, 2); 5895b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine /* clock - lower 0x8X values lead to fps > 30 */ 590c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8700, 0x8a); 5917879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine /* 0x8f 0x85 0x27 clock */ 592c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8112, 0x1e | 0x20); 593c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x850b, 0x03); 5945b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine memcpy(gspca_dev->usb_buf, Reg8391, 8); 5955b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine reg_w_buf(gspca_dev, 0x8391, 8); 5965b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine reg_w_buf(gspca_dev, 0x8390, 8); 5976b33e5e7fe03c6577ccbaeeb028ab4ec1f26f2b0Hans de Goede 5986b33e5e7fe03c6577ccbaeeb028ab4ec1f26f2b0Hans de Goede /* Led ON (bit 3 -> 0 */ 599c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8114, 0x00); 60072ab97cecb7225a4c9f74cdd80268b50b74697bbJean-Francois Moine return 0; 6017879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine} 60272ab97cecb7225a4c9f74cdd80268b50b74697bbJean-Francois Moinestatic int sd_start_72a(struct gspca_dev *gspca_dev) 6037879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{ 6043fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil struct sd *sd = (struct sd *) gspca_dev; 6057879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine int Clck; 6067879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine int mode; 6077879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine 6080dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine write_vector(gspca_dev, rev72a_reset); 6090dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine msleep(200); 6100dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine write_vector(gspca_dev, rev72a_init_data1); 6110dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine write_sensor_72a(gspca_dev, rev72a_init_sensor1); 6120dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine 6137879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 6147879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine switch (mode) { 6157879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine default: 616a48196a2f74a2e19e67debe194e337dfc583702fJean-Francois Moine case 0: 617a48196a2f74a2e19e67debe194e337dfc583702fJean-Francois Moine Clck = 0x27; /* ms-win 0x87 */ 618a48196a2f74a2e19e67debe194e337dfc583702fJean-Francois Moine break; 619a48196a2f74a2e19e67debe194e337dfc583702fJean-Francois Moine case 1: 6207879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine Clck = 0x25; 6217879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine break; 6227879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine case 2: 6237879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine Clck = 0x22; 6247879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine break; 6257879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine case 3: 6267879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine Clck = 0x21; 6276a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine break; 6286a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine } 629c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8700, Clck); /* 0x27 clock */ 630c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8702, 0x81); 631c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8500, mode); /* mode */ 6320dbc2c1674b346ff22f729af14efa4822f81325cJean-Francois Moine write_sensor_72a(gspca_dev, rev72a_init_sensor2); 6333fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil setwhite(gspca_dev, v4l2_ctrl_g_ctrl(sd->hue), 6343fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil v4l2_ctrl_g_ctrl(sd->contrast)); 6355b7ed28ec5deb57f790e38af8d813310b830743cJean-Francois Moine/* setbrightness(gspca_dev); * fixme: bad values */ 6363fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain)); 637c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8112, 0x10 | 0x20); 63872ab97cecb7225a4c9f74cdd80268b50b74697bbJean-Francois Moine return 0; 6396a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine} 6406a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 6416a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void sd_stopN(struct gspca_dev *gspca_dev) 6426a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{ 643d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine struct sd *sd = (struct sd *) gspca_dev; 644d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine 645d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine if (sd->chip_revision == Rev012A) { 646c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8112, 0x0e); 6476b33e5e7fe03c6577ccbaeeb028ab4ec1f26f2b0Hans de Goede /* Led Off (bit 3 -> 1 */ 648c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8114, 0x08); 649d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine } else { 650c93396e13576928a073154b5715761ff8a998368Theodore Kilgore reg_w_val(gspca_dev, 0x8112, 0x20); 651c93396e13576928a073154b5715761ff8a998368Theodore Kilgore/* reg_w_val(gspca_dev, 0x8102, 0x00); ?? */ 652d698dc6b0477d3165a7f320b3ce36d1cbd361c94Jean-Francois Moine } 6536a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine} 6546a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 655cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moinestatic void do_autogain(struct gspca_dev *gspca_dev) 6566a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{ 6576a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine struct sd *sd = (struct sd *) gspca_dev; 658cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine int expotimes; 659cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine int pixelclk; 660cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine int gainG; 6616a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine __u8 R, Gr, Gb, B; 6626a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine int y; 6636a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine __u8 luma_mean = 110; 6646a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine __u8 luma_delta = 20; 6656a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine __u8 spring = 4; 6666a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 667cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine if (sd->ag_cnt < 0) 668cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine return; 669cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine if (--sd->ag_cnt >= 0) 670cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine return; 671cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine sd->ag_cnt = AG_CNT_START; 672cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine 6736a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine switch (sd->chip_revision) { 6746a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine case Rev072A: 675739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine reg_r(gspca_dev, 0x8621, 1); 676739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine Gr = gspca_dev->usb_buf[0]; 677739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine reg_r(gspca_dev, 0x8622, 1); 678739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine R = gspca_dev->usb_buf[0]; 679739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine reg_r(gspca_dev, 0x8623, 1); 680739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine B = gspca_dev->usb_buf[0]; 681739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine reg_r(gspca_dev, 0x8624, 1); 682739570bb218bb4607df1f197282561e97a98e54aJean-Francois Moine Gb = gspca_dev->usb_buf[0]; 6836a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8; 6846a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */ 6856a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */ 6866a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */ 6876a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 6886a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine if (y < luma_mean - luma_delta || 6896a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine y > luma_mean + luma_delta) { 6906a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine expotimes = i2c_read(gspca_dev, 0x09, 0x10); 6916a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine pixelclk = 0x0800; 6926a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine expotimes = expotimes & 0x07ff; 6936a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* PDEBUG(D_PACK, 6946a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine "Exposition Times 0x%03X Clock 0x%04X ", 6956a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine expotimes,pixelclk); */ 6966a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine gainG = i2c_read(gspca_dev, 0x35, 0x10); 6976a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* PDEBUG(D_PACK, 6986a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine "reading Gain register %d", gainG); */ 6996a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 7006a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine expotimes += (luma_mean - y) >> spring; 7016a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine gainG += (luma_mean - y) / 50; 7026a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* PDEBUG(D_PACK, 7036a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine "compute expotimes %d gain %d", 7046a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine expotimes,gainG); */ 7056a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 7066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine if (gainG > 0x3f) 7076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine gainG = 0x3f; 70835dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine else if (gainG < 3) 7096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine gainG = 3; 7106a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine i2c_write(gspca_dev, gainG, 0x35); 7116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 71235dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine if (expotimes > 0x0256) 7136a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine expotimes = 0x0256; 71435dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine else if (expotimes < 3) 7156a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine expotimes = 3; 7166a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine i2c_write(gspca_dev, expotimes | pixelclk, 0x09); 7176a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine } 7186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine break; 7196a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine } 7206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine} 7216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 7226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic void sd_pkt_scan(struct gspca_dev *gspca_dev, 72376dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine u8 *data, /* isoc packet */ 7246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine int len) /* iso packet length */ 7256a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{ 7260fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede struct sd *sd = (struct sd *) gspca_dev; 7270fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede 728576ed7b5696b9435e8e6a6ec0c57da1f19c7e469Jean-Francois Moine len--; 729576ed7b5696b9435e8e6a6ec0c57da1f19c7e469Jean-Francois Moine switch (*data++) { /* sequence number */ 73035dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine case 0: /* start of frame */ 73176dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 732436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede 733436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede /* This should never happen */ 734436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede if (len < 2) { 735c93396e13576928a073154b5715761ff8a998368Theodore Kilgore PERR("Short SOF packet, ignoring"); 736436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede gspca_dev->last_packet_type = DISCARD_PACKET; 737436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede return; 738436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede } 739436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede 74060d21563785535e518589ab58b0295ecaa06233fPeter Senna Tschudin#if IS_ENABLED(CONFIG_INPUT) 741436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede if (data[0] & 0x20) { 742436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); 743436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede input_sync(gspca_dev->input_dev); 744436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); 745436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede input_sync(gspca_dev->input_dev); 746436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede } 747436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede#endif 748436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede 7496a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine if (data[1] & 0x10) { 7506a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine /* compressed bayer */ 75176dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); 7526a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine } else { 75354ab92ca05550550bcec2462de2605f35d079b66Hans de Goede /* raw bayer (with a header, which we skip) */ 7540fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede if (sd->chip_revision == Rev012A) { 7550fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede data += 20; 7560fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede len -= 20; 7570fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede } else { 7580fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede data += 16; 7590fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede len -= 16; 7600fc23d20699a6a3b7e34b3be2cc5e60317ba7849Hans de Goede } 76176dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); 7626a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine } 7636a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine return; 76435dc1b4cfa75dc0fa5ed44991b41db814e0f7741Jean-Francois Moine case 0xff: /* drop (empty mpackets) */ 7656a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine return; 7666a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine } 76776dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 7686a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine} 7696a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 7703fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuilstatic int sd_s_ctrl(struct v4l2_ctrl *ctrl) 7716a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{ 7723fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil struct gspca_dev *gspca_dev = 7733fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 7743fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil struct sd *sd = (struct sd *)gspca_dev; 7756a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 7763fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil gspca_dev->usb_err = 0; 7776a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 7783fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil if (!gspca_dev->streaming) 7793fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil return 0; 7806a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 7813fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil switch (ctrl->id) { 7823fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil case V4L2_CID_BRIGHTNESS: 7833fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil setbrightness(gspca_dev, ctrl->val); 7843fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil break; 7853fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil case V4L2_CID_CONTRAST: 7863fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil /* hue/contrast control cluster for 72a */ 7873fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil setwhite(gspca_dev, sd->hue->val, ctrl->val); 7883fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil break; 7893fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil case V4L2_CID_HUE: 7903fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil /* just plain hue control for 12a */ 7913fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil setwhite(gspca_dev, ctrl->val, 0); 7923fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil break; 7933fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil case V4L2_CID_EXPOSURE: 7943fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil setexposure(gspca_dev, ctrl->val); 7953fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil break; 7963fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil case V4L2_CID_GAIN: 7973fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil setgain(gspca_dev, ctrl->val); 7983fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil break; 7993fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil case V4L2_CID_AUTOGAIN: 8003fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil setautogain(gspca_dev, ctrl->val); 8013fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil break; 8023fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil } 8033fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil return gspca_dev->usb_err; 8046c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine} 8056c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine 8063fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuilstatic const struct v4l2_ctrl_ops sd_ctrl_ops = { 8073fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil .s_ctrl = sd_s_ctrl, 8083fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil}; 8096c9d3c59e6fdb8dfadaf7ba38f1d0b64ff066b36Jean-Francois Moine 8103fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuilstatic int sd_init_controls_12a(struct gspca_dev *gspca_dev) 8117879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{ 8123fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; 8137879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine 8143fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil gspca_dev->vdev.ctrl_handler = hdl; 8153fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil v4l2_ctrl_handler_init(hdl, 3); 8163fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 8173fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil V4L2_CID_HUE, 1, 0x7f, 1, 0x40); 8183fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 819a8931d5948cdd55f899f107c61f375d34a580304Hans de Goede V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); 820a8931d5948cdd55f899f107c61f375d34a580304Hans de Goede v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 8213fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil V4L2_CID_EXPOSURE, 1, EXPOSURE_MAX, 1, 700); 8223fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 8233fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil V4L2_CID_GAIN, 0, 255, 1, 63); 8247879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine 8253fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil if (hdl->error) { 8263fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil pr_err("Could not initialize controls\n"); 8273fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil return hdl->error; 8283fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil } 8297879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine return 0; 8307879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine} 8317879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine 8323fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuilstatic int sd_init_controls_72a(struct gspca_dev *gspca_dev) 8337879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine{ 8343fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil struct sd *sd = (struct sd *)gspca_dev; 8353fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; 8367879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine 8373fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil gspca_dev->vdev.ctrl_handler = hdl; 8383fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil v4l2_ctrl_handler_init(hdl, 4); 8393fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 8403fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil V4L2_CID_CONTRAST, 0, 0x3f, 1, 0x20); 8413fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 8423fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil V4L2_CID_HUE, 1, 0x7f, 1, 0x40); 8433fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 8443fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil V4L2_CID_BRIGHTNESS, 0, 0x3f, 1, 0x20); 8453fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 8463fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 8477879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine 8483fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil if (hdl->error) { 8493fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil pr_err("Could not initialize controls\n"); 8503fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil return hdl->error; 8513fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil } 8523fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil v4l2_ctrl_cluster(2, &sd->contrast); 8537879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine return 0; 8547879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine} 8557879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine 8566a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* sub-driver description */ 8577879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic const struct sd_desc sd_desc_12a = { 8586a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine .name = MODULE_NAME, 8593fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil .init_controls = sd_init_controls_12a, 8606a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine .config = sd_config, 861012d6b029ec17f45374303bbdccd0bc206725751Jean-Francois Moine .init = sd_init_12a, 8627879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine .start = sd_start_12a, 8637879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine .stopN = sd_stopN, 8647879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine .pkt_scan = sd_pkt_scan, 86560d21563785535e518589ab58b0295ecaa06233fPeter Senna Tschudin#if IS_ENABLED(CONFIG_INPUT) 866436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede .other_input = 1, 867436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede#endif 8687879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine}; 8697879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic const struct sd_desc sd_desc_72a = { 8707879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine .name = MODULE_NAME, 8713fa24bf5e159d10d160015e08decb48cfa1663a8Hans Verkuil .init_controls = sd_init_controls_72a, 8727879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine .config = sd_config, 873012d6b029ec17f45374303bbdccd0bc206725751Jean-Francois Moine .init = sd_init_72a, 8747879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine .start = sd_start_72a, 8756a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine .stopN = sd_stopN, 8766a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine .pkt_scan = sd_pkt_scan, 877cebf3b67f7f80fd69bd1ff5787fee69ab8fd3c2aJean-Francois Moine .dq_callback = do_autogain, 87860d21563785535e518589ab58b0295ecaa06233fPeter Senna Tschudin#if IS_ENABLED(CONFIG_INPUT) 879436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede .other_input = 1, 880436c2c533a2a2f98d95347f4d5b4022becb046f6Hans de Goede#endif 8816a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}; 8827879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moinestatic const struct sd_desc *sd_desc[2] = { 8837879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine &sd_desc_12a, 8847879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine &sd_desc_72a 8857879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine}; 8866a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 8876a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* -- module initialisation -- */ 88895c967c167785eb991cf6b22fb854dd8d61d0ff8Jean-François Moinestatic const struct usb_device_id device_table[] = { 88987581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A}, 89087581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A}, 89187581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A}, 892f8f73d01a31488ec8e923b2148043579d43d0378John Ellson {USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A}, 89387581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A}, 89487581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A}, 89587581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A}, 89687581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A}, 89787581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A}, 89887581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A}, 89987581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A}, 90087581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A}, 90187581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A}, 90287581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A}, 90387581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A}, 90487581aa5f10959224fc7e1a30ac9af53949d0ef2Jean-Francois Moine {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A}, 9056a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine {} 9066a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}; 9076a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 9086a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois MoineMODULE_DEVICE_TABLE(usb, device_table); 9096a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 9106a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine/* -- device connect -- */ 9116a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic int sd_probe(struct usb_interface *intf, 9126a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine const struct usb_device_id *id) 9136a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine{ 9147879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine return gspca_dev_probe(intf, id, 9157879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine sd_desc[id->driver_info], 9167879d459f1601be742d0d63930d17cd4aac956fdJean-Francois Moine sizeof(struct sd), 9176a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine THIS_MODULE); 9186a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine} 9196a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 9206a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moinestatic struct usb_driver sd_driver = { 9216a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine .name = MODULE_NAME, 9226a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine .id_table = device_table, 9236a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine .probe = sd_probe, 9246a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine .disconnect = gspca_disconnect, 9256a709749228c5f76f128c69c16f39a52d639bd96Jean-Francois Moine#ifdef CONFIG_PM 9266a709749228c5f76f128c69c16f39a52d639bd96Jean-Francois Moine .suspend = gspca_suspend, 9276a709749228c5f76f128c69c16f39a52d639bd96Jean-Francois Moine .resume = gspca_resume, 9288bb58964bc139d5ff5285f84aa302977d221754dHans de Goede .reset_resume = gspca_resume, 9296a709749228c5f76f128c69c16f39a52d639bd96Jean-Francois Moine#endif 9306a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine}; 9316a7eba24e4f0ff725d33159f6265e3a79d53a833Jean-Francois Moine 932ecb3b2b35db49778b6d89e3ffd0c400776c20735Greg Kroah-Hartmanmodule_usb_driver(sd_driver); 933