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#ifdef GSPCA_DEBUG
 348                        if (len > USB_BUF_SZ) {
 349                                PDEBUG(D_ERR|D_STREAM,
 350                                        "Incorrect variable sequence");
 351                                return;
 352                        }
 353#endif
 354                        while (len > 0) {
 355                                if (len < 8) {
 356                                        reg_w_buf(gspca_dev,
 357                                                index, seq, len);
 358                                        seq += len;
 359                                        break;
 360                                }
 361                                reg_w_buf(gspca_dev, index, seq, 8);
 362                                seq += 8;
 363                                index += 8;
 364                                len -= 8;
 365                        }
 366                }
 367        }
 368        /* not reached */
 369}
 370
 371/* this function is called at probe time for pac7302 */
 372static int sd_config(struct gspca_dev *gspca_dev,
 373                        const struct usb_device_id *id)
 374{
 375        struct sd *sd = (struct sd *) gspca_dev;
 376        struct cam *cam;
 377
 378        cam = &gspca_dev->cam;
 379
 380        cam->cam_mode = vga_mode;       /* only 640x480 */
 381        cam->nmodes = ARRAY_SIZE(vga_mode);
 382
 383        sd->flags = id->driver_info;
 384        return 0;
 385}
 386
 387static void setbrightcont(struct gspca_dev *gspca_dev)
 388{
 389        struct sd *sd = (struct sd *) gspca_dev;
 390        int i, v;
 391        static const u8 max[10] =
 392                {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
 393                 0xd4, 0xec};
 394        static const u8 delta[10] =
 395                {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
 396                 0x11, 0x0b};
 397
 398        reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
 399        for (i = 0; i < 10; i++) {
 400                v = max[i];
 401                v += (sd->brightness->val - sd->brightness->maximum)
 402                        * 150 / sd->brightness->maximum; /* 200 ? */
 403                v -= delta[i] * sd->contrast->val / sd->contrast->maximum;
 404                if (v < 0)
 405                        v = 0;
 406                else if (v > 0xff)
 407                        v = 0xff;
 408                reg_w(gspca_dev, 0xa2 + i, v);
 409        }
 410        reg_w(gspca_dev, 0xdc, 0x01);
 411}
 412
 413static void setcolors(struct gspca_dev *gspca_dev)
 414{
 415        struct sd *sd = (struct sd *) gspca_dev;
 416        int i, v;
 417        static const int a[9] =
 418                {217, -212, 0, -101, 170, -67, -38, -315, 355};
 419        static const int b[9] =
 420                {19, 106, 0, 19, 106, 1, 19, 106, 1};
 421
 422        reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
 423        reg_w(gspca_dev, 0x11, 0x01);
 424        reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
 425        for (i = 0; i < 9; i++) {
 426                v = a[i] * sd->saturation->val / sd->saturation->maximum;
 427                v += b[i];
 428                reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
 429                reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
 430        }
 431        reg_w(gspca_dev, 0xdc, 0x01);
 432}
 433
 434static void setwhitebalance(struct gspca_dev *gspca_dev)
 435{
 436        struct sd *sd = (struct sd *) gspca_dev;
 437
 438        reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
 439        reg_w(gspca_dev, 0xc6, sd->white_balance->val);
 440
 441        reg_w(gspca_dev, 0xdc, 0x01);
 442}
 443
 444static u8 rgbbalance_ctrl_to_reg_value(s32 rgb_ctrl_val)
 445{
 446        const unsigned int k = 1000;    /* precision factor */
 447        unsigned int norm;
 448
 449        /* Normed value [0...k] */
 450        norm = k * (rgb_ctrl_val - PAC7302_RGB_BALANCE_MIN)
 451                    / (PAC7302_RGB_BALANCE_MAX - PAC7302_RGB_BALANCE_MIN);
 452        /* Qudratic apporach improves control at small (register) values: */
 453        return 64 * norm * norm / (k*k)  +  32 * norm / k  +  32;
 454        /* Y = 64*X*X + 32*X + 32
 455         * => register values 0x20-0x80; Windows driver uses these limits */
 456
 457        /* NOTE: for full value range (0x00-0xff) use
 458         *         Y = 254*X*X + X
 459         *         => 254 * norm * norm / (k*k)  +  1 * norm / k        */
 460}
 461
 462static void setredbalance(struct gspca_dev *gspca_dev)
 463{
 464        struct sd *sd = (struct sd *) gspca_dev;
 465
 466        reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
 467        reg_w(gspca_dev, 0x01,
 468              rgbbalance_ctrl_to_reg_value(sd->red_balance->val));
 469
 470        reg_w(gspca_dev, 0xdc, 0x01);
 471}
 472
 473static void setbluebalance(struct gspca_dev *gspca_dev)
 474{
 475        struct sd *sd = (struct sd *) gspca_dev;
 476
 477        reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
 478        reg_w(gspca_dev, 0x03,
 479              rgbbalance_ctrl_to_reg_value(sd->blue_balance->val));
 480
 481        reg_w(gspca_dev, 0xdc, 0x01);
 482}
 483
 484static void setgain(struct gspca_dev *gspca_dev)
 485{
 486        u8 reg10, reg12;
 487
 488        if (gspca_dev->gain->val < 32) {
 489                reg10 = gspca_dev->gain->val;
 490                reg12 = 0;
 491        } else {
 492                reg10 = 31;
 493                reg12 = gspca_dev->gain->val - 31;
 494        }
 495
 496        reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
 497        reg_w(gspca_dev, 0x10, reg10);
 498        reg_w(gspca_dev, 0x12, reg12);
 499
 500        /* load registers to sensor (Bit 0, auto clear) */
 501        reg_w(gspca_dev, 0x11, 0x01);
 502}
 503
 504static void setexposure(struct gspca_dev *gspca_dev)
 505{
 506        u8 clockdiv;
 507        u16 exposure;
 508
 509        /*
 510         * Register 2 of frame 3 contains the clock divider configuring the
 511         * no fps according to the formula: 90 / reg. sd->exposure is the
 512         * desired exposure time in 0.5 ms.
 513         */
 514        clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000;
 515
 516        /*
 517         * Note clockdiv = 3 also works, but when running at 30 fps, depending
 518         * on the scene being recorded, the camera switches to another
 519         * quantization table for certain JPEG blocks, and we don't know how
 520         * to decompress these blocks. So we cap the framerate at 15 fps.
 521         */
 522        if (clockdiv < 6)
 523                clockdiv = 6;
 524        else if (clockdiv > 63)
 525                clockdiv = 63;
 526
 527        /*
 528         * Register 2 MUST be a multiple of 3, except when between 6 and 12?
 529         * Always round up, otherwise we cannot get the desired frametime
 530         * using the partial frame time exposure control.
 531         */
 532        if (clockdiv < 6 || clockdiv > 12)
 533                clockdiv = ((clockdiv + 2) / 3) * 3;
 534
 535        /*
 536         * frame exposure time in ms = 1000 * clockdiv / 90    ->
 537         * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
 538         */
 539        exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv);
 540        /* 0 = use full frametime, 448 = no exposure, reverse it */
 541        exposure = 448 - exposure;
 542
 543        reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
 544        reg_w(gspca_dev, 0x02, clockdiv);
 545        reg_w(gspca_dev, 0x0e, exposure & 0xff);
 546        reg_w(gspca_dev, 0x0f, exposure >> 8);
 547
 548        /* load registers to sensor (Bit 0, auto clear) */
 549        reg_w(gspca_dev, 0x11, 0x01);
 550}
 551
 552static void sethvflip(struct gspca_dev *gspca_dev)
 553{
 554        struct sd *sd = (struct sd *) gspca_dev;
 555        u8 data, hflip, vflip;
 556
 557        hflip = sd->hflip->val;
 558        if (sd->flags & FL_HFLIP)
 559                hflip = !hflip;
 560        vflip = sd->vflip->val;
 561        if (sd->flags & FL_VFLIP)
 562                vflip = !vflip;
 563
 564        reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
 565        data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
 566        reg_w(gspca_dev, 0x21, data);
 567
 568        /* load registers to sensor (Bit 0, auto clear) */
 569        reg_w(gspca_dev, 0x11, 0x01);
 570}
 571
 572static void setsharpness(struct gspca_dev *gspca_dev)
 573{
 574        struct sd *sd = (struct sd *) gspca_dev;
 575
 576        reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
 577        reg_w(gspca_dev, 0xb6, sd->sharpness->val);
 578
 579        reg_w(gspca_dev, 0xdc, 0x01);
 580}
 581
 582/* this function is called at probe and resume time for pac7302 */
 583static int sd_init(struct gspca_dev *gspca_dev)
 584{
 585        reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
 586        return gspca_dev->usb_err;
 587}
 588
 589static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
 590{
 591        struct gspca_dev *gspca_dev =
 592                container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 593        struct sd *sd = (struct sd *)gspca_dev;
 594
 595        gspca_dev->usb_err = 0;
 596
 597        if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
 598                /* when switching to autogain set defaults to make sure
 599                   we are on a valid point of the autogain gain /
 600                   exposure knee graph, and give this change time to
 601                   take effect before doing autogain. */
 602                gspca_dev->exposure->val    = PAC7302_EXPOSURE_DEFAULT;
 603                gspca_dev->gain->val        = PAC7302_GAIN_DEFAULT;
 604                sd->autogain_ignore_frames  = PAC_AUTOGAIN_IGNORE_FRAMES;
 605        }
 606
 607        if (!gspca_dev->streaming)
 608                return 0;
 609
 610        switch (ctrl->id) {
 611        case V4L2_CID_BRIGHTNESS:
 612                setbrightcont(gspca_dev);
 613                break;
 614        case V4L2_CID_SATURATION:
 615                setcolors(gspca_dev);
 616                break;
 617        case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
 618                setwhitebalance(gspca_dev);
 619                break;
 620        case V4L2_CID_RED_BALANCE:
 621                setredbalance(gspca_dev);
 622                break;
 623        case V4L2_CID_BLUE_BALANCE:
 624                setbluebalance(gspca_dev);
 625                break;
 626        case V4L2_CID_AUTOGAIN:
 627                if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
 628                        setexposure(gspca_dev);
 629                if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
 630                        setgain(gspca_dev);
 631                break;
 632        case V4L2_CID_HFLIP:
 633                sethvflip(gspca_dev);
 634                break;
 635        case V4L2_CID_SHARPNESS:
 636                setsharpness(gspca_dev);
 637                break;
 638        default:
 639                return -EINVAL;
 640        }
 641        return gspca_dev->usb_err;
 642}
 643
 644static const struct v4l2_ctrl_ops sd_ctrl_ops = {
 645        .s_ctrl = sd_s_ctrl,
 646};
 647
 648/* this function is called at probe time */
 649static int sd_init_controls(struct gspca_dev *gspca_dev)
 650{
 651        struct sd *sd = (struct sd *) gspca_dev;
 652        struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
 653
 654        gspca_dev->vdev.ctrl_handler = hdl;
 655        v4l2_ctrl_handler_init(hdl, 12);
 656
 657        sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 658                                        V4L2_CID_BRIGHTNESS, 0, 32, 1, 16);
 659        sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 660                                        V4L2_CID_CONTRAST, 0, 255, 1, 127);
 661
 662        sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 663                                        V4L2_CID_SATURATION, 0, 255, 1, 127);
 664        sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 665                                        V4L2_CID_WHITE_BALANCE_TEMPERATURE,
 666                                        0, 255, 1, 55);
 667        sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 668                                        V4L2_CID_RED_BALANCE,
 669                                        PAC7302_RGB_BALANCE_MIN,
 670                                        PAC7302_RGB_BALANCE_MAX,
 671                                        1, PAC7302_RGB_BALANCE_DEFAULT);
 672        sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 673                                        V4L2_CID_BLUE_BALANCE,
 674                                        PAC7302_RGB_BALANCE_MIN,
 675                                        PAC7302_RGB_BALANCE_MAX,
 676                                        1, PAC7302_RGB_BALANCE_DEFAULT);
 677
 678        gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 679                                        V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
 680        gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 681                                        V4L2_CID_EXPOSURE, 0, 1023, 1,
 682                                        PAC7302_EXPOSURE_DEFAULT);
 683        gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 684                                        V4L2_CID_GAIN, 0, 62, 1,
 685                                        PAC7302_GAIN_DEFAULT);
 686
 687        sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 688                V4L2_CID_HFLIP, 0, 1, 1, 0);
 689        sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 690                V4L2_CID_VFLIP, 0, 1, 1, 0);
 691
 692        sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 693                                        V4L2_CID_SHARPNESS, 0, 15, 1, 8);
 694
 695        if (hdl->error) {
 696                pr_err("Could not initialize controls\n");
 697                return hdl->error;
 698        }
 699
 700        v4l2_ctrl_cluster(2, &sd->brightness);
 701        v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
 702        v4l2_ctrl_cluster(2, &sd->hflip);
 703        return 0;
 704}
 705
 706/* -- start the camera -- */
 707static int sd_start(struct gspca_dev *gspca_dev)
 708{
 709        struct sd *sd = (struct sd *) gspca_dev;
 710
 711        reg_w_var(gspca_dev, start_7302,
 712                page3_7302, sizeof(page3_7302));
 713
 714        sd->sof_read = 0;
 715        sd->autogain_ignore_frames = 0;
 716        atomic_set(&sd->avg_lum, 270 + sd->brightness->val);
 717
 718        /* start stream */
 719        reg_w(gspca_dev, 0xff, 0x01);
 720        reg_w(gspca_dev, 0x78, 0x01);
 721
 722        return gspca_dev->usb_err;
 723}
 724
 725static void sd_stopN(struct gspca_dev *gspca_dev)
 726{
 727
 728        /* stop stream */
 729        reg_w(gspca_dev, 0xff, 0x01);
 730        reg_w(gspca_dev, 0x78, 0x00);
 731}
 732
 733/* called on streamoff with alt 0 and on disconnect for pac7302 */
 734static void sd_stop0(struct gspca_dev *gspca_dev)
 735{
 736        if (!gspca_dev->present)
 737                return;
 738        reg_w(gspca_dev, 0xff, 0x01);
 739        reg_w(gspca_dev, 0x78, 0x40);
 740}
 741
 742static void do_autogain(struct gspca_dev *gspca_dev)
 743{
 744        struct sd *sd = (struct sd *) gspca_dev;
 745        int avg_lum = atomic_read(&sd->avg_lum);
 746        int desired_lum;
 747        const int deadzone = 30;
 748
 749        if (sd->autogain_ignore_frames < 0)
 750                return;
 751
 752        if (sd->autogain_ignore_frames > 0) {
 753                sd->autogain_ignore_frames--;
 754        } else {
 755                desired_lum = 270 + sd->brightness->val;
 756
 757                if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum,
 758                                        deadzone, PAC7302_GAIN_KNEE,
 759                                        PAC7302_EXPOSURE_KNEE))
 760                        sd->autogain_ignore_frames =
 761                                                PAC_AUTOGAIN_IGNORE_FRAMES;
 762        }
 763}
 764
 765/* JPEG header */
 766static const u8 jpeg_header[] = {
 767        0xff, 0xd8,     /* SOI: Start of Image */
 768
 769        0xff, 0xc0,     /* SOF0: Start of Frame (Baseline DCT) */
 770        0x00, 0x11,     /* length = 17 bytes (including this length field) */
 771        0x08,           /* Precision: 8 */
 772        0x02, 0x80,     /* height = 640 (image rotated) */
 773        0x01, 0xe0,     /* width = 480 */
 774        0x03,           /* Number of image components: 3 */
 775        0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
 776        0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
 777        0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
 778
 779        0xff, 0xda,     /* SOS: Start Of Scan */
 780        0x00, 0x0c,     /* length = 12 bytes (including this length field) */
 781        0x03,           /* number of components: 3 */
 782        0x01, 0x00,     /* selector 1, table 0x00 */
 783        0x02, 0x11,     /* selector 2, table 0x11 */
 784        0x03, 0x11,     /* selector 3, table 0x11 */
 785        0x00, 0x3f,     /* Spectral selection: 0 .. 63 */
 786        0x00            /* Successive approximation: 0 */
 787};
 788
 789/* this function is run at interrupt level */
 790static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 791                        u8 *data,                       /* isoc packet */
 792                        int len)                        /* iso packet length */
 793{
 794        struct sd *sd = (struct sd *) gspca_dev;
 795        u8 *image;
 796        u8 *sof;
 797
 798        sof = pac_find_sof(&sd->sof_read, data, len);
 799        if (sof) {
 800                int n, lum_offset, footer_length;
 801
 802                /*
 803                 * 6 bytes after the FF D9 EOF marker a number of lumination
 804                 * bytes are send corresponding to different parts of the
 805                 * image, the 14th and 15th byte after the EOF seem to
 806                 * correspond to the center of the image.
 807                 */
 808                lum_offset = 61 + sizeof pac_sof_marker;
 809                footer_length = 74;
 810
 811                /* Finish decoding current frame */
 812                n = (sof - data) - (footer_length + sizeof pac_sof_marker);
 813                if (n < 0) {
 814                        gspca_dev->image_len += n;
 815                        n = 0;
 816                } else {
 817                        gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
 818                }
 819
 820                image = gspca_dev->image;
 821                if (image != NULL
 822                 && image[gspca_dev->image_len - 2] == 0xff
 823                 && image[gspca_dev->image_len - 1] == 0xd9)
 824                        gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 825
 826                n = sof - data;
 827                len -= n;
 828                data = sof;
 829
 830                /* Get average lumination */
 831                if (gspca_dev->last_packet_type == LAST_PACKET &&
 832                                n >= lum_offset)
 833                        atomic_set(&sd->avg_lum, data[-lum_offset] +
 834                                                data[-lum_offset + 1]);
 835
 836                /* Start the new frame with the jpeg header */
 837                /* The PAC7302 has the image rotated 90 degrees */
 838                gspca_frame_add(gspca_dev, FIRST_PACKET,
 839                                jpeg_header, sizeof jpeg_header);
 840        }
 841        gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 842}
 843
 844#ifdef CONFIG_VIDEO_ADV_DEBUG
 845static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
 846                        struct v4l2_dbg_register *reg)
 847{
 848        u8 index;
 849        u8 value;
 850
 851        /*
 852         * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
 853         *                     long on the USB bus)
 854         */
 855        if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
 856            reg->match.addr == 0 &&
 857            (reg->reg < 0x000000ff) &&
 858            (reg->val <= 0x000000ff)
 859        ) {
 860                /* Currently writing to page 0 is only supported. */
 861                /* reg_w() only supports 8bit index */
 862                index = reg->reg;
 863                value = reg->val;
 864
 865                /*
 866                 * Note that there shall be no access to other page
 867                 * by any other function between the page switch and
 868                 * the actual register write.
 869                 */
 870                reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
 871                reg_w(gspca_dev, index, value);
 872
 873                reg_w(gspca_dev, 0xdc, 0x01);
 874        }
 875        return gspca_dev->usb_err;
 876}
 877
 878static int sd_chip_ident(struct gspca_dev *gspca_dev,
 879                        struct v4l2_dbg_chip_ident *chip)
 880{
 881        int ret = -EINVAL;
 882
 883        if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
 884            chip->match.addr == 0) {
 885                chip->revision = 0;
 886                chip->ident = V4L2_IDENT_UNKNOWN;
 887                ret = 0;
 888        }
 889        return ret;
 890}
 891#endif
 892
 893#if IS_ENABLED(CONFIG_INPUT)
 894static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
 895                        u8 *data,               /* interrupt packet data */
 896                        int len)                /* interrput packet length */
 897{
 898        int ret = -EINVAL;
 899        u8 data0, data1;
 900
 901        if (len == 2) {
 902                data0 = data[0];
 903                data1 = data[1];
 904                if ((data0 == 0x00 && data1 == 0x11) ||
 905                    (data0 == 0x22 && data1 == 0x33) ||
 906                    (data0 == 0x44 && data1 == 0x55) ||
 907                    (data0 == 0x66 && data1 == 0x77) ||
 908                    (data0 == 0x88 && data1 == 0x99) ||
 909                    (data0 == 0xaa && data1 == 0xbb) ||
 910                    (data0 == 0xcc && data1 == 0xdd) ||
 911                    (data0 == 0xee && data1 == 0xff)) {
 912                        input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
 913                        input_sync(gspca_dev->input_dev);
 914                        input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
 915                        input_sync(gspca_dev->input_dev);
 916                        ret = 0;
 917                }
 918        }
 919
 920        return ret;
 921}
 922#endif
 923
 924/* sub-driver description for pac7302 */
 925static const struct sd_desc sd_desc = {
 926        .name = KBUILD_MODNAME,
 927        .config = sd_config,
 928        .init = sd_init,
 929        .init_controls = sd_init_controls,
 930        .start = sd_start,
 931        .stopN = sd_stopN,
 932        .stop0 = sd_stop0,
 933        .pkt_scan = sd_pkt_scan,
 934        .dq_callback = do_autogain,
 935#ifdef CONFIG_VIDEO_ADV_DEBUG
 936        .set_register = sd_dbg_s_register,
 937        .get_chip_ident = sd_chip_ident,
 938#endif
 939#if IS_ENABLED(CONFIG_INPUT)
 940        .int_pkt_scan = sd_int_pkt_scan,
 941#endif
 942};
 943
 944/* -- module initialisation -- */
 945static const struct usb_device_id device_table[] = {
 946        {USB_DEVICE(0x06f8, 0x3009)},
 947        {USB_DEVICE(0x06f8, 0x301b)},
 948        {USB_DEVICE(0x093a, 0x2620)},
 949        {USB_DEVICE(0x093a, 0x2621)},
 950        {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
 951        {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
 952        {USB_DEVICE(0x093a, 0x2625)},
 953        {USB_DEVICE(0x093a, 0x2626)},
 954        {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
 955        {USB_DEVICE(0x093a, 0x2628)},
 956        {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
 957        {USB_DEVICE(0x093a, 0x262a)},
 958        {USB_DEVICE(0x093a, 0x262c)},
 959        {USB_DEVICE(0x145f, 0x013c)},
 960        {USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
 961        {}
 962};
 963MODULE_DEVICE_TABLE(usb, device_table);
 964
 965/* -- device connect -- */
 966static int sd_probe(struct usb_interface *intf,
 967                        const struct usb_device_id *id)
 968{
 969        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 970                                THIS_MODULE);
 971}
 972
 973static struct usb_driver sd_driver = {
 974        .name = KBUILD_MODNAME,
 975        .id_table = device_table,
 976        .probe = sd_probe,
 977        .disconnect = gspca_disconnect,
 978#ifdef CONFIG_PM
 979        .suspend = gspca_suspend,
 980        .resume = gspca_resume,
 981        .reset_resume = gspca_resume,
 982#endif
 983};
 984
 985module_usb_driver(sd_driver);
 986
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.