linux/drivers/media/video/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 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23
  24#define MODULE_NAME "jeilinj"
  25
  26#include <linux/workqueue.h>
  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_DATA_TIMEOUT 1000
  38
  39/* Maximum transfer size to use. */
  40#define JEILINJ_MAX_TRANSFER 0x200
  41
  42#define FRAME_HEADER_LEN 0x10
  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        const struct v4l2_pix_format *cap_mode;
  48        /* Driver stuff */
  49        struct work_struct work_struct;
  50        struct workqueue_struct *work_thread;
  51        u8 quality;                              /* image quality */
  52        u8 jpegqual;                            /* webcam quality */
  53        u8 jpeg_hdr[JPEG_HDR_SZ];
  54};
  55
  56        struct jlj_command {
  57                unsigned char instruction[2];
  58                unsigned char ack_wanted;
  59        };
  60
  61/* AFAICT these cameras will only do 320x240. */
  62static struct v4l2_pix_format jlj_mode[] = {
  63        { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  64                .bytesperline = 320,
  65                .sizeimage = 320 * 240,
  66                .colorspace = V4L2_COLORSPACE_JPEG,
  67                .priv = 0}
  68};
  69
  70/*
  71 * cam uses endpoint 0x03 to send commands, 0x84 for read commands,
  72 * and 0x82 for bulk transfer.
  73 */
  74
  75/* All commands are two bytes only */
  76static int jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
  77{
  78        int retval;
  79
  80        memcpy(gspca_dev->usb_buf, command, 2);
  81        retval = usb_bulk_msg(gspca_dev->dev,
  82                        usb_sndbulkpipe(gspca_dev->dev, 3),
  83                        gspca_dev->usb_buf, 2, NULL, 500);
  84        if (retval < 0)
  85                err("command write [%02x] error %d",
  86                                gspca_dev->usb_buf[0], retval);
  87        return retval;
  88}
  89
  90/* Responses are one byte only */
  91static int jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
  92{
  93        int retval;
  94
  95        retval = usb_bulk_msg(gspca_dev->dev,
  96        usb_rcvbulkpipe(gspca_dev->dev, 0x84),
  97                                gspca_dev->usb_buf, 1, NULL, 500);
  98        response = gspca_dev->usb_buf[0];
  99        if (retval < 0)
 100                err("read command [%02x] error %d",
 101                                gspca_dev->usb_buf[0], retval);
 102        return retval;
 103}
 104
 105static int jlj_start(struct gspca_dev *gspca_dev)
 106{
 107        int i;
 108        int retval = -1;
 109        u8 response = 0xff;
 110        struct jlj_command start_commands[] = {
 111                {{0x71, 0x81}, 0},
 112                {{0x70, 0x05}, 0},
 113                {{0x95, 0x70}, 1},
 114                {{0x71, 0x81}, 0},
 115                {{0x70, 0x04}, 0},
 116                {{0x95, 0x70}, 1},
 117                {{0x71, 0x00}, 0},
 118                {{0x70, 0x08}, 0},
 119                {{0x95, 0x70}, 1},
 120                {{0x94, 0x02}, 0},
 121                {{0xde, 0x24}, 0},
 122                {{0x94, 0x02}, 0},
 123                {{0xdd, 0xf0}, 0},
 124                {{0x94, 0x02}, 0},
 125                {{0xe3, 0x2c}, 0},
 126                {{0x94, 0x02}, 0},
 127                {{0xe4, 0x00}, 0},
 128                {{0x94, 0x02}, 0},
 129                {{0xe5, 0x00}, 0},
 130                {{0x94, 0x02}, 0},
 131                {{0xe6, 0x2c}, 0},
 132                {{0x94, 0x03}, 0},
 133                {{0xaa, 0x00}, 0},
 134                {{0x71, 0x1e}, 0},
 135                {{0x70, 0x06}, 0},
 136                {{0x71, 0x80}, 0},
 137                {{0x70, 0x07}, 0}
 138        };
 139        for (i = 0; i < ARRAY_SIZE(start_commands); i++) {
 140                retval = jlj_write2(gspca_dev, start_commands[i].instruction);
 141                if (retval < 0)
 142                        return retval;
 143                if (start_commands[i].ack_wanted)
 144                        retval = jlj_read1(gspca_dev, response);
 145                if (retval < 0)
 146                        return retval;
 147        }
 148        PDEBUG(D_ERR, "jlj_start retval is %d", retval);
 149        return retval;
 150}
 151
 152static int jlj_stop(struct gspca_dev *gspca_dev)
 153{
 154        int i;
 155        int retval;
 156        struct jlj_command stop_commands[] = {
 157                {{0x71, 0x00}, 0},
 158                {{0x70, 0x09}, 0},
 159                {{0x71, 0x80}, 0},
 160                {{0x70, 0x05}, 0}
 161        };
 162        for (i = 0; i < ARRAY_SIZE(stop_commands); i++) {
 163                retval = jlj_write2(gspca_dev, stop_commands[i].instruction);
 164                if (retval < 0)
 165                        return retval;
 166        }
 167        return retval;
 168}
 169
 170/* This function is called as a workqueue function and runs whenever the camera
 171 * is streaming data. Because it is a workqueue function it is allowed to sleep
 172 * so we can use synchronous USB calls. To avoid possible collisions with other
 173 * threads attempting to use the camera's USB interface the gspca usb_lock is
 174 * used when performing the one USB control operation inside the workqueue,
 175 * which tells the camera to close the stream. In practice the only thing
 176 * which needs to be protected against is the usb_set_interface call that
 177 * gspca makes during stream_off. Otherwise the camera doesn't provide any
 178 * controls that the user could try to change.
 179 */
 180
 181static void jlj_dostream(struct work_struct *work)
 182{
 183        struct sd *dev = container_of(work, struct sd, work_struct);
 184        struct gspca_dev *gspca_dev = &dev->gspca_dev;
 185        int blocks_left; /* 0x200-sized blocks remaining in current frame. */
 186        int size_in_blocks;
 187        int act_len;
 188        int packet_type;
 189        int ret;
 190        u8 *buffer;
 191
 192        buffer = kmalloc(JEILINJ_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
 193        if (!buffer) {
 194                err("Couldn't allocate USB buffer");
 195                goto quit_stream;
 196        }
 197        while (gspca_dev->present && gspca_dev->streaming) {
 198                /*
 199                 * Now request data block 0. Line 0 reports the size
 200                 * to download, in blocks of size 0x200, and also tells the
 201                 * "actual" data size, in bytes, which seems best to ignore.
 202                 */
 203                ret = usb_bulk_msg(gspca_dev->dev,
 204                                usb_rcvbulkpipe(gspca_dev->dev, 0x82),
 205                                buffer, JEILINJ_MAX_TRANSFER, &act_len,
 206                                JEILINJ_DATA_TIMEOUT);
 207                PDEBUG(D_STREAM,
 208                        "Got %d bytes out of %d for Block 0",
 209                        act_len, JEILINJ_MAX_TRANSFER);
 210                if (ret < 0 || act_len < FRAME_HEADER_LEN)
 211                        goto quit_stream;
 212                size_in_blocks = buffer[0x0a];
 213                blocks_left = buffer[0x0a] - 1;
 214                PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
 215
 216                /* Start a new frame, and add the JPEG header, first thing */
 217                gspca_frame_add(gspca_dev, FIRST_PACKET,
 218                                dev->jpeg_hdr, JPEG_HDR_SZ);
 219                /* Toss line 0 of data block 0, keep the rest. */
 220                gspca_frame_add(gspca_dev, INTER_PACKET,
 221                                buffer + FRAME_HEADER_LEN,
 222                                JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
 223
 224                while (blocks_left > 0) {
 225                        if (!gspca_dev->present)
 226                                goto quit_stream;
 227                        ret = usb_bulk_msg(gspca_dev->dev,
 228                                usb_rcvbulkpipe(gspca_dev->dev, 0x82),
 229                                buffer, JEILINJ_MAX_TRANSFER, &act_len,
 230                                JEILINJ_DATA_TIMEOUT);
 231                        if (ret < 0 || act_len < JEILINJ_MAX_TRANSFER)
 232                                goto quit_stream;
 233                        PDEBUG(D_STREAM,
 234                                "%d blocks remaining for frame", blocks_left);
 235                        blocks_left -= 1;
 236                        if (blocks_left == 0)
 237                                packet_type = LAST_PACKET;
 238                        else
 239                                packet_type = INTER_PACKET;
 240                        gspca_frame_add(gspca_dev, packet_type,
 241                                        buffer, JEILINJ_MAX_TRANSFER);
 242                }
 243        }
 244quit_stream:
 245        mutex_lock(&gspca_dev->usb_lock);
 246        if (gspca_dev->present)
 247                jlj_stop(gspca_dev);
 248        mutex_unlock(&gspca_dev->usb_lock);
 249        kfree(buffer);
 250}
 251
 252/* This function is called at probe time just before sd_init */
 253static int sd_config(struct gspca_dev *gspca_dev,
 254                const struct usb_device_id *id)
 255{
 256        struct cam *cam = &gspca_dev->cam;
 257        struct sd *dev  = (struct sd *) gspca_dev;
 258
 259        dev->quality  = 85;
 260        dev->jpegqual = 85;
 261        PDEBUG(D_PROBE,
 262                "JEILINJ camera detected"
 263                " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
 264        cam->cam_mode = jlj_mode;
 265        cam->nmodes = 1;
 266        cam->bulk = 1;
 267        /* We don't use the buffer gspca allocates so make it small. */
 268        cam->bulk_size = 32;
 269        INIT_WORK(&dev->work_struct, jlj_dostream);
 270        return 0;
 271}
 272
 273/* called on streamoff with alt==0 and on disconnect */
 274/* the usb_lock is held at entry - restore on exit */
 275static void sd_stop0(struct gspca_dev *gspca_dev)
 276{
 277        struct sd *dev = (struct sd *) gspca_dev;
 278
 279        /* wait for the work queue to terminate */
 280        mutex_unlock(&gspca_dev->usb_lock);
 281        /* This waits for jlj_dostream to finish */
 282        destroy_workqueue(dev->work_thread);
 283        dev->work_thread = NULL;
 284        mutex_lock(&gspca_dev->usb_lock);
 285}
 286
 287/* this function is called at probe and resume time */
 288static int sd_init(struct gspca_dev *gspca_dev)
 289{
 290        return 0;
 291}
 292
 293/* Set up for getting frames. */
 294static int sd_start(struct gspca_dev *gspca_dev)
 295{
 296        struct sd *dev = (struct sd *) gspca_dev;
 297        int ret;
 298
 299        /* create the JPEG header */
 300        jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
 301                        0x21);          /* JPEG 422 */
 302        jpeg_set_qual(dev->jpeg_hdr, dev->quality);
 303        PDEBUG(D_STREAM, "Start streaming at 320x240");
 304        ret = jlj_start(gspca_dev);
 305        if (ret < 0) {
 306                PDEBUG(D_ERR, "Start streaming command failed");
 307                return ret;
 308        }
 309        /* Start the workqueue function to do the streaming */
 310        dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
 311        queue_work(dev->work_thread, &dev->work_struct);
 312
 313        return 0;
 314}
 315
 316/* Table of supported USB devices */
 317static const struct usb_device_id device_table[] = {
 318        {USB_DEVICE(0x0979, 0x0280)},
 319        {}
 320};
 321
 322MODULE_DEVICE_TABLE(usb, device_table);
 323
 324/* sub-driver description */
 325static const struct sd_desc sd_desc = {
 326        .name   = MODULE_NAME,
 327        .config = sd_config,
 328        .init   = sd_init,
 329        .start  = sd_start,
 330        .stop0  = sd_stop0,
 331};
 332
 333/* -- device connect -- */
 334static int sd_probe(struct usb_interface *intf,
 335                const struct usb_device_id *id)
 336{
 337        return gspca_dev_probe(intf, id,
 338                        &sd_desc,
 339                        sizeof(struct sd),
 340                        THIS_MODULE);
 341}
 342
 343static struct usb_driver sd_driver = {
 344        .name       = MODULE_NAME,
 345        .id_table   = device_table,
 346        .probe      = sd_probe,
 347        .disconnect = gspca_disconnect,
 348#ifdef CONFIG_PM
 349        .suspend = gspca_suspend,
 350        .resume  = gspca_resume,
 351#endif
 352};
 353
 354/* -- module insert / remove -- */
 355static int __init sd_mod_init(void)
 356{
 357        return usb_register(&sd_driver);
 358}
 359
 360static void __exit sd_mod_exit(void)
 361{
 362        usb_deregister(&sd_driver);
 363}
 364
 365module_init(sd_mod_init);
 366module_exit(sd_mod_exit);
 367