linux/drivers/media/usb/gspca/pac7311.c
<<
>>
Prefs
   1/*
   2 *              Pixart PAC7311 library
   3 *              Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
   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/* Some documentation about various registers as determined by trial and error.
  23 *
  24 * Register page 1:
  25 *
  26 * Address      Description
  27 * 0x08         Unknown compressor related, must always be 8 except when not
  28 *              in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
  29 * 0x1b         Auto white balance related, bit 0 is AWB enable (inverted)
  30 *              bits 345 seem to toggle per color gains on/off (inverted)
  31 * 0x78         Global control, bit 6 controls the LED (inverted)
  32 * 0x80         Compression balance, interesting settings:
  33 *              0x01 Use this to allow the camera to switch to higher compr.
  34 *                   on the fly. Needed to stay within bandwidth @ 640x480@30
  35 *              0x1c From usb captures under Windows for 640x480
  36 *              0x2a Values >= this switch the camera to a lower compression,
  37 *                   using the same table for both luminance and chrominance.
  38 *                   This gives a sharper picture. Usable only at 640x480@ <
  39 *                   15 fps or 320x240 / 160x120. Note currently the driver
  40 *                   does not use this as the quality gain is small and the
  41 *                   generated JPG-s are only understood by v4l-utils >= 0.8.9
  42 *              0x3f From usb captures under Windows for 320x240
  43 *              0x69 From usb captures under Windows for 160x120
  44 *
  45 * Register page 4:
  46 *
  47 * Address      Description
  48 * 0x02         Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
  49 *              the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
  50 * 0x0f         Master gain 1-245, low value = high gain
  51 * 0x10         Another gain 0-15, limited influence (1-2x gain I guess)
  52 * 0x21         Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
  53 *              Note setting vflip disabled leads to a much lower image quality,
  54 *              so we always vflip, and tell userspace to flip it back
  55 * 0x27         Seems to toggle various gains on / off, Setting bit 7 seems to
  56 *              completely disable the analog amplification block. Set to 0x68
  57 *              for max gain, 0x14 for minimal gain.
  58 */
  59
  60#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  61
  62#define MODULE_NAME "pac7311"
  63
  64#include <linux/input.h>
  65#include "gspca.h"
  66/* Include pac common sof detection functions */
  67#include "pac_common.h"
  68
  69#define PAC7311_GAIN_DEFAULT     122
  70#define PAC7311_EXPOSURE_DEFAULT   3 /* 20 fps, avoid using high compr. */
  71
  72MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
  73MODULE_DESCRIPTION("Pixart PAC7311");
  74MODULE_LICENSE("GPL");
  75
  76struct sd {
  77        struct gspca_dev gspca_dev;             /* !! must be the first item */
  78
  79        struct v4l2_ctrl *contrast;
  80        struct v4l2_ctrl *hflip;
  81
  82        u8 sof_read;
  83        u8 autogain_ignore_frames;
  84
  85        atomic_t avg_lum;
  86};
  87
  88static const struct v4l2_pix_format vga_mode[] = {
  89        {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
  90                .bytesperline = 160,
  91                .sizeimage = 160 * 120 * 3 / 8 + 590,
  92                .colorspace = V4L2_COLORSPACE_JPEG,
  93                .priv = 2},
  94        {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
  95                .bytesperline = 320,
  96                .sizeimage = 320 * 240 * 3 / 8 + 590,
  97                .colorspace = V4L2_COLORSPACE_JPEG,
  98                .priv = 1},
  99        {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
 100                .bytesperline = 640,
 101                .sizeimage = 640 * 480 * 3 / 8 + 590,
 102                .colorspace = V4L2_COLORSPACE_JPEG,
 103                .priv = 0},
 104};
 105
 106#define LOAD_PAGE4              254
 107#define END_OF_SEQUENCE         0
 108
 109static const __u8 init_7311[] = {
 110        0xff, 0x01,
 111        0x78, 0x40,     /* Bit_0=start stream, Bit_6=LED */
 112        0x78, 0x40,     /* Bit_0=start stream, Bit_6=LED */
 113        0x78, 0x44,     /* Bit_0=start stream, Bit_6=LED */
 114        0xff, 0x04,
 115        0x27, 0x80,
 116        0x28, 0xca,
 117        0x29, 0x53,
 118        0x2a, 0x0e,
 119        0xff, 0x01,
 120        0x3e, 0x20,
 121};
 122
 123static const __u8 start_7311[] = {
 124/*      index, len, [value]* */
 125        0xff, 1,        0x01,           /* page 1 */
 126        0x02, 43,       0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
 127                        0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
 128                        0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
 129                        0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
 130                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 131                        0x00, 0x00, 0x00,
 132        0x3e, 42,       0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
 133                        0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
 134                        0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
 135                        0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
 136                        0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
 137                        0xd0, 0xff,
 138        0x78, 6,        0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
 139        0x7f, 18,       0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
 140                        0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
 141                        0x18, 0x20,
 142        0x96, 3,        0x01, 0x08, 0x04,
 143        0xa0, 4,        0x44, 0x44, 0x44, 0x04,
 144        0xf0, 13,       0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
 145                        0x3f, 0x00, 0x0a, 0x01, 0x00,
 146        0xff, 1,        0x04,           /* page 4 */
 147        0, LOAD_PAGE4,                  /* load the page 4 */
 148        0x11, 1,        0x01,
 149        0, END_OF_SEQUENCE              /* end of sequence */
 150};
 151
 152#define SKIP            0xaa
 153/* page 4 - the value SKIP says skip the index - see reg_w_page() */
 154static const __u8 page4_7311[] = {
 155        SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
 156        0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
 157        0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
 158        0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
 159        SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
 160        0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
 161        0x23, 0x28, 0x04, 0x11, 0x00, 0x00
 162};
 163
 164static void reg_w_buf(struct gspca_dev *gspca_dev,
 165                  __u8 index,
 166                  const u8 *buffer, int len)
 167{
 168        int ret;
 169
 170        if (gspca_dev->usb_err < 0)
 171                return;
 172        memcpy(gspca_dev->usb_buf, buffer, len);
 173        ret = usb_control_msg(gspca_dev->dev,
 174                        usb_sndctrlpipe(gspca_dev->dev, 0),
 175                        0,              /* request */
 176                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 177                        0,              /* value */
 178                        index, gspca_dev->usb_buf, len,
 179                        500);
 180        if (ret < 0) {
 181                pr_err("reg_w_buf() failed index 0x%02x, error %d\n",
 182                       index, ret);
 183                gspca_dev->usb_err = ret;
 184        }
 185}
 186
 187
 188static void reg_w(struct gspca_dev *gspca_dev,
 189                  __u8 index,
 190                  __u8 value)
 191{
 192        int ret;
 193
 194        if (gspca_dev->usb_err < 0)
 195                return;
 196        gspca_dev->usb_buf[0] = value;
 197        ret = usb_control_msg(gspca_dev->dev,
 198                        usb_sndctrlpipe(gspca_dev->dev, 0),
 199                        0,                      /* request */
 200                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 201                        0, index, gspca_dev->usb_buf, 1,
 202                        500);
 203        if (ret < 0) {
 204                pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n",
 205                       index, value, ret);
 206                gspca_dev->usb_err = ret;
 207        }
 208}
 209
 210static void reg_w_seq(struct gspca_dev *gspca_dev,
 211                const __u8 *seq, int len)
 212{
 213        while (--len >= 0) {
 214                reg_w(gspca_dev, seq[0], seq[1]);
 215                seq += 2;
 216        }
 217}
 218
 219/* load the beginning of a page */
 220static void reg_w_page(struct gspca_dev *gspca_dev,
 221                        const __u8 *page, int len)
 222{
 223        int index;
 224        int ret = 0;
 225
 226        if (gspca_dev->usb_err < 0)
 227                return;
 228        for (index = 0; index < len; index++) {
 229                if (page[index] == SKIP)                /* skip this index */
 230                        continue;
 231                gspca_dev->usb_buf[0] = page[index];
 232                ret = usb_control_msg(gspca_dev->dev,
 233                                usb_sndctrlpipe(gspca_dev->dev, 0),
 234                                0,                      /* request */
 235                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 236                                0, index, gspca_dev->usb_buf, 1,
 237                                500);
 238                if (ret < 0) {
 239                        pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n",
 240                               index, page[index], ret);
 241                        gspca_dev->usb_err = ret;
 242                        break;
 243                }
 244        }
 245}
 246
 247/* output a variable sequence */
 248static void reg_w_var(struct gspca_dev *gspca_dev,
 249                        const __u8 *seq,
 250                        const __u8 *page4, unsigned int page4_len)
 251{
 252        int index, len;
 253
 254        for (;;) {
 255                index = *seq++;
 256                len = *seq++;
 257                switch (len) {
 258                case END_OF_SEQUENCE:
 259                        return;
 260                case LOAD_PAGE4:
 261                        reg_w_page(gspca_dev, page4, page4_len);
 262                        break;
 263                default:
 264                        if (len > USB_BUF_SZ) {
 265                                PDEBUG(D_ERR|D_STREAM,
 266                                        "Incorrect variable sequence");
 267                                return;
 268                        }
 269                        while (len > 0) {
 270                                if (len < 8) {
 271                                        reg_w_buf(gspca_dev,
 272                                                index, seq, len);
 273                                        seq += len;
 274                                        break;
 275                                }
 276                                reg_w_buf(gspca_dev, index, seq, 8);
 277                                seq += 8;
 278                                index += 8;
 279                                len -= 8;
 280                        }
 281                }
 282        }
 283        /* not reached */
 284}
 285
 286/* this function is called at probe time for pac7311 */
 287static int sd_config(struct gspca_dev *gspca_dev,
 288                        const struct usb_device_id *id)
 289{
 290        struct cam *cam = &gspca_dev->cam;
 291
 292        cam->cam_mode = vga_mode;
 293        cam->nmodes = ARRAY_SIZE(vga_mode);
 294        cam->input_flags = V4L2_IN_ST_VFLIP;
 295
 296        return 0;
 297}
 298
 299static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
 300{
 301        reg_w(gspca_dev, 0xff, 0x04);
 302        reg_w(gspca_dev, 0x10, val);
 303        /* load registers to sensor (Bit 0, auto clear) */
 304        reg_w(gspca_dev, 0x11, 0x01);
 305}
 306
 307static void setgain(struct gspca_dev *gspca_dev, s32 val)
 308{
 309        reg_w(gspca_dev, 0xff, 0x04);                   /* page 4 */
 310        reg_w(gspca_dev, 0x0e, 0x00);
 311        reg_w(gspca_dev, 0x0f, gspca_dev->gain->maximum - val + 1);
 312
 313        /* load registers to sensor (Bit 0, auto clear) */
 314        reg_w(gspca_dev, 0x11, 0x01);
 315}
 316
 317static void setexposure(struct gspca_dev *gspca_dev, s32 val)
 318{
 319        reg_w(gspca_dev, 0xff, 0x04);                   /* page 4 */
 320        reg_w(gspca_dev, 0x02, val);
 321
 322        /* load registers to sensor (Bit 0, auto clear) */
 323        reg_w(gspca_dev, 0x11, 0x01);
 324
 325        /*
 326         * Page 1 register 8 must always be 0x08 except when not in
 327         *  640x480 mode and page 4 reg 2 <= 3 then it must be 9
 328         */
 329        reg_w(gspca_dev, 0xff, 0x01);
 330        if (gspca_dev->width != 640 && val <= 3)
 331                reg_w(gspca_dev, 0x08, 0x09);
 332        else
 333                reg_w(gspca_dev, 0x08, 0x08);
 334
 335        /*
 336         * Page1 register 80 sets the compression balance, normally we
 337         * want / use 0x1c, but for 640x480@30fps we must allow the
 338         * camera to use higher compression or we may run out of
 339         * bandwidth.
 340         */
 341        if (gspca_dev->width == 640 && val == 2)
 342                reg_w(gspca_dev, 0x80, 0x01);
 343        else
 344                reg_w(gspca_dev, 0x80, 0x1c);
 345
 346        /* load registers to sensor (Bit 0, auto clear) */
 347        reg_w(gspca_dev, 0x11, 0x01);
 348}
 349
 350static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
 351{
 352        __u8 data;
 353
 354        reg_w(gspca_dev, 0xff, 0x04);                   /* page 4 */
 355        data = (hflip ? 0x04 : 0x00) |
 356               (vflip ? 0x08 : 0x00);
 357        reg_w(gspca_dev, 0x21, data);
 358
 359        /* load registers to sensor (Bit 0, auto clear) */
 360        reg_w(gspca_dev, 0x11, 0x01);
 361}
 362
 363/* this function is called at probe and resume time for pac7311 */
 364static int sd_init(struct gspca_dev *gspca_dev)
 365{
 366        reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
 367        return gspca_dev->usb_err;
 368}
 369
 370static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
 371{
 372        struct gspca_dev *gspca_dev =
 373                container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 374        struct sd *sd = (struct sd *)gspca_dev;
 375
 376        gspca_dev->usb_err = 0;
 377
 378        if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
 379                /* when switching to autogain set defaults to make sure
 380                   we are on a valid point of the autogain gain /
 381                   exposure knee graph, and give this change time to
 382                   take effect before doing autogain. */
 383                gspca_dev->exposure->val    = PAC7311_EXPOSURE_DEFAULT;
 384                gspca_dev->gain->val        = PAC7311_GAIN_DEFAULT;
 385                sd->autogain_ignore_frames  = PAC_AUTOGAIN_IGNORE_FRAMES;
 386        }
 387
 388        if (!gspca_dev->streaming)
 389                return 0;
 390
 391        switch (ctrl->id) {
 392        case V4L2_CID_CONTRAST:
 393                setcontrast(gspca_dev, ctrl->val);
 394                break;
 395        case V4L2_CID_AUTOGAIN:
 396                if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
 397                        setexposure(gspca_dev, gspca_dev->exposure->val);
 398                if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
 399                        setgain(gspca_dev, gspca_dev->gain->val);
 400                break;
 401        case V4L2_CID_HFLIP:
 402                sethvflip(gspca_dev, sd->hflip->val, 1);
 403                break;
 404        default:
 405                return -EINVAL;
 406        }
 407        return gspca_dev->usb_err;
 408}
 409
 410static const struct v4l2_ctrl_ops sd_ctrl_ops = {
 411        .s_ctrl = sd_s_ctrl,
 412};
 413
 414/* this function is called at probe time */
 415static int sd_init_controls(struct gspca_dev *gspca_dev)
 416{
 417        struct sd *sd = (struct sd *) gspca_dev;
 418        struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
 419
 420        gspca_dev->vdev.ctrl_handler = hdl;
 421        v4l2_ctrl_handler_init(hdl, 5);
 422
 423        sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 424                                        V4L2_CID_CONTRAST, 0, 15, 1, 7);
 425        gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 426                                        V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
 427        gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 428                                        V4L2_CID_EXPOSURE, 2, 63, 1,
 429                                        PAC7311_EXPOSURE_DEFAULT);
 430        gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 431                                        V4L2_CID_GAIN, 0, 244, 1,
 432                                        PAC7311_GAIN_DEFAULT);
 433        sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 434                V4L2_CID_HFLIP, 0, 1, 1, 0);
 435
 436        if (hdl->error) {
 437                pr_err("Could not initialize controls\n");
 438                return hdl->error;
 439        }
 440
 441        v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
 442        return 0;
 443}
 444
 445/* -- start the camera -- */
 446static int sd_start(struct gspca_dev *gspca_dev)
 447{
 448        struct sd *sd = (struct sd *) gspca_dev;
 449
 450        sd->sof_read = 0;
 451
 452        reg_w_var(gspca_dev, start_7311,
 453                page4_7311, sizeof(page4_7311));
 454        setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast));
 455        setgain(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->gain));
 456        setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure));
 457        sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), 1);
 458
 459        /* set correct resolution */
 460        switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
 461        case 2:                                 /* 160x120 */
 462                reg_w(gspca_dev, 0xff, 0x01);
 463                reg_w(gspca_dev, 0x17, 0x20);
 464                reg_w(gspca_dev, 0x87, 0x10);
 465                break;
 466        case 1:                                 /* 320x240 */
 467                reg_w(gspca_dev, 0xff, 0x01);
 468                reg_w(gspca_dev, 0x17, 0x30);
 469                reg_w(gspca_dev, 0x87, 0x11);
 470                break;
 471        case 0:                                 /* 640x480 */
 472                reg_w(gspca_dev, 0xff, 0x01);
 473                reg_w(gspca_dev, 0x17, 0x00);
 474                reg_w(gspca_dev, 0x87, 0x12);
 475                break;
 476        }
 477
 478        sd->sof_read = 0;
 479        sd->autogain_ignore_frames = 0;
 480        atomic_set(&sd->avg_lum, -1);
 481
 482        /* start stream */
 483        reg_w(gspca_dev, 0xff, 0x01);
 484        reg_w(gspca_dev, 0x78, 0x05);
 485
 486        return gspca_dev->usb_err;
 487}
 488
 489static void sd_stopN(struct gspca_dev *gspca_dev)
 490{
 491        reg_w(gspca_dev, 0xff, 0x04);
 492        reg_w(gspca_dev, 0x27, 0x80);
 493        reg_w(gspca_dev, 0x28, 0xca);
 494        reg_w(gspca_dev, 0x29, 0x53);
 495        reg_w(gspca_dev, 0x2a, 0x0e);
 496        reg_w(gspca_dev, 0xff, 0x01);
 497        reg_w(gspca_dev, 0x3e, 0x20);
 498        reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
 499        reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
 500        reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
 501}
 502
 503static void do_autogain(struct gspca_dev *gspca_dev)
 504{
 505        struct sd *sd = (struct sd *) gspca_dev;
 506        int avg_lum = atomic_read(&sd->avg_lum);
 507        int desired_lum, deadzone;
 508
 509        if (avg_lum == -1)
 510                return;
 511
 512        desired_lum = 170;
 513        deadzone = 20;
 514
 515        if (sd->autogain_ignore_frames > 0)
 516                sd->autogain_ignore_frames--;
 517        else if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
 518                                                    desired_lum, deadzone))
 519                sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
 520}
 521
 522/* JPEG header, part 1 */
 523static const unsigned char pac_jpeg_header1[] = {
 524  0xff, 0xd8,           /* SOI: Start of Image */
 525
 526  0xff, 0xc0,           /* SOF0: Start of Frame (Baseline DCT) */
 527  0x00, 0x11,           /* length = 17 bytes (including this length field) */
 528  0x08                  /* Precision: 8 */
 529  /* 2 bytes is placed here: number of image lines */
 530  /* 2 bytes is placed here: samples per line */
 531};
 532
 533/* JPEG header, continued */
 534static const unsigned char pac_jpeg_header2[] = {
 535  0x03,                 /* Number of image components: 3 */
 536  0x01, 0x21, 0x00,     /* ID=1, Subsampling 1x1, Quantization table: 0 */
 537  0x02, 0x11, 0x01,     /* ID=2, Subsampling 2x1, Quantization table: 1 */
 538  0x03, 0x11, 0x01,     /* ID=3, Subsampling 2x1, Quantization table: 1 */
 539
 540  0xff, 0xda,           /* SOS: Start Of Scan */
 541  0x00, 0x0c,           /* length = 12 bytes (including this length field) */
 542  0x03,                 /* number of components: 3 */
 543  0x01, 0x00,           /* selector 1, table 0x00 */
 544  0x02, 0x11,           /* selector 2, table 0x11 */
 545  0x03, 0x11,           /* selector 3, table 0x11 */
 546  0x00, 0x3f,           /* Spectral selection: 0 .. 63 */
 547  0x00                  /* Successive approximation: 0 */
 548};
 549
 550static void pac_start_frame(struct gspca_dev *gspca_dev,
 551                __u16 lines, __u16 samples_per_line)
 552{
 553        unsigned char tmpbuf[4];
 554
 555        gspca_frame_add(gspca_dev, FIRST_PACKET,
 556                pac_jpeg_header1, sizeof(pac_jpeg_header1));
 557
 558        tmpbuf[0] = lines >> 8;
 559        tmpbuf[1] = lines & 0xff;
 560        tmpbuf[2] = samples_per_line >> 8;
 561        tmpbuf[3] = samples_per_line & 0xff;
 562
 563        gspca_frame_add(gspca_dev, INTER_PACKET,
 564                tmpbuf, sizeof(tmpbuf));
 565        gspca_frame_add(gspca_dev, INTER_PACKET,
 566                pac_jpeg_header2, sizeof(pac_jpeg_header2));
 567}
 568
 569/* this function is run at interrupt level */
 570static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 571                        u8 *data,                       /* isoc packet */
 572                        int len)                        /* iso packet length */
 573{
 574        struct sd *sd = (struct sd *) gspca_dev;
 575        u8 *image;
 576        unsigned char *sof;
 577
 578        sof = pac_find_sof(&sd->sof_read, data, len);
 579        if (sof) {
 580                int n, lum_offset, footer_length;
 581
 582                /*
 583                 * 6 bytes after the FF D9 EOF marker a number of lumination
 584                 * bytes are send corresponding to different parts of the
 585                 * image, the 14th and 15th byte after the EOF seem to
 586                 * correspond to the center of the image.
 587                 */
 588                lum_offset = 24 + sizeof pac_sof_marker;
 589                footer_length = 26;
 590
 591                /* Finish decoding current frame */
 592                n = (sof - data) - (footer_length + sizeof pac_sof_marker);
 593                if (n < 0) {
 594                        gspca_dev->image_len += n;
 595                        n = 0;
 596                } else {
 597                        gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
 598                }
 599                image = gspca_dev->image;
 600                if (image != NULL
 601                 && image[gspca_dev->image_len - 2] == 0xff
 602                 && image[gspca_dev->image_len - 1] == 0xd9)
 603                        gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 604
 605                n = sof - data;
 606                len -= n;
 607                data = sof;
 608
 609                /* Get average lumination */
 610                if (gspca_dev->last_packet_type == LAST_PACKET &&
 611                                n >= lum_offset)
 612                        atomic_set(&sd->avg_lum, data[-lum_offset] +
 613                                                data[-lum_offset + 1]);
 614                else
 615                        atomic_set(&sd->avg_lum, -1);
 616
 617                /* Start the new frame with the jpeg header */
 618                pac_start_frame(gspca_dev,
 619                        gspca_dev->height, gspca_dev->width);
 620        }
 621        gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 622}
 623
 624#if IS_ENABLED(CONFIG_INPUT)
 625static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
 626                        u8 *data,               /* interrupt packet data */
 627                        int len)                /* interrupt packet length */
 628{
 629        int ret = -EINVAL;
 630        u8 data0, data1;
 631
 632        if (len == 2) {
 633                data0 = data[0];
 634                data1 = data[1];
 635                if ((data0 == 0x00 && data1 == 0x11) ||
 636                    (data0 == 0x22 && data1 == 0x33) ||
 637                    (data0 == 0x44 && data1 == 0x55) ||
 638                    (data0 == 0x66 && data1 == 0x77) ||
 639                    (data0 == 0x88 && data1 == 0x99) ||
 640                    (data0 == 0xaa && data1 == 0xbb) ||
 641                    (data0 == 0xcc && data1 == 0xdd) ||
 642                    (data0 == 0xee && data1 == 0xff)) {
 643                        input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
 644                        input_sync(gspca_dev->input_dev);
 645                        input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
 646                        input_sync(gspca_dev->input_dev);
 647                        ret = 0;
 648                }
 649        }
 650
 651        return ret;
 652}
 653#endif
 654
 655static const struct sd_desc sd_desc = {
 656        .name = MODULE_NAME,
 657        .config = sd_config,
 658        .init = sd_init,
 659        .init_controls = sd_init_controls,
 660        .start = sd_start,
 661        .stopN = sd_stopN,
 662        .pkt_scan = sd_pkt_scan,
 663        .dq_callback = do_autogain,
 664#if IS_ENABLED(CONFIG_INPUT)
 665        .int_pkt_scan = sd_int_pkt_scan,
 666#endif
 667};
 668
 669/* -- module initialisation -- */
 670static const struct usb_device_id device_table[] = {
 671        {USB_DEVICE(0x093a, 0x2600)},
 672        {USB_DEVICE(0x093a, 0x2601)},
 673        {USB_DEVICE(0x093a, 0x2603)},
 674        {USB_DEVICE(0x093a, 0x2608)},
 675        {USB_DEVICE(0x093a, 0x260e)},
 676        {USB_DEVICE(0x093a, 0x260f)},
 677        {}
 678};
 679MODULE_DEVICE_TABLE(usb, device_table);
 680
 681/* -- device connect -- */
 682static int sd_probe(struct usb_interface *intf,
 683                        const struct usb_device_id *id)
 684{
 685        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 686                                THIS_MODULE);
 687}
 688
 689static struct usb_driver sd_driver = {
 690        .name = MODULE_NAME,
 691        .id_table = device_table,
 692        .probe = sd_probe,
 693        .disconnect = gspca_disconnect,
 694#ifdef CONFIG_PM
 695        .suspend = gspca_suspend,
 696        .resume = gspca_resume,
 697        .reset_resume = gspca_resume,
 698#endif
 699};
 700
 701module_usb_driver(sd_driver);
 702
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.