linux/drivers/media/usb/gspca/pac7302.c
<<
>>
Prefs
   1/*
   2 * Pixart PAC7302 driver
   3 *
   4 * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr>
   5 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
   6 *
   7 * Separated from Pixart PAC7311 library by Márton Németh
   8 * Camera button input handling by Márton Németh <nm127@freemail.hu>
   9 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation; either version 2 of the License, or
  14 * any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  24 */
  25
  26/*
  27 * Some documentation about various registers as determined by trial and error.
  28 *
  29 * Register page 0:
  30 *
  31 * Address      Description
  32 * 0x01         Red balance control
  33 * 0x02         Green balance control
  34 * 0x03         Blue balance control
  35 *                   The Windows driver uses a quadratic approach to map
  36 *                   the settable values (0-200) on register values:
  37 *                   min=0x20, default=0x40, max=0x80
  38 * 0x0f-0x20    Color and saturation control
  39 * 0xa2-0xab    Brightness, contrast and gamma control
  40 * 0xb6         Sharpness control (bits 0-4)
  41 *
  42 * Register page 1:
  43 *
  44 * Address      Description
  45 * 0x78         Global control, bit 6 controls the LED (inverted)
  46 * 0x80         Compression balance, 2 interesting settings:
  47 *              0x0f Default
  48 *              0x50 Values >= this switch the camera to a lower compression,
  49 *                   using the same table for both luminance and chrominance.
  50 *                   This gives a sharper picture. Only usable when running
  51 *                   at < 15 fps! Note currently the driver does not use this
  52 *                   as the quality gain is small and the generated JPG-s are
  53 *                   only understood by v4l-utils >= 0.8.9
  54 *
  55 * Register page 3:
  56 *
  57 * Address      Description
  58 * 0x02         Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
  59 *              the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
  60 * 0x03         Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
  61 * 0x04         Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
  62 *              63 -> ~27 fps, the 2 msb's must always be 1 !!
  63 * 0x05         Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
  64 *              1 -> ~30 fps, 2 -> ~20 fps
  65 * 0x0e         Exposure bits 0-7, 0-448, 0 = use full frame time
  66 * 0x0f         Exposure bit 8, 0-448, 448 = no exposure at all
  67 * 0x10         Gain 0-31
  68 * 0x12         Another gain 0-31, unlike 0x10 this one seems to start with an
  69 *              amplification value of 1 rather then 0 at its lowest setting
  70 * 0x21         Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
  71 * 0x80         Another framerate control, best left at 1, moving it from 1 to
  72 *              2 causes the framerate to become 3/4th of what it was, and
  73 *              also seems to cause pixel averaging, resulting in an effective
  74 *              resolution of 320x240 and thus a much blockier image
  75 *
  76 * The registers are accessed in the following functions:
  77 *
  78 * Page | Register   | Function
  79 * -----+------------+---------------------------------------------------
  80 *  0   | 0x01       | setredbalance()
  81 *  0   | 0x03       | setbluebalance()
  82 *  0   | 0x0f..0x20 | setcolors()
  83 *  0   | 0xa2..0xab | setbrightcont()
  84 *  0   | 0xb6       | setsharpness()
  85 *  0   | 0xc6       | setwhitebalance()
  86 *  0   | 0xdc       | setbrightcont(), setcolors()
  87 *  3   | 0x02       | setexposure()
  88 *  3   | 0x10, 0x12 | setgain()
  89 *  3   | 0x11       | setcolors(), setgain(), setexposure(), sethvflip()
  90 *  3   | 0x21       | sethvflip()
  91 */
  92
  93#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  94
  95#include <linux/input.h>
  96#include <media/v4l2-chip-ident.h>
  97#include "gspca.h"
  98/* Include pac common sof detection functions */
  99#include "pac_common.h"
 100
 101#define PAC7302_RGB_BALANCE_MIN           0
 102#define PAC7302_RGB_BALANCE_MAX         200
 103#define PAC7302_RGB_BALANCE_DEFAULT     100
 104#define PAC7302_GAIN_DEFAULT             15
 105#define PAC7302_GAIN_KNEE                42
 106#define PAC7302_EXPOSURE_DEFAULT         66 /* 33 ms / 30 fps */
 107#define PAC7302_EXPOSURE_KNEE           133 /* 66 ms / 15 fps */
 108
 109MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
 110                "Thomas Kaiser thomas@kaiser-linux.li");
 111MODULE_DESCRIPTION("Pixart PAC7302");
 112MODULE_LICENSE("GPL");
 113
 114struct sd {
 115        struct gspca_dev gspca_dev;             /* !! must be the first item */
 116
 117        struct { /* brightness / contrast cluster */
 118                struct v4l2_ctrl *brightness;
 119                struct v4l2_ctrl *contrast;
 120        };
 121        struct v4l2_ctrl *saturation;
 122        struct v4l2_ctrl *white_balance;
 123        struct v4l2_ctrl *red_balance;
 124        struct v4l2_ctrl *blue_balance;
 125        struct { /* flip cluster */
 126                struct v4l2_ctrl *hflip;
 127                struct v4l2_ctrl *vflip;
 128        };
 129        struct v4l2_ctrl *sharpness;
 130        u8 flags;
 131#define FL_HFLIP 0x01           /* mirrored by default */
 132#define FL_VFLIP 0x02           /* vertical flipped by default */
 133
 134        u8 sof_read;
 135        s8 autogain_ignore_frames;
 136
 137        atomic_t avg_lum;
 138};
 139
 140static const struct v4l2_pix_format vga_mode[] = {
 141        {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
 142                .bytesperline = 640,
 143                .sizeimage = 640 * 480 * 3 / 8 + 590,
 144                .colorspace = V4L2_COLORSPACE_JPEG,
 145        },
 146};
 147
 148#define LOAD_PAGE3              255
 149#define END_OF_SEQUENCE         0
 150
 151static const u8 init_7302[] = {
 152/*      index,value */
 153        0xff, 0x01,             /* page 1 */
 154        0x78, 0x00,             /* deactivate */
 155        0xff, 0x01,
 156        0x78, 0x40,             /* led off */
 157};
 158static const u8 start_7302[] = {
 159/*      index, len, [value]* */
 160        0xff, 1,        0x00,           /* page 0 */
 161        0x00, 12,       0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
 162                        0x00, 0x00, 0x00, 0x00,
 163        0x0d, 24,       0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
 164                        0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
 165                        0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
 166        0x26, 2,        0xaa, 0xaa,
 167        0x2e, 1,        0x31,
 168        0x38, 1,        0x01,
 169        0x3a, 3,        0x14, 0xff, 0x5a,
 170        0x43, 11,       0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
 171                        0x00, 0x54, 0x11,
 172        0x55, 1,        0x00,
 173        0x62, 4,        0x10, 0x1e, 0x1e, 0x18,
 174        0x6b, 1,        0x00,
 175        0x6e, 3,        0x08, 0x06, 0x00,
 176        0x72, 3,        0x00, 0xff, 0x00,
 177        0x7d, 23,       0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
 178                        0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
 179                        0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
 180        0xa2, 10,       0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
 181                        0xd2, 0xeb,
 182        0xaf, 1,        0x02,
 183        0xb5, 2,        0x08, 0x08,
 184        0xb8, 2,        0x08, 0x88,
 185        0xc4, 4,        0xae, 0x01, 0x04, 0x01,
 186        0xcc, 1,        0x00,
 187        0xd1, 11,       0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
 188                        0xc1, 0xd7, 0xec,
 189        0xdc, 1,        0x01,
 190        0xff, 1,        0x01,           /* page 1 */
 191        0x12, 3,        0x02, 0x00, 0x01,
 192        0x3e, 2,        0x00, 0x00,
 193        0x76, 5,        0x01, 0x20, 0x40, 0x00, 0xf2,
 194        0x7c, 1,        0x00,
 195        0x7f, 10,       0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
 196                        0x02, 0x00,
 197        0x96, 5,        0x01, 0x10, 0x04, 0x01, 0x04,
 198        0xc8, 14,       0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
 199                        0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
 200        0xd8, 1,        0x01,
 201        0xdb, 2,        0x00, 0x01,
 202        0xde, 7,        0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
 203        0xe6, 4,        0x00, 0x00, 0x00, 0x01,
 204        0xeb, 1,        0x00,
 205        0xff, 1,        0x02,           /* page 2 */
 206        0x22, 1,        0x00,
 207        0xff, 1,        0x03,           /* page 3 */
 208        0, LOAD_PAGE3,                  /* load the page 3 */
 209        0x11, 1,        0x01,
 210        0xff, 1,        0x02,           /* page 2 */
 211        0x13, 1,        0x00,
 212        0x22, 4,        0x1f, 0xa4, 0xf0, 0x96,
 213        0x27, 2,        0x14, 0x0c,
 214        0x2a, 5,        0xc8, 0x00, 0x18, 0x12, 0x22,
 215        0x64, 8,        0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
 216        0x6e, 1,        0x08,
 217        0xff, 1,        0x01,           /* page 1 */
 218        0x78, 1,        0x00,
 219        0, END_OF_SEQUENCE              /* end of sequence */
 220};
 221
 222#define SKIP            0xaa
 223/* page 3 - the value SKIP says skip the index - see reg_w_page() */
 224static const u8 page3_7302[] = {
 225        0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
 226        0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
 227        0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 228        0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
 229        0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
 230        0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
 231        0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
 232        0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 233        0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
 234        SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
 235        0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 236        0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
 237        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 238        0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
 239        0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
 240        0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
 241        0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
 242        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 243        0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
 244        0x00
 245};
 246
 247static void reg_w_buf(struct gspca_dev *gspca_dev,
 248                u8 index,
 249                  const u8 *buffer, int len)
 250{
 251        int ret;
 252
 253        if (gspca_dev->usb_err < 0)
 254                return;
 255        memcpy(gspca_dev->usb_buf, buffer, len);
 256        ret = usb_control_msg(gspca_dev->dev,
 257                        usb_sndctrlpipe(gspca_dev->dev, 0),
 258                        0,              /* request */
 259                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 260                        0,              /* value */
 261                        index, gspca_dev->usb_buf, len,
 262                        500);
 263        if (ret < 0) {
 264                pr_err("reg_w_buf failed i: %02x error %d\n",
 265                       index, ret);
 266                gspca_dev->usb_err = ret;
 267        }
 268}
 269
 270
 271static void reg_w(struct gspca_dev *gspca_dev,
 272                u8 index,
 273                u8 value)
 274{
 275        int ret;
 276
 277        if (gspca_dev->usb_err < 0)
 278                return;
 279        gspca_dev->usb_buf[0] = value;
 280        ret = usb_control_msg(gspca_dev->dev,
 281                        usb_sndctrlpipe(gspca_dev->dev, 0),
 282                        0,                      /* request */
 283                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 284                        0, index, gspca_dev->usb_buf, 1,
 285                        500);
 286        if (ret < 0) {
 287                pr_err("reg_w() failed i: %02x v: %02x error %d\n",
 288                       index, value, ret);
 289                gspca_dev->usb_err = ret;
 290        }
 291}
 292
 293static void reg_w_seq(struct gspca_dev *gspca_dev,
 294                const u8 *seq, int len)
 295{
 296        while (--len >= 0) {
 297                reg_w(gspca_dev, seq[0], seq[1]);
 298                seq += 2;
 299        }
 300}
 301
 302/* load the beginning of a page */
 303static void reg_w_page(struct gspca_dev *gspca_dev,
 304                        const u8 *page, int len)
 305{
 306        int index;
 307        int ret = 0;
 308
 309        if (gspca_dev->usb_err < 0)
 310                return;
 311        for (index = 0; index < len; index++) {
 312                if (page[index] == SKIP)                /* skip this index */
 313                        continue;
 314                gspca_dev->usb_buf[0] = page[index];
 315                ret = usb_control_msg(gspca_dev->dev,
 316                                usb_sndctrlpipe(gspca_dev->dev, 0),
 317                                0,                      /* request */
 318                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 319                                0, index, gspca_dev->usb_buf, 1,
 320                                500);
 321                if (ret < 0) {
 322                        pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
 323                               index, page[index], ret);
 324                        gspca_dev->usb_err = ret;
 325                        break;
 326                }
 327        }
 328}
 329
 330/* output a variable sequence */
 331static void reg_w_var(struct gspca_dev *gspca_dev,
 332                        const u8 *seq,
 333                        const u8 *page3, unsigned int page3_len)
 334{
 335        int index, len;
 336
 337        for (;;) {
 338                index = *seq++;
 339                len = *seq++;
 340                switch (len) {
 341                case END_OF_SEQUENCE:
 342                        return;
 343                case LOAD_PAGE3:
 344                        reg_w_page(gspca_dev, page3, page3_len);
 345                        break;
 346                default:
 347                        if (len > USB_BUF_SZ) {
 348                                PERR("Incorrect variable sequence");
 349                                return;
 350                        }
 351                        while (len > 0) {
 352                                if (len < 8) {
 353                                        reg_w_buf(gspca_dev,
 354                                                index, seq, len);
 355                                        seq += len;
 356                                        break;
 357                                }
 358                                reg_w_buf(gspca_dev, index, seq, 8);
 359                                seq += 8;
 360                                index += 8;
 361                                len -= 8;
 362                        }
 363                }
 364        }
 365        /* not reached */
 366}
 367
 368/* this function is called at probe time for pac7302 */
 369static int sd_config(struct gspca_dev *gspca_dev,
 370                        const struct usb_device_id *id)
 371{
 372        struct sd *sd = (struct sd *) gspca_dev;
 373        struct cam *cam;
 374
 375        cam = &gspca_dev->cam;
 376
 377        cam->cam_mode = vga_mode;       /* only 640x480 */
 378        cam->nmodes = ARRAY_SIZE(vga_mode);
 379
 380        sd->flags = id->driver_info;
 381        return 0;
 382}
 383
 384static void setbrightcont(struct gspca_dev *gspca_dev)
 385{
 386        struct sd *sd = (struct sd *) gspca_dev;
 387        int i, v;
 388        static const u8 max[10] =
 389                {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
 390                 0xd4, 0xec};
 391        static const u8 delta[10] =
 392                {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
 393                 0x11, 0x0b};
 394
 395        reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
 396        for (i = 0; i < 10; i++) {
 397                v = max[i];
 398                v += (sd->brightness->val - sd->brightness->maximum)
 399                        * 150 / sd->brightness->maximum; /* 200 ? */
 400                v -= delta[i] * sd->contrast->val / sd->contrast->maximum;
 401                if (v < 0)
 402                        v = 0;
 403                else if (v > 0xff)
 404                        v = 0xff;
 405                reg_w(gspca_dev, 0xa2 + i, v);
 406        }
 407        reg_w(gspca_dev, 0xdc, 0x01);
 408}
 409
 410static void setcolors(struct gspca_dev *gspca_dev)
 411{
 412        struct sd *sd = (struct sd *) gspca_dev;
 413        int i, v;
 414        static const int a[9] =
 415                {217, -212, 0, -101, 170, -67, -38, -315, 355};
 416        static const int b[9] =
 417                {19, 106, 0, 19, 106, 1, 19, 106, 1};
 418
 419        reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
 420        reg_w(gspca_dev, 0x11, 0x01);
 421        reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
 422        for (i = 0; i < 9; i++) {
 423                v = a[i] * sd->saturation->val / sd->saturation->maximum;
 424                v += b[i];
 425                reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
 426                reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
 427        }
 428        reg_w(gspca_dev, 0xdc, 0x01);
 429}
 430
 431static void setwhitebalance(struct gspca_dev *gspca_dev)
 432{
 433        struct sd *sd = (struct sd *) gspca_dev;
 434
 435        reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
 436        reg_w(gspca_dev, 0xc6, sd->white_balance->val);
 437
 438        reg_w(gspca_dev, 0xdc, 0x01);
 439}
 440
 441static u8 rgbbalance_ctrl_to_reg_value(s32 rgb_ctrl_val)
 442{
 443        const unsigned int k = 1000;    /* precision factor */
 444        unsigned int norm;
 445
 446        /* Normed value [0...k] */
 447        norm = k * (rgb_ctrl_val - PAC7302_RGB_BALANCE_MIN)
 448                    / (PAC7302_RGB_BALANCE_MAX - PAC7302_RGB_BALANCE_MIN);
 449        /* Qudratic apporach improves control at small (register) values: */
 450        return 64 * norm * norm / (k*k)  +  32 * norm / k  +  32;
 451        /* Y = 64*X*X + 32*X + 32
 452         * => register values 0x20-0x80; Windows driver uses these limits */
 453
 454        /* NOTE: for full value range (0x00-0xff) use
 455         *         Y = 254*X*X + X
 456         *         => 254 * norm * norm / (k*k)  +  1 * norm / k        */
 457}
 458
 459static void setredbalance(struct gspca_dev *gspca_dev)
 460{
 461        struct sd *sd = (struct sd *) gspca_dev;
 462
 463        reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
 464        reg_w(gspca_dev, 0x01,
 465              rgbbalance_ctrl_to_reg_value(sd->red_balance->val));
 466
 467        reg_w(gspca_dev, 0xdc, 0x01);
 468}
 469
 470static void setbluebalance(struct gspca_dev *gspca_dev)
 471{
 472        struct sd *sd = (struct sd *) gspca_dev;
 473
 474        reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
 475        reg_w(gspca_dev, 0x03,
 476              rgbbalance_ctrl_to_reg_value(sd->blue_balance->val));
 477
 478        reg_w(gspca_dev, 0xdc, 0x01);
 479}
 480
 481static void setgain(struct gspca_dev *gspca_dev)
 482{
 483        u8 reg10, reg12;
 484
 485        if (gspca_dev->gain->val < 32) {
 486                reg10 = gspca_dev->gain->val;
 487                reg12 = 0;
 488        } else {
 489                reg10 = 31;
 490                reg12 = gspca_dev->gain->val - 31;
 491        }
 492
 493        reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
 494        reg_w(gspca_dev, 0x10, reg10);
 495        reg_w(gspca_dev, 0x12, reg12);
 496
 497        /* load registers to sensor (Bit 0, auto clear) */
 498        reg_w(gspca_dev, 0x11, 0x01);
 499}
 500
 501static void setexposure(struct gspca_dev *gspca_dev)
 502{
 503        u8 clockdiv;
 504        u16 exposure;
 505
 506        /*
 507         * Register 2 of frame 3 contains the clock divider configuring the
 508         * no fps according to the formula: 90 / reg. sd->exposure is the
 509         * desired exposure time in 0.5 ms.
 510         */
 511        clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000;
 512
 513        /*
 514         * Note clockdiv = 3 also works, but when running at 30 fps, depending
 515         * on the scene being recorded, the camera switches to another
 516         * quantization table for certain JPEG blocks, and we don't know how
 517         * to decompress these blocks. So we cap the framerate at 15 fps.
 518         */
 519        if (clockdiv < 6)
 520                clockdiv = 6;
 521        else if (clockdiv > 63)
 522                clockdiv = 63;
 523
 524        /*
 525         * Register 2 MUST be a multiple of 3, except when between 6 and 12?
 526         * Always round up, otherwise we cannot get the desired frametime
 527         * using the partial frame time exposure control.
 528         */
 529        if (clockdiv < 6 || clockdiv > 12)
 530                clockdiv = ((clockdiv + 2) / 3) * 3;
 531
 532        /*
 533         * frame exposure time in ms = 1000 * clockdiv / 90    ->
 534         * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
 535         */
 536        exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv);
 537        /* 0 = use full frametime, 448 = no exposure, reverse it */
 538        exposure = 448 - exposure;
 539
 540        reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
 541        reg_w(gspca_dev, 0x02, clockdiv);
 542        reg_w(gspca_dev, 0x0e, exposure & 0xff);
 543        reg_w(gspca_dev, 0x0f, exposure >> 8);
 544
 545        /* load registers to sensor (Bit 0, auto clear) */
 546        reg_w(gspca_dev, 0x11, 0x01);
 547}
 548
 549static void sethvflip(struct gspca_dev *gspca_dev)
 550{
 551        struct sd *sd = (struct sd *) gspca_dev;
 552        u8 data, hflip, vflip;
 553
 554        hflip = sd->hflip->val;
 555        if (sd->flags & FL_HFLIP)
 556                hflip = !hflip;
 557        vflip = sd->vflip->val;
 558        if (sd->flags & FL_VFLIP)
 559                vflip = !vflip;
 560
 561        reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
 562        data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
 563        reg_w(gspca_dev, 0x21, data);
 564
 565        /* load registers to sensor (Bit 0, auto clear) */
 566        reg_w(gspca_dev, 0x11, 0x01);
 567}
 568
 569static void setsharpness(struct gspca_dev *gspca_dev)
 570{
 571        struct sd *sd = (struct sd *) gspca_dev;
 572
 573        reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
 574        reg_w(gspca_dev, 0xb6, sd->sharpness->val);
 575
 576        reg_w(gspca_dev, 0xdc, 0x01);
 577}
 578
 579/* this function is called at probe and resume time for pac7302 */
 580static int sd_init(struct gspca_dev *gspca_dev)
 581{
 582        reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
 583        return gspca_dev->usb_err;
 584}
 585
 586static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
 587{
 588        struct gspca_dev *gspca_dev =
 589                container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 590        struct sd *sd = (struct sd *)gspca_dev;
 591
 592        gspca_dev->usb_err = 0;
 593
 594        if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
 595                /* when switching to autogain set defaults to make sure
 596                   we are on a valid point of the autogain gain /
 597                   exposure knee graph, and give this change time to
 598                   take effect before doing autogain. */
 599                gspca_dev->exposure->val    = PAC7302_EXPOSURE_DEFAULT;
 600                gspca_dev->gain->val        = PAC7302_GAIN_DEFAULT;
 601                sd->autogain_ignore_frames  = PAC_AUTOGAIN_IGNORE_FRAMES;
 602        }
 603
 604        if (!gspca_dev->streaming)
 605                return 0;
 606
 607        switch (ctrl->id) {
 608        case V4L2_CID_BRIGHTNESS:
 609                setbrightcont(gspca_dev);
 610                break;
 611        case V4L2_CID_SATURATION:
 612                setcolors(gspca_dev);
 613                break;
 614        case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
 615                setwhitebalance(gspca_dev);
 616                break;
 617        case V4L2_CID_RED_BALANCE:
 618                setredbalance(gspca_dev);
 619                break;
 620        case V4L2_CID_BLUE_BALANCE:
 621                setbluebalance(gspca_dev);
 622                break;
 623        case V4L2_CID_AUTOGAIN:
 624                if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
 625                        setexposure(gspca_dev);
 626                if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
 627                        setgain(gspca_dev);
 628                break;
 629        case V4L2_CID_HFLIP:
 630                sethvflip(gspca_dev);
 631                break;
 632        case V4L2_CID_SHARPNESS:
 633                setsharpness(gspca_dev);
 634                break;
 635        default:
 636                return -EINVAL;
 637        }
 638        return gspca_dev->usb_err;
 639}
 640
 641static const struct v4l2_ctrl_ops sd_ctrl_ops = {
 642        .s_ctrl = sd_s_ctrl,
 643};
 644
 645/* this function is called at probe time */
 646static int sd_init_controls(struct gspca_dev *gspca_dev)
 647{
 648        struct sd *sd = (struct sd *) gspca_dev;
 649        struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
 650
 651        gspca_dev->vdev.ctrl_handler = hdl;
 652        v4l2_ctrl_handler_init(hdl, 12);
 653
 654        sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 655                                        V4L2_CID_BRIGHTNESS, 0, 32, 1, 16);
 656        sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 657                                        V4L2_CID_CONTRAST, 0, 255, 1, 127);
 658
 659        sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 660                                        V4L2_CID_SATURATION, 0, 255, 1, 127);
 661        sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 662                                        V4L2_CID_WHITE_BALANCE_TEMPERATURE,
 663                                        0, 255, 1, 55);
 664        sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 665                                        V4L2_CID_RED_BALANCE,
 666                                        PAC7302_RGB_BALANCE_MIN,
 667                                        PAC7302_RGB_BALANCE_MAX,
 668                                        1, PAC7302_RGB_BALANCE_DEFAULT);
 669        sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 670                                        V4L2_CID_BLUE_BALANCE,
 671                                        PAC7302_RGB_BALANCE_MIN,
 672                                        PAC7302_RGB_BALANCE_MAX,
 673                                        1, PAC7302_RGB_BALANCE_DEFAULT);
 674
 675        gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 676                                        V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
 677        gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 678                                        V4L2_CID_EXPOSURE, 0, 1023, 1,
 679                                        PAC7302_EXPOSURE_DEFAULT);
 680        gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 681                                        V4L2_CID_GAIN, 0, 62, 1,
 682                                        PAC7302_GAIN_DEFAULT);
 683
 684        sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 685                V4L2_CID_HFLIP, 0, 1, 1, 0);
 686        sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 687                V4L2_CID_VFLIP, 0, 1, 1, 0);
 688
 689        sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 690                                        V4L2_CID_SHARPNESS, 0, 15, 1, 8);
 691
 692        if (hdl->error) {
 693                pr_err("Could not initialize controls\n");
 694                return hdl->error;
 695        }
 696
 697        v4l2_ctrl_cluster(2, &sd->brightness);
 698        v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
 699        v4l2_ctrl_cluster(2, &sd->hflip);
 700        return 0;
 701}
 702
 703/* -- start the camera -- */
 704static int sd_start(struct gspca_dev *gspca_dev)
 705{
 706        struct sd *sd = (struct sd *) gspca_dev;
 707
 708        reg_w_var(gspca_dev, start_7302,
 709                page3_7302, sizeof(page3_7302));
 710
 711        sd->sof_read = 0;
 712        sd->autogain_ignore_frames = 0;
 713        atomic_set(&sd->avg_lum, 270 + sd->brightness->val);
 714
 715        /* start stream */
 716        reg_w(gspca_dev, 0xff, 0x01);
 717        reg_w(gspca_dev, 0x78, 0x01);
 718
 719        return gspca_dev->usb_err;
 720}
 721
 722static void sd_stopN(struct gspca_dev *gspca_dev)
 723{
 724
 725        /* stop stream */
 726        reg_w(gspca_dev, 0xff, 0x01);
 727        reg_w(gspca_dev, 0x78, 0x00);
 728}
 729
 730/* called on streamoff with alt 0 and on disconnect for pac7302 */
 731static void sd_stop0(struct gspca_dev *gspca_dev)
 732{
 733        if (!gspca_dev->present)
 734                return;
 735        reg_w(gspca_dev, 0xff, 0x01);
 736        reg_w(gspca_dev, 0x78, 0x40);
 737}
 738
 739static void do_autogain(struct gspca_dev *gspca_dev)
 740{
 741        struct sd *sd = (struct sd *) gspca_dev;
 742        int avg_lum = atomic_read(&sd->avg_lum);
 743        int desired_lum;
 744        const int deadzone = 30;
 745
 746        if (sd->autogain_ignore_frames < 0)
 747                return;
 748
 749        if (sd->autogain_ignore_frames > 0) {
 750                sd->autogain_ignore_frames--;
 751        } else {
 752                desired_lum = 270 + sd->brightness->val;
 753
 754                if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum,
 755                                        deadzone, PAC7302_GAIN_KNEE,
 756                                        PAC7302_EXPOSURE_KNEE))
 757                        sd->autogain_ignore_frames =
 758                                                PAC_AUTOGAIN_IGNORE_FRAMES;
 759        }
 760}
 761
 762/* JPEG header */
 763static const u8 jpeg_header[] = {
 764        0xff, 0xd8,     /* SOI: Start of Image */
 765
 766        0xff, 0xc0,     /* SOF0: Start of Frame (Baseline DCT) */
 767        0x00, 0x11,     /* length = 17 bytes (including this length field) */
 768        0x08,           /* Precision: 8 */
 769        0x02, 0x80,     /* height = 640 (image rotated) */
 770        0x01, 0xe0,     /* width = 480 */
 771        0x03,           /* Number of image components: 3 */
 772        0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
 773        0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
 774        0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
 775
 776        0xff, 0xda,     /* SOS: Start Of Scan */
 777        0x00, 0x0c,     /* length = 12 bytes (including this length field) */
 778        0x03,           /* number of components: 3 */
 779        0x01, 0x00,     /* selector 1, table 0x00 */
 780        0x02, 0x11,     /* selector 2, table 0x11 */
 781        0x03, 0x11,     /* selector 3, table 0x11 */
 782        0x00, 0x3f,     /* Spectral selection: 0 .. 63 */
 783        0x00            /* Successive approximation: 0 */
 784};
 785
 786/* this function is run at interrupt level */
 787static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 788                        u8 *data,                       /* isoc packet */
 789                        int len)                        /* iso packet length */
 790{
 791        struct sd *sd = (struct sd *) gspca_dev;
 792        u8 *image;
 793        u8 *sof;
 794
 795        sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
 796        if (sof) {
 797                int n, lum_offset, footer_length;
 798
 799                /*
 800                 * 6 bytes after the FF D9 EOF marker a number of lumination
 801                 * bytes are send corresponding to different parts of the
 802                 * image, the 14th and 15th byte after the EOF seem to
 803                 * correspond to the center of the image.
 804                 */
 805                lum_offset = 61 + sizeof pac_sof_marker;
 806                footer_length = 74;
 807
 808                /* Finish decoding current frame */
 809                n = (sof - data) - (footer_length + sizeof pac_sof_marker);
 810                if (n < 0) {
 811                        gspca_dev->image_len += n;
 812                        n = 0;
 813                } else {
 814                        gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
 815                }
 816
 817                image = gspca_dev->image;
 818                if (image != NULL
 819                 && image[gspca_dev->image_len - 2] == 0xff
 820                 && image[gspca_dev->image_len - 1] == 0xd9)
 821                        gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 822
 823                n = sof - data;
 824                len -= n;
 825                data = sof;
 826
 827                /* Get average lumination */
 828                if (gspca_dev->last_packet_type == LAST_PACKET &&
 829                                n >= lum_offset)
 830                        atomic_set(&sd->avg_lum, data[-lum_offset] +
 831                                                data[-lum_offset + 1]);
 832
 833                /* Start the new frame with the jpeg header */
 834                /* The PAC7302 has the image rotated 90 degrees */
 835                gspca_frame_add(gspca_dev, FIRST_PACKET,
 836                                jpeg_header, sizeof jpeg_header);
 837        }
 838        gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 839}
 840
 841#ifdef CONFIG_VIDEO_ADV_DEBUG
 842static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
 843                        const struct v4l2_dbg_register *reg)
 844{
 845        u8 index;
 846        u8 value;
 847
 848        /*
 849         * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
 850         *                     long on the USB bus)
 851         */
 852        if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
 853            reg->match.addr == 0 &&
 854            (reg->reg < 0x000000ff) &&
 855            (reg->val <= 0x000000ff)
 856        ) {
 857                /* Currently writing to page 0 is only supported. */
 858                /* reg_w() only supports 8bit index */
 859                index = reg->reg;
 860                value = reg->val;
 861
 862                /*
 863                 * Note that there shall be no access to other page
 864                 * by any other function between the page switch and
 865                 * the actual register write.
 866                 */
 867                reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
 868                reg_w(gspca_dev, index, value);
 869
 870                reg_w(gspca_dev, 0xdc, 0x01);
 871        }
 872        return gspca_dev->usb_err;
 873}
 874
 875static int sd_chip_ident(struct gspca_dev *gspca_dev,
 876                        struct v4l2_dbg_chip_ident *chip)
 877{
 878        int ret = -EINVAL;
 879
 880        if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
 881            chip->match.addr == 0) {
 882                chip->revision = 0;
 883                chip->ident = V4L2_IDENT_UNKNOWN;
 884                ret = 0;
 885        }
 886        return ret;
 887}
 888#endif
 889
 890#if IS_ENABLED(CONFIG_INPUT)
 891static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
 892                        u8 *data,               /* interrupt packet data */
 893                        int len)                /* interrput packet length */
 894{
 895        int ret = -EINVAL;
 896        u8 data0, data1;
 897
 898        if (len == 2) {
 899                data0 = data[0];
 900                data1 = data[1];
 901                if ((data0 == 0x00 && data1 == 0x11) ||
 902                    (data0 == 0x22 && data1 == 0x33) ||
 903                    (data0 == 0x44 && data1 == 0x55) ||
 904                    (data0 == 0x66 && data1 == 0x77) ||
 905                    (data0 == 0x88 && data1 == 0x99) ||
 906                    (data0 == 0xaa && data1 == 0xbb) ||
 907                    (data0 == 0xcc && data1 == 0xdd) ||
 908                    (data0 == 0xee && data1 == 0xff)) {
 909                        input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
 910                        input_sync(gspca_dev->input_dev);
 911                        input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
 912                        input_sync(gspca_dev->input_dev);
 913                        ret = 0;
 914                }
 915        }
 916
 917        return ret;
 918}
 919#endif
 920
 921/* sub-driver description for pac7302 */
 922static const struct sd_desc sd_desc = {
 923        .name = KBUILD_MODNAME,
 924        .config = sd_config,
 925        .init = sd_init,
 926        .init_controls = sd_init_controls,
 927        .start = sd_start,
 928        .stopN = sd_stopN,
 929        .stop0 = sd_stop0,
 930        .pkt_scan = sd_pkt_scan,
 931        .dq_callback = do_autogain,
 932#ifdef CONFIG_VIDEO_ADV_DEBUG
 933        .set_register = sd_dbg_s_register,
 934        .get_chip_ident = sd_chip_ident,
 935#endif
 936#if IS_ENABLED(CONFIG_INPUT)
 937        .int_pkt_scan = sd_int_pkt_scan,
 938#endif
 939};
 940
 941/* -- module initialisation -- */
 942static const struct usb_device_id device_table[] = {
 943        {USB_DEVICE(0x06f8, 0x3009)},
 944        {USB_DEVICE(0x06f8, 0x301b)},
 945        {USB_DEVICE(0x093a, 0x2620)},
 946        {USB_DEVICE(0x093a, 0x2621)},
 947        {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
 948        {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
 949        {USB_DEVICE(0x093a, 0x2625)},
 950        {USB_DEVICE(0x093a, 0x2626)},
 951        {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
 952        {USB_DEVICE(0x093a, 0x2628)},
 953        {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
 954        {USB_DEVICE(0x093a, 0x262a)},
 955        {USB_DEVICE(0x093a, 0x262c)},
 956        {USB_DEVICE(0x145f, 0x013c)},
 957        {USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
 958        {}
 959};
 960MODULE_DEVICE_TABLE(usb, device_table);
 961
 962/* -- device connect -- */
 963static int sd_probe(struct usb_interface *intf,
 964                        const struct usb_device_id *id)
 965{
 966        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 967                                THIS_MODULE);
 968}
 969
 970static struct usb_driver sd_driver = {
 971        .name = KBUILD_MODNAME,
 972        .id_table = device_table,
 973        .probe = sd_probe,
 974        .disconnect = gspca_disconnect,
 975#ifdef CONFIG_PM
 976        .suspend = gspca_suspend,
 977        .resume = gspca_resume,
 978        .reset_resume = gspca_resume,
 979#endif
 980};
 981
 982module_usb_driver(sd_driver);
 983