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

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

DEFINITIONS

This source file includes following definitions.
  1. jlj_write2
  2. jlj_read1
  3. setfreq
  4. setcamquality
  5. setautogain
  6. setred
  7. setgreen
  8. setblue
  9. jlj_start
  10. sd_pkt_scan
  11. sd_config
  12. sd_stopN
  13. sd_init
  14. sd_start
  15. sd_s_ctrl
  16. sd_init_controls
  17. sd_set_jcomp
  18. sd_get_jcomp
  19. sd_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Jeilinj subdriver
   4  *
   5  * Supports some Jeilin dual-mode cameras which use bulk transport and
   6  * download raw JPEG data.
   7  *
   8  * Copyright (C) 2009 Theodore Kilgore
   9  *
  10  * Sportscam DV15 support and control settings are
  11  * Copyright (C) 2011 Patrice Chotard
  12  */
  13 
  14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  15 
  16 #define MODULE_NAME "jeilinj"
  17 
  18 #include <linux/slab.h>
  19 #include "gspca.h"
  20 #include "jpeg.h"
  21 
  22 MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
  23 MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver");
  24 MODULE_LICENSE("GPL");
  25 
  26 /* Default timeouts, in ms */
  27 #define JEILINJ_CMD_TIMEOUT 500
  28 #define JEILINJ_CMD_DELAY 160
  29 #define JEILINJ_DATA_TIMEOUT 1000
  30 
  31 /* Maximum transfer size to use. */
  32 #define JEILINJ_MAX_TRANSFER 0x200
  33 #define FRAME_HEADER_LEN 0x10
  34 #define FRAME_START 0xFFFFFFFF
  35 
  36 enum {
  37         SAKAR_57379,
  38         SPORTSCAM_DV15,
  39 };
  40 
  41 #define CAMQUALITY_MIN 0        /* highest cam quality */
  42 #define CAMQUALITY_MAX 97       /* lowest cam quality  */
  43 
  44 /* Structure to hold all of our device specific stuff */
  45 struct sd {
  46         struct gspca_dev gspca_dev;     /* !! must be the first item */
  47         int blocks_left;
  48         const struct v4l2_pix_format *cap_mode;
  49         struct v4l2_ctrl *freq;
  50         struct v4l2_ctrl *jpegqual;
  51         /* Driver stuff */
  52         u8 type;
  53         u8 quality;                              /* image quality */
  54 #define QUALITY_MIN 35
  55 #define QUALITY_MAX 85
  56 #define QUALITY_DEF 85
  57         u8 jpeg_hdr[JPEG_HDR_SZ];
  58 };
  59 
  60 struct jlj_command {
  61         unsigned char instruction[2];
  62         unsigned char ack_wanted;
  63         unsigned char delay;
  64 };
  65 
  66 /* AFAICT these cameras will only do 320x240. */
  67 static struct v4l2_pix_format jlj_mode[] = {
  68         { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  69                 .bytesperline = 320,
  70                 .sizeimage = 320 * 240,
  71                 .colorspace = V4L2_COLORSPACE_JPEG,
  72                 .priv = 0},
  73         { 640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  74                 .bytesperline = 640,
  75                 .sizeimage = 640 * 480,
  76                 .colorspace = V4L2_COLORSPACE_JPEG,
  77                 .priv = 0}
  78 };
  79 
  80 /*
  81  * cam uses endpoint 0x03 to send commands, 0x84 for read commands,
  82  * and 0x82 for bulk transfer.
  83  */
  84 
  85 /* All commands are two bytes only */
  86 static void jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
  87 {
  88         int retval;
  89 
  90         if (gspca_dev->usb_err < 0)
  91                 return;
  92         memcpy(gspca_dev->usb_buf, command, 2);
  93         retval = usb_bulk_msg(gspca_dev->dev,
  94                         usb_sndbulkpipe(gspca_dev->dev, 3),
  95                         gspca_dev->usb_buf, 2, NULL, 500);
  96         if (retval < 0) {
  97                 pr_err("command write [%02x] error %d\n",
  98                        gspca_dev->usb_buf[0], retval);
  99                 gspca_dev->usb_err = retval;
 100         }
 101 }
 102 
 103 /* Responses are one byte only */
 104 static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char *response)
 105 {
 106         int retval;
 107 
 108         if (gspca_dev->usb_err < 0)
 109                 return;
 110         retval = usb_bulk_msg(gspca_dev->dev,
 111         usb_rcvbulkpipe(gspca_dev->dev, 0x84),
 112                                 gspca_dev->usb_buf, 1, NULL, 500);
 113         *response = gspca_dev->usb_buf[0];
 114         if (retval < 0) {
 115                 pr_err("read command [%02x] error %d\n",
 116                        gspca_dev->usb_buf[0], retval);
 117                 gspca_dev->usb_err = retval;
 118         }
 119 }
 120 
 121 static void setfreq(struct gspca_dev *gspca_dev, s32 val)
 122 {
 123         u8 freq_commands[][2] = {
 124                 {0x71, 0x80},
 125                 {0x70, 0x07}
 126         };
 127 
 128         freq_commands[0][1] |= val >> 1;
 129 
 130         jlj_write2(gspca_dev, freq_commands[0]);
 131         jlj_write2(gspca_dev, freq_commands[1]);
 132 }
 133 
 134 static void setcamquality(struct gspca_dev *gspca_dev, s32 val)
 135 {
 136         u8 quality_commands[][2] = {
 137                 {0x71, 0x1E},
 138                 {0x70, 0x06}
 139         };
 140         u8 camquality;
 141 
 142         /* adapt camera quality from jpeg quality */
 143         camquality = ((QUALITY_MAX - val) * CAMQUALITY_MAX)
 144                 / (QUALITY_MAX - QUALITY_MIN);
 145         quality_commands[0][1] += camquality;
 146 
 147         jlj_write2(gspca_dev, quality_commands[0]);
 148         jlj_write2(gspca_dev, quality_commands[1]);
 149 }
 150 
 151 static void setautogain(struct gspca_dev *gspca_dev, s32 val)
 152 {
 153         u8 autogain_commands[][2] = {
 154                 {0x94, 0x02},
 155                 {0xcf, 0x00}
 156         };
 157 
 158         autogain_commands[1][1] = val << 4;
 159 
 160         jlj_write2(gspca_dev, autogain_commands[0]);
 161         jlj_write2(gspca_dev, autogain_commands[1]);
 162 }
 163 
 164 static void setred(struct gspca_dev *gspca_dev, s32 val)
 165 {
 166         u8 setred_commands[][2] = {
 167                 {0x94, 0x02},
 168                 {0xe6, 0x00}
 169         };
 170 
 171         setred_commands[1][1] = val;
 172 
 173         jlj_write2(gspca_dev, setred_commands[0]);
 174         jlj_write2(gspca_dev, setred_commands[1]);
 175 }
 176 
 177 static void setgreen(struct gspca_dev *gspca_dev, s32 val)
 178 {
 179         u8 setgreen_commands[][2] = {
 180                 {0x94, 0x02},
 181                 {0xe7, 0x00}
 182         };
 183 
 184         setgreen_commands[1][1] = val;
 185 
 186         jlj_write2(gspca_dev, setgreen_commands[0]);
 187         jlj_write2(gspca_dev, setgreen_commands[1]);
 188 }
 189 
 190 static void setblue(struct gspca_dev *gspca_dev, s32 val)
 191 {
 192         u8 setblue_commands[][2] = {
 193                 {0x94, 0x02},
 194                 {0xe9, 0x00}
 195         };
 196 
 197         setblue_commands[1][1] = val;
 198 
 199         jlj_write2(gspca_dev, setblue_commands[0]);
 200         jlj_write2(gspca_dev, setblue_commands[1]);
 201 }
 202 
 203 static int jlj_start(struct gspca_dev *gspca_dev)
 204 {
 205         int i;
 206         int start_commands_size;
 207         u8 response = 0xff;
 208         struct sd *sd = (struct sd *) gspca_dev;
 209         struct jlj_command start_commands[] = {
 210                 {{0x71, 0x81}, 0, 0},
 211                 {{0x70, 0x05}, 0, JEILINJ_CMD_DELAY},
 212                 {{0x95, 0x70}, 1, 0},
 213                 {{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0},
 214                 {{0x70, 0x04}, 0, JEILINJ_CMD_DELAY},
 215                 {{0x95, 0x70}, 1, 0},
 216                 {{0x71, 0x00}, 0, 0},   /* start streaming ??*/
 217                 {{0x70, 0x08}, 0, JEILINJ_CMD_DELAY},
 218                 {{0x95, 0x70}, 1, 0},
 219 #define SPORTSCAM_DV15_CMD_SIZE 9
 220                 {{0x94, 0x02}, 0, 0},
 221                 {{0xde, 0x24}, 0, 0},
 222                 {{0x94, 0x02}, 0, 0},
 223                 {{0xdd, 0xf0}, 0, 0},
 224                 {{0x94, 0x02}, 0, 0},
 225                 {{0xe3, 0x2c}, 0, 0},
 226                 {{0x94, 0x02}, 0, 0},
 227                 {{0xe4, 0x00}, 0, 0},
 228                 {{0x94, 0x02}, 0, 0},
 229                 {{0xe5, 0x00}, 0, 0},
 230                 {{0x94, 0x02}, 0, 0},
 231                 {{0xe6, 0x2c}, 0, 0},
 232                 {{0x94, 0x03}, 0, 0},
 233                 {{0xaa, 0x00}, 0, 0}
 234         };
 235 
 236         sd->blocks_left = 0;
 237         /* Under Windows, USB spy shows that only the 9 first start
 238          * commands are used for SPORTSCAM_DV15 webcam
 239          */
 240         if (sd->type == SPORTSCAM_DV15)
 241                 start_commands_size = SPORTSCAM_DV15_CMD_SIZE;
 242         else
 243                 start_commands_size = ARRAY_SIZE(start_commands);
 244 
 245         for (i = 0; i < start_commands_size; i++) {
 246                 jlj_write2(gspca_dev, start_commands[i].instruction);
 247                 if (start_commands[i].delay)
 248                         msleep(start_commands[i].delay);
 249                 if (start_commands[i].ack_wanted)
 250                         jlj_read1(gspca_dev, &response);
 251         }
 252         setcamquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual));
 253         msleep(2);
 254         setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
 255         if (gspca_dev->usb_err < 0)
 256                 gspca_err(gspca_dev, "Start streaming command failed\n");
 257         return gspca_dev->usb_err;
 258 }
 259 
 260 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 261                         u8 *data, int len)
 262 {
 263         struct sd *sd = (struct sd *) gspca_dev;
 264         int packet_type;
 265         u32 header_marker;
 266 
 267         gspca_dbg(gspca_dev, D_STREAM, "Got %d bytes out of %d for Block 0\n",
 268                   len, JEILINJ_MAX_TRANSFER);
 269         if (len != JEILINJ_MAX_TRANSFER) {
 270                 gspca_dbg(gspca_dev, D_PACK, "bad length\n");
 271                 goto discard;
 272         }
 273         /* check if it's start of frame */
 274         header_marker = ((u32 *)data)[0];
 275         if (header_marker == FRAME_START) {
 276                 sd->blocks_left = data[0x0a] - 1;
 277                 gspca_dbg(gspca_dev, D_STREAM, "blocks_left = 0x%x\n",
 278                           sd->blocks_left);
 279                 /* Start a new frame, and add the JPEG header, first thing */
 280                 gspca_frame_add(gspca_dev, FIRST_PACKET,
 281                                 sd->jpeg_hdr, JPEG_HDR_SZ);
 282                 /* Toss line 0 of data block 0, keep the rest. */
 283                 gspca_frame_add(gspca_dev, INTER_PACKET,
 284                                 data + FRAME_HEADER_LEN,
 285                                 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
 286         } else if (sd->blocks_left > 0) {
 287                 gspca_dbg(gspca_dev, D_STREAM, "%d blocks remaining for frame\n",
 288                           sd->blocks_left);
 289                 sd->blocks_left -= 1;
 290                 if (sd->blocks_left == 0)
 291                         packet_type = LAST_PACKET;
 292                 else
 293                         packet_type = INTER_PACKET;
 294                 gspca_frame_add(gspca_dev, packet_type,
 295                                 data, JEILINJ_MAX_TRANSFER);
 296         } else
 297                 goto discard;
 298         return;
 299 discard:
 300         /* Discard data until a new frame starts. */
 301         gspca_dev->last_packet_type = DISCARD_PACKET;
 302 }
 303 
 304 /* This function is called at probe time just before sd_init */
 305 static int sd_config(struct gspca_dev *gspca_dev,
 306                 const struct usb_device_id *id)
 307 {
 308         struct cam *cam = &gspca_dev->cam;
 309         struct sd *dev  = (struct sd *) gspca_dev;
 310 
 311         dev->type = id->driver_info;
 312         dev->quality = QUALITY_DEF;
 313 
 314         cam->cam_mode = jlj_mode;
 315         cam->nmodes = ARRAY_SIZE(jlj_mode);
 316         cam->bulk = 1;
 317         cam->bulk_nurbs = 1;
 318         cam->bulk_size = JEILINJ_MAX_TRANSFER;
 319         return 0;
 320 }
 321 
 322 static void sd_stopN(struct gspca_dev *gspca_dev)
 323 {
 324         int i;
 325         u8 *buf;
 326         static u8 stop_commands[][2] = {
 327                 {0x71, 0x00},
 328                 {0x70, 0x09},
 329                 {0x71, 0x80},
 330                 {0x70, 0x05}
 331         };
 332 
 333         for (;;) {
 334                 /* get the image remaining blocks */
 335                 usb_bulk_msg(gspca_dev->dev,
 336                                 gspca_dev->urb[0]->pipe,
 337                                 gspca_dev->urb[0]->transfer_buffer,
 338                                 JEILINJ_MAX_TRANSFER, NULL,
 339                                 JEILINJ_DATA_TIMEOUT);
 340 
 341                 /* search for 0xff 0xd9  (EOF for JPEG) */
 342                 i = 0;
 343                 buf = gspca_dev->urb[0]->transfer_buffer;
 344                 while ((i < (JEILINJ_MAX_TRANSFER - 1)) &&
 345                         ((buf[i] != 0xff) || (buf[i+1] != 0xd9)))
 346                         i++;
 347 
 348                 if (i != (JEILINJ_MAX_TRANSFER - 1))
 349                         /* last remaining block found */
 350                         break;
 351                 }
 352 
 353         for (i = 0; i < ARRAY_SIZE(stop_commands); i++)
 354                 jlj_write2(gspca_dev, stop_commands[i]);
 355 }
 356 
 357 /* this function is called at probe and resume time */
 358 static int sd_init(struct gspca_dev *gspca_dev)
 359 {
 360         return gspca_dev->usb_err;
 361 }
 362 
 363 /* Set up for getting frames. */
 364 static int sd_start(struct gspca_dev *gspca_dev)
 365 {
 366         struct sd *dev = (struct sd *) gspca_dev;
 367 
 368         /* create the JPEG header */
 369         jpeg_define(dev->jpeg_hdr, gspca_dev->pixfmt.height,
 370                         gspca_dev->pixfmt.width,
 371                         0x21);          /* JPEG 422 */
 372         jpeg_set_qual(dev->jpeg_hdr, dev->quality);
 373         gspca_dbg(gspca_dev, D_STREAM, "Start streaming at %dx%d\n",
 374                   gspca_dev->pixfmt.height, gspca_dev->pixfmt.width);
 375         jlj_start(gspca_dev);
 376         return gspca_dev->usb_err;
 377 }
 378 
 379 /* Table of supported USB devices */
 380 static const struct usb_device_id device_table[] = {
 381         {USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379},
 382         {USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15},
 383         {}
 384 };
 385 
 386 MODULE_DEVICE_TABLE(usb, device_table);
 387 
 388 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
 389 {
 390         struct gspca_dev *gspca_dev =
 391                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 392         struct sd *sd = (struct sd *)gspca_dev;
 393 
 394         gspca_dev->usb_err = 0;
 395 
 396         if (!gspca_dev->streaming)
 397                 return 0;
 398 
 399         switch (ctrl->id) {
 400         case V4L2_CID_POWER_LINE_FREQUENCY:
 401                 setfreq(gspca_dev, ctrl->val);
 402                 break;
 403         case V4L2_CID_RED_BALANCE:
 404                 setred(gspca_dev, ctrl->val);
 405                 break;
 406         case V4L2_CID_GAIN:
 407                 setgreen(gspca_dev, ctrl->val);
 408                 break;
 409         case V4L2_CID_BLUE_BALANCE:
 410                 setblue(gspca_dev, ctrl->val);
 411                 break;
 412         case V4L2_CID_AUTOGAIN:
 413                 setautogain(gspca_dev, ctrl->val);
 414                 break;
 415         case V4L2_CID_JPEG_COMPRESSION_QUALITY:
 416                 jpeg_set_qual(sd->jpeg_hdr, ctrl->val);
 417                 setcamquality(gspca_dev, ctrl->val);
 418                 break;
 419         }
 420         return gspca_dev->usb_err;
 421 }
 422 
 423 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
 424         .s_ctrl = sd_s_ctrl,
 425 };
 426 
 427 static int sd_init_controls(struct gspca_dev *gspca_dev)
 428 {
 429         struct sd *sd = (struct sd *)gspca_dev;
 430         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
 431         static const struct v4l2_ctrl_config custom_autogain = {
 432                 .ops = &sd_ctrl_ops,
 433                 .id = V4L2_CID_AUTOGAIN,
 434                 .type = V4L2_CTRL_TYPE_INTEGER,
 435                 .name = "Automatic Gain (and Exposure)",
 436                 .max = 3,
 437                 .step = 1,
 438                 .def = 0,
 439         };
 440 
 441         gspca_dev->vdev.ctrl_handler = hdl;
 442         v4l2_ctrl_handler_init(hdl, 6);
 443         sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
 444                         V4L2_CID_POWER_LINE_FREQUENCY,
 445                         V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
 446                         V4L2_CID_POWER_LINE_FREQUENCY_60HZ);
 447         v4l2_ctrl_new_custom(hdl, &custom_autogain, NULL);
 448         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 449                         V4L2_CID_RED_BALANCE, 0, 3, 1, 2);
 450         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 451                         V4L2_CID_GAIN, 0, 3, 1, 2);
 452         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 453                         V4L2_CID_BLUE_BALANCE, 0, 3, 1, 2);
 454         sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 455                         V4L2_CID_JPEG_COMPRESSION_QUALITY,
 456                         QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
 457 
 458         if (hdl->error) {
 459                 pr_err("Could not initialize controls\n");
 460                 return hdl->error;
 461         }
 462         return 0;
 463 }
 464 
 465 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
 466                         const struct v4l2_jpegcompression *jcomp)
 467 {
 468         struct sd *sd = (struct sd *) gspca_dev;
 469 
 470         v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
 471         return 0;
 472 }
 473 
 474 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
 475                         struct v4l2_jpegcompression *jcomp)
 476 {
 477         struct sd *sd = (struct sd *) gspca_dev;
 478 
 479         memset(jcomp, 0, sizeof *jcomp);
 480         jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
 481         jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
 482                         | V4L2_JPEG_MARKER_DQT;
 483         return 0;
 484 }
 485 
 486 
 487 /* sub-driver description */
 488 static const struct sd_desc sd_desc_sakar_57379 = {
 489         .name   = MODULE_NAME,
 490         .config = sd_config,
 491         .init   = sd_init,
 492         .start  = sd_start,
 493         .stopN  = sd_stopN,
 494         .pkt_scan = sd_pkt_scan,
 495 };
 496 
 497 /* sub-driver description */
 498 static const struct sd_desc sd_desc_sportscam_dv15 = {
 499         .name   = MODULE_NAME,
 500         .config = sd_config,
 501         .init   = sd_init,
 502         .init_controls = sd_init_controls,
 503         .start  = sd_start,
 504         .stopN  = sd_stopN,
 505         .pkt_scan = sd_pkt_scan,
 506         .get_jcomp = sd_get_jcomp,
 507         .set_jcomp = sd_set_jcomp,
 508 };
 509 
 510 static const struct sd_desc *sd_desc[2] = {
 511         &sd_desc_sakar_57379,
 512         &sd_desc_sportscam_dv15
 513 };
 514 
 515 /* -- device connect -- */
 516 static int sd_probe(struct usb_interface *intf,
 517                 const struct usb_device_id *id)
 518 {
 519         return gspca_dev_probe(intf, id,
 520                         sd_desc[id->driver_info],
 521                         sizeof(struct sd),
 522                         THIS_MODULE);
 523 }
 524 
 525 static struct usb_driver sd_driver = {
 526         .name       = MODULE_NAME,
 527         .id_table   = device_table,
 528         .probe      = sd_probe,
 529         .disconnect = gspca_disconnect,
 530 #ifdef CONFIG_PM
 531         .suspend = gspca_suspend,
 532         .resume  = gspca_resume,
 533         .reset_resume = gspca_resume,
 534 #endif
 535 };
 536 
 537 module_usb_driver(sd_driver);

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