linux/drivers/media/video/gspca/sonixj.c
<<
>>
Prefs
   1/*
   2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
   3 *
   4 * Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr>
   5 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20 */
  21
  22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  23
  24#define MODULE_NAME "sonixj"
  25
  26#include <linux/input.h>
  27#include "gspca.h"
  28#include "jpeg.h"
  29
  30MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
  31MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
  32MODULE_LICENSE("GPL");
  33
  34/* controls */
  35enum e_ctrl {
  36        BRIGHTNESS,
  37        CONTRAST,
  38        COLORS,
  39        BLUE,
  40        RED,
  41        GAMMA,
  42        AUTOGAIN,
  43        HFLIP,
  44        VFLIP,
  45        SHARPNESS,
  46        ILLUM,
  47        FREQ,
  48        NCTRLS          /* number of controls */
  49};
  50
  51/* specific webcam descriptor */
  52struct sd {
  53        struct gspca_dev gspca_dev;     /* !! must be the first item */
  54
  55        struct gspca_ctrl ctrls[NCTRLS];
  56
  57        atomic_t avg_lum;
  58        u32 exposure;
  59
  60        struct work_struct work;
  61        struct workqueue_struct *work_thread;
  62
  63        u32 pktsz;                      /* (used by pkt_scan) */
  64        u16 npkt;
  65        s8 nchg;
  66        s8 short_mark;
  67
  68        u8 quality;                     /* image quality */
  69#define QUALITY_MIN 25
  70#define QUALITY_MAX 90
  71#define QUALITY_DEF 70
  72
  73        u8 reg01;
  74        u8 reg17;
  75        u8 reg18;
  76        u8 flags;
  77
  78        s8 ag_cnt;
  79#define AG_CNT_START 13
  80
  81        u8 bridge;
  82#define BRIDGE_SN9C102P 0
  83#define BRIDGE_SN9C105 1
  84#define BRIDGE_SN9C110 2
  85#define BRIDGE_SN9C120 3
  86        u8 sensor;                      /* Type of image sensor chip */
  87        u8 i2c_addr;
  88
  89        u8 jpeg_hdr[JPEG_HDR_SZ];
  90};
  91enum sensors {
  92        SENSOR_ADCM1700,
  93        SENSOR_GC0307,
  94        SENSOR_HV7131R,
  95        SENSOR_MI0360,
  96        SENSOR_MI0360B,
  97        SENSOR_MO4000,
  98        SENSOR_MT9V111,
  99        SENSOR_OM6802,
 100        SENSOR_OV7630,
 101        SENSOR_OV7648,
 102        SENSOR_OV7660,
 103        SENSOR_PO1030,
 104        SENSOR_PO2030N,
 105        SENSOR_SOI768,
 106        SENSOR_SP80708,
 107};
 108
 109static void qual_upd(struct work_struct *work);
 110
 111/* device flags */
 112#define F_PDN_INV       0x01    /* inverse pin S_PWR_DN / sn_xxx tables */
 113#define F_ILLUM         0x02    /* presence of illuminator */
 114
 115/* sn9c1xx definitions */
 116/* register 0x01 */
 117#define S_PWR_DN        0x01    /* sensor power down */
 118#define S_PDN_INV       0x02    /* inverse pin S_PWR_DN */
 119#define V_TX_EN         0x04    /* video transfer enable */
 120#define LED             0x08    /* output to pin LED */
 121#define SCL_SEL_OD      0x20    /* open-drain mode */
 122#define SYS_SEL_48M     0x40    /* system clock 0: 24MHz, 1: 48MHz */
 123/* register 0x17 */
 124#define MCK_SIZE_MASK   0x1f    /* sensor master clock */
 125#define SEN_CLK_EN      0x20    /* enable sensor clock */
 126#define DEF_EN          0x80    /* defect pixel by 0: soft, 1: hard */
 127
 128/* V4L2 controls supported by the driver */
 129static void setbrightness(struct gspca_dev *gspca_dev);
 130static void setcontrast(struct gspca_dev *gspca_dev);
 131static void setcolors(struct gspca_dev *gspca_dev);
 132static void setredblue(struct gspca_dev *gspca_dev);
 133static void setgamma(struct gspca_dev *gspca_dev);
 134static void setautogain(struct gspca_dev *gspca_dev);
 135static void sethvflip(struct gspca_dev *gspca_dev);
 136static void setsharpness(struct gspca_dev *gspca_dev);
 137static void setillum(struct gspca_dev *gspca_dev);
 138static void setfreq(struct gspca_dev *gspca_dev);
 139
 140static const struct ctrl sd_ctrls[NCTRLS] = {
 141[BRIGHTNESS] = {
 142            {
 143                .id      = V4L2_CID_BRIGHTNESS,
 144                .type    = V4L2_CTRL_TYPE_INTEGER,
 145                .name    = "Brightness",
 146                .minimum = 0,
 147                .maximum = 0xff,
 148                .step    = 1,
 149                .default_value = 0x80,
 150            },
 151            .set_control = setbrightness
 152        },
 153[CONTRAST] = {
 154            {
 155                .id      = V4L2_CID_CONTRAST,
 156                .type    = V4L2_CTRL_TYPE_INTEGER,
 157                .name    = "Contrast",
 158                .minimum = 0,
 159#define CONTRAST_MAX 127
 160                .maximum = CONTRAST_MAX,
 161                .step    = 1,
 162                .default_value = 20,
 163            },
 164            .set_control = setcontrast
 165        },
 166[COLORS] = {
 167            {
 168                .id      = V4L2_CID_SATURATION,
 169                .type    = V4L2_CTRL_TYPE_INTEGER,
 170                .name    = "Saturation",
 171                .minimum = 0,
 172                .maximum = 40,
 173                .step    = 1,
 174#define COLORS_DEF 25
 175                .default_value = COLORS_DEF,
 176            },
 177            .set_control = setcolors
 178        },
 179[BLUE] = {
 180            {
 181                .id      = V4L2_CID_BLUE_BALANCE,
 182                .type    = V4L2_CTRL_TYPE_INTEGER,
 183                .name    = "Blue Balance",
 184                .minimum = 24,
 185                .maximum = 40,
 186                .step    = 1,
 187                .default_value = 32,
 188            },
 189            .set_control = setredblue
 190        },
 191[RED] = {
 192            {
 193                .id      = V4L2_CID_RED_BALANCE,
 194                .type    = V4L2_CTRL_TYPE_INTEGER,
 195                .name    = "Red Balance",
 196                .minimum = 24,
 197                .maximum = 40,
 198                .step    = 1,
 199                .default_value = 32,
 200            },
 201            .set_control = setredblue
 202        },
 203[GAMMA] = {
 204            {
 205                .id      = V4L2_CID_GAMMA,
 206                .type    = V4L2_CTRL_TYPE_INTEGER,
 207                .name    = "Gamma",
 208                .minimum = 0,
 209                .maximum = 40,
 210                .step    = 1,
 211#define GAMMA_DEF 20
 212                .default_value = GAMMA_DEF,
 213            },
 214            .set_control = setgamma
 215        },
 216[AUTOGAIN] = {
 217            {
 218                .id      = V4L2_CID_AUTOGAIN,
 219                .type    = V4L2_CTRL_TYPE_BOOLEAN,
 220                .name    = "Auto Gain",
 221                .minimum = 0,
 222                .maximum = 1,
 223                .step    = 1,
 224                .default_value = 1
 225            },
 226            .set_control = setautogain
 227        },
 228[HFLIP] = {
 229            {
 230                .id      = V4L2_CID_HFLIP,
 231                .type    = V4L2_CTRL_TYPE_BOOLEAN,
 232                .name    = "Mirror",
 233                .minimum = 0,
 234                .maximum = 1,
 235                .step    = 1,
 236                .default_value = 0,
 237            },
 238            .set_control = sethvflip
 239        },
 240[VFLIP] = {
 241            {
 242                .id      = V4L2_CID_VFLIP,
 243                .type    = V4L2_CTRL_TYPE_BOOLEAN,
 244                .name    = "Vflip",
 245                .minimum = 0,
 246                .maximum = 1,
 247                .step    = 1,
 248                .default_value = 0,
 249            },
 250            .set_control = sethvflip
 251        },
 252[SHARPNESS] = {
 253            {
 254                .id      = V4L2_CID_SHARPNESS,
 255                .type    = V4L2_CTRL_TYPE_INTEGER,
 256                .name    = "Sharpness",
 257                .minimum = 0,
 258                .maximum = 255,
 259                .step    = 1,
 260                .default_value = 90,
 261            },
 262            .set_control = setsharpness
 263        },
 264[ILLUM] = {
 265            {
 266                .id      = V4L2_CID_ILLUMINATORS_1,
 267                .type    = V4L2_CTRL_TYPE_BOOLEAN,
 268                .name    = "Illuminator / infrared",
 269                .minimum = 0,
 270                .maximum = 1,
 271                .step    = 1,
 272                .default_value = 0,
 273            },
 274            .set_control = setillum
 275        },
 276/* ov7630/ov7648/ov7660 only */
 277[FREQ] = {
 278            {
 279                .id      = V4L2_CID_POWER_LINE_FREQUENCY,
 280                .type    = V4L2_CTRL_TYPE_MENU,
 281                .name    = "Light frequency filter",
 282                .minimum = 0,
 283                .maximum = 2,   /* 0: 0, 1: 50Hz, 2:60Hz */
 284                .step    = 1,
 285                .default_value = 1,
 286            },
 287            .set_control = setfreq
 288        },
 289};
 290
 291/* table of the disabled controls */
 292static const __u32 ctrl_dis[] = {
 293[SENSOR_ADCM1700] =     (1 << AUTOGAIN) |
 294                        (1 << HFLIP) |
 295                        (1 << VFLIP) |
 296                        (1 << FREQ),
 297
 298[SENSOR_GC0307] =       (1 << HFLIP) |
 299                        (1 << VFLIP) |
 300                        (1 << FREQ),
 301
 302[SENSOR_HV7131R] =      (1 << HFLIP) |
 303                        (1 << FREQ),
 304
 305[SENSOR_MI0360] =       (1 << HFLIP) |
 306                        (1 << VFLIP) |
 307                        (1 << FREQ),
 308
 309[SENSOR_MI0360B] =      (1 << HFLIP) |
 310                        (1 << VFLIP) |
 311                        (1 << FREQ),
 312
 313[SENSOR_MO4000] =       (1 << HFLIP) |
 314                        (1 << VFLIP) |
 315                        (1 << FREQ),
 316
 317[SENSOR_MT9V111] =      (1 << HFLIP) |
 318                        (1 << VFLIP) |
 319                        (1 << FREQ),
 320
 321[SENSOR_OM6802] =       (1 << HFLIP) |
 322                        (1 << VFLIP) |
 323                        (1 << FREQ),
 324
 325[SENSOR_OV7630] =       (1 << HFLIP),
 326
 327[SENSOR_OV7648] =       (1 << HFLIP),
 328
 329[SENSOR_OV7660] =       (1 << AUTOGAIN) |
 330                        (1 << HFLIP) |
 331                        (1 << VFLIP),
 332
 333[SENSOR_PO1030] =       (1 << AUTOGAIN) |
 334                        (1 << HFLIP) |
 335                        (1 << VFLIP) |
 336                        (1 << FREQ),
 337
 338[SENSOR_PO2030N] =      (1 << AUTOGAIN) |
 339                        (1 << FREQ),
 340
 341[SENSOR_SOI768] =       (1 << AUTOGAIN) |
 342                        (1 << HFLIP) |
 343                        (1 << VFLIP) |
 344                        (1 << FREQ),
 345
 346[SENSOR_SP80708] =      (1 << AUTOGAIN) |
 347                        (1 << HFLIP) |
 348                        (1 << VFLIP) |
 349                        (1 << FREQ),
 350};
 351
 352static const struct v4l2_pix_format cif_mode[] = {
 353        {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 354                .bytesperline = 352,
 355                .sizeimage = 352 * 288 * 4 / 8 + 590,
 356                .colorspace = V4L2_COLORSPACE_JPEG,
 357                .priv = 0},
 358};
 359static const struct v4l2_pix_format vga_mode[] = {
 360        {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 361                .bytesperline = 160,
 362                .sizeimage = 160 * 120 * 4 / 8 + 590,
 363                .colorspace = V4L2_COLORSPACE_JPEG,
 364                .priv = 2},
 365        {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 366                .bytesperline = 320,
 367                .sizeimage = 320 * 240 * 3 / 8 + 590,
 368                .colorspace = V4L2_COLORSPACE_JPEG,
 369                .priv = 1},
 370        {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 371                .bytesperline = 640,
 372                /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
 373                .sizeimage = 640 * 480 * 3 / 4 + 590,
 374                .colorspace = V4L2_COLORSPACE_JPEG,
 375                .priv = 0},
 376};
 377
 378static const u8 sn_adcm1700[0x1c] = {
 379/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 380        0x00,   0x43,   0x60,   0x00,   0x1a,   0x00,   0x00,   0x00,
 381/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 382        0x80,   0x51,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 383/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 384        0x03,   0x00,   0x05,   0x01,   0x05,   0x16,   0x12,   0x42,
 385/*      reg18   reg19   reg1a   reg1b */
 386        0x06,   0x00,   0x00,   0x00
 387};
 388
 389static const u8 sn_gc0307[0x1c] = {
 390/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 391        0x00,   0x61,   0x62,   0x00,   0x1a,   0x00,   0x00,   0x00,
 392/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 393        0x80,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 394/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 395        0x03,   0x00,   0x03,   0x01,   0x08,   0x28,   0x1e,   0x02,
 396/*      reg18   reg19   reg1a   reg1b */
 397        0x06,   0x00,   0x00,   0x00
 398};
 399
 400static const u8 sn_hv7131[0x1c] = {
 401/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 402        0x00,   0x03,   0x60,   0x00,   0x1a,   0x20,   0x20,   0x20,
 403/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 404        0x81,   0x11,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 405/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 406        0x03,   0x00,   0x00,   0x01,   0x03,   0x28,   0x1e,   0x41,
 407/*      reg18   reg19   reg1a   reg1b */
 408        0x0a,   0x00,   0x00,   0x00
 409};
 410
 411static const u8 sn_mi0360[0x1c] = {
 412/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 413        0x00,   0x63,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
 414/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 415        0x81,   0x5d,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 416/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 417        0x03,   0x00,   0x00,   0x02,   0x0a,   0x28,   0x1e,   0x61,
 418/*      reg18   reg19   reg1a   reg1b */
 419        0x06,   0x00,   0x00,   0x00
 420};
 421
 422static const u8 sn_mi0360b[0x1c] = {
 423/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 424        0x00,   0x61,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
 425/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 426        0x81,   0x5d,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 427/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 428        0x03,   0x00,   0x00,   0x02,   0x0a,   0x28,   0x1e,   0x40,
 429/*      reg18   reg19   reg1a   reg1b */
 430        0x06,   0x00,   0x00,   0x00
 431};
 432
 433static const u8 sn_mo4000[0x1c] = {
 434/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 435        0x00,   0x23,   0x60,   0x00,   0x1a,   0x00,   0x20,   0x18,
 436/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 437        0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 438/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 439        0x03,    0x00,  0x0b,   0x0f,   0x14,   0x28,   0x1e,   0x40,
 440/*      reg18   reg19   reg1a   reg1b */
 441        0x08,   0x00,   0x00,   0x00
 442};
 443
 444static const u8 sn_mt9v111[0x1c] = {
 445/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 446        0x00,   0x61,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
 447/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 448        0x81,   0x5c,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 449/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 450        0x03,   0x00,   0x00,   0x02,   0x1c,   0x28,   0x1e,   0x40,
 451/*      reg18   reg19   reg1a   reg1b */
 452        0x06,   0x00,   0x00,   0x00
 453};
 454
 455static const u8 sn_om6802[0x1c] = {
 456/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 457        0x00,   0x23,   0x72,   0x00,   0x1a,   0x20,   0x20,   0x19,
 458/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 459        0x80,   0x34,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 460/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 461        0x03,   0x00,   0x51,   0x01,   0x00,   0x28,   0x1e,   0x40,
 462/*      reg18   reg19   reg1a   reg1b */
 463        0x05,   0x00,   0x00,   0x00
 464};
 465
 466static const u8 sn_ov7630[0x1c] = {
 467/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 468        0x00,   0x21,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
 469/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 470        0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 471/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 472        0x03,   0x00,   0x04,   0x01,   0x0a,   0x28,   0x1e,   0xc2,
 473/*      reg18   reg19   reg1a   reg1b */
 474        0x0b,   0x00,   0x00,   0x00
 475};
 476
 477static const u8 sn_ov7648[0x1c] = {
 478/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 479        0x00,   0x63,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
 480/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 481        0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 482/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 483        0x03,   0x00,   0x00,   0x01,   0x00,   0x28,   0x1e,   0x00,
 484/*      reg18   reg19   reg1a   reg1b */
 485        0x0b,   0x00,   0x00,   0x00
 486};
 487
 488static const u8 sn_ov7660[0x1c] = {
 489/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 490        0x00,   0x61,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
 491/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 492        0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 493/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 494        0x03,   0x00,   0x01,   0x01,   0x08,   0x28,   0x1e,   0x20,
 495/*      reg18   reg19   reg1a   reg1b */
 496        0x07,   0x00,   0x00,   0x00
 497};
 498
 499static const u8 sn_po1030[0x1c] = {
 500/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 501        0x00,   0x21,   0x62,   0x00,   0x1a,   0x20,   0x20,   0x20,
 502/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 503        0x81,   0x6e,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 504/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 505        0x03,   0x00,   0x00,   0x06,   0x06,   0x28,   0x1e,   0x00,
 506/*      reg18   reg19   reg1a   reg1b */
 507        0x07,   0x00,   0x00,   0x00
 508};
 509
 510static const u8 sn_po2030n[0x1c] = {
 511/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 512        0x00,   0x63,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
 513/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 514        0x81,   0x6e,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 515/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 516        0x03,   0x00,   0x00,   0x01,   0x14,   0x28,   0x1e,   0x00,
 517/*      reg18   reg19   reg1a   reg1b */
 518        0x07,   0x00,   0x00,   0x00
 519};
 520
 521static const u8 sn_soi768[0x1c] = {
 522/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 523        0x00,   0x21,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
 524/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 525        0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 526/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 527        0x03,   0x00,   0x00,   0x01,   0x08,   0x28,   0x1e,   0x00,
 528/*      reg18   reg19   reg1a   reg1b */
 529        0x07,   0x00,   0x00,   0x00
 530};
 531
 532static const u8 sn_sp80708[0x1c] = {
 533/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 534        0x00,   0x63,   0x60,   0x00,   0x1a,   0x20,   0x20,   0x20,
 535/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 536        0x81,   0x18,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 537/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 538        0x03,   0x00,   0x00,   0x03,   0x04,   0x28,   0x1e,   0x00,
 539/*      reg18   reg19   reg1a   reg1b */
 540        0x07,   0x00,   0x00,   0x00
 541};
 542
 543/* sequence specific to the sensors - !! index = SENSOR_xxx */
 544static const u8 *sn_tb[] = {
 545[SENSOR_ADCM1700] =     sn_adcm1700,
 546[SENSOR_GC0307] =       sn_gc0307,
 547[SENSOR_HV7131R] =      sn_hv7131,
 548[SENSOR_MI0360] =       sn_mi0360,
 549[SENSOR_MI0360B] =      sn_mi0360b,
 550[SENSOR_MO4000] =       sn_mo4000,
 551[SENSOR_MT9V111] =      sn_mt9v111,
 552[SENSOR_OM6802] =       sn_om6802,
 553[SENSOR_OV7630] =       sn_ov7630,
 554[SENSOR_OV7648] =       sn_ov7648,
 555[SENSOR_OV7660] =       sn_ov7660,
 556[SENSOR_PO1030] =       sn_po1030,
 557[SENSOR_PO2030N] =      sn_po2030n,
 558[SENSOR_SOI768] =       sn_soi768,
 559[SENSOR_SP80708] =      sn_sp80708,
 560};
 561
 562/* default gamma table */
 563static const u8 gamma_def[17] = {
 564        0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
 565        0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
 566};
 567/* gamma for sensor ADCM1700 */
 568static const u8 gamma_spec_0[17] = {
 569        0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
 570        0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
 571};
 572/* gamma for sensors HV7131R and MT9V111 */
 573static const u8 gamma_spec_1[17] = {
 574        0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
 575        0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
 576};
 577/* gamma for sensor GC0307 */
 578static const u8 gamma_spec_2[17] = {
 579        0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
 580        0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
 581};
 582/* gamma for sensor SP80708 */
 583static const u8 gamma_spec_3[17] = {
 584        0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
 585        0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
 586};
 587
 588/* color matrix and offsets */
 589static const u8 reg84[] = {
 590        0x14, 0x00, 0x27, 0x00, 0x07, 0x00,     /* YR YG YB gains */
 591        0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00,     /* UR UG UB */
 592        0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f,     /* VR VG VB */
 593        0x00, 0x00, 0x00                        /* YUV offsets */
 594};
 595
 596#define DELAY   0xdd
 597
 598static const u8 adcm1700_sensor_init[][8] = {
 599        {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
 600        {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10},       /* reset */
 601        {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 602        {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
 603        {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 604        {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
 605        {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
 606        {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
 607        {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
 608        {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
 609        {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 610        {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
 611        {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 612        {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
 613        {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
 614        {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
 615        {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
 616        {}
 617};
 618static const u8 adcm1700_sensor_param1[][8] = {
 619        {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10},       /* exposure? */
 620        {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
 621
 622        {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
 623        {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
 624        {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
 625        {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
 626        {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10},       /* exposure? */
 627
 628        {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
 629        {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
 630        {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
 631        {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
 632        {}
 633};
 634static const u8 gc0307_sensor_init[][8] = {
 635        {0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
 636        {0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
 637        {0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
 638        {0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
 639        {0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
 640        {0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
 641        {0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
 642        {0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
 643        {0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
 644        {0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
 645        {0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
 646        {0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
 647        {0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
 648        {0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
 649        {0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
 650        {0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
 651        {0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
 652        {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
 653        {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
 654        {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
 655        {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
 656        {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
 657        {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
 658        {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
 659        {0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
 660        {0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
 661        {0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
 662        {0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
 663        {0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
 664        {0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
 665        {0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
 666        {0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
 667        {0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
 668        {0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
 669        {0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
 670        {0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
 671        {0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
 672        {0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
 673        {}
 674};
 675static const u8 gc0307_sensor_param1[][8] = {
 676        {0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
 677        {0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
 678        {0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
 679        {0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
 680/*param3*/
 681        {0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
 682        {0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
 683        {}
 684};
 685
 686static const u8 hv7131r_sensor_init[][8] = {
 687        {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
 688        {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
 689        {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
 690/*      {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
 691        {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
 692        {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
 693/*      {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
 694
 695        {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
 696        {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
 697        {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
 698        {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
 699        {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
 700        {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
 701        {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
 702        {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
 703
 704        {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
 705        {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 706        {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
 707        {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 708        {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
 709
 710        {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
 711        {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 712        {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
 713        {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 714        {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
 715        {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
 716                                                        /* set sensor clock */
 717        {}
 718};
 719static const u8 mi0360_sensor_init[][8] = {
 720        {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
 721        {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
 722        {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
 723        {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
 724        {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
 725        {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
 726        {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
 727        {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
 728        {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
 729        {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
 730        {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
 731        {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
 732        {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
 733        {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
 734        {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
 735        {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
 736        {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
 737        {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
 738        {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
 739        {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 740        {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
 741        {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
 742        {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
 743        {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
 744        {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
 745        {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
 746        {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
 747        {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
 748        {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
 749        {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
 750        {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
 751        {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
 752        {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
 753
 754        {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
 755        {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
 756        {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
 757        {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
 758        {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
 759
 760        {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
 761        {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
 762        {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
 763        {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
 764
 765        {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
 766        {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
 767/*      {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
 768/*      {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
 769        {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
 770        {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
 771        {}
 772};
 773static const u8 mi0360b_sensor_init[][8] = {
 774        {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
 775        {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
 776        {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
 777        {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
 778        {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
 779        {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
 780        {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
 781        {0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
 782        {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
 783        {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
 784        {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
 785        {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
 786        {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
 787        {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
 788        {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
 789        {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
 790        {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
 791        {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
 792        {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
 793        {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
 794        {0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
 795        {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 796        {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
 797        {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
 798        {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
 799        {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
 800        {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
 801        {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
 802        {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
 803        {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
 804        {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
 805        {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
 806        {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
 807        {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
 808        {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
 809
 810        {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
 811        {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
 812        {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
 813        {0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10},
 814        {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10},
 815        {}
 816};
 817static const u8 mi0360b_sensor_param1[][8] = {
 818        {0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
 819        {0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10},
 820        {0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10},
 821        {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
 822
 823        {0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10},
 824        {0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10},
 825        {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
 826        {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
 827        {}
 828};
 829static const u8 mo4000_sensor_init[][8] = {
 830        {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
 831        {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
 832        {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
 833        {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
 834        {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
 835        {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
 836        {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
 837        {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
 838        {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
 839        {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
 840        {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
 841        {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
 842        {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
 843        {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
 844        {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
 845        {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
 846        {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
 847        {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
 848        {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
 849        {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
 850        {}
 851};
 852static const u8 mt9v111_sensor_init[][8] = {
 853        {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
 854        {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 855        {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
 856        {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
 857        {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
 858        {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
 859        {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
 860        {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
 861        {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
 862        {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
 863        {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
 864        {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
 865        {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
 866        {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
 867        {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
 868        {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
 869        {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
 870        {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 871        {}
 872};
 873static const u8 mt9v111_sensor_param1[][8] = {
 874        {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xad, 0x10}, /* G1 and B gains */
 875        {0xd1, 0x5c, 0x2d, 0x00, 0xad, 0x00, 0x33, 0x10}, /* R and G2 gains */
 876        {0xb1, 0x5c, 0x06, 0x00, 0x40, 0x00, 0x00, 0x10}, /* vert blanking */
 877        {0xb1, 0x5c, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, /* horiz blanking */
 878        {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
 879        {}
 880};
 881static const u8 om6802_init0[2][8] = {
 882/*fixme: variable*/
 883        {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
 884        {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
 885};
 886static const u8 om6802_sensor_init[][8] = {
 887        {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
 888                                                /* factory mode */
 889        {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
 890                                                /* output raw RGB */
 891        {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
 892/*      {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
 893        {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
 894                /* auto-exposure speed (0) / white balance mode (auto RGB) */
 895/*      {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
 896                                                         * set color mode */
 897/*      {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
 898                                                 * max AGC value in AE */
 899/*      {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
 900                                                         * preset AGC */
 901/*      {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
 902                                                 * preset brightness */
 903/*      {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
 904                                                         * preset contrast */
 905/*      {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
 906                                                         * preset gamma */
 907        {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
 908                                /* luminance mode (0x4f -> AutoExpo on) */
 909        {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
 910                                                        /* preset shutter */
 911/*      {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
 912                                                         * auto frame rate */
 913/*      {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
 914        {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
 915        {}
 916};
 917static const u8 om6802_sensor_param1[][8] = {
 918        {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
 919        {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
 920        {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
 921        {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
 922        {}
 923};
 924static const u8 ov7630_sensor_init[][8] = {
 925        {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
 926        {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
 927        {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 928        {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 929        {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
 930        {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 931        {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 932/* win: i2c_r from 00 to 80 */
 933        {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
 934        {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
 935/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
 936        0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
 937        {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
 938        {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
 939        {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
 940        {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
 941        {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
 942        {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
 943        {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
 944        {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
 945        {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
 946        {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
 947        {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 948        {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
 949        {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
 950        {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
 951        {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
 952        {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
 953        {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
 954        {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
 955        {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
 956        {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
 957        {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
 958        {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
 959        {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
 960        {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
 961        {}
 962};
 963static const u8 ov7630_sensor_param1[][8] = {
 964        {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 965        {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 966/*fixme: + 0x12, 0x04*/
 967/*      {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},  * COMN
 968                                                         * set by setvflip */
 969        {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
 970        {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
 971        {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
 972/* */
 973/*      {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
 974/*      {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
 975/* */
 976        {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
 977/*      {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
 978        {}
 979};
 980
 981static const u8 ov7648_sensor_init[][8] = {
 982        {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
 983        {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},       /* reset */
 984        {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
 985        {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
 986        {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
 987        {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
 988        {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
 989        {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
 990        {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
 991        {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
 992        {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
 993        {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
 994        {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
 995        {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
 996        {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
 997        {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
 998        {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
 999        {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
1000        {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
1001        {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
1002        {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
1003        {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
1004
1005        {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
1006/*      {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
1007/*      {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
1008/*      {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
1009        {}
1010};
1011static const u8 ov7648_sensor_param1[][8] = {
1012/*      {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
1013/*      {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10},   * COMN
1014                                                         * set by setvflip */
1015        {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
1016        {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
1017/*      {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1018/*      {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},  * GAIN - def */
1019/*      {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10},  * B R - def: 80 */
1020/*...*/
1021        {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
1022/*      {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1023/*      {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1024/*      {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
1025/*      {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1026/*      {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10},  * B R - def: 80 */
1027
1028        {}
1029};
1030
1031static const u8 ov7660_sensor_init[][8] = {
1032        {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
1033        {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
1034        {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
1035                                                /* Outformat = rawRGB */
1036        {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
1037        {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
1038                                                /* GAIN BLUE RED VREF */
1039        {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
1040                                                /* COM 1 BAVE GEAVE AECHH */
1041        {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
1042        {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
1043        {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
1044                                                /* AECH CLKRC COM7 COM8 */
1045        {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
1046        {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
1047                                                /* HSTART HSTOP VSTRT VSTOP */
1048        {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
1049        {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
1050        {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
1051                                        /* BOS GBOS GROS ROS (BGGR offset) */
1052/*      {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
1053        {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
1054                                                /* AEW AEB VPT BBIAS */
1055        {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
1056                                                /* GbBIAS RSVD EXHCH EXHCL */
1057        {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
1058                                                /* RBIAS ADVFL ASDVFH YAVE */
1059        {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
1060                                                /* HSYST HSYEN HREF */
1061        {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
1062        {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
1063                                                /* ADC ACOM OFON TSLB */
1064        {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
1065                                                /* COM11 COM12 COM13 COM14 */
1066        {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
1067                                                /* EDGE COM15 COM16 COM17 */
1068        {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
1069        {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
1070        {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1071        {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
1072        {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
1073        {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
1074        {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
1075        {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
1076        {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1077        {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
1078                                                /* LCC1 LCC2 LCC3 LCC4 */
1079        {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
1080        {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
1081        {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
1082                                        /* band gap reference [0:3] DBLV */
1083        {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
1084        {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
1085        {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
1086        {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
1087        {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
1088        {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
1089        {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
1090        {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
1091        {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
1092        {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
1093/* not in all ms-win traces*/
1094        {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
1095        {}
1096};
1097static const u8 ov7660_sensor_param1[][8] = {
1098        {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
1099                                                /* bits[3..0]reserved */
1100        {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
1101        {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1102                                                /* VREF vertical frame ctrl */
1103        {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1104        {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
1105        {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
1106        {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
1107        {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
1108/*      {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
1109/****** (some exchanges in the win trace) ******/
1110/*fixme:param2*/
1111        {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
1112        {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
1113        {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
1114        {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
1115/*      {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},  * RED */
1116/****** (some exchanges in the win trace) ******/
1117/******!! startsensor KO if changed !!****/
1118/*fixme: param3*/
1119        {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
1120        {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
1121        {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
1122        {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
1123        {}
1124};
1125
1126static const u8 po1030_sensor_init[][8] = {
1127/* the sensor registers are described in m5602/m5602_po1030.h */
1128        {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
1129        {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
1130        {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
1131        {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
1132        {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
1133        {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
1134        {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
1135        {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
1136        {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
1137        {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
1138        {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
1139        {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
1140        {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
1141        {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1142        {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
1143        {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
1144        {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
1145        {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
1146        {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
1147        {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
1148        {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
1149        {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
1150        {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
1151        {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
1152        {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
1153        {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
1154        {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
1155        {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
1156
1157        {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
1158        {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
1159        {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
1160        {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
1161        {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
1162        {}
1163};
1164static const u8 po1030_sensor_param1[][8] = {
1165/* from ms-win traces - these values change with auto gain/expo/wb.. */
1166        {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1167        {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1168/* mean values */
1169        {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
1170        {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
1171        {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
1172
1173        {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
1174        {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
1175        {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
1176/*      {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
1177        {}
1178};
1179
1180static const u8 po2030n_sensor_init[][8] = {
1181        {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
1182        {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
1183        {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1184        {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
1185        {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
1186        {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1187        {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
1188        {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1189        {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
1190        {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1191        {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1192        {0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
1193        {0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
1194        {0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
1195        {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1196        {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
1197        {0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
1198        {0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1199        {0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
1200        {0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
1201        {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
1202        {0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
1203        {0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
1204        {0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
1205        {0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
1206        {0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
1207        {0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
1208        {0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
1209        {0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
1210        {0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
1211        {0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
1212        {0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
1213        {0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
1214        {0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
1215        {0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
1216        {0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
1217        {0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
1218        {0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
1219        {0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
1220        {0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
1221        {0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
1222        {0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
1223        {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1224        {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
1225        {0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
1226        {0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
1227        {0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
1228        {0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
1229        {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
1230        {0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
1231        {}
1232};
1233static const u8 po2030n_sensor_param1[][8] = {
1234        {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
1235        {DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
1236        {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
1237        {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1238        {0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10},
1239/*param2*/
1240        {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
1241        {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1242        {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
1243        {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1244        {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1245        {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1246        {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10},
1247/*after start*/
1248        {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10},
1249        {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1250        {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10},
1251        {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1252        {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10},
1253        {}
1254};
1255
1256static const u8 soi768_sensor_init[][8] = {
1257        {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
1258        {DELAY, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
1259        {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1260        {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
1261        {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
1262        {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
1263        {}
1264};
1265static const u8 soi768_sensor_param1[][8] = {
1266        {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
1267        {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1268        {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1269        {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1270        {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
1271/* */
1272/*      {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1273/*      {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
1274        {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1275/*      {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1276        {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
1277/* the next sequence should be used for auto gain */
1278        {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
1279                        /* global gain ? : 07 - change with 0x15 at the end */
1280        {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
1281        {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
1282        {0xb1, 0x21, 0x2d, 0x63, 0x03, 0x00, 0x00, 0x10},
1283                        /* exposure ? : 0200 - change with 0x1e at the end */
1284        {}
1285};
1286
1287static const u8 sp80708_sensor_init[][8] = {
1288        {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
1289        {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
1290        {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
1291        {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
1292        {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1293        {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
1294        {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
1295        {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
1296        {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
1297        {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
1298        {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
1299        {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
1300        {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
1301        {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
1302        {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
1303        {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
1304        {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
1305        {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
1306        {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
1307        {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
1308        {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
1309        {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
1310        {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
1311        {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
1312        {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
1313        {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
1314        {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
1315        {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
1316        {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
1317        {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
1318        {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
1319        {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
1320        {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
1321        {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
1322        {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
1323        {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
1324        {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
1325        {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
1326        {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
1327        {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
1328        {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
1329        {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
1330        {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
1331        {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
1332        {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
1333        {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
1334        {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
1335        {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
1336        {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
1337        {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
1338        {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
1339        {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
1340        {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
1341        {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
1342        {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
1343        {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
1344        {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
1345        {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
1346        {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
1347        {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
1348        {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
1349        {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
1350        {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
1351        {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
1352        {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
1353        {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
1354        {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
1355        {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
1356        {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
1357        {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
1358        {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
1359        {}
1360};
1361static const u8 sp80708_sensor_param1[][8] = {
1362        {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1363        {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1364        {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
1365        {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
1366        {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
1367        {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
1368        {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
1369        {}
1370};
1371
1372static const u8 (*sensor_init[])[8] = {
1373[SENSOR_ADCM1700] =     adcm1700_sensor_init,
1374[SENSOR_GC0307] =       gc0307_sensor_init,
1375[SENSOR_HV7131R] =      hv7131r_sensor_init,
1376[SENSOR_MI0360] =       mi0360_sensor_init,
1377[SENSOR_MI0360B] =      mi0360b_sensor_init,
1378[SENSOR_MO4000] =       mo4000_sensor_init,
1379[SENSOR_MT9V111] =      mt9v111_sensor_init,
1380[SENSOR_OM6802] =       om6802_sensor_init,
1381[SENSOR_OV7630] =       ov7630_sensor_init,
1382[SENSOR_OV7648] =       ov7648_sensor_init,
1383[SENSOR_OV7660] =       ov7660_sensor_init,
1384[SENSOR_PO1030] =       po1030_sensor_init,
1385[SENSOR_PO2030N] =      po2030n_sensor_init,
1386[SENSOR_SOI768] =       soi768_sensor_init,
1387[SENSOR_SP80708] =      sp80708_sensor_init,
1388};
1389
1390/* read <len> bytes to gspca_dev->usb_buf */
1391static void reg_r(struct gspca_dev *gspca_dev,
1392                  u16 value, int len)
1393{
1394        int ret;
1395
1396        if (gspca_dev->usb_err < 0)
1397                return;
1398#ifdef GSPCA_DEBUG
1399        if (len > USB_BUF_SZ) {
1400                pr_err("reg_r: buffer overflow\n");
1401                return;
1402        }
1403#endif
1404        ret = usb_control_msg(gspca_dev->dev,
1405                        usb_rcvctrlpipe(gspca_dev->dev, 0),
1406                        0,
1407                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1408                        value, 0,
1409                        gspca_dev->usb_buf, len,
1410                        500);
1411        PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
1412        if (ret < 0) {
1413                pr_err("reg_r err %d\n", ret);
1414                gspca_dev->usb_err = ret;
1415        }
1416}
1417
1418static void reg_w1(struct gspca_dev *gspca_dev,
1419                   u16 value,
1420                   u8 data)
1421{
1422        int ret;
1423
1424        if (gspca_dev->usb_err < 0)
1425                return;
1426        PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
1427        gspca_dev->usb_buf[0] = data;
1428        ret = usb_control_msg(gspca_dev->dev,
1429                        usb_sndctrlpipe(gspca_dev->dev, 0),
1430                        0x08,
1431                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1432                        value,
1433                        0,
1434                        gspca_dev->usb_buf, 1,
1435                        500);
1436        if (ret < 0) {
1437                pr_err("reg_w1 err %d\n", ret);
1438                gspca_dev->usb_err = ret;
1439        }
1440}
1441static void reg_w(struct gspca_dev *gspca_dev,
1442                          u16 value,
1443                          const u8 *buffer,
1444                          int len)
1445{
1446        int ret;
1447
1448        if (gspca_dev->usb_err < 0)
1449                return;
1450        PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
1451                value, buffer[0], buffer[1]);
1452#ifdef GSPCA_DEBUG
1453        if (len > USB_BUF_SZ) {
1454                pr_err("reg_w: buffer overflow\n");
1455                return;
1456        }
1457#endif
1458        memcpy(gspca_dev->usb_buf, buffer, len);
1459        ret = usb_control_msg(gspca_dev->dev,
1460                        usb_sndctrlpipe(gspca_dev->dev, 0),
1461                        0x08,
1462                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1463                        value, 0,
1464                        gspca_dev->usb_buf, len,
1465                        500);
1466        if (ret < 0) {
1467                pr_err("reg_w err %d\n", ret);
1468                gspca_dev->usb_err = ret;
1469        }
1470}
1471
1472/* I2C write 1 byte */
1473static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1474{
1475        struct sd *sd = (struct sd *) gspca_dev;
1476        int ret;
1477
1478        if (gspca_dev->usb_err < 0)
1479                return;
1480        PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
1481        switch (sd->sensor) {
1482        case SENSOR_ADCM1700:
1483        case SENSOR_OM6802:
1484        case SENSOR_GC0307:             /* i2c command = a0 (100 kHz) */
1485                gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1486                break;
1487        default:                        /* i2c command = a1 (400 kHz) */
1488                gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1489                break;
1490        }
1491        gspca_dev->usb_buf[1] = sd->i2c_addr;
1492        gspca_dev->usb_buf[2] = reg;
1493        gspca_dev->usb_buf[3] = val;
1494        gspca_dev->usb_buf[4] = 0;
1495        gspca_dev->usb_buf[5] = 0;
1496        gspca_dev->usb_buf[6] = 0;
1497        gspca_dev->usb_buf[7] = 0x10;
1498        ret = usb_control_msg(gspca_dev->dev,
1499                        usb_sndctrlpipe(gspca_dev->dev, 0),
1500                        0x08,
1501                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1502                        0x08,                   /* value = i2c */
1503                        0,
1504                        gspca_dev->usb_buf, 8,
1505                        500);
1506        if (ret < 0) {
1507                pr_err("i2c_w1 err %d\n", ret);
1508                gspca_dev->usb_err = ret;
1509        }
1510}
1511
1512/* I2C write 8 bytes */
1513static void i2c_w8(struct gspca_dev *gspca_dev,
1514                   const u8 *buffer)
1515{
1516        int ret;
1517
1518        if (gspca_dev->usb_err < 0)
1519                return;
1520        PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
1521                buffer[2], buffer[3]);
1522        memcpy(gspca_dev->usb_buf, buffer, 8);
1523        ret = usb_control_msg(gspca_dev->dev,
1524                        usb_sndctrlpipe(gspca_dev->dev, 0),
1525                        0x08,
1526                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1527                        0x08, 0,                /* value, index */
1528                        gspca_dev->usb_buf, 8,
1529                        500);
1530        msleep(2);
1531        if (ret < 0) {
1532                pr_err("i2c_w8 err %d\n", ret);
1533                gspca_dev->usb_err = ret;
1534        }
1535}
1536
1537/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1538static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
1539{
1540        struct sd *sd = (struct sd *) gspca_dev;
1541        u8 mode[8];
1542
1543        switch (sd->sensor) {
1544        case SENSOR_ADCM1700:
1545        case SENSOR_OM6802:
1546        case SENSOR_GC0307:             /* i2c command = a0 (100 kHz) */
1547                mode[0] = 0x80 | 0x10;
1548                break;
1549        default:                        /* i2c command = 91 (400 kHz) */
1550                mode[0] = 0x81 | 0x10;
1551                break;
1552        }
1553        mode[1] = sd->i2c_addr;
1554        mode[2] = reg;
1555        mode[3] = 0;
1556        mode[4] = 0;
1557        mode[5] = 0;
1558        mode[6] = 0;
1559        mode[7] = 0x10;
1560        i2c_w8(gspca_dev, mode);
1561        msleep(2);
1562        mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
1563        mode[2] = 0;
1564        i2c_w8(gspca_dev, mode);
1565        msleep(2);
1566        reg_r(gspca_dev, 0x0a, 5);
1567}
1568
1569static void i2c_w_seq(struct gspca_dev *gspca_dev,
1570                        const u8 (*data)[8])
1571{
1572        while ((*data)[0] != 0) {
1573                if ((*data)[0] != DELAY)
1574                        i2c_w8(gspca_dev, *data);
1575                else
1576                        msleep((*data)[1]);
1577                data++;
1578        }
1579}
1580
1581/* check the ID of the hv7131 sensor */
1582/* this sequence is needed because it activates the sensor */
1583static void hv7131r_probe(struct gspca_dev *gspca_dev)
1584{
1585        i2c_w1(gspca_dev, 0x02, 0);             /* sensor wakeup */
1586        msleep(10);
1587        reg_w1(gspca_dev, 0x02, 0x66);          /* Gpio on */
1588        msleep(10);
1589        i2c_r(gspca_dev, 0, 5);                 /* read sensor id */
1590        if (gspca_dev->usb_buf[0] == 0x02       /* chip ID (02 is R) */
1591            && gspca_dev->usb_buf[1] == 0x09
1592            && gspca_dev->usb_buf[2] == 0x01) {
1593                PDEBUG(D_PROBE, "Sensor HV7131R found");
1594                return;
1595        }
1596        pr_warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x\n",
1597                gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1598                gspca_dev->usb_buf[2]);
1599}
1600
1601static void mi0360_probe(struct gspca_dev *gspca_dev)
1602{
1603        struct sd *sd = (struct sd *) gspca_dev;
1604        int i, j;
1605        u16 val = 0;
1606        static const u8 probe_tb[][4][8] = {
1607            {                                   /* mi0360 */
1608                {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1609                {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1610                {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1611                {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1612            },
1613            {                                   /* mt9v111 */
1614                {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1615                {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1616                {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1617                {}
1618            },
1619        };
1620
1621        for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1622                reg_w1(gspca_dev, 0x17, 0x62);
1623                reg_w1(gspca_dev, 0x01, 0x08);
1624                for (j = 0; j < 3; j++)
1625                        i2c_w8(gspca_dev, probe_tb[i][j]);
1626                msleep(2);
1627                reg_r(gspca_dev, 0x0a, 5);
1628                val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1629                if (probe_tb[i][3][0] != 0)
1630                        i2c_w8(gspca_dev, probe_tb[i][3]);
1631                reg_w1(gspca_dev, 0x01, 0x29);
1632                reg_w1(gspca_dev, 0x17, 0x42);
1633                if (val != 0xffff)
1634                        break;
1635        }
1636        if (gspca_dev->usb_err < 0)
1637                return;
1638        switch (val) {
1639        case 0x8221:
1640                PDEBUG(D_PROBE, "Sensor mi0360b");
1641                sd->sensor = SENSOR_MI0360B;
1642                break;
1643        case 0x823a:
1644                PDEBUG(D_PROBE, "Sensor mt9v111");
1645                sd->sensor = SENSOR_MT9V111;
1646                break;
1647        case 0x8243:
1648                PDEBUG(D_PROBE, "Sensor mi0360");
1649                break;
1650        default:
1651                PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1652                break;
1653        }
1654}
1655
1656static void ov7630_probe(struct gspca_dev *gspca_dev)
1657{
1658        struct sd *sd = (struct sd *) gspca_dev;
1659        u16 val;
1660
1661        /* check ov76xx */
1662        reg_w1(gspca_dev, 0x17, 0x62);
1663        reg_w1(gspca_dev, 0x01, 0x08);
1664        sd->i2c_addr = 0x21;
1665        i2c_r(gspca_dev, 0x0a, 2);
1666        val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1667        reg_w1(gspca_dev, 0x01, 0x29);
1668        reg_w1(gspca_dev, 0x17, 0x42);
1669        if (gspca_dev->usb_err < 0)
1670                return;
1671        if (val == 0x7628) {                    /* soi768 */
1672                sd->sensor = SENSOR_SOI768;
1673/*fixme: only valid for 0c45:613e?*/
1674                gspca_dev->cam.input_flags =
1675                                V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
1676                PDEBUG(D_PROBE, "Sensor soi768");
1677                return;
1678        }
1679        PDEBUG(D_PROBE, "Sensor ov%04x", val);
1680}
1681
1682static void ov7648_probe(struct gspca_dev *gspca_dev)
1683{
1684        struct sd *sd = (struct sd *) gspca_dev;
1685        u16 val;
1686
1687        /* check ov76xx */
1688        reg_w1(gspca_dev, 0x17, 0x62);
1689        reg_w1(gspca_dev, 0x01, 0x08);
1690        sd->i2c_addr = 0x21;
1691        i2c_r(gspca_dev, 0x0a, 2);
1692        val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1693        reg_w1(gspca_dev, 0x01, 0x29);
1694        reg_w1(gspca_dev, 0x17, 0x42);
1695        if ((val & 0xff00) == 0x7600) {         /* ov76xx */
1696                PDEBUG(D_PROBE, "Sensor ov%04x", val);
1697                return;
1698        }
1699
1700        /* check po1030 */
1701        reg_w1(gspca_dev, 0x17, 0x62);
1702        reg_w1(gspca_dev, 0x01, 0x08);
1703        sd->i2c_addr = 0x6e;
1704        i2c_r(gspca_dev, 0x00, 2);
1705        val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1706        reg_w1(gspca_dev, 0x01, 0x29);
1707        reg_w1(gspca_dev, 0x17, 0x42);
1708        if (gspca_dev->usb_err < 0)
1709                return;
1710        if (val == 0x1030) {                    /* po1030 */
1711                PDEBUG(D_PROBE, "Sensor po1030");
1712                sd->sensor = SENSOR_PO1030;
1713                return;
1714        }
1715        pr_err("Unknown sensor %04x\n", val);
1716}
1717
1718/* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
1719static void po2030n_probe(struct gspca_dev *gspca_dev)
1720{
1721        struct sd *sd = (struct sd *) gspca_dev;
1722        u16 val;
1723
1724        /* check gc0307 */
1725        reg_w1(gspca_dev, 0x17, 0x62);
1726        reg_w1(gspca_dev, 0x01, 0x08);
1727        reg_w1(gspca_dev, 0x02, 0x22);
1728        sd->i2c_addr = 0x21;
1729        i2c_r(gspca_dev, 0x00, 1);
1730        val = gspca_dev->usb_buf[4];
1731        reg_w1(gspca_dev, 0x01, 0x29);          /* reset */
1732        reg_w1(gspca_dev, 0x17, 0x42);
1733        if (val == 0x99) {                      /* gc0307 (?) */
1734                PDEBUG(D_PROBE, "Sensor gc0307");
1735                sd->sensor = SENSOR_GC0307;
1736                return;
1737        }
1738
1739        /* check po2030n */
1740        reg_w1(gspca_dev, 0x17, 0x62);
1741        reg_w1(gspca_dev, 0x01, 0x0a);
1742        sd->i2c_addr = 0x6e;
1743        i2c_r(gspca_dev, 0x00, 2);
1744        val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1745        reg_w1(gspca_dev, 0x01, 0x29);
1746        reg_w1(gspca_dev, 0x17, 0x42);
1747        if (gspca_dev->usb_err < 0)
1748                return;
1749        if (val == 0x2030) {
1750                PDEBUG(D_PROBE, "Sensor po2030n");
1751/*              sd->sensor = SENSOR_PO2030N; */
1752        } else {
1753                pr_err("Unknown sensor ID %04x\n", val);
1754        }
1755}
1756
1757/* this function is called at probe time */
1758static int sd_config(struct gspca_dev *gspca_dev,
1759                        const struct usb_device_id *id)
1760{
1761        struct sd *sd = (struct sd *) gspca_dev;
1762        struct cam *cam;
1763
1764        sd->bridge = id->driver_info >> 16;
1765        sd->sensor = id->driver_info >> 8;
1766        sd->flags = id->driver_info;
1767
1768        cam = &gspca_dev->cam;
1769        if (sd->sensor == SENSOR_ADCM1700) {
1770                cam->cam_mode = cif_mode;
1771                cam->nmodes = ARRAY_SIZE(cif_mode);
1772        } else {
1773                cam->cam_mode = vga_mode;
1774                cam->nmodes = ARRAY_SIZE(vga_mode);
1775        }
1776        cam->npkt = 24;                 /* 24 packets per ISOC message */
1777        cam->ctrls = sd->ctrls;
1778
1779        sd->ag_cnt = -1;
1780        sd->quality = QUALITY_DEF;
1781
1782        /* if USB 1.1, let some bandwidth for the audio device */
1783        if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH)
1784                gspca_dev->nbalt--;
1785
1786        INIT_WORK(&sd->work, qual_upd);
1787
1788        return 0;
1789}
1790
1791/* this function is called at probe and resume time */
1792static int sd_init(struct gspca_dev *gspca_dev)
1793{
1794        struct sd *sd = (struct sd *) gspca_dev;
1795        const u8 *sn9c1xx;
1796        u8 regGpio[] = { 0x29, 0x70 };          /* no audio */
1797        u8 regF1;
1798
1799        /* setup a selector by bridge */
1800        reg_w1(gspca_dev, 0xf1, 0x01);
1801        reg_r(gspca_dev, 0x00, 1);
1802        reg_w1(gspca_dev, 0xf1, 0x00);
1803        reg_r(gspca_dev, 0x00, 1);              /* get sonix chip id */
1804        regF1 = gspca_dev->usb_buf[0];
1805        if (gspca_dev->usb_err < 0)
1806                return gspca_dev->usb_err;
1807        PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1808        if (gspca_dev->audio)
1809                regGpio[1] |= 0x04;             /* with audio */
1810        switch (sd->bridge) {
1811        case BRIDGE_SN9C102P:
1812        case BRIDGE_SN9C105:
1813                if (regF1 != 0x11)
1814                        return -ENODEV;
1815                break;
1816        default:
1817/*      case BRIDGE_SN9C110: */
1818/*      case BRIDGE_SN9C120: */
1819                if (regF1 != 0x12)
1820                        return -ENODEV;
1821        }
1822
1823        switch (sd->sensor) {
1824        case SENSOR_MI0360:
1825                mi0360_probe(gspca_dev);
1826                break;
1827        case SENSOR_OV7630:
1828                ov7630_probe(gspca_dev);
1829                break;
1830        case SENSOR_OV7648:
1831                ov7648_probe(gspca_dev);
1832                break;
1833        case SENSOR_PO2030N:
1834                po2030n_probe(gspca_dev);
1835                break;
1836        }
1837
1838        switch (sd->bridge) {
1839        case BRIDGE_SN9C102P:
1840                reg_w1(gspca_dev, 0x02, regGpio[1]);
1841                break;
1842        default:
1843                reg_w(gspca_dev, 0x01, regGpio, 2);
1844                break;
1845        }
1846
1847        if (sd->sensor == SENSOR_OM6802)
1848                sd->ctrls[SHARPNESS].def = 0x10;
1849
1850        /* Note we do not disable the sensor clock here (power saving mode),
1851           as that also disables the button on the cam. */
1852        reg_w1(gspca_dev, 0xf1, 0x00);
1853
1854        /* set the i2c address */
1855        sn9c1xx = sn_tb[sd->sensor];
1856        sd->i2c_addr = sn9c1xx[9];
1857
1858        gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1859        if (!(sd->flags & F_ILLUM))
1860                gspca_dev->ctrl_dis |= (1 << ILLUM);
1861
1862        return gspca_dev->usb_err;
1863}
1864
1865static u32 setexposure(struct gspca_dev *gspca_dev,
1866                        u32 expo)
1867{
1868        struct sd *sd = (struct sd *) gspca_dev;
1869
1870        switch (sd->sensor) {
1871        case SENSOR_GC0307: {
1872                int a, b;
1873
1874                /* expo = 0..255 -> a = 19..43 */
1875                a = 19 + expo * 25 / 256;
1876                i2c_w1(gspca_dev, 0x68, a);
1877                a -= 12;
1878                b = a * a * 4;                  /* heuristic */
1879                i2c_w1(gspca_dev, 0x03, b >> 8);
1880                i2c_w1(gspca_dev, 0x04, b);
1881                break;
1882            }
1883        case SENSOR_HV7131R: {
1884                u8 Expodoit[] =
1885                        { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
1886
1887                Expodoit[3] = expo >> 16;
1888                Expodoit[4] = expo >> 8;
1889                Expodoit[5] = expo;
1890                i2c_w8(gspca_dev, Expodoit);
1891                break;
1892            }
1893        case SENSOR_MI0360:
1894        case SENSOR_MI0360B: {
1895                u8 expoMi[] =           /* exposure 0x0635 -> 4 fp/s 0x10 */
1896                        { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
1897                static const u8 doit[] =                /* update sensor */
1898                        { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1899                static const u8 sensorgo[] =            /* sensor on */
1900                        { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1901
1902                if (expo > 0x0635)
1903                        expo = 0x0635;
1904                else if (expo < 0x0001)
1905                        expo = 0x0001;
1906                expoMi[3] = expo >> 8;
1907                expoMi[4] = expo;
1908                i2c_w8(gspca_dev, expoMi);
1909                i2c_w8(gspca_dev, doit);
1910                i2c_w8(gspca_dev, sensorgo);
1911                break;
1912            }
1913        case SENSOR_MO4000: {
1914                u8 expoMof[] =
1915                        { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
1916                u8 expoMo10[] =
1917                        { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
1918                static const u8 gainMo[] =
1919                        { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1920
1921                if (expo > 0x1fff)
1922                        expo = 0x1fff;
1923                else if (expo < 0x0001)
1924                        expo = 0x0001;
1925                expoMof[3] = (expo & 0x03fc) >> 2;
1926                i2c_w8(gspca_dev, expoMof);
1927                expoMo10[3] = ((expo & 0x1c00) >> 10)
1928                                | ((expo & 0x0003) << 4);
1929                i2c_w8(gspca_dev, expoMo10);
1930                i2c_w8(gspca_dev, gainMo);
1931                PDEBUG(D_FRAM, "set exposure %d",
1932                        ((expoMo10[3] & 0x07) << 10)
1933                        | (expoMof[3] << 2)
1934                        | ((expoMo10[3] & 0x30) >> 4));
1935                break;
1936            }
1937        case SENSOR_MT9V111: {
1938                u8 expo_c1[] =
1939                        { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1940
1941                if (expo > 0x0390)
1942                        expo = 0x0390;
1943                else if (expo < 0x0060)
1944                        expo = 0x0060;
1945                expo_c1[3] = expo >> 8;
1946                expo_c1[4] = expo;
1947                i2c_w8(gspca_dev, expo_c1);
1948                break;
1949            }
1950        case SENSOR_OM6802: {
1951                u8 gainOm[] =
1952                        { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1953                                /* preset AGC - works when AutoExpo = off */
1954
1955                if (expo > 0x03ff)
1956                        expo = 0x03ff;
1957                 if (expo < 0x0001)
1958                        expo = 0x0001;
1959                gainOm[3] = expo >> 2;
1960                i2c_w8(gspca_dev, gainOm);
1961                reg_w1(gspca_dev, 0x96, expo >> 5);
1962                PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
1963                break;
1964            }
1965        }
1966        return expo;
1967}
1968
1969static void setbrightness(struct gspca_dev *gspca_dev)
1970{
1971        struct sd *sd = (struct sd *) gspca_dev;
1972        unsigned int expo;
1973        int brightness;
1974        u8 k2;
1975
1976        brightness = sd->ctrls[BRIGHTNESS].val;
1977        k2 = (brightness - 0x80) >> 2;
1978        switch (sd->sensor) {
1979        case SENSOR_ADCM1700:
1980                if (k2 > 0x1f)
1981                        k2 = 0;         /* only positive Y offset */
1982                break;
1983        case SENSOR_HV7131R:
1984                expo = brightness << 12;
1985                if (expo > 0x002dc6c0)
1986                        expo = 0x002dc6c0;
1987                else if (expo < 0x02a0)
1988                        expo = 0x02a0;
1989                sd->exposure = setexposure(gspca_dev, expo);
1990                break;
1991        case SENSOR_MI0360:
1992        case SENSOR_MO4000:
1993                expo = brightness << 4;
1994                sd->exposure = setexposure(gspca_dev, expo);
1995                break;
1996        case SENSOR_MI0360B:
1997                expo = brightness << 2;
1998                sd->exposure = setexposure(gspca_dev, expo);
1999                break;
2000        case SENSOR_GC0307:
2001                expo = brightness;
2002                sd->exposure = setexposure(gspca_dev, expo);
2003                return;                 /* don't set the Y offset */
2004        case SENSOR_MT9V111:
2005                expo = brightness << 2;
2006                sd->exposure = setexposure(gspca_dev, expo);
2007                return;                 /* don't set the Y offset */
2008        case SENSOR_OM6802:
2009                expo = brightness << 2;
2010                sd->exposure = setexposure(gspca_dev, expo);
2011                return;                 /* Y offset already set */
2012        }
2013
2014        reg_w1(gspca_dev, 0x96, k2);    /* color matrix Y offset */
2015}
2016
2017static void setcontrast(struct gspca_dev *gspca_dev)
2018{
2019        struct sd *sd = (struct sd *) gspca_dev;
2020        u8 k2;
2021        u8 contrast[6];
2022
2023        k2 = sd->ctrls[CONTRAST].val * 37 / (CONTRAST_MAX + 1)
2024                                + 37;           /* 37..73 */
2025        contrast[0] = (k2 + 1) / 2;             /* red */
2026        contrast[1] = 0;
2027        contrast[2] = k2;                       /* green */
2028        contrast[3] = 0;
2029        contrast[4] = k2 / 5;                   /* blue */
2030        contrast[5] = 0;
2031        reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
2032}
2033
2034static void setcolors(struct gspca_dev *gspca_dev)
2035{
2036        struct sd *sd = (struct sd *) gspca_dev;
2037        int i, v, colors;
2038        const s16 *uv;
2039        u8 reg8a[12];                   /* U & V gains */
2040        static const s16 uv_com[6] = {  /* same as reg84 in signed decimal */
2041                -24, -38, 64,           /* UR UG UB */
2042                 62, -51, -9            /* VR VG VB */
2043        };
2044        static const s16 uv_mi0360b[6] = {
2045                -20, -38, 64,           /* UR UG UB */
2046                 60, -51, -9            /* VR VG VB */
2047        };
2048
2049        colors = sd->ctrls[COLORS].val;
2050        if (sd->sensor == SENSOR_MI0360B)
2051                uv = uv_mi0360b;
2052        else
2053                uv = uv_com;
2054        for (i = 0; i < 6; i++) {
2055                v = uv[i] * colors / COLORS_DEF;
2056                reg8a[i * 2] = v;
2057                reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
2058        }
2059        reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
2060}
2061
2062static void setredblue(struct gspca_dev *gspca_dev)
2063{
2064        struct sd *sd = (struct sd *) gspca_dev;
2065
2066        reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val);
2067/*      reg_w1(gspca_dev, 0x07, 32); */
2068        reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val);
2069}
2070
2071static void setgamma(struct gspca_dev *gspca_dev)
2072{
2073        struct sd *sd = (struct sd *) gspca_dev;
2074        int i, val;
2075        u8 gamma[17];
2076        const u8 *gamma_base;
2077        static const u8 delta[17] = {
2078                0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
2079                0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
2080        };
2081
2082        switch (sd->sensor) {
2083        case SENSOR_ADCM1700:
2084                gamma_base = gamma_spec_0;
2085                break;
2086        case SENSOR_HV7131R:
2087        case SENSOR_MI0360B:
2088        case SENSOR_MT9V111:
2089                gamma_base = gamma_spec_1;
2090                break;
2091        case SENSOR_GC0307:
2092                gamma_base = gamma_spec_2;
2093                break;
2094        case SENSOR_SP80708:
2095                gamma_base = gamma_spec_3;
2096                break;
2097        default:
2098                gamma_base = gamma_def;
2099                break;
2100        }
2101
2102        val = sd->ctrls[GAMMA].val;
2103        for (i = 0; i < sizeof gamma; i++)
2104                gamma[i] = gamma_base[i]
2105                        + delta[i] * (val - GAMMA_DEF) / 32;
2106        reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
2107}
2108
2109static void setautogain(struct gspca_dev *gspca_dev)
2110{
2111        struct sd *sd = (struct sd *) gspca_dev;
2112
2113        if (gspca_dev->ctrl_dis & (1 << AUTOGAIN))
2114                return;
2115        switch (sd->sensor) {
2116        case SENSOR_OV7630:
2117        case SENSOR_OV7648: {
2118                u8 comb;
2119
2120                if (sd->sensor == SENSOR_OV7630)
2121                        comb = 0xc0;
2122                else
2123                        comb = 0xa0;
2124                if (sd->ctrls[AUTOGAIN].val)
2125                        comb |= 0x03;
2126                i2c_w1(&sd->gspca_dev, 0x13, comb);
2127                return;
2128            }
2129        }
2130        if (sd->ctrls[AUTOGAIN].val)
2131                sd->ag_cnt = AG_CNT_START;
2132        else
2133                sd->ag_cnt = -1;
2134}
2135
2136static void sethvflip(struct gspca_dev *gspca_dev)
2137{
2138        struct sd *sd = (struct sd *) gspca_dev;
2139        u8 comn;
2140
2141        switch (sd->sensor) {
2142        case SENSOR_HV7131R:
2143                comn = 0x18;                    /* clkdiv = 1, ablcen = 1 */
2144                if (sd->ctrls[VFLIP].val)
2145                        comn |= 0x01;
2146                i2c_w1(gspca_dev, 0x01, comn);  /* sctra */
2147                break;
2148        case SENSOR_OV7630:
2149                comn = 0x02;
2150                if (!sd->ctrls[VFLIP].val)
2151                        comn |= 0x80;
2152                i2c_w1(gspca_dev, 0x75, comn);
2153                break;
2154        case SENSOR_OV7648:
2155                comn = 0x06;
2156                if (sd->ctrls[VFLIP].val)
2157                        comn |= 0x80;
2158                i2c_w1(gspca_dev, 0x75, comn);
2159                break;
2160        case SENSOR_PO2030N:
2161                /* Reg. 0x1E: Timing Generator Control Register 2 (Tgcontrol2)
2162                 * (reset value: 0x0A)
2163                 * bit7: HM: Horizontal Mirror: 0: disable, 1: enable
2164                 * bit6: VM: Vertical Mirror: 0: disable, 1: enable
2165                 * bit5: ST: Shutter Selection: 0: electrical, 1: mechanical
2166                 * bit4: FT: Single Frame Transfer: 0: disable, 1: enable
2167                 * bit3-0: X
2168                 */
2169                comn = 0x0a;
2170                if (sd->ctrls[HFLIP].val)
2171                        comn |= 0x80;
2172                if (sd->ctrls[VFLIP].val)
2173                        comn |= 0x40;
2174                i2c_w1(&sd->gspca_dev, 0x1e, comn);
2175                break;
2176        }
2177}
2178
2179static void setsharpness(struct gspca_dev *gspca_dev)
2180{
2181        struct sd *sd = (struct sd *) gspca_dev;
2182
2183        reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val);
2184}
2185
2186static void setillum(struct gspca_dev *gspca_dev)
2187{
2188        struct sd *sd = (struct sd *) gspca_dev;
2189
2190        if (gspca_dev->ctrl_dis & (1 << ILLUM))
2191                return;
2192        switch (sd->sensor) {
2193        case SENSOR_ADCM1700:
2194                reg_w1(gspca_dev, 0x02,                         /* gpio */
2195                        sd->ctrls[ILLUM].val ? 0x64 : 0x60);
2196                break;
2197        case SENSOR_MT9V111:
2198                reg_w1(gspca_dev, 0x02,
2199                        sd->ctrls[ILLUM].val ? 0x77 : 0x74);
2200/* should have been: */
2201/*                                              0x55 : 0x54);   * 370i */
2202/*                                              0x66 : 0x64);   * Clip */
2203                break;
2204        }
2205}
2206
2207static void setfreq(struct gspca_dev *gspca_dev)
2208{
2209        struct sd *sd = (struct sd *) gspca_dev;
2210
2211        if (gspca_dev->ctrl_dis & (1 << FREQ))
2212                return;
2213        if (sd->sensor == SENSOR_OV7660) {
2214                u8 com8;
2215
2216                com8 = 0xdf;            /* auto gain/wb/expo */
2217                switch (sd->ctrls[FREQ].val) {
2218                case 0: /* Banding filter disabled */
2219                        i2c_w1(gspca_dev, 0x13, com8 | 0x20);
2220                        break;
2221                case 1: /* 50 hz */
2222                        i2c_w1(gspca_dev, 0x13, com8);
2223                        i2c_w1(gspca_dev, 0x3b, 0x0a);
2224                        break;
2225                case 2: /* 60 hz */
2226                        i2c_w1(gspca_dev, 0x13, com8);
2227                        i2c_w1(gspca_dev, 0x3b, 0x02);
2228                        break;
2229                }
2230        } else {
2231                u8 reg2a = 0, reg2b = 0, reg2d = 0;
2232
2233                /* Get reg2a / reg2d base values */
2234                switch (sd->sensor) {
2235                case SENSOR_OV7630:
2236                        reg2a = 0x08;
2237                        reg2d = 0x01;
2238                        break;
2239                case SENSOR_OV7648:
2240                        reg2a = 0x11;
2241                        reg2d = 0x81;
2242                        break;
2243                }
2244
2245                switch (sd->ctrls[FREQ].val) {
2246                case 0: /* Banding filter disabled */
2247                        break;
2248                case 1: /* 50 hz (filter on and framerate adj) */
2249                        reg2a |= 0x80;
2250                        reg2b = 0xac;
2251                        reg2d |= 0x04;
2252                        break;
2253                case 2: /* 60 hz (filter on, no framerate adj) */
2254                        reg2a |= 0x80;
2255                        reg2d |= 0x04;
2256                        break;
2257                }
2258                i2c_w1(gspca_dev, 0x2a, reg2a);
2259                i2c_w1(gspca_dev, 0x2b, reg2b);
2260                i2c_w1(gspca_dev, 0x2d, reg2d);
2261        }
2262}
2263
2264static void setjpegqual(struct gspca_dev *gspca_dev)
2265{
2266        struct sd *sd = (struct sd *) gspca_dev;
2267
2268        jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2269#if USB_BUF_SZ < 64
2270#error "No room enough in usb_buf for quantization table"
2271#endif
2272        memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2273        usb_control_msg(gspca_dev->dev,
2274                        usb_sndctrlpipe(gspca_dev->dev, 0),
2275                        0x08,
2276                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2277                        0x0100, 0,
2278                        gspca_dev->usb_buf, 64,
2279                        500);
2280        memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2281        usb_control_msg(gspca_dev->dev,
2282                        usb_sndctrlpipe(gspca_dev->dev, 0),
2283                        0x08,
2284                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2285                        0x0140, 0,
2286                        gspca_dev->usb_buf, 64,
2287                        500);
2288
2289        sd->reg18 ^= 0x40;
2290        reg_w1(gspca_dev, 0x18, sd->reg18);
2291}
2292
2293/* JPEG quality update */
2294/* This function is executed from a work queue. */
2295static void qual_upd(struct work_struct *work)
2296{
2297        struct sd *sd = container_of(work, struct sd, work);
2298        struct gspca_dev *gspca_dev = &sd->gspca_dev;
2299
2300        mutex_lock(&gspca_dev->usb_lock);
2301        PDEBUG(D_STREAM, "qual_upd %d%%", sd->quality);
2302        setjpegqual(gspca_dev);
2303        mutex_unlock(&gspca_dev->usb_lock);
2304}
2305
2306/* -- start the camera -- */
2307static int sd_start(struct gspca_dev *gspca_dev)
2308{
2309        struct sd *sd = (struct sd *) gspca_dev;
2310        int i;
2311        u8 reg01, reg17;
2312        u8 reg0102[2];
2313        const u8 *sn9c1xx;
2314        const u8 (*init)[8];
2315        const u8 *reg9a;
2316        int mode;
2317        static const u8 reg9a_def[] =
2318                {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
2319        static const u8 reg9a_spec[] =
2320                {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
2321        static const u8 regd4[] = {0x60, 0x00, 0x00};
2322        static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
2323        static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
2324        static const u8 CA_adcm1700[] =
2325                                { 0x14, 0xec, 0x0a, 0xf6 };
2326        static const u8 CA_po2030n[] =
2327                                { 0x1e, 0xe2, 0x14, 0xec };
2328        static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };      /* MI0360 */
2329        static const u8 CE_gc0307[] =
2330                                { 0x32, 0xce, 0x2d, 0xd3 };
2331        static const u8 CE_ov76xx[] =
2332                                { 0x32, 0xdd, 0x32, 0xdd };
2333        static const u8 CE_po2030n[] =
2334                                { 0x14, 0xe7, 0x1e, 0xdd };
2335
2336        /* create the JPEG header */
2337        jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
2338                        0x21);          /* JPEG 422 */
2339
2340        /* initialize the bridge */
2341        sn9c1xx = sn_tb[sd->sensor];
2342
2343        /* sensor clock already enabled in sd_init */
2344        /* reg_w1(gspca_dev, 0xf1, 0x00); */
2345        reg01 = sn9c1xx[1];
2346        if (sd->flags & F_PDN_INV)
2347                reg01 ^= S_PDN_INV;             /* power down inverted */
2348        reg_w1(gspca_dev, 0x01, reg01);
2349
2350        /* configure gpio */
2351        reg0102[0] = reg01;
2352        reg0102[1] = sn9c1xx[2];
2353        if (gspca_dev->audio)
2354                reg0102[1] |= 0x04;     /* keep the audio connection */
2355        reg_w(gspca_dev, 0x01, reg0102, 2);
2356        reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
2357        reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
2358        switch (sd->sensor) {
2359        case SENSOR_GC0307:
2360        case SENSOR_OV7660:
2361        case SENSOR_PO1030:
2362        case SENSOR_PO2030N:
2363        case SENSOR_SOI768:
2364        case SENSOR_SP80708:
2365                reg9a = reg9a_spec;
2366                break;
2367        default:
2368                reg9a = reg9a_def;
2369                break;
2370        }
2371        reg_w(gspca_dev, 0x9a, reg9a, 6);
2372
2373        reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
2374
2375        reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
2376
2377        reg17 = sn9c1xx[0x17];
2378        switch (sd->sensor) {
2379        case SENSOR_GC0307:
2380                msleep(50);             /*fixme: is it useful? */
2381                break;
2382        case SENSOR_OM6802:
2383                msleep(10);
2384                reg_w1(gspca_dev, 0x02, 0x73);
2385                reg17 |= SEN_CLK_EN;
2386                reg_w1(gspca_dev, 0x17, reg17);
2387                reg_w1(gspca_dev, 0x01, 0x22);
2388                msleep(100);
2389                reg01 = SCL_SEL_OD | S_PDN_INV;
2390                reg17 &= ~MCK_SIZE_MASK;
2391                reg17 |= 0x04;          /* clock / 4 */
2392                break;
2393        }
2394        reg01 |= SYS_SEL_48M;
2395        reg_w1(gspca_dev, 0x01, reg01);
2396        reg17 |= SEN_CLK_EN;
2397        reg_w1(gspca_dev, 0x17, reg17);
2398        reg01 &= ~S_PWR_DN;             /* sensor power on */
2399        reg_w1(gspca_dev, 0x01, reg01);
2400        reg01 &= ~SYS_SEL_48M;
2401        reg_w1(gspca_dev, 0x01, reg01);
2402
2403        switch (sd->sensor) {
2404        case SENSOR_HV7131R:
2405                hv7131r_probe(gspca_dev);       /*fixme: is it useful? */
2406                break;
2407        case SENSOR_OM6802:
2408                msleep(10);
2409                reg_w1(gspca_dev, 0x01, reg01);
2410                i2c_w8(gspca_dev, om6802_init0[0]);
2411                i2c_w8(gspca_dev, om6802_init0[1]);
2412                msleep(15);
2413                reg_w1(gspca_dev, 0x02, 0x71);
2414                msleep(150);
2415                break;
2416        case SENSOR_SP80708:
2417                msleep(100);
2418                reg_w1(gspca_dev, 0x02, 0x62);
2419                break;
2420        }
2421
2422        /* initialize the sensor */
2423        i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
2424
2425        reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
2426        reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
2427        reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
2428        reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
2429        reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2430        if (sd->sensor == SENSOR_ADCM1700) {
2431                reg_w1(gspca_dev, 0xd2, 0x3a);  /* AE_H_SIZE = 116 */
2432                reg_w1(gspca_dev, 0xd3, 0x30);  /* AE_V_SIZE = 96 */
2433        } else {
2434                reg_w1(gspca_dev, 0xd2, 0x6a);  /* AE_H_SIZE = 212 */
2435                reg_w1(gspca_dev, 0xd3, 0x50);  /* AE_V_SIZE = 160 */
2436        }
2437        reg_w1(gspca_dev, 0xc6, 0x00);
2438        reg_w1(gspca_dev, 0xc7, 0x00);
2439        if (sd->sensor == SENSOR_ADCM1700) {
2440                reg_w1(gspca_dev, 0xc8, 0x2c);  /* AW_H_STOP = 352 */
2441                reg_w1(gspca_dev, 0xc9, 0x24);  /* AW_V_STOP = 288 */
2442        } else {
2443                reg_w1(gspca_dev, 0xc8, 0x50);  /* AW_H_STOP = 640 */
2444                reg_w1(gspca_dev, 0xc9, 0x3c);  /* AW_V_STOP = 480 */
2445        }
2446        reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2447        switch (sd->sensor) {
2448        case SENSOR_OM6802:
2449/*      case SENSOR_OV7648:             * fixme: sometimes */
2450                break;
2451        default:
2452                reg17 |= DEF_EN;
2453                break;
2454        }
2455        reg_w1(gspca_dev, 0x17, reg17);
2456
2457        reg_w1(gspca_dev, 0x05, 0x00);          /* red */
2458        reg_w1(gspca_dev, 0x07, 0x00);          /* green */
2459        reg_w1(gspca_dev, 0x06, 0x00);          /* blue */
2460        reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
2461
2462        setgamma(gspca_dev);
2463
2464/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
2465        for (i = 0; i < 8; i++)
2466                reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2467        switch (sd->sensor) {
2468        case SENSOR_ADCM1700:
2469        case SENSOR_OV7660:
2470        case SENSOR_SP80708:
2471                reg_w1(gspca_dev, 0x9a, 0x05);
2472                break;
2473        case SENSOR_GC0307:
2474        case SENSOR_MT9V111:
2475        case SENSOR_MI0360B:
2476                reg_w1(gspca_dev, 0x9a, 0x07);
2477                break;
2478        case SENSOR_OV7630:
2479        case SENSOR_OV7648:
2480                reg_w1(gspca_dev, 0x9a, 0x0a);
2481                break;
2482        case SENSOR_PO2030N:
2483        case SENSOR_SOI768:
2484                reg_w1(gspca_dev, 0x9a, 0x06);
2485                break;
2486        default:
2487                reg_w1(gspca_dev, 0x9a, 0x08);
2488                break;
2489        }
2490        setsharpness(gspca_dev);
2491
2492        reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2493        reg_w1(gspca_dev, 0x05, 0x20);          /* red */
2494        reg_w1(gspca_dev, 0x07, 0x20);          /* green */
2495        reg_w1(gspca_dev, 0x06, 0x20);          /* blue */
2496
2497        init = NULL;
2498        mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
2499        reg01 |= SYS_SEL_48M | V_TX_EN;
2500        reg17 &= ~MCK_SIZE_MASK;
2501        reg17 |= 0x02;                  /* clock / 2 */
2502        switch (sd->sensor) {
2503        case SENSOR_ADCM1700:
2504                init = adcm1700_sensor_param1;
2505                break;
2506        case SENSOR_GC0307:
2507                init = gc0307_sensor_param1;
2508                break;
2509        case SENSOR_HV7131R:
2510        case SENSOR_MI0360:
2511                if (!mode)
2512                        reg01 &= ~SYS_SEL_48M;  /* 640x480: clk 24Mhz */
2513                reg17 &= ~MCK_SIZE_MASK;
2514                reg17 |= 0x01;                  /* clock / 1 */
2515                break;
2516        case SENSOR_MI0360B:
2517                init = mi0360b_sensor_param1;
2518                break;
2519        case SENSOR_MO4000:
2520                if (mode) {                     /* if 320x240 */
2521                        reg01 &= ~SYS_SEL_48M;  /* clk 24Mz */
2522                        reg17 &= ~MCK_SIZE_MASK;
2523                        reg17 |= 0x01;          /* clock / 1 */
2524                }
2525                break;
2526        case SENSOR_MT9V111:
2527                init = mt9v111_sensor_param1;
2528                break;
2529        case SENSOR_OM6802:
2530                init = om6802_sensor_param1;
2531                if (!mode) {                    /* if 640x480 */
2532                        reg17 &= ~MCK_SIZE_MASK;
2533                        reg17 |= 0x04;          /* clock / 4 */
2534                } else {
2535                        reg01 &= ~SYS_SEL_48M;  /* clk 24Mz */
2536                        reg17 &= ~MCK_SIZE_MASK;
2537                        reg17 |= 0x02;          /* clock / 2 */
2538                }
2539                break;
2540        case SENSOR_OV7630:
2541                init = ov7630_sensor_param1;
2542                break;
2543        case SENSOR_OV7648:
2544                init = ov7648_sensor_param1;
2545                reg17 &= ~MCK_SIZE_MASK;
2546                reg17 |= 0x01;                  /* clock / 1 */
2547                break;
2548        case SENSOR_OV7660:
2549                init = ov7660_sensor_param1;
2550                break;
2551        case SENSOR_PO1030:
2552                init = po1030_sensor_param1;
2553                break;
2554        case SENSOR_PO2030N:
2555                init = po2030n_sensor_param1;
2556                break;
2557        case SENSOR_SOI768:
2558                init = soi768_sensor_param1;
2559                break;
2560        case SENSOR_SP80708:
2561                init = sp80708_sensor_param1;
2562                break;
2563        }
2564
2565        /* more sensor initialization - param1 */
2566        if (init != NULL) {
2567                i2c_w_seq(gspca_dev, init);
2568/*              init = NULL; */
2569        }
2570
2571        reg_w(gspca_dev, 0xc0, C0, 6);
2572        switch (sd->sensor) {
2573        case SENSOR_ADCM1700:
2574        case SENSOR_GC0307:
2575        case SENSOR_SOI768:
2576                reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2577                break;
2578        case SENSOR_PO2030N:
2579                reg_w(gspca_dev, 0xca, CA_po2030n, 4);
2580                break;
2581        default:
2582                reg_w(gspca_dev, 0xca, CA, 4);
2583                break;
2584        }
2585        switch (sd->sensor) {
2586        case SENSOR_ADCM1700:
2587        case SENSOR_OV7630:
2588        case SENSOR_OV7648:
2589        case SENSOR_OV7660:
2590        case SENSOR_SOI768:
2591                reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
2592                break;
2593        case SENSOR_GC0307:
2594                reg_w(gspca_dev, 0xce, CE_gc0307, 4);
2595                break;
2596        case SENSOR_PO2030N:
2597                reg_w(gspca_dev, 0xce, CE_po2030n, 4);
2598                break;
2599        default:
2600                reg_w(gspca_dev, 0xce, CE, 4);
2601                                        /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
2602                break;
2603        }
2604
2605        /* here change size mode 0 -> VGA; 1 -> CIF */
2606        sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
2607        reg_w1(gspca_dev, 0x18, sd->reg18);
2608        setjpegqual(gspca_dev);
2609
2610        reg_w1(gspca_dev, 0x17, reg17);
2611        reg_w1(gspca_dev, 0x01, reg01);
2612        sd->reg01 = reg01;
2613        sd->reg17 = reg17;
2614
2615        sethvflip(gspca_dev);
2616        setbrightness(gspca_dev);
2617        setcontrast(gspca_dev);
2618        setcolors(gspca_dev);
2619        setautogain(gspca_dev);
2620        setfreq(gspca_dev);
2621
2622        sd->pktsz = sd->npkt = 0;
2623        sd->nchg = sd->short_mark = 0;
2624        sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
2625
2626        return gspca_dev->usb_err;
2627}
2628
2629static void sd_stopN(struct gspca_dev *gspca_dev)
2630{
2631        struct sd *sd = (struct sd *) gspca_dev;
2632        static const u8 stophv7131[] =
2633                { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
2634        static const u8 stopmi0360[] =
2635                { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
2636        static const u8 stopov7648[] =
2637                { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
2638        static const u8 stopsoi768[] =
2639                { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
2640        u8 reg01;
2641        u8 reg17;
2642
2643        reg01 = sd->reg01;
2644        reg17 = sd->reg17 & ~SEN_CLK_EN;
2645        switch (sd->sensor) {
2646        case SENSOR_ADCM1700:
2647        case SENSOR_GC0307:
2648        case SENSOR_PO2030N:
2649        case SENSOR_SP80708:
2650                reg01 |= LED;
2651                reg_w1(gspca_dev, 0x01, reg01);
2652                reg01 &= ~(LED | V_TX_EN);
2653                reg_w1(gspca_dev, 0x01, reg01);
2654/*              reg_w1(gspca_dev, 0x02, 0x??);   * LED off ? */
2655                break;
2656        case SENSOR_HV7131R:
2657                reg01 &= ~V_TX_EN;
2658                reg_w1(gspca_dev, 0x01, reg01);
2659                i2c_w8(gspca_dev, stophv7131);
2660                break;
2661        case SENSOR_MI0360:
2662        case SENSOR_MI0360B:
2663                reg01 &= ~V_TX_EN;
2664                reg_w1(gspca_dev, 0x01, reg01);
2665/*              reg_w1(gspca_dev, 0x02, 0x40);    * LED off ? */
2666                i2c_w8(gspca_dev, stopmi0360);
2667                break;
2668        case SENSOR_MT9V111:
2669        case SENSOR_OM6802:
2670        case SENSOR_PO1030:
2671                reg01 &= ~V_TX_EN;
2672                reg_w1(gspca_dev, 0x01, reg01);
2673                break;
2674        case SENSOR_OV7630:
2675        case SENSOR_OV7648:
2676                reg01 &= ~V_TX_EN;
2677                reg_w1(gspca_dev, 0x01, reg01);
2678                i2c_w8(gspca_dev, stopov7648);
2679                break;
2680        case SENSOR_OV7660:
2681                reg01 &= ~V_TX_EN;
2682                reg_w1(gspca_dev, 0x01, reg01);
2683                break;
2684        case SENSOR_SOI768:
2685                i2c_w8(gspca_dev, stopsoi768);
2686                break;
2687        }
2688
2689        reg01 |= SCL_SEL_OD;
2690        reg_w1(gspca_dev, 0x01, reg01);
2691        reg01 |= S_PWR_DN;              /* sensor power down */
2692        reg_w1(gspca_dev, 0x01, reg01);
2693        reg_w1(gspca_dev, 0x17, reg17);
2694        reg01 &= ~SYS_SEL_48M;          /* clock 24MHz */
2695        reg_w1(gspca_dev, 0x01, reg01);
2696        reg01 |= LED;
2697        reg_w1(gspca_dev, 0x01, reg01);
2698        /* Don't disable sensor clock as that disables the button on the cam */
2699        /* reg_w1(gspca_dev, 0xf1, 0x01); */
2700}
2701
2702/* called on streamoff with alt==0 and on disconnect */
2703/* the usb_lock is held at entry - restore on exit */
2704static void sd_stop0(struct gspca_dev *gspca_dev)
2705{
2706        struct sd *sd = (struct sd *) gspca_dev;
2707
2708        if (sd->work_thread != NULL) {
2709                mutex_unlock(&gspca_dev->usb_lock);
2710                destroy_workqueue(sd->work_thread);
2711                mutex_lock(&gspca_dev->usb_lock);
2712                sd->work_thread = NULL;
2713        }
2714}
2715
2716static void do_autogain(struct gspca_dev *gspca_dev)
2717{
2718        struct sd *sd = (struct sd *) gspca_dev;
2719        int delta;
2720        int expotimes;
2721        u8 luma_mean = 130;
2722        u8 luma_delta = 20;
2723
2724        /* Thanks S., without your advice, autobright should not work :) */
2725        if (sd->ag_cnt < 0)
2726                return;
2727        if (--sd->ag_cnt >= 0)
2728                return;
2729        sd->ag_cnt = AG_CNT_START;
2730
2731        delta = atomic_read(&sd->avg_lum);
2732        PDEBUG(D_FRAM, "mean lum %d", delta);
2733        if (delta < luma_mean - luma_delta ||
2734            delta > luma_mean + luma_delta) {
2735                switch (sd->sensor) {
2736                case SENSOR_GC0307:
2737                        expotimes = sd->exposure;
2738                        expotimes += (luma_mean - delta) >> 6;
2739                        if (expotimes < 0)
2740                                expotimes = 0;
2741                        sd->exposure = setexposure(gspca_dev,
2742                                                   (unsigned int) expotimes);
2743                        break;
2744                case SENSOR_HV7131R:
2745                        expotimes = sd->exposure >> 8;
2746                        expotimes += (luma_mean - delta) >> 4;
2747                        if (expotimes < 0)
2748                                expotimes = 0;
2749                        sd->exposure = setexposure(gspca_dev,
2750                                        (unsigned int) (expotimes << 8));
2751                        break;
2752                case SENSOR_OM6802:
2753                case SENSOR_MT9V111:
2754                        expotimes = sd->exposure;
2755                        expotimes += (luma_mean - delta) >> 2;
2756                        if (expotimes < 0)
2757                                expotimes = 0;
2758                        sd->exposure = setexposure(gspca_dev,
2759                                                   (unsigned int) expotimes);
2760                        setredblue(gspca_dev);
2761                        break;
2762                default:
2763/*              case SENSOR_MO4000: */
2764/*              case SENSOR_MI0360: */
2765/*              case SENSOR_MI0360B: */
2766                        expotimes = sd->exposure;
2767                        expotimes += (luma_mean - delta) >> 6;
2768                        if (expotimes < 0)
2769                                expotimes = 0;
2770                        sd->exposure = setexposure(gspca_dev,
2771                                                   (unsigned int) expotimes);
2772                        setredblue(gspca_dev);
2773                        break;
2774                }
2775        }
2776}
2777
2778/* set the average luminosity from an isoc marker */
2779static void set_lum(struct sd *sd,
2780                    u8 *data)
2781{
2782        int avg_lum;
2783
2784        /*      w0 w1 w2
2785         *      w3 w4 w5
2786         *      w6 w7 w8
2787         */
2788        avg_lum = (data[27] << 8) + data[28]            /* w3 */
2789
2790                + (data[31] << 8) + data[32]            /* w5 */
2791
2792                + (data[23] << 8) + data[24]            /* w1 */
2793
2794                + (data[35] << 8) + data[36]            /* w7 */
2795
2796                + (data[29] << 10) + (data[30] << 2);   /* w4 * 4 */
2797        avg_lum >>= 10;
2798        atomic_set(&sd->avg_lum, avg_lum);
2799}
2800
2801/* scan the URB packets */
2802/* This function is run at interrupt level. */
2803static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2804                        u8 *data,                       /* isoc packet */
2805                        int len)                        /* iso packet length */
2806{
2807        struct sd *sd = (struct sd *) gspca_dev;
2808        int i, new_qual;
2809
2810        /*
2811         * A frame ends on the marker
2812         *              ff ff 00 c4 c4 96 ..
2813         * which is 62 bytes long and is followed by various information
2814         * including statuses and luminosity.
2815         *
2816         * A marker may be splitted on two packets.
2817         *
2818         * The 6th byte of a marker contains the bits:
2819         *      0x08: USB full
2820         *      0xc0: frame sequence
2821         * When the bit 'USB full' is set, the frame must be discarded;
2822         * this is also the case when the 2 bytes before the marker are
2823         * not the JPEG end of frame ('ff d9').
2824         */
2825
2826/*fixme: assumption about the following code:
2827 *      - there can be only one marker in a packet
2828 */
2829
2830        /* skip the remaining bytes of a short marker */
2831        i = sd->short_mark;
2832        if (i != 0) {
2833                sd->short_mark = 0;
2834                if (i < 0       /* if 'ff' at end of previous packet */
2835                 && data[0] == 0xff
2836                 && data[1] == 0x00)
2837                        goto marker_found;
2838                if (data[0] == 0xff && data[1] == 0xff) {
2839                        i = 0;
2840                        goto marker_found;
2841                }
2842                len -= i;
2843                if (len <= 0)
2844                        return;
2845                data += i;
2846        }
2847
2848        /* count the packets and their size */
2849        sd->npkt++;
2850        sd->pktsz += len;
2851
2852        /* search backwards if there is a marker in the packet */
2853        for (i = len - 1; --i >= 0; ) {
2854                if (data[i] != 0xff) {
2855                        i--;
2856                        continue;
2857                }
2858                if (data[i + 1] == 0xff) {
2859
2860                        /* (there may be 'ff ff' inside a marker) */
2861                        if (i + 2 >= len || data[i + 2] == 0x00)
2862                                goto marker_found;
2863                }
2864        }
2865
2866        /* no marker found */
2867        /* add the JPEG header if first fragment */
2868        if (data[len - 1] == 0xff)
2869                sd->short_mark = -1;
2870        if (gspca_dev->last_packet_type == LAST_PACKET)
2871                gspca_frame_add(gspca_dev, FIRST_PACKET,
2872                                sd->jpeg_hdr, JPEG_HDR_SZ);
2873        gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2874        return;
2875
2876        /* marker found */
2877        /* if some error, discard the frame and decrease the quality */
2878marker_found:
2879        new_qual = 0;
2880        if (i > 2) {
2881                if (data[i - 2] != 0xff || data[i - 1] != 0xd9) {
2882                        gspca_dev->last_packet_type = DISCARD_PACKET;
2883                        new_qual = -3;
2884                }
2885        } else if (i + 6 < len) {
2886                if (data[i + 6] & 0x08) {
2887                        gspca_dev->last_packet_type = DISCARD_PACKET;
2888                        new_qual = -5;
2889                }
2890        }
2891
2892        gspca_frame_add(gspca_dev, LAST_PACKET, data, i);
2893
2894        /* compute the filling rate and a new JPEG quality */
2895        if (new_qual == 0) {
2896                int r;
2897
2898                r = (sd->pktsz * 100) /
2899                        (sd->npkt *
2900                                gspca_dev->urb[0]->iso_frame_desc[0].length);
2901                if (r >= 85)
2902                        new_qual = -3;
2903                else if (r < 75)
2904                        new_qual = 2;
2905        }
2906        if (new_qual != 0) {
2907                sd->nchg += new_qual;
2908                if (sd->nchg < -6 || sd->nchg >= 12) {
2909                        sd->nchg = 0;
2910                        new_qual += sd->quality;
2911                        if (new_qual < QUALITY_MIN)
2912                                new_qual = QUALITY_MIN;
2913                        else if (new_qual > QUALITY_MAX)
2914                                new_qual = QUALITY_MAX;
2915                        if (new_qual != sd->quality) {
2916                                sd->quality = new_qual;
2917                                queue_work(sd->work_thread, &sd->work);
2918                        }
2919                }
2920        } else {
2921                sd->nchg = 0;
2922        }
2923        sd->pktsz = sd->npkt = 0;
2924
2925        /* if the marker is smaller than 62 bytes,
2926         * memorize the number of bytes to skip in the next packet */
2927        if (i + 62 > len) {                     /* no more usable data */
2928                sd->short_mark = i + 62 - len;
2929                return;
2930        }
2931        if (sd->ag_cnt >= 0)
2932                set_lum(sd, data + i);
2933
2934        /* if more data, start a new frame */
2935        i += 62;
2936        if (i < len) {
2937                data += i;
2938                len -= i;
2939                gspca_frame_add(gspca_dev, FIRST_PACKET,
2940                                sd->jpeg_hdr, JPEG_HDR_SZ);
2941                gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2942        }
2943}
2944
2945static int sd_get_jcomp(struct gspca_dev *gspca_dev,
2946                        struct v4l2_jpegcompression *jcomp)
2947{
2948        struct sd *sd = (struct sd *) gspca_dev;
2949
2950        memset(jcomp, 0, sizeof *jcomp);
2951        jcomp->quality = sd->quality;
2952        jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
2953                        | V4L2_JPEG_MARKER_DQT;
2954        return 0;
2955}
2956
2957static int sd_querymenu(struct gspca_dev *gspca_dev,
2958                        struct v4l2_querymenu *menu)
2959{
2960        switch (menu->id) {
2961        case V4L2_CID_POWER_LINE_FREQUENCY:
2962                switch (menu->index) {
2963                case 0:         /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2964                        strcpy((char *) menu->name, "NoFliker");
2965                        return 0;
2966                case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2967                        strcpy((char *) menu->name, "50 Hz");
2968                        return 0;
2969                case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2970                        strcpy((char *) menu->name, "60 Hz");
2971                        return 0;
2972                }
2973                break;
2974        }
2975        return -EINVAL;
2976}
2977
2978#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2979static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2980                        u8 *data,               /* interrupt packet data */
2981                        int len)                /* interrupt packet length */
2982{
2983        int ret = -EINVAL;
2984
2985        if (len == 1 && data[0] == 1) {
2986                input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2987                input_sync(gspca_dev->input_dev);
2988                input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2989                input_sync(gspca_dev->input_dev);
2990                ret = 0;
2991        }
2992
2993        return ret;
2994}
2995#endif
2996
2997/* sub-driver description */
2998static const struct sd_desc sd_desc = {
2999        .name = MODULE_NAME,
3000        .ctrls = sd_ctrls,
3001        .nctrls = NCTRLS,
3002        .config = sd_config,
3003        .init = sd_init,
3004        .start = sd_start,
3005        .stopN = sd_stopN,
3006        .stop0 = sd_stop0,
3007        .pkt_scan = sd_pkt_scan,
3008        .dq_callback = do_autogain,
3009        .get_jcomp = sd_get_jcomp,
3010        .querymenu = sd_querymenu,
3011#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
3012        .int_pkt_scan = sd_int_pkt_scan,
3013#endif
3014};
3015
3016/* -- module initialisation -- */
3017#define BS(bridge, sensor) \
3018        .driver_info = (BRIDGE_ ## bridge << 16) \
3019                        | (SENSOR_ ## sensor << 8)
3020#define BSF(bridge, sensor, flags) \
3021        .driver_info = (BRIDGE_ ## bridge << 16) \
3022                        | (SENSOR_ ## sensor << 8) \
3023                        | (flags)
3024static const struct usb_device_id device_table[] = {
3025        {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
3026        {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
3027        {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)},
3028        {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)},
3029        {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
3030        {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
3031        {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
3032        {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
3033        {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
3034/*      {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
3035        {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
3036/*      {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
3037/*      {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
3038        {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
3039/*      {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
3040        {USB_DEVICE(0x0c45, 0x60c0), BSF(SN9C105, MI0360, F_ILLUM)},
3041                                                /* or MT9V111 */
3042/*      {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
3043/*      {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
3044/*      {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
3045        {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
3046        {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
3047/*      {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
3048/*      {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
3049/*      {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
3050        {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
3051        {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
3052        {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
3053        {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)},      /*sn9c128*/
3054        {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)},     /* /GC0305*/
3055/*      {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
3056        {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)},      /*sn9c128*/
3057        {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)},      /*sn9c128*/
3058        {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)},     /*sn9c128*/
3059        {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)},      /*sn9c128*/
3060/*      {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
3061/*      {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
3062/*      {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
3063        {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)},      /*sn9c325?*/
3064/*bw600.inf:*/
3065        {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)},      /*sn9c325?*/
3066        {USB_DEVICE(0x0c45, 0x612b), BS(SN9C110, ADCM1700)},
3067        {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
3068        {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
3069/*      {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
3070        {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
3071                                                /* or MT9V111 / MI0360B */
3072/*      {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
3073        {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
3074        {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
3075        {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
3076        {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
3077        {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
3078        {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)},     /*sn9c120b*/
3079                                                /* or GC0305 / GC0307 */
3080        {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)},     /*sn9c120b*/
3081        {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)},      /*sn9c120b*/
3082        {USB_DEVICE(0x0c45, 0x614a), BSF(SN9C120, ADCM1700, F_ILLUM)},
3083/*      {USB_DEVICE(0x0c45, 0x614c), BS(SN9C120, GC0306)}, */   /*sn9c120b*/
3084        {}
3085};
3086MODULE_DEVICE_TABLE(usb, device_table);
3087
3088/* -- device connect -- */
3089static int sd_probe(struct usb_interface *intf,
3090                    const struct usb_device_id *id)
3091{
3092        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
3093                                THIS_MODULE);
3094}
3095
3096static struct usb_driver sd_driver = {
3097        .name = MODULE_NAME,
3098        .id_table = device_table,
3099        .probe = sd_probe,
3100        .disconnect = gspca_disconnect,
3101#ifdef CONFIG_PM
3102        .suspend = gspca_suspend,
3103        .resume = gspca_resume,
3104#endif
3105};
3106
3107/* -- module insert / remove -- */
3108static int __init sd_mod_init(void)
3109{
3110        return usb_register(&sd_driver);
3111}
3112static void __exit sd_mod_exit(void)
3113{
3114        usb_deregister(&sd_driver);
3115}
3116
3117module_init(sd_mod_init);
3118module_exit(sd_mod_exit);
3119
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.