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