linux/drivers/media/video/gspca/sonixj.c
<<
>>
Prefs
   1/*
   2 *              Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
   3 *              Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
   4 *
   5 * V4L2 by Jean-Francois Moine <http://moinejf.free.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 MODULE_NAME "sonixj"
  23
  24#include "gspca.h"
  25#include "jpeg.h"
  26
  27#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
  28
  29MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  30MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
  31MODULE_LICENSE("GPL");
  32
  33/* specific webcam descriptor */
  34struct sd {
  35        struct gspca_dev gspca_dev;     /* !! must be the first item */
  36
  37        atomic_t avg_lum;
  38        u32 exposure;
  39
  40        u16 brightness;
  41        u8 contrast;
  42        u8 colors;
  43        u8 autogain;
  44        u8 blue;
  45        u8 red;
  46        u8 gamma;
  47        u8 vflip;                       /* ov7630/ov7648 only */
  48        u8 infrared;                    /* mt9v111 only */
  49        u8 freq;                        /* ov76xx only */
  50        u8 quality;                     /* image quality */
  51#define QUALITY_MIN 60
  52#define QUALITY_MAX 95
  53#define QUALITY_DEF 80
  54        u8 jpegqual;                    /* webcam quality */
  55
  56        u8 reg18;
  57
  58        s8 ag_cnt;
  59#define AG_CNT_START 13
  60
  61        u8 bridge;
  62#define BRIDGE_SN9C102P 0
  63#define BRIDGE_SN9C105 1
  64#define BRIDGE_SN9C110 2
  65#define BRIDGE_SN9C120 3
  66        u8 sensor;                      /* Type of image sensor chip */
  67#define SENSOR_HV7131R 0
  68#define SENSOR_MI0360 1
  69#define SENSOR_MO4000 2
  70#define SENSOR_MT9V111 3
  71#define SENSOR_OM6802 4
  72#define SENSOR_OV7630 5
  73#define SENSOR_OV7648 6
  74#define SENSOR_OV7660 7
  75#define SENSOR_SP80708 8
  76        u8 i2c_base;
  77
  78        u8 *jpeg_hdr;
  79};
  80
  81/* V4L2 controls supported by the driver */
  82static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
  83static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
  84static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
  85static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
  86static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
  87static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
  88static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
  89static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
  90static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
  91static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
  92static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
  93static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
  94static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
  95static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
  96static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
  97static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
  98static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
  99static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
 100static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
 101static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
 102
 103static struct ctrl sd_ctrls[] = {
 104#define BRIGHTNESS_IDX 0
 105        {
 106            {
 107                .id      = V4L2_CID_BRIGHTNESS,
 108                .type    = V4L2_CTRL_TYPE_INTEGER,
 109                .name    = "Brightness",
 110                .minimum = 0,
 111#define BRIGHTNESS_MAX 0xffff
 112                .maximum = BRIGHTNESS_MAX,
 113                .step    = 1,
 114#define BRIGHTNESS_DEF 0x8000
 115                .default_value = BRIGHTNESS_DEF,
 116            },
 117            .set = sd_setbrightness,
 118            .get = sd_getbrightness,
 119        },
 120#define CONTRAST_IDX 1
 121        {
 122            {
 123                .id      = V4L2_CID_CONTRAST,
 124                .type    = V4L2_CTRL_TYPE_INTEGER,
 125                .name    = "Contrast",
 126                .minimum = 0,
 127#define CONTRAST_MAX 127
 128                .maximum = CONTRAST_MAX,
 129                .step    = 1,
 130#define CONTRAST_DEF 63
 131                .default_value = CONTRAST_DEF,
 132            },
 133            .set = sd_setcontrast,
 134            .get = sd_getcontrast,
 135        },
 136#define COLOR_IDX 2
 137        {
 138            {
 139                .id      = V4L2_CID_SATURATION,
 140                .type    = V4L2_CTRL_TYPE_INTEGER,
 141                .name    = "Saturation",
 142                .minimum = 0,
 143                .maximum = 40,
 144                .step    = 1,
 145#define COLOR_DEF 25
 146                .default_value = COLOR_DEF,
 147            },
 148            .set = sd_setcolors,
 149            .get = sd_getcolors,
 150        },
 151#define BLUE_BALANCE_IDX 3
 152        {
 153            {
 154                .id      = V4L2_CID_BLUE_BALANCE,
 155                .type    = V4L2_CTRL_TYPE_INTEGER,
 156                .name    = "Blue Balance",
 157                .minimum = 24,
 158                .maximum = 40,
 159                .step    = 1,
 160#define BLUE_BALANCE_DEF 32
 161                .default_value = BLUE_BALANCE_DEF,
 162            },
 163            .set = sd_setblue_balance,
 164            .get = sd_getblue_balance,
 165        },
 166#define RED_BALANCE_IDX 4
 167        {
 168            {
 169                .id      = V4L2_CID_RED_BALANCE,
 170                .type    = V4L2_CTRL_TYPE_INTEGER,
 171                .name    = "Red Balance",
 172                .minimum = 24,
 173                .maximum = 40,
 174                .step    = 1,
 175#define RED_BALANCE_DEF 32
 176                .default_value = RED_BALANCE_DEF,
 177            },
 178            .set = sd_setred_balance,
 179            .get = sd_getred_balance,
 180        },
 181#define GAMMA_IDX 5
 182        {
 183            {
 184                .id      = V4L2_CID_GAMMA,
 185                .type    = V4L2_CTRL_TYPE_INTEGER,
 186                .name    = "Gamma",
 187                .minimum = 0,
 188                .maximum = 40,
 189                .step    = 1,
 190#define GAMMA_DEF 20
 191                .default_value = GAMMA_DEF,
 192            },
 193            .set = sd_setgamma,
 194            .get = sd_getgamma,
 195        },
 196#define AUTOGAIN_IDX 6
 197        {
 198            {
 199                .id      = V4L2_CID_AUTOGAIN,
 200                .type    = V4L2_CTRL_TYPE_BOOLEAN,
 201                .name    = "Auto Gain",
 202                .minimum = 0,
 203                .maximum = 1,
 204                .step    = 1,
 205#define AUTOGAIN_DEF 1
 206                .default_value = AUTOGAIN_DEF,
 207            },
 208            .set = sd_setautogain,
 209            .get = sd_getautogain,
 210        },
 211/* ov7630/ov7648 only */
 212#define VFLIP_IDX 7
 213        {
 214            {
 215                .id      = V4L2_CID_VFLIP,
 216                .type    = V4L2_CTRL_TYPE_BOOLEAN,
 217                .name    = "Vflip",
 218                .minimum = 0,
 219                .maximum = 1,
 220                .step    = 1,
 221#define VFLIP_DEF 0
 222                .default_value = VFLIP_DEF,
 223            },
 224            .set = sd_setvflip,
 225            .get = sd_getvflip,
 226        },
 227/* mt9v111 only */
 228#define INFRARED_IDX 8
 229        {
 230            {
 231                .id      = V4L2_CID_INFRARED,
 232                .type    = V4L2_CTRL_TYPE_BOOLEAN,
 233                .name    = "Infrared",
 234                .minimum = 0,
 235                .maximum = 1,
 236                .step    = 1,
 237#define INFRARED_DEF 0
 238                .default_value = INFRARED_DEF,
 239            },
 240            .set = sd_setinfrared,
 241            .get = sd_getinfrared,
 242        },
 243/* ov7630/ov7648/ov7660 only */
 244#define FREQ_IDX 9
 245        {
 246            {
 247                .id      = V4L2_CID_POWER_LINE_FREQUENCY,
 248                .type    = V4L2_CTRL_TYPE_MENU,
 249                .name    = "Light frequency filter",
 250                .minimum = 0,
 251                .maximum = 2,   /* 0: 0, 1: 50Hz, 2:60Hz */
 252                .step    = 1,
 253#define FREQ_DEF 2
 254                .default_value = FREQ_DEF,
 255            },
 256            .set = sd_setfreq,
 257            .get = sd_getfreq,
 258        },
 259};
 260
 261/* table of the disabled controls */
 262static __u32 ctrl_dis[] = {
 263        (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
 264                                                /* SENSOR_HV7131R 0 */
 265        (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
 266                                                /* SENSOR_MI0360 1 */
 267        (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
 268                                                /* SENSOR_MO4000 2 */
 269        (1 << VFLIP_IDX) | (1 << FREQ_IDX),
 270                                                /* SENSOR_MT9V111 3 */
 271        (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
 272                                                /* SENSOR_OM6802 4 */
 273        (1 << INFRARED_IDX),
 274                                                /* SENSOR_OV7630 5 */
 275        (1 << INFRARED_IDX),
 276                                                /* SENSOR_OV7648 6 */
 277        (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
 278                                                /* SENSOR_OV7660 7 */
 279        (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
 280                              (1 << FREQ_IDX),  /* SENSOR_SP80708 8 */
 281};
 282
 283static const struct v4l2_pix_format vga_mode[] = {
 284        {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 285                .bytesperline = 160,
 286                .sizeimage = 160 * 120 * 4 / 8 + 590,
 287                .colorspace = V4L2_COLORSPACE_JPEG,
 288                .priv = 2},
 289        {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 290                .bytesperline = 320,
 291                .sizeimage = 320 * 240 * 3 / 8 + 590,
 292                .colorspace = V4L2_COLORSPACE_JPEG,
 293                .priv = 1},
 294        {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 295                .bytesperline = 640,
 296                /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
 297                .sizeimage = 640 * 480 * 3 / 4 + 590,
 298                .colorspace = V4L2_COLORSPACE_JPEG,
 299                .priv = 0},
 300};
 301
 302/*Data from sn9c102p+hv7131r */
 303static const u8 sn_hv7131[0x1c] = {
 304/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 305        0x00,   0x03,   0x64,   0x00,   0x1a,   0x20,   0x20,   0x20,
 306/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 307        0xa1,   0x11,   0x02,   0x09,   0x00,   0x00,   0x00,   0x10,
 308/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 309        0x03,   0x00,   0x00,   0x01,   0x03,   0x28,   0x1e,   0x41,
 310/*      reg18   reg19   reg1a   reg1b */
 311        0x0a,   0x00,   0x00,   0x00
 312};
 313
 314static const u8 sn_mi0360[0x1c] = {
 315/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 316        0x00,   0x61,   0x44,   0x00,   0x1a,   0x20,   0x20,   0x20,
 317/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 318        0xb1,   0x5d,   0x07,   0x00,   0x00,   0x00,   0x00,   0x10,
 319/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 320        0x03,   0x00,   0x00,   0x02,   0x0a,   0x28,   0x1e,   0x61,
 321/*      reg18   reg19   reg1a   reg1b */
 322        0x06,   0x00,   0x00,   0x00
 323};
 324
 325static const u8 sn_mo4000[0x1c] = {
 326/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 327        0x00,   0x23,   0x60,   0x00,   0x1a,   0x00,   0x20,   0x18,
 328/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 329        0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 330/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 331        0x03,    0x00,  0x0b,   0x0f,   0x14,   0x28,   0x1e,   0x40,
 332/*      reg18   reg19   reg1a   reg1b */
 333        0x08,   0x00,   0x00,   0x00
 334};
 335
 336static const u8 sn_mt9v111[0x1c] = {
 337/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 338        0x00,   0x61,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
 339/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 340        0x81,   0x5c,   0x07,   0x00,   0x00,   0x00,   0x00,   0x00,
 341/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 342        0x03,   0x00,   0x00,   0x02,   0x1c,   0x28,   0x1e,   0x40,
 343/*      reg18   reg19   reg1a   reg1b */
 344        0x06,   0x00,   0x00,   0x00
 345};
 346
 347static const u8 sn_om6802[0x1c] = {
 348/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 349        0x00,   0x23,   0x72,   0x00,   0x1a,   0x34,   0x27,   0x20,
 350/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 351        0x80,   0x34,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 352/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 353        0x03,   0x00,   0x51,   0x01,   0x00,   0x28,   0x1e,   0x40,
 354/*      reg18   reg19   reg1a   reg1b */
 355        0x05,   0x00,   0x00,   0x00
 356};
 357
 358static const u8 sn_ov7630[0x1c] = {
 359/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 360        0x00,   0x21,   0x40,   0x00,   0x1a,   0x20,   0x1f,   0x20,
 361/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 362        0xa1,   0x21,   0x76,   0x21,   0x00,   0x00,   0x00,   0x10,
 363/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 364        0x03,   0x00,   0x04,   0x01,   0x0a,   0x28,   0x1e,   0xc2,
 365/*      reg18   reg19   reg1a   reg1b */
 366        0x0b,   0x00,   0x00,   0x00
 367};
 368
 369static const u8 sn_ov7648[0x1c] = {
 370/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 371        0x00,   0x63,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
 372/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 373        0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x10,
 374/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 375        0x03,   0x00,   0x00,   0x01,   0x00,   0x28,   0x1e,   0x00,
 376/*      reg18   reg19   reg1a   reg1b */
 377        0x0b,   0x00,   0x00,   0x00
 378};
 379
 380static const u8 sn_ov7660[0x1c] = {
 381/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 382        0x00,   0x61,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
 383/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 384        0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
 385/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 386        0x03,   0x00,   0x01,   0x01,   0x08,   0x28,   0x1e,   0x20,
 387/*      reg18   reg19   reg1a   reg1b */
 388        0x07,   0x00,   0x00,   0x00
 389};
 390
 391static const u8 sn_sp80708[0x1c] = {
 392/*      reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
 393        0x00,   0x63,   0x60,   0x00,   0x1a,   0x20,   0x20,   0x20,
 394/*      reg8    reg9    rega    regb    regc    regd    rege    regf */
 395        0x81,   0x18,   0x07,   0x00,   0x00,   0x00,   0x00,   0x00,
 396/*      reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
 397        0x03,   0x00,   0x00,   0x03,   0x04,   0x28,   0x1e,   0x00,
 398/*      reg18   reg19   reg1a   reg1b */
 399        0x07,   0x00,   0x00,   0x00
 400};
 401
 402/* sequence specific to the sensors - !! index = SENSOR_xxx */
 403static const u8 *sn_tb[] = {
 404        sn_hv7131,
 405        sn_mi0360,
 406        sn_mo4000,
 407        sn_mt9v111,
 408        sn_om6802,
 409        sn_ov7630,
 410        sn_ov7648,
 411        sn_ov7660,
 412        sn_sp80708
 413};
 414
 415/* default gamma table */
 416static const u8 gamma_def[17] = {
 417        0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
 418        0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
 419};
 420/* gamma for sensors HV7131R and MT9V111 */
 421static const u8 gamma_spec_1[17] = {
 422        0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
 423        0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
 424};
 425/* gamma for sensor SP80708 */
 426static const u8 gamma_spec_2[17] = {
 427        0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
 428        0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
 429};
 430
 431/* color matrix and offsets */
 432static const u8 reg84[] = {
 433        0x14, 0x00, 0x27, 0x00, 0x07, 0x00,     /* YR YG YB gains */
 434        0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00,     /* UR UG UB */
 435        0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f,     /* VR VG VB */
 436        0x00, 0x00, 0x00                        /* YUV offsets */
 437};
 438static const u8 hv7131r_sensor_init[][8] = {
 439        {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
 440        {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
 441        {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
 442/*      {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
 443        {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
 444        {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
 445/*      {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
 446
 447        {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
 448        {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
 449        {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
 450        {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
 451        {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
 452        {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
 453        {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
 454        {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
 455
 456        {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
 457        {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 458        {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
 459        {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 460        {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
 461
 462        {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
 463        {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 464        {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
 465        {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 466        {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
 467        {}
 468};
 469static const u8 mi0360_sensor_init[][8] = {
 470        {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
 471        {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
 472        {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
 473        {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
 474        {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
 475        {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
 476        {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
 477        {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
 478        {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
 479        {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
 480        {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
 481        {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
 482        {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
 483        {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
 484        {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
 485        {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
 486        {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
 487        {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
 488        {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
 489        {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 490        {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
 491        {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
 492        {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
 493        {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
 494        {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
 495        {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
 496        {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
 497        {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
 498        {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
 499        {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
 500        {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
 501        {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
 502        {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
 503
 504        {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
 505        {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
 506        {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
 507        {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
 508        {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
 509
 510        {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
 511        {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
 512        {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
 513        {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
 514
 515        {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
 516        {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
 517/*      {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
 518/*      {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
 519        {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
 520        {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
 521        {}
 522};
 523static const u8 mo4000_sensor_init[][8] = {
 524        {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
 525        {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
 526        {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
 527        {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
 528        {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
 529        {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
 530        {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
 531        {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
 532        {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
 533        {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
 534        {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
 535        {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
 536        {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
 537        {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
 538        {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
 539        {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
 540        {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
 541        {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
 542        {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
 543        {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
 544        {}
 545};
 546static const u8 mt9v111_sensor_init[][8] = {
 547        {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
 548        /* delay 20 ms */
 549        {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
 550        {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
 551        {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
 552        {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
 553        {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
 554        {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
 555        {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
 556        {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
 557        {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
 558        {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
 559        {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
 560        {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
 561        {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
 562        {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
 563        {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
 564        {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
 565        {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
 566        {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
 567        {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
 568        {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
 569        {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
 570        {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
 571        {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
 572        {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
 573        {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
 574        {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 575        /*******/
 576        {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 577        {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
 578        {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
 579        {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
 580        {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
 581        /*******/
 582        {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
 583        {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
 584        {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
 585        {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
 586        {}
 587};
 588static const u8 om6802_sensor_init[][8] = {
 589        {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
 590        {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
 591        {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
 592        {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
 593/*      {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
 594        {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
 595                                        /* white balance & auto-exposure */
 596/*      {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
 597                                                         * set color mode */
 598/*      {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
 599                                                 * max AGC value in AE */
 600/*      {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
 601                                                         * preset AGC */
 602/*      {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
 603                                                 * preset brightness */
 604/*      {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
 605                                                         * preset contrast */
 606/*      {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
 607                                                         * preset gamma */
 608        {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
 609                                        /* luminance mode (0x4f = AE) */
 610        {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
 611                                                        /* preset shutter */
 612/*      {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
 613                                                         * auto frame rate */
 614/*      {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
 615
 616/*      {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
 617/*      {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
 618/*      {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
 619/*      {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
 620        {}
 621};
 622static const u8 ov7630_sensor_init[][8] = {
 623        {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
 624        {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
 625/* win: delay 20ms */
 626        {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 627        {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
 628/* win: delay 20ms */
 629        {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 630/* win: i2c_r from 00 to 80 */
 631        {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
 632        {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
 633/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
 634        0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
 635        {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
 636        {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
 637        {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
 638        {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
 639        {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
 640        {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
 641        {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
 642        {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
 643        {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
 644        {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
 645        {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
 646        {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
 647        {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
 648        {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
 649        {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
 650        {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
 651        {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
 652        {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
 653        {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
 654        {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
 655        {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
 656        {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
 657        {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
 658        {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
 659/* */
 660        {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 661        {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
 662/*fixme: + 0x12, 0x04*/
 663/*      {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},  * COMN
 664                                                         * set by setvflip */
 665        {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
 666        {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
 667        {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
 668/* */
 669/*      {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
 670/*      {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
 671/* */
 672        {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
 673/*      {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
 674        {}
 675};
 676
 677static const u8 ov7648_sensor_init[][8] = {
 678        {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
 679        {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},       /* reset */
 680        {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
 681        {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
 682        {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
 683        {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
 684        {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
 685        {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
 686        {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
 687        {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
 688        {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
 689        {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
 690        {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
 691        {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
 692        {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
 693        {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
 694        {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
 695        {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
 696        {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
 697        {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
 698        {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
 699
 700        {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
 701/*      {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
 702/*      {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
 703/*      {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
 704/*...*/
 705/*      {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
 706/*      {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10},   * COMN
 707                                                         * set by setvflip */
 708        {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
 709        {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
 710/*      {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
 711/*      {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},  * GAIN - def */
 712/*      {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10},  * B R - def: 80 */
 713/*...*/
 714        {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
 715/*      {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
 716/*      {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
 717/*      {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
 718/*      {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
 719/*      {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10},  * B R - def: 80 */
 720
 721        {}
 722};
 723
 724static const u8 ov7660_sensor_init[][8] = {
 725        {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
 726/*              (delay 20ms) */
 727        {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
 728                                                /* Outformat = rawRGB */
 729        {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
 730        {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
 731                                                /* GAIN BLUE RED VREF */
 732        {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
 733                                                /* COM 1 BAVE GEAVE AECHH */
 734        {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
 735        {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
 736        {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
 737                                                /* AECH CLKRC COM7 COM8 */
 738        {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
 739        {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
 740                                                /* HSTART HSTOP VSTRT VSTOP */
 741        {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
 742        {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
 743        {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
 744                                        /* BOS GBOS GROS ROS (BGGR offset) */
 745/*      {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
 746        {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
 747                                                /* AEW AEB VPT BBIAS */
 748        {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
 749                                                /* GbBIAS RSVD EXHCH EXHCL */
 750        {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
 751                                                /* RBIAS ADVFL ASDVFH YAVE */
 752        {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
 753                                                /* HSYST HSYEN HREF */
 754        {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
 755        {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
 756                                                /* ADC ACOM OFON TSLB */
 757        {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
 758                                                /* COM11 COM12 COM13 COM14 */
 759        {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
 760                                                /* EDGE COM15 COM16 COM17 */
 761        {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
 762        {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
 763        {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
 764        {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
 765        {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
 766        {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
 767        {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
 768        {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
 769        {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
 770        {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
 771                                                /* LCC1 LCC2 LCC3 LCC4 */
 772        {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
 773        {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
 774        {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
 775                                        /* band gap reference [0:3] DBLV */
 776        {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
 777        {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
 778        {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
 779        {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
 780        {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
 781        {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
 782        {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
 783        {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
 784        {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
 785        {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
 786        {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
 787/****** (some exchanges in the win trace) ******/
 788        {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
 789                                                /* bits[3..0]reserved */
 790        {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
 791        {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
 792                                                /* VREF vertical frame ctrl */
 793        {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
 794        {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
 795        {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
 796        {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
 797        {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
 798/*      {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
 799/****** (some exchanges in the win trace) ******/
 800        {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
 801        {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
 802        {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
 803        {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
 804/*      {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},  * RED */
 805/****** (some exchanges in the win trace) ******/
 806/******!! startsensor KO if changed !!****/
 807        {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
 808        {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
 809        {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
 810        {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
 811        {}
 812};
 813
 814static const u8 sp80708_sensor_init[][8] = {
 815        {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
 816        {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
 817        {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
 818        {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
 819        {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
 820        {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
 821        {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
 822        {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
 823        {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
 824        {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
 825        {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
 826        {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
 827        {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
 828        {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
 829        {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
 830        {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
 831        {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
 832        {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
 833        {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
 834        {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
 835        {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
 836        {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
 837        {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
 838        {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
 839        {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
 840        {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
 841        {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
 842        {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
 843        {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
 844        {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
 845        {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
 846        {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
 847        {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
 848        {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
 849        {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
 850        {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
 851        {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
 852        {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
 853        {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
 854        {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
 855        {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
 856        {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
 857        {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
 858        {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
 859        {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
 860        {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
 861        {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
 862        {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
 863        {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
 864        {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
 865        {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
 866        {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
 867        {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
 868        {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
 869        {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
 870        {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
 871        {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
 872        {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
 873        {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
 874        {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
 875        {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
 876        {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
 877        {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
 878        {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
 879        {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
 880        {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
 881        {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
 882        {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
 883        {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
 884        {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
 885        {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
 886        /********/
 887        {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
 888        {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
 889        {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
 890        {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
 891        {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
 892        {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
 893        {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
 894        {}
 895};
 896
 897/* read <len> bytes to gspca_dev->usb_buf */
 898static void reg_r(struct gspca_dev *gspca_dev,
 899                  u16 value, int len)
 900{
 901#ifdef GSPCA_DEBUG
 902        if (len > USB_BUF_SZ) {
 903                err("reg_r: buffer overflow");
 904                return;
 905        }
 906#endif
 907        usb_control_msg(gspca_dev->dev,
 908                        usb_rcvctrlpipe(gspca_dev->dev, 0),
 909                        0,
 910                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 911                        value, 0,
 912                        gspca_dev->usb_buf, len,
 913                        500);
 914        PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
 915}
 916
 917static void reg_w1(struct gspca_dev *gspca_dev,
 918                   u16 value,
 919                   u8 data)
 920{
 921        PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
 922        gspca_dev->usb_buf[0] = data;
 923        usb_control_msg(gspca_dev->dev,
 924                        usb_sndctrlpipe(gspca_dev->dev, 0),
 925                        0x08,
 926                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 927                        value,
 928                        0,
 929                        gspca_dev->usb_buf, 1,
 930                        500);
 931}
 932static void reg_w(struct gspca_dev *gspca_dev,
 933                          u16 value,
 934                          const u8 *buffer,
 935                          int len)
 936{
 937        PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
 938                value, buffer[0], buffer[1]);
 939#ifdef GSPCA_DEBUG
 940        if (len > USB_BUF_SZ) {
 941                err("reg_w: buffer overflow");
 942                return;
 943        }
 944#endif
 945        memcpy(gspca_dev->usb_buf, buffer, len);
 946        usb_control_msg(gspca_dev->dev,
 947                        usb_sndctrlpipe(gspca_dev->dev, 0),
 948                        0x08,
 949                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 950                        value, 0,
 951                        gspca_dev->usb_buf, len,
 952                        500);
 953}
 954
 955/* I2C write 1 byte */
 956static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
 957{
 958        struct sd *sd = (struct sd *) gspca_dev;
 959
 960        PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
 961        gspca_dev->usb_buf[0] = 0x81 | (2 << 4);        /* = a1 */
 962        gspca_dev->usb_buf[1] = sd->i2c_base;
 963        gspca_dev->usb_buf[2] = reg;
 964        gspca_dev->usb_buf[3] = val;
 965        gspca_dev->usb_buf[4] = 0;
 966        gspca_dev->usb_buf[5] = 0;
 967        gspca_dev->usb_buf[6] = 0;
 968        gspca_dev->usb_buf[7] = 0x10;
 969        usb_control_msg(gspca_dev->dev,
 970                        usb_sndctrlpipe(gspca_dev->dev, 0),
 971                        0x08,
 972                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 973                        0x08,                   /* value = i2c */
 974                        0,
 975                        gspca_dev->usb_buf, 8,
 976                        500);
 977}
 978
 979/* I2C write 8 bytes */
 980static void i2c_w8(struct gspca_dev *gspca_dev,
 981                   const u8 *buffer)
 982{
 983        memcpy(gspca_dev->usb_buf, buffer, 8);
 984        usb_control_msg(gspca_dev->dev,
 985                        usb_sndctrlpipe(gspca_dev->dev, 0),
 986                        0x08,
 987                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 988                        0x08, 0,                /* value, index */
 989                        gspca_dev->usb_buf, 8,
 990                        500);
 991        msleep(2);
 992}
 993
 994/* read 5 bytes in gspca_dev->usb_buf */
 995static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
 996{
 997        struct sd *sd = (struct sd *) gspca_dev;
 998        u8 mode[8];
 999
1000        mode[0] = 0x81 | 0x10;
1001        mode[1] = sd->i2c_base;
1002        mode[2] = reg;
1003        mode[3] = 0;
1004        mode[4] = 0;
1005        mode[5] = 0;
1006        mode[6] = 0;
1007        mode[7] = 0x10;
1008        i2c_w8(gspca_dev, mode);
1009        msleep(2);
1010        mode[0] = 0x81 | (5 << 4) | 0x02;
1011        mode[2] = 0;
1012        i2c_w8(gspca_dev, mode);
1013        msleep(2);
1014        reg_r(gspca_dev, 0x0a, 5);
1015}
1016
1017static int hv7131r_probe(struct gspca_dev *gspca_dev)
1018{
1019        i2c_w1(gspca_dev, 0x02, 0);                     /* sensor wakeup */
1020        msleep(10);
1021        reg_w1(gspca_dev, 0x02, 0x66);                  /* Gpio on */
1022        msleep(10);
1023        i2c_r5(gspca_dev, 0);                           /* read sensor id */
1024        if (gspca_dev->usb_buf[0] == 0x02
1025            && gspca_dev->usb_buf[1] == 0x09
1026            && gspca_dev->usb_buf[2] == 0x01
1027            && gspca_dev->usb_buf[3] == 0x00
1028            && gspca_dev->usb_buf[4] == 0x00) {
1029                PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
1030                return 0;
1031        }
1032        PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
1033                gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1034                gspca_dev->usb_buf[2]);
1035        PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1036        return -ENODEV;
1037}
1038
1039static void mi0360_probe(struct gspca_dev *gspca_dev)
1040{
1041        struct sd *sd = (struct sd *) gspca_dev;
1042        int i, j;
1043        u16 val = 0;
1044        static const u8 probe_tb[][4][8] = {
1045            {                                   /* mi0360 */
1046                {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1047                {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1048                {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1049                {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1050            },
1051            {                                   /* mt9v111 */
1052                {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1053                {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1054                {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1055                {}
1056            },
1057        };
1058
1059        for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1060                reg_w1(gspca_dev, 0x17, 0x62);
1061                reg_w1(gspca_dev, 0x01, 0x08);
1062                for (j = 0; j < 3; j++)
1063                        i2c_w8(gspca_dev, probe_tb[i][j]);
1064                msleep(2);
1065                reg_r(gspca_dev, 0x0a, 5);
1066                val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1067                if (probe_tb[i][3][0] != 0)
1068                        i2c_w8(gspca_dev, probe_tb[i][3]);
1069                reg_w1(gspca_dev, 0x01, 0x29);
1070                reg_w1(gspca_dev, 0x17, 0x42);
1071                if (val != 0xffff)
1072                        break;
1073        }
1074        switch (val) {
1075        case 0x823a:
1076                PDEBUG(D_PROBE, "Sensor mt9v111");
1077                sd->sensor = SENSOR_MT9V111;
1078                sd->i2c_base = 0x5c;
1079                break;
1080        case 0x8243:
1081                PDEBUG(D_PROBE, "Sensor mi0360");
1082                break;
1083        default:
1084                PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1085                break;
1086        }
1087}
1088
1089static int configure_gpio(struct gspca_dev *gspca_dev,
1090                          const u8 *sn9c1xx)
1091{
1092        struct sd *sd = (struct sd *) gspca_dev;
1093        const u8 *reg9a;
1094        static const u8 reg9a_def[] =
1095                {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
1096        static const u8 reg9a_spec[] =
1097                {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
1098        static const u8 regd4[] = {0x60, 0x00, 0x00};
1099
1100        reg_w1(gspca_dev, 0xf1, 0x00);
1101        reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1102
1103        /* configure gpio */
1104        reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1105        reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1106        reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);      /* jfm len was 3 */
1107        switch (sd->sensor) {
1108        case SENSOR_OV7660:
1109        case SENSOR_SP80708:
1110                reg9a = reg9a_spec;
1111                break;
1112        default:
1113                reg9a = reg9a_def;
1114                break;
1115        }
1116        reg_w(gspca_dev, 0x9a, reg9a, 6);
1117
1118        reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
1119
1120        reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
1121
1122        switch (sd->sensor) {
1123        case SENSOR_MT9V111:
1124                reg_w1(gspca_dev, 0x01, 0x61);
1125                reg_w1(gspca_dev, 0x17, 0x61);
1126                reg_w1(gspca_dev, 0x01, 0x60);
1127                reg_w1(gspca_dev, 0x01, 0x40);
1128                break;
1129        case SENSOR_OM6802:
1130                reg_w1(gspca_dev, 0x02, 0x71);
1131                reg_w1(gspca_dev, 0x01, 0x42);
1132                reg_w1(gspca_dev, 0x17, 0x64);
1133                reg_w1(gspca_dev, 0x01, 0x42);
1134                break;
1135        case SENSOR_OV7630:
1136                reg_w1(gspca_dev, 0x01, 0x61);
1137                reg_w1(gspca_dev, 0x17, 0xe2);
1138                reg_w1(gspca_dev, 0x01, 0x60);
1139                reg_w1(gspca_dev, 0x01, 0x40);
1140                break;
1141        case SENSOR_OV7648:
1142                reg_w1(gspca_dev, 0x01, 0x63);
1143                reg_w1(gspca_dev, 0x17, 0x20);
1144                reg_w1(gspca_dev, 0x01, 0x62);
1145                reg_w1(gspca_dev, 0x01, 0x42);
1146                break;
1147        case SENSOR_OV7660:
1148        case SENSOR_SP80708:
1149                reg_w1(gspca_dev, 0x01, 0x63);
1150                reg_w1(gspca_dev, 0x17, 0x20);
1151                reg_w1(gspca_dev, 0x01, 0x62);
1152                reg_w1(gspca_dev, 0x01, 0x42);
1153                msleep(100);
1154                reg_w1(gspca_dev, 0x02, 0x62);
1155                break;
1156/*      case SENSOR_HV7131R: */
1157/*      case SENSOR_MI0360: */
1158/*      case SENSOR_MO4000: */
1159        default:
1160                reg_w1(gspca_dev, 0x01, 0x43);
1161                reg_w1(gspca_dev, 0x17, 0x61);
1162                reg_w1(gspca_dev, 0x01, 0x42);
1163                if (sd->sensor == SENSOR_HV7131R) {
1164                        if (hv7131r_probe(gspca_dev) < 0)
1165                                return -ENODEV;
1166                }
1167                break;
1168        }
1169        return 0;
1170}
1171
1172static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1173{
1174        int i = 0;
1175        static const u8 SetSensorClk[] =        /* 0x08 Mclk */
1176                { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1177
1178        while (hv7131r_sensor_init[i][0]) {
1179                i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
1180                i++;
1181        }
1182        i2c_w8(gspca_dev, SetSensorClk);
1183}
1184
1185static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1186{
1187        int i = 0;
1188
1189        while (mi0360_sensor_init[i][0]) {
1190                i2c_w8(gspca_dev, mi0360_sensor_init[i]);
1191                i++;
1192        }
1193}
1194
1195static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1196{
1197        int i = 0;
1198
1199        while (mo4000_sensor_init[i][0]) {
1200                i2c_w8(gspca_dev, mo4000_sensor_init[i]);
1201                i++;
1202        }
1203}
1204
1205static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1206{
1207        int i = 0;
1208
1209        i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1210        i++;
1211        msleep(20);
1212        while (mt9v111_sensor_init[i][0]) {
1213                i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1214                i++;
1215        }
1216}
1217
1218static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1219{
1220        int i = 0;
1221
1222        while (om6802_sensor_init[i][0]) {
1223                i2c_w8(gspca_dev, om6802_sensor_init[i]);
1224                i++;
1225        }
1226}
1227
1228static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1229{
1230        int i = 0;
1231
1232        i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 76 01 */
1233        i++;
1234        i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 c8 (RGB+SRST) */
1235        i++;
1236        msleep(20);
1237        i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 48 */
1238        i++;
1239        i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 c8 */
1240        i++;
1241        msleep(20);
1242        i2c_w8(gspca_dev, ov7630_sensor_init[i]);       /* 12 48 */
1243        i++;
1244/*jfm:win i2c_r from 00 to 80*/
1245
1246        while (ov7630_sensor_init[i][0]) {
1247                i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1248                i++;
1249        }
1250}
1251
1252static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1253{
1254        int i = 0;
1255
1256        i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1257        i++;
1258/* win: dble reset */
1259        i2c_w8(gspca_dev, ov7648_sensor_init[i]);       /* reset */
1260        i++;
1261        msleep(20);
1262/* win: i2c reg read 00..7f */
1263        while (ov7648_sensor_init[i][0]) {
1264                i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1265                i++;
1266        }
1267}
1268
1269static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1270{
1271        int i = 0;
1272
1273        i2c_w8(gspca_dev, ov7660_sensor_init[i]);       /* reset SCCB */
1274        i++;
1275        msleep(20);
1276        while (ov7660_sensor_init[i][0]) {
1277                i2c_w8(gspca_dev, ov7660_sensor_init[i]);
1278                i++;
1279        }
1280}
1281
1282static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1283{
1284        int i = 0;
1285
1286        i2c_w8(gspca_dev, sp80708_sensor_init[i]);      /* reset SCCB */
1287        i++;
1288        msleep(20);
1289        while (sp80708_sensor_init[i][0]) {
1290                i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1291                i++;
1292        }
1293}
1294
1295/* this function is called at probe time */
1296static int sd_config(struct gspca_dev *gspca_dev,
1297                        const struct usb_device_id *id)
1298{
1299        struct sd *sd = (struct sd *) gspca_dev;
1300        struct cam *cam;
1301
1302        cam = &gspca_dev->cam;
1303        cam->cam_mode = vga_mode;
1304        cam->nmodes = ARRAY_SIZE(vga_mode);
1305        cam->npkt = 24;                 /* 24 packets per ISOC message */
1306
1307        sd->bridge = id->driver_info >> 16;
1308        sd->sensor = id->driver_info >> 8;
1309        sd->i2c_base = id->driver_info;
1310
1311        sd->brightness = BRIGHTNESS_DEF;
1312        sd->contrast = CONTRAST_DEF;
1313        sd->colors = COLOR_DEF;
1314        sd->blue = BLUE_BALANCE_DEF;
1315        sd->red = RED_BALANCE_DEF;
1316        sd->gamma = GAMMA_DEF;
1317        sd->autogain = AUTOGAIN_DEF;
1318        sd->ag_cnt = -1;
1319        sd->vflip = VFLIP_DEF;
1320        sd->infrared = INFRARED_DEF;
1321        sd->freq = FREQ_DEF;
1322        sd->quality = QUALITY_DEF;
1323        sd->jpegqual = 80;
1324
1325        gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1326        return 0;
1327}
1328
1329/* this function is called at probe and resume time */
1330static int sd_init(struct gspca_dev *gspca_dev)
1331{
1332        struct sd *sd = (struct sd *) gspca_dev;
1333        u8 regGpio[] = { 0x29, 0x74 };
1334        u8 regF1;
1335
1336        /* setup a selector by bridge */
1337        reg_w1(gspca_dev, 0xf1, 0x01);
1338        reg_r(gspca_dev, 0x00, 1);
1339        reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1340        reg_r(gspca_dev, 0x00, 1);              /* get sonix chip id */
1341        regF1 = gspca_dev->usb_buf[0];
1342        PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1343        switch (sd->bridge) {
1344        case BRIDGE_SN9C102P:
1345                if (regF1 != 0x11)
1346                        return -ENODEV;
1347                reg_w1(gspca_dev, 0x02, regGpio[1]);
1348                break;
1349        case BRIDGE_SN9C105:
1350                if (regF1 != 0x11)
1351                        return -ENODEV;
1352                if (sd->sensor == SENSOR_MI0360)
1353                        mi0360_probe(gspca_dev);
1354                reg_w(gspca_dev, 0x01, regGpio, 2);
1355                break;
1356        case BRIDGE_SN9C120:
1357                if (regF1 != 0x12)
1358                        return -ENODEV;
1359                if (sd->sensor == SENSOR_MI0360)
1360                        mi0360_probe(gspca_dev);
1361                regGpio[1] = 0x70;
1362                reg_w(gspca_dev, 0x01, regGpio, 2);
1363                break;
1364        default:
1365/*      case BRIDGE_SN9C110: */
1366/*      case BRIDGE_SN9C325: */
1367                if (regF1 != 0x12)
1368                        return -ENODEV;
1369                reg_w1(gspca_dev, 0x02, 0x62);
1370                break;
1371        }
1372
1373        reg_w1(gspca_dev, 0xf1, 0x01);
1374
1375        return 0;
1376}
1377
1378static u32 setexposure(struct gspca_dev *gspca_dev,
1379                        u32 expo)
1380{
1381        struct sd *sd = (struct sd *) gspca_dev;
1382
1383        switch (sd->sensor) {
1384        case SENSOR_HV7131R: {
1385                u8 Expodoit[] =
1386                        { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1387
1388                Expodoit[3] = expo >> 16;
1389                Expodoit[4] = expo >> 8;
1390                Expodoit[5] = expo;
1391                i2c_w8(gspca_dev, Expodoit);
1392                break;
1393            }
1394        case SENSOR_MI0360: {
1395                u8 expoMi[] =           /* exposure 0x0635 -> 4 fp/s 0x10 */
1396                        { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1397                static const u8 doit[] =                /* update sensor */
1398                        { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1399                static const u8 sensorgo[] =            /* sensor on */
1400                        { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1401
1402                if (expo > 0x0635)
1403                        expo = 0x0635;
1404                else if (expo < 0x0001)
1405                        expo = 0x0001;
1406                expoMi[3] = expo >> 8;
1407                expoMi[4] = expo;
1408                i2c_w8(gspca_dev, expoMi);
1409                i2c_w8(gspca_dev, doit);
1410                i2c_w8(gspca_dev, sensorgo);
1411                break;
1412            }
1413        case SENSOR_MO4000: {
1414                u8 expoMof[] =
1415                        { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1416                u8 expoMo10[] =
1417                        { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1418                static const u8 gainMo[] =
1419                        { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1420
1421                if (expo > 0x1fff)
1422                        expo = 0x1fff;
1423                else if (expo < 0x0001)
1424                        expo = 0x0001;
1425                expoMof[3] = (expo & 0x03fc) >> 2;
1426                i2c_w8(gspca_dev, expoMof);
1427                expoMo10[3] = ((expo & 0x1c00) >> 10)
1428                                | ((expo & 0x0003) << 4);
1429                i2c_w8(gspca_dev, expoMo10);
1430                i2c_w8(gspca_dev, gainMo);
1431                PDEBUG(D_FRAM, "set exposure %d",
1432                        ((expoMo10[3] & 0x07) << 10)
1433                        | (expoMof[3] << 2)
1434                        | ((expoMo10[3] & 0x30) >> 4));
1435                break;
1436            }
1437        case SENSOR_MT9V111: {
1438                u8 expo_c1[] =
1439                        { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1440
1441                if (expo > 0x0280)
1442                        expo = 0x0280;
1443                else if (expo < 0x0040)
1444                        expo = 0x0040;
1445                expo_c1[3] = expo >> 8;
1446                expo_c1[4] = expo;
1447                i2c_w8(gspca_dev, expo_c1);
1448                break;
1449            }
1450        case SENSOR_OM6802: {
1451                u8 gainOm[] =
1452                        { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1453
1454                if (expo > 0x03ff)
1455                        expo = 0x03ff;
1456                 if (expo < 0x0001)
1457                        expo = 0x0001;
1458                gainOm[3] = expo >> 2;
1459                i2c_w8(gspca_dev, gainOm);
1460                reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1461                PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
1462                break;
1463            }
1464        }
1465        return expo;
1466}
1467
1468static void setbrightness(struct gspca_dev *gspca_dev)
1469{
1470        struct sd *sd = (struct sd *) gspca_dev;
1471        unsigned int expo;
1472        u8 k2;
1473
1474        k2 = ((int) sd->brightness - 0x8000) >> 10;
1475        switch (sd->sensor) {
1476        case SENSOR_HV7131R:
1477                expo = sd->brightness << 4;
1478                if (expo > 0x002dc6c0)
1479                        expo = 0x002dc6c0;
1480                else if (expo < 0x02a0)
1481                        expo = 0x02a0;
1482                sd->exposure = setexposure(gspca_dev, expo);
1483                break;
1484        case SENSOR_MI0360:
1485        case SENSOR_MO4000:
1486                expo = sd->brightness >> 4;
1487                sd->exposure = setexposure(gspca_dev, expo);
1488                break;
1489        case SENSOR_MT9V111:
1490                expo = sd->brightness >> 8;
1491                sd->exposure = setexposure(gspca_dev, expo);
1492                break;
1493        case SENSOR_OM6802:
1494                expo = sd->brightness >> 6;
1495                sd->exposure = setexposure(gspca_dev, expo);
1496                k2 = sd->brightness >> 11;
1497                break;
1498        }
1499
1500        if (sd->sensor != SENSOR_MT9V111)
1501                reg_w1(gspca_dev, 0x96, k2);    /* color matrix Y offset */
1502}
1503
1504static void setcontrast(struct gspca_dev *gspca_dev)
1505{
1506        struct sd *sd = (struct sd *) gspca_dev;
1507        u8 k2;
1508        u8 contrast[6];
1509
1510        k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10;   /* 10..40 */
1511        contrast[0] = (k2 + 1) / 2;             /* red */
1512        contrast[1] = 0;
1513        contrast[2] = k2;                       /* green */
1514        contrast[3] = 0;
1515        contrast[4] = (k2 + 1) / 5;             /* blue */
1516        contrast[5] = 0;
1517        reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
1518}
1519
1520static void setcolors(struct gspca_dev *gspca_dev)
1521{
1522        struct sd *sd = (struct sd *) gspca_dev;
1523        int i, v;
1524        u8 reg8a[12];                   /* U & V gains */
1525        static s16 uv[6] = {            /* same as reg84 in signed decimal */
1526                -24, -38, 64,           /* UR UG UB */
1527                 62, -51, -9            /* VR VG VB */
1528        };
1529        for (i = 0; i < 6; i++) {
1530                v = uv[i] * sd->colors / COLOR_DEF;
1531                reg8a[i * 2] = v;
1532                reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1533        }
1534        reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
1535}
1536
1537static void setredblue(struct gspca_dev *gspca_dev)
1538{
1539        struct sd *sd = (struct sd *) gspca_dev;
1540
1541        reg_w1(gspca_dev, 0x05, sd->red);
1542/*      reg_w1(gspca_dev, 0x07, 32); */
1543        reg_w1(gspca_dev, 0x06, sd->blue);
1544}
1545
1546static void setgamma(struct gspca_dev *gspca_dev)
1547{
1548        struct sd *sd = (struct sd *) gspca_dev;
1549        int i;
1550        u8 gamma[17];
1551        const u8 *gamma_base;
1552        static const u8 delta[17] = {
1553                0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1554                0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1555        };
1556
1557        switch (sd->sensor) {
1558        case SENSOR_HV7131R:
1559        case SENSOR_MT9V111:
1560                gamma_base = gamma_spec_1;
1561                break;
1562        case SENSOR_SP80708:
1563                gamma_base = gamma_spec_2;
1564                break;
1565        default:
1566                gamma_base = gamma_def;
1567                break;
1568        }
1569
1570        for (i = 0; i < sizeof gamma; i++)
1571                gamma[i] = gamma_base[i]
1572                        + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1573        reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1574}
1575
1576static void setautogain(struct gspca_dev *gspca_dev)
1577{
1578        struct sd *sd = (struct sd *) gspca_dev;
1579
1580        if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1581                return;
1582        switch (sd->sensor) {
1583        case SENSOR_OV7630:
1584        case SENSOR_OV7648: {
1585                u8 comb;
1586
1587                if (sd->sensor == SENSOR_OV7630)
1588                        comb = 0xc0;
1589                else
1590                        comb = 0xa0;
1591                if (sd->autogain)
1592                        comb |= 0x03;
1593                i2c_w1(&sd->gspca_dev, 0x13, comb);
1594                return;
1595            }
1596        }
1597        if (sd->autogain)
1598                sd->ag_cnt = AG_CNT_START;
1599        else
1600                sd->ag_cnt = -1;
1601}
1602
1603/* ov7630/ov7648 only */
1604static void setvflip(struct sd *sd)
1605{
1606        u8 comn;
1607
1608        if (sd->sensor == SENSOR_OV7630) {
1609                comn = 0x02;
1610                if (!sd->vflip)
1611                        comn |= 0x80;
1612        } else {
1613                comn = 0x06;
1614                if (sd->vflip)
1615                        comn |= 0x80;
1616        }
1617        i2c_w1(&sd->gspca_dev, 0x75, comn);
1618}
1619
1620static void setinfrared(struct sd *sd)
1621{
1622        if (sd->gspca_dev.ctrl_dis & (1 << INFRARED_IDX))
1623                return;
1624/*fixme: different sequence for StarCam Clip and StarCam 370i */
1625/* Clip */
1626        i2c_w1(&sd->gspca_dev, 0x02,                    /* gpio */
1627                sd->infrared ? 0x66 : 0x64);
1628}
1629
1630static void setfreq(struct gspca_dev *gspca_dev)
1631{
1632        struct sd *sd = (struct sd *) gspca_dev;
1633
1634        if (gspca_dev->ctrl_dis & (1 << FREQ_IDX))
1635                return;
1636        if (sd->sensor == SENSOR_OV7660) {
1637                u8 com8;
1638
1639                com8 = 0xdf;            /* auto gain/wb/expo */
1640                switch (sd->freq) {
1641                case 0: /* Banding filter disabled */
1642                        i2c_w1(gspca_dev, 0x13, com8 | 0x20);
1643                        break;
1644                case 1: /* 50 hz */
1645                        i2c_w1(gspca_dev, 0x13, com8);
1646                        i2c_w1(gspca_dev, 0x3b, 0x0a);
1647                        break;
1648                case 2: /* 60 hz */
1649                        i2c_w1(gspca_dev, 0x13, com8);
1650                        i2c_w1(gspca_dev, 0x3b, 0x02);
1651                        break;
1652                }
1653        } else {
1654                u8 reg2a = 0, reg2b = 0, reg2d = 0;
1655
1656                /* Get reg2a / reg2d base values */
1657                switch (sd->sensor) {
1658                case SENSOR_OV7630:
1659                        reg2a = 0x08;
1660                        reg2d = 0x01;
1661                        break;
1662                case SENSOR_OV7648:
1663                        reg2a = 0x11;
1664                        reg2d = 0x81;
1665                        break;
1666                }
1667
1668                switch (sd->freq) {
1669                case 0: /* Banding filter disabled */
1670                        break;
1671                case 1: /* 50 hz (filter on and framerate adj) */
1672                        reg2a |= 0x80;
1673                        reg2b = 0xac;
1674                        reg2d |= 0x04;
1675                        break;
1676                case 2: /* 60 hz (filter on, no framerate adj) */
1677                        reg2a |= 0x80;
1678                        reg2d |= 0x04;
1679                        break;
1680                }
1681                i2c_w1(gspca_dev, 0x2a, reg2a);
1682                i2c_w1(gspca_dev, 0x2b, reg2b);
1683                i2c_w1(gspca_dev, 0x2d, reg2d);
1684        }
1685}
1686
1687static void setjpegqual(struct gspca_dev *gspca_dev)
1688{
1689        struct sd *sd = (struct sd *) gspca_dev;
1690        int i, sc;
1691
1692        if (sd->jpegqual < 50)
1693                sc = 5000 / sd->jpegqual;
1694        else
1695                sc = 200 - sd->jpegqual * 2;
1696#if USB_BUF_SZ < 64
1697#error "No room enough in usb_buf for quantization table"
1698#endif
1699        for (i = 0; i < 64; i++)
1700                gspca_dev->usb_buf[i] =
1701                        (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
1702        usb_control_msg(gspca_dev->dev,
1703                        usb_sndctrlpipe(gspca_dev->dev, 0),
1704                        0x08,
1705                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1706                        0x0100, 0,
1707                        gspca_dev->usb_buf, 64,
1708                        500);
1709        for (i = 0; i < 64; i++)
1710                gspca_dev->usb_buf[i] =
1711                        (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
1712        usb_control_msg(gspca_dev->dev,
1713                        usb_sndctrlpipe(gspca_dev->dev, 0),
1714                        0x08,
1715                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1716                        0x0140, 0,
1717                        gspca_dev->usb_buf, 64,
1718                        500);
1719
1720        sd->reg18 ^= 0x40;
1721        reg_w1(gspca_dev, 0x18, sd->reg18);
1722}
1723
1724/* -- start the camera -- */
1725static int sd_start(struct gspca_dev *gspca_dev)
1726{
1727        struct sd *sd = (struct sd *) gspca_dev;
1728        int i;
1729        u8 reg1, reg17;
1730        const u8 *sn9c1xx;
1731        int mode;
1732        static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1733        static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1734        static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };      /* MI0360 */
1735        static const u8 CE_ov76xx[] =
1736                                { 0x32, 0xdd, 0x32, 0xdd };
1737
1738        /* create the JPEG header */
1739        sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
1740        if (!sd->jpeg_hdr)
1741                return -ENOMEM;
1742        jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
1743                        0x21);          /* JPEG 422 */
1744        jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1745
1746        sn9c1xx = sn_tb[(int) sd->sensor];
1747        configure_gpio(gspca_dev, sn9c1xx);
1748
1749        reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1750        reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1751        reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1752        reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1753        reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1754        reg_w1(gspca_dev, 0xd2, 0x6a);          /* DC29 */
1755        reg_w1(gspca_dev, 0xd3, 0x50);
1756        reg_w1(gspca_dev, 0xc6, 0x00);
1757        reg_w1(gspca_dev, 0xc7, 0x00);
1758        reg_w1(gspca_dev, 0xc8, 0x50);
1759        reg_w1(gspca_dev, 0xc9, 0x3c);
1760        reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1761        switch (sd->sensor) {
1762        case SENSOR_MT9V111:
1763                reg17 = 0xe0;
1764                break;
1765        case SENSOR_OV7630:
1766                reg17 = 0xe2;
1767                break;
1768        case SENSOR_OV7648:
1769                reg17 = 0x20;
1770                break;
1771        case SENSOR_OV7660:
1772                reg17 = 0xa0;
1773                break;
1774        default:
1775                reg17 = 0x60;
1776                break;
1777        }
1778        reg_w1(gspca_dev, 0x17, reg17);
1779/* set reg1 was here */
1780        reg_w1(gspca_dev, 0x05, sn9c1xx[5]);    /* red */
1781        reg_w1(gspca_dev, 0x07, sn9c1xx[7]);    /* green */
1782        reg_w1(gspca_dev, 0x06, sn9c1xx[6]);    /* blue */
1783        reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1784
1785        setgamma(gspca_dev);
1786
1787        for (i = 0; i < 8; i++)
1788                reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1789        switch (sd->sensor) {
1790        case SENSOR_MT9V111:
1791                reg_w1(gspca_dev, 0x9a, 0x07);
1792                reg_w1(gspca_dev, 0x99, 0x59);
1793                break;
1794        case SENSOR_OV7648:
1795                reg_w1(gspca_dev, 0x9a, 0x0a);
1796                reg_w1(gspca_dev, 0x99, 0x60);
1797                break;
1798        case SENSOR_OV7660:
1799        case SENSOR_SP80708:
1800                reg_w1(gspca_dev, 0x9a, 0x05);
1801                reg_w1(gspca_dev, 0x99, 0x59);
1802                break;
1803        default:
1804                reg_w1(gspca_dev, 0x9a, 0x08);
1805                reg_w1(gspca_dev, 0x99, 0x59);
1806                break;
1807        }
1808
1809        mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1810        if (mode)
1811                reg1 = 0x46;    /* 320x240: clk 48Mhz, video trf enable */
1812        else
1813                reg1 = 0x06;    /* 640x480: clk 24Mhz, video trf enable */
1814        reg17 = 0x61;           /* 0x:20: enable sensor clock */
1815        switch (sd->sensor) {
1816        case SENSOR_HV7131R:
1817                hv7131R_InitSensor(gspca_dev);
1818                break;
1819        case SENSOR_MI0360:
1820                mi0360_InitSensor(gspca_dev);
1821                break;
1822        case SENSOR_MO4000:
1823                mo4000_InitSensor(gspca_dev);
1824                if (mode) {
1825/*                      reg1 = 0x46;     * 320 clk 48Mhz 60fp/s */
1826                        reg1 = 0x06;    /* clk 24Mz */
1827                } else {
1828                        reg17 = 0x22;   /* 640 MCKSIZE */
1829/*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
1830                }
1831                break;
1832        case SENSOR_MT9V111:
1833                mt9v111_InitSensor(gspca_dev);
1834                if (mode) {
1835                        reg1 = 0x04;    /* 320 clk 48Mhz */
1836                } else {
1837/*                      reg1 = 0x06;     * 640 clk 24Mz (done) */
1838                        reg17 = 0xc2;
1839                }
1840                break;
1841        case SENSOR_OM6802:
1842                om6802_InitSensor(gspca_dev);
1843                reg17 = 0x64;           /* 640 MCKSIZE */
1844                break;
1845        case SENSOR_OV7630:
1846                ov7630_InitSensor(gspca_dev);
1847                setvflip(sd);
1848                reg17 = 0xe2;
1849                reg1 = 0x44;
1850                break;
1851        case SENSOR_OV7648:
1852                ov7648_InitSensor(gspca_dev);
1853                reg17 = 0x21;
1854/*              reg1 = 0x42;             * 42 - 46? */
1855                break;
1856        case SENSOR_OV7660:
1857                ov7660_InitSensor(gspca_dev);
1858                if (sd->bridge == BRIDGE_SN9C120) {
1859                        if (mode) {             /* 320x240 - 160x120 */
1860                                reg17 = 0xa2;
1861                                reg1 = 0x44;    /* 48 Mhz, video trf eneble */
1862                        }
1863                } else {
1864                        reg17 = 0x22;
1865                        reg1 = 0x06;    /* 24 Mhz, video trf eneble
1866                                         * inverse power down */
1867                }
1868                break;
1869        default:
1870/*      case SENSOR_SP80708: */
1871                sp80708_InitSensor(gspca_dev);
1872                if (mode) {
1873/*??                    reg1 = 0x04;     * 320 clk 48Mhz */
1874                } else {
1875                        reg1 = 0x46;     /* 640 clk 48Mz */
1876                        reg17 = 0xa2;
1877                }
1878                break;
1879        }
1880        reg_w(gspca_dev, 0xc0, C0, 6);
1881        reg_w(gspca_dev, 0xca, CA, 4);
1882        switch (sd->sensor) {
1883        case SENSOR_OV7630:
1884        case SENSOR_OV7648:
1885        case SENSOR_OV7660:
1886                reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1887                break;
1888        default:
1889                reg_w(gspca_dev, 0xce, CE, 4);
1890                                        /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1891                break;
1892        }
1893
1894        /* here change size mode 0 -> VGA; 1 -> CIF */
1895        sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
1896        reg_w1(gspca_dev, 0x18, sd->reg18);
1897        setjpegqual(gspca_dev);
1898
1899        reg_w1(gspca_dev, 0x17, reg17);
1900        reg_w1(gspca_dev, 0x01, reg1);
1901        switch (sd->sensor) {
1902        case SENSOR_OV7630:
1903                setvflip(sd);
1904                break;
1905        }
1906        setbrightness(gspca_dev);
1907        setcontrast(gspca_dev);
1908        setautogain(gspca_dev);
1909        setfreq(gspca_dev);
1910        return 0;
1911}
1912
1913static void sd_stopN(struct gspca_dev *gspca_dev)
1914{
1915        struct sd *sd = (struct sd *) gspca_dev;
1916        static const u8 stophv7131[] =
1917                { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1918        static const u8 stopmi0360[] =
1919                { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1920        static const u8 stopov7648[] =
1921                { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1922        u8 data;
1923        const u8 *sn9c1xx;
1924
1925        data = 0x0b;
1926        switch (sd->sensor) {
1927        case SENSOR_HV7131R:
1928                i2c_w8(gspca_dev, stophv7131);
1929                data = 0x2b;
1930                break;
1931        case SENSOR_MI0360:
1932                i2c_w8(gspca_dev, stopmi0360);
1933                data = 0x29;
1934                break;
1935        case SENSOR_OV7648:
1936                i2c_w8(gspca_dev, stopov7648);
1937                /* fall thru */
1938        case SENSOR_MT9V111:
1939        case SENSOR_OV7630:
1940                data = 0x29;
1941                break;
1942        default:
1943/*      case SENSOR_MO4000: */
1944/*      case SENSOR_OV7660: */
1945                break;
1946        }
1947        sn9c1xx = sn_tb[(int) sd->sensor];
1948        reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1949        reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1950        reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1951        reg_w1(gspca_dev, 0x01, data);
1952        reg_w1(gspca_dev, 0xf1, 0x00);
1953}
1954
1955static void sd_stop0(struct gspca_dev *gspca_dev)
1956{
1957        struct sd *sd = (struct sd *) gspca_dev;
1958
1959        kfree(sd->jpeg_hdr);
1960}
1961
1962static void do_autogain(struct gspca_dev *gspca_dev)
1963{
1964        struct sd *sd = (struct sd *) gspca_dev;
1965        int delta;
1966        int expotimes;
1967        u8 luma_mean = 130;
1968        u8 luma_delta = 20;
1969
1970        /* Thanks S., without your advice, autobright should not work :) */
1971        if (sd->ag_cnt < 0)
1972                return;
1973        if (--sd->ag_cnt >= 0)
1974                return;
1975        sd->ag_cnt = AG_CNT_START;
1976
1977        delta = atomic_read(&sd->avg_lum);
1978        PDEBUG(D_FRAM, "mean lum %d", delta);
1979        if (delta < luma_mean - luma_delta ||
1980            delta > luma_mean + luma_delta) {
1981                switch (sd->sensor) {
1982                case SENSOR_HV7131R:
1983                        expotimes = sd->exposure >> 8;
1984                        expotimes += (luma_mean - delta) >> 4;
1985                        if (expotimes < 0)
1986                                expotimes = 0;
1987                        sd->exposure = setexposure(gspca_dev,
1988                                        (unsigned int) (expotimes << 8));
1989                        break;
1990                default:
1991/*              case SENSOR_MO4000: */
1992/*              case SENSOR_MI0360: */
1993/*              case SENSOR_MT9V111: */
1994/*              case SENSOR_OM6802: */
1995                        expotimes = sd->exposure;
1996                        expotimes += (luma_mean - delta) >> 6;
1997                        if (expotimes < 0)
1998                                expotimes = 0;
1999                        sd->exposure = setexposure(gspca_dev,
2000                                                   (unsigned int) expotimes);
2001                        setredblue(gspca_dev);
2002                        break;
2003                }
2004        }
2005}
2006
2007/* scan the URB packets */
2008/* This function is run at interrupt level. */
2009static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2010                        struct gspca_frame *frame,      /* target */
2011                        u8 *data,                       /* isoc packet */
2012                        int len)                        /* iso packet length */
2013{
2014        struct sd *sd = (struct sd *) gspca_dev;
2015        int sof, avg_lum;
2016
2017        sof = len - 64;
2018        if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
2019
2020                /* end of frame */
2021                gspca_frame_add(gspca_dev, LAST_PACKET,
2022                                frame, data, sof + 2);
2023                if (sd->ag_cnt < 0)
2024                        return;
2025/* w1 w2 w3 */
2026/* w4 w5 w6 */
2027/* w7 w8 */
2028/* w4 */
2029                avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
2030/* w6 */
2031                avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
2032/* w2 */
2033                avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
2034/* w8 */
2035                avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
2036/* w5 */
2037                avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
2038                avg_lum >>= 4;
2039                atomic_set(&sd->avg_lum, avg_lum);
2040                return;
2041        }
2042        if (gspca_dev->last_packet_type == LAST_PACKET) {
2043
2044                /* put the JPEG 422 header */
2045                gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
2046                        sd->jpeg_hdr, JPEG_HDR_SZ);
2047        }
2048        gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
2049}
2050
2051static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
2052{
2053        struct sd *sd = (struct sd *) gspca_dev;
2054
2055        sd->brightness = val;
2056        if (gspca_dev->streaming)
2057                setbrightness(gspca_dev);
2058        return 0;
2059}
2060
2061static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
2062{
2063        struct sd *sd = (struct sd *) gspca_dev;
2064
2065        *val = sd->brightness;
2066        return 0;
2067}
2068
2069static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2070{
2071        struct sd *sd = (struct sd *) gspca_dev;
2072
2073        sd->contrast = val;
2074        if (gspca_dev->streaming)
2075                setcontrast(gspca_dev);
2076        return 0;
2077}
2078
2079static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2080{
2081        struct sd *sd = (struct sd *) gspca_dev;
2082
2083        *val = sd->contrast;
2084        return 0;
2085}
2086
2087static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
2088{
2089        struct sd *sd = (struct sd *) gspca_dev;
2090
2091        sd->colors = val;
2092        if (gspca_dev->streaming)
2093                setcolors(gspca_dev);
2094        return 0;
2095}
2096
2097static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2098{
2099        struct sd *sd = (struct sd *) gspca_dev;
2100
2101        *val = sd->colors;
2102        return 0;
2103}
2104
2105static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
2106{
2107        struct sd *sd = (struct sd *) gspca_dev;
2108
2109        sd->blue = val;
2110        if (gspca_dev->streaming)
2111                setredblue(gspca_dev);
2112        return 0;
2113}
2114
2115static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
2116{
2117        struct sd *sd = (struct sd *) gspca_dev;
2118
2119        *val = sd->blue;
2120        return 0;
2121}
2122
2123static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
2124{
2125        struct sd *sd = (struct sd *) gspca_dev;
2126
2127        sd->red = val;
2128        if (gspca_dev->streaming)
2129                setredblue(gspca_dev);
2130        return 0;
2131}
2132
2133static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
2134{
2135        struct sd *sd = (struct sd *) gspca_dev;
2136
2137        *val = sd->red;
2138        return 0;
2139}
2140
2141static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
2142{
2143        struct sd *sd = (struct sd *) gspca_dev;
2144
2145        sd->gamma = val;
2146        if (gspca_dev->streaming)
2147                setgamma(gspca_dev);
2148        return 0;
2149}
2150
2151static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2152{
2153        struct sd *sd = (struct sd *) gspca_dev;
2154
2155        *val = sd->gamma;
2156        return 0;
2157}
2158
2159static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2160{
2161        struct sd *sd = (struct sd *) gspca_dev;
2162
2163        sd->autogain = val;
2164        if (gspca_dev->streaming)
2165                setautogain(gspca_dev);
2166        return 0;
2167}
2168
2169static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2170{
2171        struct sd *sd = (struct sd *) gspca_dev;
2172
2173        *val = sd->autogain;
2174        return 0;
2175}
2176
2177static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2178{
2179        struct sd *sd = (struct sd *) gspca_dev;
2180
2181        sd->vflip = val;
2182        if (gspca_dev->streaming)
2183                setvflip(sd);
2184        return 0;
2185}
2186
2187static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2188{
2189        struct sd *sd = (struct sd *) gspca_dev;
2190
2191        *val = sd->vflip;
2192        return 0;
2193}
2194
2195static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2196{
2197        struct sd *sd = (struct sd *) gspca_dev;
2198
2199        sd->infrared = val;
2200        if (gspca_dev->streaming)
2201                setinfrared(sd);
2202        return 0;
2203}
2204
2205static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2206{
2207        struct sd *sd = (struct sd *) gspca_dev;
2208
2209        *val = sd->infrared;
2210        return 0;
2211}
2212
2213static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
2214{
2215        struct sd *sd = (struct sd *) gspca_dev;
2216
2217        sd->freq = val;
2218        if (gspca_dev->streaming)
2219                setfreq(gspca_dev);
2220        return 0;
2221}
2222
2223static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
2224{
2225        struct sd *sd = (struct sd *) gspca_dev;
2226
2227        *val = sd->freq;
2228        return 0;
2229}
2230
2231static int sd_set_jcomp(struct gspca_dev *gspca_dev,
2232                        struct v4l2_jpegcompression *jcomp)
2233{
2234        struct sd *sd = (struct sd *) gspca_dev;
2235
2236        if (jcomp->quality < QUALITY_MIN)
2237                sd->quality = QUALITY_MIN;
2238        else if (jcomp->quality > QUALITY_MAX)
2239                sd->quality = QUALITY_MAX;
2240        else
2241                sd->quality = jcomp->quality;
2242        if (gspca_dev->streaming)
2243                jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2244        return 0;
2245}
2246
2247static int sd_get_jcomp(struct gspca_dev *gspca_dev,
2248                        struct v4l2_jpegcompression *jcomp)
2249{
2250        struct sd *sd = (struct sd *) gspca_dev;
2251
2252        memset(jcomp, 0, sizeof *jcomp);
2253        jcomp->quality = sd->quality;
2254        jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
2255                        | V4L2_JPEG_MARKER_DQT;
2256        return 0;
2257}
2258
2259static int sd_querymenu(struct gspca_dev *gspca_dev,
2260                        struct v4l2_querymenu *menu)
2261{
2262        switch (menu->id) {
2263        case V4L2_CID_POWER_LINE_FREQUENCY:
2264                switch (menu->index) {
2265                case 0:         /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2266                        strcpy((char *) menu->name, "NoFliker");
2267                        return 0;
2268                case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2269                        strcpy((char *) menu->name, "50 Hz");
2270                        return 0;
2271                case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2272                        strcpy((char *) menu->name, "60 Hz");
2273                        return 0;
2274                }
2275                break;
2276        }
2277        return -EINVAL;
2278}
2279
2280/* sub-driver description */
2281static const struct sd_desc sd_desc = {
2282        .name = MODULE_NAME,
2283        .ctrls = sd_ctrls,
2284        .nctrls = ARRAY_SIZE(sd_ctrls),
2285        .config = sd_config,
2286        .init = sd_init,
2287        .start = sd_start,
2288        .stopN = sd_stopN,
2289        .stop0 = sd_stop0,
2290        .pkt_scan = sd_pkt_scan,
2291        .dq_callback = do_autogain,
2292        .get_jcomp = sd_get_jcomp,
2293        .set_jcomp = sd_set_jcomp,
2294        .querymenu = sd_querymenu,
2295};
2296
2297/* -- module initialisation -- */
2298#define BSI(bridge, sensor, i2c_addr) \
2299        .driver_info = (BRIDGE_ ## bridge << 16) \
2300                        | (SENSOR_ ## sensor << 8) \
2301                        | (i2c_addr)
2302static const __devinitdata struct usb_device_id device_table[] = {
2303#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2304        {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
2305        {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
2306#endif
2307        {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2308        {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
2309        {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
2310        {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
2311        {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
2312        {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
2313        {USB_DEVICE(0x06f8, 0x3008), BSI(SN9C105, OV7660, 0x21)},
2314        {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2315/* bw600.inf:
2316        {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2317/*      {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2318/*      {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2319        {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2320/*      {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
2321        {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
2322/*      {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x??)}, */
2323/*      {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2324        {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2325/*      {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2326/*      {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2327        {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2328#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2329        {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
2330        {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2331#endif
2332        {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/
2333/*      {USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, PO2030N, ??)}, */
2334/*      {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x21)}, */
2335        {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/
2336        {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/
2337        {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/
2338        {USB_DEVICE(0x0c45, 0x610e), BSI(SN9C120, OV7630, 0x21)}, /*sn9c128*/
2339/*      {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2340/*      {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
2341        {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2342/*bw600.inf:*/
2343        {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
2344        {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
2345        {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
2346/*      {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
2347#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2348        {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
2349#endif
2350/*      {USB_DEVICE(0x0c45, 0x6132), BSI(SN9C120, OV7670, 0x21)}, */
2351        {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
2352        {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
2353#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2354        {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
2355#endif
2356        {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2357        {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)},
2358/*      {USB_DEVICE(0x0c45, 0x6142), BSI(SN9C120, PO2030N, ??)}, *sn9c120b*/
2359        {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, /*sn9c120b*/
2360        {USB_DEVICE(0x0c45, 0x6148), BSI(SN9C120, OM6802, 0x21)}, /*sn9c120b*/
2361        {}
2362};
2363MODULE_DEVICE_TABLE(usb, device_table);
2364
2365/* -- device connect -- */
2366static int sd_probe(struct usb_interface *intf,
2367                    const struct usb_device_id *id)
2368{
2369        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2370                                THIS_MODULE);
2371}
2372
2373static struct usb_driver sd_driver = {
2374        .name = MODULE_NAME,
2375        .id_table = device_table,
2376        .probe = sd_probe,
2377        .disconnect = gspca_disconnect,
2378#ifdef CONFIG_PM
2379        .suspend = gspca_suspend,
2380        .resume = gspca_resume,
2381#endif
2382};
2383
2384/* -- module insert / remove -- */
2385static int __init sd_mod_init(void)
2386{
2387        int ret;
2388        ret = usb_register(&sd_driver);
2389        if (ret < 0)
2390                return ret;
2391        info("registered");
2392        return 0;
2393}
2394static void __exit sd_mod_exit(void)
2395{
2396        usb_deregister(&sd_driver);
2397        info("deregistered");
2398}
2399
2400module_init(sd_mod_init);
2401module_exit(sd_mod_exit);
2402