Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Jeilinj subdriver
0004  *
0005  * Supports some Jeilin dual-mode cameras which use bulk transport and
0006  * download raw JPEG data.
0007  *
0008  * Copyright (C) 2009 Theodore Kilgore
0009  *
0010  * Sportscam DV15 support and control settings are
0011  * Copyright (C) 2011 Patrice Chotard
0012  */
0013 
0014 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0015 
0016 #define MODULE_NAME "jeilinj"
0017 
0018 #include <linux/slab.h>
0019 #include "gspca.h"
0020 #include "jpeg.h"
0021 
0022 MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
0023 MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver");
0024 MODULE_LICENSE("GPL");
0025 
0026 /* Default timeouts, in ms */
0027 #define JEILINJ_CMD_TIMEOUT 500
0028 #define JEILINJ_CMD_DELAY 160
0029 #define JEILINJ_DATA_TIMEOUT 1000
0030 
0031 /* Maximum transfer size to use. */
0032 #define JEILINJ_MAX_TRANSFER 0x200
0033 #define FRAME_HEADER_LEN 0x10
0034 #define FRAME_START 0xFFFFFFFF
0035 
0036 enum {
0037     SAKAR_57379,
0038     SPORTSCAM_DV15,
0039 };
0040 
0041 #define CAMQUALITY_MIN 0    /* highest cam quality */
0042 #define CAMQUALITY_MAX 97   /* lowest cam quality  */
0043 
0044 /* Structure to hold all of our device specific stuff */
0045 struct sd {
0046     struct gspca_dev gspca_dev; /* !! must be the first item */
0047     int blocks_left;
0048     const struct v4l2_pix_format *cap_mode;
0049     struct v4l2_ctrl *freq;
0050     struct v4l2_ctrl *jpegqual;
0051     /* Driver stuff */
0052     u8 type;
0053     u8 quality;              /* image quality */
0054 #define QUALITY_MIN 35
0055 #define QUALITY_MAX 85
0056 #define QUALITY_DEF 85
0057     u8 jpeg_hdr[JPEG_HDR_SZ];
0058 };
0059 
0060 struct jlj_command {
0061     unsigned char instruction[2];
0062     unsigned char ack_wanted;
0063     unsigned char delay;
0064 };
0065 
0066 /* AFAICT these cameras will only do 320x240. */
0067 static struct v4l2_pix_format jlj_mode[] = {
0068     { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0069         .bytesperline = 320,
0070         .sizeimage = 320 * 240,
0071         .colorspace = V4L2_COLORSPACE_JPEG,
0072         .priv = 0},
0073     { 640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0074         .bytesperline = 640,
0075         .sizeimage = 640 * 480,
0076         .colorspace = V4L2_COLORSPACE_JPEG,
0077         .priv = 0}
0078 };
0079 
0080 /*
0081  * cam uses endpoint 0x03 to send commands, 0x84 for read commands,
0082  * and 0x82 for bulk transfer.
0083  */
0084 
0085 /* All commands are two bytes only */
0086 static void jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
0087 {
0088     int retval;
0089 
0090     if (gspca_dev->usb_err < 0)
0091         return;
0092     memcpy(gspca_dev->usb_buf, command, 2);
0093     retval = usb_bulk_msg(gspca_dev->dev,
0094             usb_sndbulkpipe(gspca_dev->dev, 3),
0095             gspca_dev->usb_buf, 2, NULL, 500);
0096     if (retval < 0) {
0097         pr_err("command write [%02x] error %d\n",
0098                gspca_dev->usb_buf[0], retval);
0099         gspca_dev->usb_err = retval;
0100     }
0101 }
0102 
0103 /* Responses are one byte only */
0104 static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char *response)
0105 {
0106     int retval;
0107 
0108     if (gspca_dev->usb_err < 0)
0109         return;
0110     retval = usb_bulk_msg(gspca_dev->dev,
0111     usb_rcvbulkpipe(gspca_dev->dev, 0x84),
0112                 gspca_dev->usb_buf, 1, NULL, 500);
0113     *response = gspca_dev->usb_buf[0];
0114     if (retval < 0) {
0115         pr_err("read command [%02x] error %d\n",
0116                gspca_dev->usb_buf[0], retval);
0117         gspca_dev->usb_err = retval;
0118     }
0119 }
0120 
0121 static void setfreq(struct gspca_dev *gspca_dev, s32 val)
0122 {
0123     u8 freq_commands[][2] = {
0124         {0x71, 0x80},
0125         {0x70, 0x07}
0126     };
0127 
0128     freq_commands[0][1] |= val >> 1;
0129 
0130     jlj_write2(gspca_dev, freq_commands[0]);
0131     jlj_write2(gspca_dev, freq_commands[1]);
0132 }
0133 
0134 static void setcamquality(struct gspca_dev *gspca_dev, s32 val)
0135 {
0136     u8 quality_commands[][2] = {
0137         {0x71, 0x1E},
0138         {0x70, 0x06}
0139     };
0140     u8 camquality;
0141 
0142     /* adapt camera quality from jpeg quality */
0143     camquality = ((QUALITY_MAX - val) * CAMQUALITY_MAX)
0144         / (QUALITY_MAX - QUALITY_MIN);
0145     quality_commands[0][1] += camquality;
0146 
0147     jlj_write2(gspca_dev, quality_commands[0]);
0148     jlj_write2(gspca_dev, quality_commands[1]);
0149 }
0150 
0151 static void setautogain(struct gspca_dev *gspca_dev, s32 val)
0152 {
0153     u8 autogain_commands[][2] = {
0154         {0x94, 0x02},
0155         {0xcf, 0x00}
0156     };
0157 
0158     autogain_commands[1][1] = val << 4;
0159 
0160     jlj_write2(gspca_dev, autogain_commands[0]);
0161     jlj_write2(gspca_dev, autogain_commands[1]);
0162 }
0163 
0164 static void setred(struct gspca_dev *gspca_dev, s32 val)
0165 {
0166     u8 setred_commands[][2] = {
0167         {0x94, 0x02},
0168         {0xe6, 0x00}
0169     };
0170 
0171     setred_commands[1][1] = val;
0172 
0173     jlj_write2(gspca_dev, setred_commands[0]);
0174     jlj_write2(gspca_dev, setred_commands[1]);
0175 }
0176 
0177 static void setgreen(struct gspca_dev *gspca_dev, s32 val)
0178 {
0179     u8 setgreen_commands[][2] = {
0180         {0x94, 0x02},
0181         {0xe7, 0x00}
0182     };
0183 
0184     setgreen_commands[1][1] = val;
0185 
0186     jlj_write2(gspca_dev, setgreen_commands[0]);
0187     jlj_write2(gspca_dev, setgreen_commands[1]);
0188 }
0189 
0190 static void setblue(struct gspca_dev *gspca_dev, s32 val)
0191 {
0192     u8 setblue_commands[][2] = {
0193         {0x94, 0x02},
0194         {0xe9, 0x00}
0195     };
0196 
0197     setblue_commands[1][1] = val;
0198 
0199     jlj_write2(gspca_dev, setblue_commands[0]);
0200     jlj_write2(gspca_dev, setblue_commands[1]);
0201 }
0202 
0203 static int jlj_start(struct gspca_dev *gspca_dev)
0204 {
0205     int i;
0206     int start_commands_size;
0207     u8 response = 0xff;
0208     struct sd *sd = (struct sd *) gspca_dev;
0209     struct jlj_command start_commands[] = {
0210         {{0x71, 0x81}, 0, 0},
0211         {{0x70, 0x05}, 0, JEILINJ_CMD_DELAY},
0212         {{0x95, 0x70}, 1, 0},
0213         {{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0},
0214         {{0x70, 0x04}, 0, JEILINJ_CMD_DELAY},
0215         {{0x95, 0x70}, 1, 0},
0216         {{0x71, 0x00}, 0, 0},   /* start streaming ??*/
0217         {{0x70, 0x08}, 0, JEILINJ_CMD_DELAY},
0218         {{0x95, 0x70}, 1, 0},
0219 #define SPORTSCAM_DV15_CMD_SIZE 9
0220         {{0x94, 0x02}, 0, 0},
0221         {{0xde, 0x24}, 0, 0},
0222         {{0x94, 0x02}, 0, 0},
0223         {{0xdd, 0xf0}, 0, 0},
0224         {{0x94, 0x02}, 0, 0},
0225         {{0xe3, 0x2c}, 0, 0},
0226         {{0x94, 0x02}, 0, 0},
0227         {{0xe4, 0x00}, 0, 0},
0228         {{0x94, 0x02}, 0, 0},
0229         {{0xe5, 0x00}, 0, 0},
0230         {{0x94, 0x02}, 0, 0},
0231         {{0xe6, 0x2c}, 0, 0},
0232         {{0x94, 0x03}, 0, 0},
0233         {{0xaa, 0x00}, 0, 0}
0234     };
0235 
0236     sd->blocks_left = 0;
0237     /* Under Windows, USB spy shows that only the 9 first start
0238      * commands are used for SPORTSCAM_DV15 webcam
0239      */
0240     if (sd->type == SPORTSCAM_DV15)
0241         start_commands_size = SPORTSCAM_DV15_CMD_SIZE;
0242     else
0243         start_commands_size = ARRAY_SIZE(start_commands);
0244 
0245     for (i = 0; i < start_commands_size; i++) {
0246         jlj_write2(gspca_dev, start_commands[i].instruction);
0247         if (start_commands[i].delay)
0248             msleep(start_commands[i].delay);
0249         if (start_commands[i].ack_wanted)
0250             jlj_read1(gspca_dev, &response);
0251     }
0252     setcamquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual));
0253     msleep(2);
0254     setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
0255     if (gspca_dev->usb_err < 0)
0256         gspca_err(gspca_dev, "Start streaming command failed\n");
0257     return gspca_dev->usb_err;
0258 }
0259 
0260 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
0261             u8 *data, int len)
0262 {
0263     struct sd *sd = (struct sd *) gspca_dev;
0264     int packet_type;
0265     u32 header_marker;
0266 
0267     gspca_dbg(gspca_dev, D_STREAM, "Got %d bytes out of %d for Block 0\n",
0268           len, JEILINJ_MAX_TRANSFER);
0269     if (len != JEILINJ_MAX_TRANSFER) {
0270         gspca_dbg(gspca_dev, D_PACK, "bad length\n");
0271         goto discard;
0272     }
0273     /* check if it's start of frame */
0274     header_marker = ((u32 *)data)[0];
0275     if (header_marker == FRAME_START) {
0276         sd->blocks_left = data[0x0a] - 1;
0277         gspca_dbg(gspca_dev, D_STREAM, "blocks_left = 0x%x\n",
0278               sd->blocks_left);
0279         /* Start a new frame, and add the JPEG header, first thing */
0280         gspca_frame_add(gspca_dev, FIRST_PACKET,
0281                 sd->jpeg_hdr, JPEG_HDR_SZ);
0282         /* Toss line 0 of data block 0, keep the rest. */
0283         gspca_frame_add(gspca_dev, INTER_PACKET,
0284                 data + FRAME_HEADER_LEN,
0285                 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
0286     } else if (sd->blocks_left > 0) {
0287         gspca_dbg(gspca_dev, D_STREAM, "%d blocks remaining for frame\n",
0288               sd->blocks_left);
0289         sd->blocks_left -= 1;
0290         if (sd->blocks_left == 0)
0291             packet_type = LAST_PACKET;
0292         else
0293             packet_type = INTER_PACKET;
0294         gspca_frame_add(gspca_dev, packet_type,
0295                 data, JEILINJ_MAX_TRANSFER);
0296     } else
0297         goto discard;
0298     return;
0299 discard:
0300     /* Discard data until a new frame starts. */
0301     gspca_dev->last_packet_type = DISCARD_PACKET;
0302 }
0303 
0304 /* This function is called at probe time just before sd_init */
0305 static int sd_config(struct gspca_dev *gspca_dev,
0306         const struct usb_device_id *id)
0307 {
0308     struct cam *cam = &gspca_dev->cam;
0309     struct sd *dev  = (struct sd *) gspca_dev;
0310 
0311     dev->type = id->driver_info;
0312     dev->quality = QUALITY_DEF;
0313 
0314     cam->cam_mode = jlj_mode;
0315     cam->nmodes = ARRAY_SIZE(jlj_mode);
0316     cam->bulk = 1;
0317     cam->bulk_nurbs = 1;
0318     cam->bulk_size = JEILINJ_MAX_TRANSFER;
0319     return 0;
0320 }
0321 
0322 static void sd_stopN(struct gspca_dev *gspca_dev)
0323 {
0324     int i;
0325     u8 *buf;
0326     static u8 stop_commands[][2] = {
0327         {0x71, 0x00},
0328         {0x70, 0x09},
0329         {0x71, 0x80},
0330         {0x70, 0x05}
0331     };
0332 
0333     for (;;) {
0334         /* get the image remaining blocks */
0335         usb_bulk_msg(gspca_dev->dev,
0336                 gspca_dev->urb[0]->pipe,
0337                 gspca_dev->urb[0]->transfer_buffer,
0338                 JEILINJ_MAX_TRANSFER, NULL,
0339                 JEILINJ_DATA_TIMEOUT);
0340 
0341         /* search for 0xff 0xd9  (EOF for JPEG) */
0342         i = 0;
0343         buf = gspca_dev->urb[0]->transfer_buffer;
0344         while ((i < (JEILINJ_MAX_TRANSFER - 1)) &&
0345             ((buf[i] != 0xff) || (buf[i+1] != 0xd9)))
0346             i++;
0347 
0348         if (i != (JEILINJ_MAX_TRANSFER - 1))
0349             /* last remaining block found */
0350             break;
0351         }
0352 
0353     for (i = 0; i < ARRAY_SIZE(stop_commands); i++)
0354         jlj_write2(gspca_dev, stop_commands[i]);
0355 }
0356 
0357 /* this function is called at probe and resume time */
0358 static int sd_init(struct gspca_dev *gspca_dev)
0359 {
0360     return gspca_dev->usb_err;
0361 }
0362 
0363 /* Set up for getting frames. */
0364 static int sd_start(struct gspca_dev *gspca_dev)
0365 {
0366     struct sd *dev = (struct sd *) gspca_dev;
0367 
0368     /* create the JPEG header */
0369     jpeg_define(dev->jpeg_hdr, gspca_dev->pixfmt.height,
0370             gspca_dev->pixfmt.width,
0371             0x21);          /* JPEG 422 */
0372     jpeg_set_qual(dev->jpeg_hdr, dev->quality);
0373     gspca_dbg(gspca_dev, D_STREAM, "Start streaming at %dx%d\n",
0374           gspca_dev->pixfmt.height, gspca_dev->pixfmt.width);
0375     jlj_start(gspca_dev);
0376     return gspca_dev->usb_err;
0377 }
0378 
0379 /* Table of supported USB devices */
0380 static const struct usb_device_id device_table[] = {
0381     {USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379},
0382     {USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15},
0383     {}
0384 };
0385 
0386 MODULE_DEVICE_TABLE(usb, device_table);
0387 
0388 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
0389 {
0390     struct gspca_dev *gspca_dev =
0391         container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
0392     struct sd *sd = (struct sd *)gspca_dev;
0393 
0394     gspca_dev->usb_err = 0;
0395 
0396     if (!gspca_dev->streaming)
0397         return 0;
0398 
0399     switch (ctrl->id) {
0400     case V4L2_CID_POWER_LINE_FREQUENCY:
0401         setfreq(gspca_dev, ctrl->val);
0402         break;
0403     case V4L2_CID_RED_BALANCE:
0404         setred(gspca_dev, ctrl->val);
0405         break;
0406     case V4L2_CID_GAIN:
0407         setgreen(gspca_dev, ctrl->val);
0408         break;
0409     case V4L2_CID_BLUE_BALANCE:
0410         setblue(gspca_dev, ctrl->val);
0411         break;
0412     case V4L2_CID_AUTOGAIN:
0413         setautogain(gspca_dev, ctrl->val);
0414         break;
0415     case V4L2_CID_JPEG_COMPRESSION_QUALITY:
0416         jpeg_set_qual(sd->jpeg_hdr, ctrl->val);
0417         setcamquality(gspca_dev, ctrl->val);
0418         break;
0419     }
0420     return gspca_dev->usb_err;
0421 }
0422 
0423 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
0424     .s_ctrl = sd_s_ctrl,
0425 };
0426 
0427 static int sd_init_controls(struct gspca_dev *gspca_dev)
0428 {
0429     struct sd *sd = (struct sd *)gspca_dev;
0430     struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
0431     static const struct v4l2_ctrl_config custom_autogain = {
0432         .ops = &sd_ctrl_ops,
0433         .id = V4L2_CID_AUTOGAIN,
0434         .type = V4L2_CTRL_TYPE_INTEGER,
0435         .name = "Automatic Gain (and Exposure)",
0436         .max = 3,
0437         .step = 1,
0438         .def = 0,
0439     };
0440 
0441     gspca_dev->vdev.ctrl_handler = hdl;
0442     v4l2_ctrl_handler_init(hdl, 6);
0443     sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
0444             V4L2_CID_POWER_LINE_FREQUENCY,
0445             V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
0446             V4L2_CID_POWER_LINE_FREQUENCY_60HZ);
0447     v4l2_ctrl_new_custom(hdl, &custom_autogain, NULL);
0448     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0449             V4L2_CID_RED_BALANCE, 0, 3, 1, 2);
0450     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0451             V4L2_CID_GAIN, 0, 3, 1, 2);
0452     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0453             V4L2_CID_BLUE_BALANCE, 0, 3, 1, 2);
0454     sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0455             V4L2_CID_JPEG_COMPRESSION_QUALITY,
0456             QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
0457 
0458     if (hdl->error) {
0459         pr_err("Could not initialize controls\n");
0460         return hdl->error;
0461     }
0462     return 0;
0463 }
0464 
0465 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
0466             const struct v4l2_jpegcompression *jcomp)
0467 {
0468     struct sd *sd = (struct sd *) gspca_dev;
0469 
0470     v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
0471     return 0;
0472 }
0473 
0474 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
0475             struct v4l2_jpegcompression *jcomp)
0476 {
0477     struct sd *sd = (struct sd *) gspca_dev;
0478 
0479     memset(jcomp, 0, sizeof *jcomp);
0480     jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
0481     jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
0482             | V4L2_JPEG_MARKER_DQT;
0483     return 0;
0484 }
0485 
0486 
0487 /* sub-driver description */
0488 static const struct sd_desc sd_desc_sakar_57379 = {
0489     .name   = MODULE_NAME,
0490     .config = sd_config,
0491     .init   = sd_init,
0492     .start  = sd_start,
0493     .stopN  = sd_stopN,
0494     .pkt_scan = sd_pkt_scan,
0495 };
0496 
0497 /* sub-driver description */
0498 static const struct sd_desc sd_desc_sportscam_dv15 = {
0499     .name   = MODULE_NAME,
0500     .config = sd_config,
0501     .init   = sd_init,
0502     .init_controls = sd_init_controls,
0503     .start  = sd_start,
0504     .stopN  = sd_stopN,
0505     .pkt_scan = sd_pkt_scan,
0506     .get_jcomp = sd_get_jcomp,
0507     .set_jcomp = sd_set_jcomp,
0508 };
0509 
0510 static const struct sd_desc *sd_desc[2] = {
0511     &sd_desc_sakar_57379,
0512     &sd_desc_sportscam_dv15
0513 };
0514 
0515 /* -- device connect -- */
0516 static int sd_probe(struct usb_interface *intf,
0517         const struct usb_device_id *id)
0518 {
0519     return gspca_dev_probe(intf, id,
0520             sd_desc[id->driver_info],
0521             sizeof(struct sd),
0522             THIS_MODULE);
0523 }
0524 
0525 static struct usb_driver sd_driver = {
0526     .name       = MODULE_NAME,
0527     .id_table   = device_table,
0528     .probe      = sd_probe,
0529     .disconnect = gspca_disconnect,
0530 #ifdef CONFIG_PM
0531     .suspend = gspca_suspend,
0532     .resume  = gspca_resume,
0533     .reset_resume = gspca_resume,
0534 #endif
0535 };
0536 
0537 module_usb_driver(sd_driver);