linux/drivers/media/usb/gspca/jeilinj.c
<<
>>
Prefs
   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
  22MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
  23MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver");
  24MODULE_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
  36enum {
  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 */
  45struct 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
  60struct 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. */
  67static 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 */
  86static 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 */
 104static 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
 121static 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
 134static 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
 151static 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
 164static 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
 177static 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
 190static 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
 203static 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
 260static 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;
 299discard:
 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 */
 305static 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
 322static 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 */
 358static int sd_init(struct gspca_dev *gspca_dev)
 359{
 360        return gspca_dev->usb_err;
 361}
 362
 363/* Set up for getting frames. */
 364static 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 */
 380static 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
 386MODULE_DEVICE_TABLE(usb, device_table);
 387
 388static 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
 423static const struct v4l2_ctrl_ops sd_ctrl_ops = {
 424        .s_ctrl = sd_s_ctrl,
 425};
 426
 427static 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
 465static 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
 474static 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 */
 488static 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 */
 498static 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
 510static const struct sd_desc *sd_desc[2] = {
 511        &sd_desc_sakar_57379,
 512        &sd_desc_sportscam_dv15
 513};
 514
 515/* -- device connect -- */
 516static 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
 525static 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
 537module_usb_driver(sd_driver);
 538