root/drivers/media/usb/gspca/pac7311.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. reg_w_buf
  2. reg_w
  3. reg_w_seq
  4. reg_w_page
  5. reg_w_var
  6. sd_config
  7. setcontrast
  8. setgain
  9. setexposure
  10. sethvflip
  11. sd_init
  12. sd_s_ctrl
  13. sd_init_controls
  14. sd_start
  15. sd_stopN
  16. do_autogain
  17. pac_start_frame
  18. sd_pkt_scan
  19. sd_int_pkt_scan
  20. sd_probe

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

/* [<][>][^][v][top][bottom][index][help] */