linux/drivers/media/video/gspca/vicam.c
<<
>>
Prefs
   1/*
   2 * gspca ViCam subdriver
   3 *
   4 * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com>
   5 *
   6 * Based on the usbvideo vicam driver, which is:
   7 *
   8 * Copyright (c) 2002 Joe Burks (jburks@wavicle.org),
   9 *                    Christopher L Cheney (ccheney@cheney.cx),
  10 *                    Pavel Machek (pavel@ucw.cz),
  11 *                    John Tyner (jtyner@cs.ucr.edu),
  12 *                    Monroe Williams (monroe@pobox.com)
  13 *
  14 * This program is free software; you can redistribute it and/or modify
  15 * it under the terms of the GNU General Public License as published by
  16 * the Free Software Foundation; either version 2 of the License, or
  17 * any later version.
  18 *
  19 * This program is distributed in the hope that it will be useful,
  20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22 * GNU General Public License for more details.
  23 *
  24 * You should have received a copy of the GNU General Public License
  25 * along with this program; if not, write to the Free Software
  26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27 */
  28
  29#define MODULE_NAME "vicam"
  30#define HEADER_SIZE 64
  31
  32#include <linux/workqueue.h>
  33#include <linux/slab.h>
  34#include <linux/firmware.h>
  35#include <linux/ihex.h>
  36#include "gspca.h"
  37
  38MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
  39MODULE_DESCRIPTION("GSPCA ViCam USB Camera Driver");
  40MODULE_LICENSE("GPL");
  41
  42enum e_ctrl {
  43        GAIN,
  44        EXPOSURE,
  45        NCTRL           /* number of controls */
  46};
  47
  48struct sd {
  49        struct gspca_dev gspca_dev;     /* !! must be the first item */
  50        struct work_struct work_struct;
  51        struct workqueue_struct *work_thread;
  52        struct gspca_ctrl ctrls[NCTRL];
  53};
  54
  55/* The vicam sensor has a resolution of 512 x 244, with I believe square
  56   pixels, but this is forced to a 4:3 ratio by optics. So it has
  57   non square pixels :( */
  58static struct v4l2_pix_format vicam_mode[] = {
  59        { 256, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
  60                .bytesperline = 256,
  61                .sizeimage = 256 * 122,
  62                .colorspace = V4L2_COLORSPACE_SRGB,},
  63        /* 2 modes with somewhat more square pixels */
  64        { 256, 200, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
  65                .bytesperline = 256,
  66                .sizeimage = 256 * 200,
  67                .colorspace = V4L2_COLORSPACE_SRGB,},
  68        { 256, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
  69                .bytesperline = 256,
  70                .sizeimage = 256 * 240,
  71                .colorspace = V4L2_COLORSPACE_SRGB,},
  72#if 0   /* This mode has extremely non square pixels, testing use only */
  73        { 512, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
  74                .bytesperline = 512,
  75                .sizeimage = 512 * 122,
  76                .colorspace = V4L2_COLORSPACE_SRGB,},
  77#endif
  78        { 512, 244, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
  79                .bytesperline = 512,
  80                .sizeimage = 512 * 244,
  81                .colorspace = V4L2_COLORSPACE_SRGB,},
  82};
  83
  84static const struct ctrl sd_ctrls[] = {
  85[GAIN] = {
  86            {
  87                .id      = V4L2_CID_GAIN,
  88                .type    = V4L2_CTRL_TYPE_INTEGER,
  89                .name    = "Gain",
  90                .minimum = 0,
  91                .maximum = 255,
  92                .step    = 1,
  93                .default_value = 200,
  94            },
  95        },
  96[EXPOSURE] = {
  97            {
  98                .id      = V4L2_CID_EXPOSURE,
  99                .type    = V4L2_CTRL_TYPE_INTEGER,
 100                .name    = "Exposure",
 101                .minimum = 0,
 102                .maximum = 2047,
 103                .step    = 1,
 104                .default_value = 256,
 105            },
 106        },
 107};
 108
 109static int vicam_control_msg(struct gspca_dev *gspca_dev, u8 request,
 110        u16 value, u16 index, u8 *data, u16 len)
 111{
 112        int ret;
 113
 114        ret = usb_control_msg(gspca_dev->dev,
 115                              usb_sndctrlpipe(gspca_dev->dev, 0),
 116                              request,
 117                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 118                              value, index, data, len, 1000);
 119        if (ret < 0)
 120                err("control msg req %02X error %d", request, ret);
 121
 122        return ret;
 123}
 124
 125static int vicam_set_camera_power(struct gspca_dev *gspca_dev, int state)
 126{
 127        int ret;
 128
 129        ret = vicam_control_msg(gspca_dev, 0x50, state, 0, NULL, 0);
 130        if (ret < 0)
 131                return ret;
 132
 133        if (state)
 134                ret = vicam_control_msg(gspca_dev, 0x55, 1, 0, NULL, 0);
 135
 136        return ret;
 137}
 138
 139/*
 140 *  request and read a block of data - see warning on vicam_command.
 141 */
 142static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size)
 143{
 144        struct sd *sd = (struct sd *)gspca_dev;
 145        int ret, unscaled_height, act_len = 0;
 146        u8 *req_data = gspca_dev->usb_buf;
 147
 148        memset(req_data, 0, 16);
 149        req_data[0] = sd->ctrls[GAIN].val;
 150        if (gspca_dev->width == 256)
 151                req_data[1] |= 0x01; /* low nibble x-scale */
 152        if (gspca_dev->height <= 122) {
 153                req_data[1] |= 0x10; /* high nibble y-scale */
 154                unscaled_height = gspca_dev->height * 2;
 155        } else
 156                unscaled_height = gspca_dev->height;
 157        req_data[2] = 0x90; /* unknown, does not seem to do anything */
 158        if (unscaled_height <= 200)
 159                req_data[3] = 0x06; /* vend? */
 160        else if (unscaled_height <= 242) /* Yes 242 not 240 */
 161                req_data[3] = 0x07; /* vend? */
 162        else /* Up to 244 lines with req_data[3] == 0x08 */
 163                req_data[3] = 0x08; /* vend? */
 164
 165        if (sd->ctrls[EXPOSURE].val < 256) {
 166                /* Frame rate maxed out, use partial frame expo time */
 167                req_data[4] = 255 - sd->ctrls[EXPOSURE].val;
 168                req_data[5] = 0x00;
 169                req_data[6] = 0x00;
 170                req_data[7] = 0x01;
 171        } else {
 172                /* Modify frame rate */
 173                req_data[4] = 0x00;
 174                req_data[5] = 0x00;
 175                req_data[6] = sd->ctrls[EXPOSURE].val & 0xFF;
 176                req_data[7] = sd->ctrls[EXPOSURE].val >> 8;
 177        }
 178        req_data[8] = ((244 - unscaled_height) / 2) & ~0x01; /* vstart */
 179        /* bytes 9-15 do not seem to affect exposure or image quality */
 180
 181        mutex_lock(&gspca_dev->usb_lock);
 182        ret = vicam_control_msg(gspca_dev, 0x51, 0x80, 0, req_data, 16);
 183        mutex_unlock(&gspca_dev->usb_lock);
 184        if (ret < 0)
 185                return ret;
 186
 187        ret = usb_bulk_msg(gspca_dev->dev,
 188                           usb_rcvbulkpipe(gspca_dev->dev, 0x81),
 189                           data, size, &act_len, 10000);
 190        /* successful, it returns 0, otherwise  negative */
 191        if (ret < 0 || act_len != size) {
 192                err("bulk read fail (%d) len %d/%d",
 193                        ret, act_len, size);
 194                return -EIO;
 195        }
 196        return 0;
 197}
 198
 199/* This function is called as a workqueue function and runs whenever the camera
 200 * is streaming data. Because it is a workqueue function it is allowed to sleep
 201 * so we can use synchronous USB calls. To avoid possible collisions with other
 202 * threads attempting to use the camera's USB interface we take the gspca
 203 * usb_lock when performing USB operations. In practice the only thing we need
 204 * to protect against is the usb_set_interface call that gspca makes during
 205 * stream_off as the camera doesn't provide any controls that the user could try
 206 * to change.
 207 */
 208static void vicam_dostream(struct work_struct *work)
 209{
 210        struct sd *sd = container_of(work, struct sd, work_struct);
 211        struct gspca_dev *gspca_dev = &sd->gspca_dev;
 212        int ret, frame_sz;
 213        u8 *buffer;
 214
 215        frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage +
 216                   HEADER_SIZE;
 217        buffer = kmalloc(frame_sz, GFP_KERNEL | GFP_DMA);
 218        if (!buffer) {
 219                err("Couldn't allocate USB buffer");
 220                goto exit;
 221        }
 222
 223        while (gspca_dev->present && gspca_dev->streaming) {
 224                ret = vicam_read_frame(gspca_dev, buffer, frame_sz);
 225                if (ret < 0)
 226                        break;
 227
 228                /* Note the frame header contents seem to be completely
 229                   constant, they do not change with either image, or
 230                   settings. So we simply discard it. The frames have
 231                   a very similar 64 byte footer, which we don't even
 232                   bother reading from the cam */
 233                gspca_frame_add(gspca_dev, FIRST_PACKET,
 234                                buffer + HEADER_SIZE,
 235                                frame_sz - HEADER_SIZE);
 236                gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 237        }
 238exit:
 239        kfree(buffer);
 240}
 241
 242/* This function is called at probe time just before sd_init */
 243static int sd_config(struct gspca_dev *gspca_dev,
 244                const struct usb_device_id *id)
 245{
 246        struct cam *cam = &gspca_dev->cam;
 247        struct sd *sd = (struct sd *)gspca_dev;
 248
 249        /* We don't use the buffer gspca allocates so make it small. */
 250        cam->bulk = 1;
 251        cam->bulk_size = 64;
 252        cam->cam_mode = vicam_mode;
 253        cam->nmodes = ARRAY_SIZE(vicam_mode);
 254        cam->ctrls = sd->ctrls;
 255
 256        INIT_WORK(&sd->work_struct, vicam_dostream);
 257
 258        return 0;
 259}
 260
 261/* this function is called at probe and resume time */
 262static int sd_init(struct gspca_dev *gspca_dev)
 263{
 264        int ret;
 265        const struct ihex_binrec *rec;
 266        const struct firmware *uninitialized_var(fw);
 267        u8 *firmware_buf;
 268
 269        ret = request_ihex_firmware(&fw, "vicam/firmware.fw",
 270                                    &gspca_dev->dev->dev);
 271        if (ret) {
 272                err("Failed to load \"vicam/firmware.fw\": %d\n", ret);
 273                return ret;
 274        }
 275
 276        firmware_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
 277        if (!firmware_buf) {
 278                ret = -ENOMEM;
 279                goto exit;
 280        }
 281        for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
 282                memcpy(firmware_buf, rec->data, be16_to_cpu(rec->len));
 283                ret = vicam_control_msg(gspca_dev, 0xff, 0, 0, firmware_buf,
 284                                        be16_to_cpu(rec->len));
 285                if (ret < 0)
 286                        break;
 287        }
 288
 289        kfree(firmware_buf);
 290exit:
 291        release_firmware(fw);
 292        return ret;
 293}
 294
 295/* Set up for getting frames. */
 296static int sd_start(struct gspca_dev *gspca_dev)
 297{
 298        struct sd *sd = (struct sd *)gspca_dev;
 299        int ret;
 300
 301        ret = vicam_set_camera_power(gspca_dev, 1);
 302        if (ret < 0)
 303                return ret;
 304
 305        /* Start the workqueue function to do the streaming */
 306        sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
 307        queue_work(sd->work_thread, &sd->work_struct);
 308
 309        return 0;
 310}
 311
 312/* called on streamoff with alt==0 and on disconnect */
 313/* the usb_lock is held at entry - restore on exit */
 314static void sd_stop0(struct gspca_dev *gspca_dev)
 315{
 316        struct sd *dev = (struct sd *)gspca_dev;
 317
 318        /* wait for the work queue to terminate */
 319        mutex_unlock(&gspca_dev->usb_lock);
 320        /* This waits for vicam_dostream to finish */
 321        destroy_workqueue(dev->work_thread);
 322        dev->work_thread = NULL;
 323        mutex_lock(&gspca_dev->usb_lock);
 324
 325        vicam_set_camera_power(gspca_dev, 0);
 326}
 327
 328/* Table of supported USB devices */
 329static const struct usb_device_id device_table[] = {
 330        {USB_DEVICE(0x04c1, 0x009d)},
 331        {USB_DEVICE(0x0602, 0x1001)},
 332        {}
 333};
 334
 335MODULE_DEVICE_TABLE(usb, device_table);
 336
 337/* sub-driver description */
 338static const struct sd_desc sd_desc = {
 339        .name   = MODULE_NAME,
 340        .ctrls  = sd_ctrls,
 341        .nctrls = ARRAY_SIZE(sd_ctrls),
 342        .config = sd_config,
 343        .init   = sd_init,
 344        .start  = sd_start,
 345        .stop0  = sd_stop0,
 346};
 347
 348/* -- device connect -- */
 349static int sd_probe(struct usb_interface *intf,
 350                const struct usb_device_id *id)
 351{
 352        return gspca_dev_probe(intf, id,
 353                        &sd_desc,
 354                        sizeof(struct sd),
 355                        THIS_MODULE);
 356}
 357
 358static struct usb_driver sd_driver = {
 359        .name       = MODULE_NAME,
 360        .id_table   = device_table,
 361        .probe      = sd_probe,
 362        .disconnect = gspca_disconnect,
 363#ifdef CONFIG_PM
 364        .suspend = gspca_suspend,
 365        .resume  = gspca_resume,
 366#endif
 367};
 368
 369/* -- module insert / remove -- */
 370static int __init sd_mod_init(void)
 371{
 372        return usb_register(&sd_driver);
 373}
 374
 375static void __exit sd_mod_exit(void)
 376{
 377        usb_deregister(&sd_driver);
 378}
 379
 380module_init(sd_mod_init);
 381module_exit(sd_mod_exit);
 382