linux/drivers/media/video/usbvideo/quickcam_messenger.c
<<
>>
Prefs
   1/*
   2 * Driver for Logitech Quickcam Messenger usb video camera
   3 * Copyright (C) Jaya Kumar
   4 *
   5 * This work was sponsored by CIS(M) Sdn Bhd.
   6 * History:
   7 * 05/08/2006 - Jaya Kumar
   8 * I wrote this based on the konicawc by Simon Evans.
   9 * -
  10 * Full credit for reverse engineering and creating an initial
  11 * working linux driver for the VV6422 goes to the qce-ga project by
  12 * Tuukka Toivonen, Jochen Hoenicke, Peter McConnell,
  13 * Cristiano De Michele, Georg Acher, Jean-Frederic Clere as well as
  14 * others.
  15 * ---
  16 * This program is free software; you can redistribute it and/or modify
  17 * it under the terms of the GNU General Public License as published by
  18 * the Free Software Foundation; either version 2 of the License, or
  19 * (at your option) any later version.
  20 *
  21 * This program is distributed in the hope that it will be useful,
  22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24 * GNU General Public License for more details.
  25 *
  26 * You should have received a copy of the GNU General Public License
  27 * along with this program; if not, write to the Free Software
  28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  29 *
  30 */
  31
  32#include <linux/kernel.h>
  33#include <linux/module.h>
  34#include <linux/init.h>
  35#include <linux/input.h>
  36#include <linux/usb/input.h>
  37#include <linux/slab.h>
  38
  39#include "usbvideo.h"
  40#include "quickcam_messenger.h"
  41
  42/*
  43 * Version Information
  44 */
  45
  46#ifdef CONFIG_USB_DEBUG
  47static int debug;
  48#define DEBUG(n, format, arg...) \
  49        if (n <= debug) {        \
  50                printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \
  51        }
  52#else
  53#define DEBUG(n, arg...)
  54static const int debug;
  55#endif
  56
  57#define DRIVER_VERSION "v0.01"
  58#define DRIVER_DESC "Logitech Quickcam Messenger USB"
  59
  60#define USB_LOGITECH_VENDOR_ID  0x046D
  61#define USB_QCM_PRODUCT_ID      0x08F0
  62
  63#define MAX_CAMERAS     1
  64
  65#define MAX_COLOUR      32768
  66#define MAX_HUE         32768
  67#define MAX_BRIGHTNESS  32768
  68#define MAX_CONTRAST    32768
  69#define MAX_WHITENESS   32768
  70
  71static int size = SIZE_320X240;
  72static int colour = MAX_COLOUR;
  73static int hue = MAX_HUE;
  74static int brightness = MAX_BRIGHTNESS;
  75static int contrast =   MAX_CONTRAST;
  76static int whiteness =  MAX_WHITENESS;
  77
  78static struct usbvideo *cams;
  79
  80static struct usb_device_id qcm_table [] = {
  81        { USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) },
  82        { }
  83};
  84MODULE_DEVICE_TABLE(usb, qcm_table);
  85
  86#ifdef CONFIG_INPUT
  87static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
  88{
  89        struct input_dev *input_dev;
  90        int error;
  91
  92        usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
  93        strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
  94
  95        cam->input = input_dev = input_allocate_device();
  96        if (!input_dev) {
  97                dev_warn(&dev->dev, "insufficient mem for cam input device\n");
  98                return;
  99        }
 100
 101        input_dev->name = "QCM button";
 102        input_dev->phys = cam->input_physname;
 103        usb_to_input_id(dev, &input_dev->id);
 104        input_dev->dev.parent = &dev->dev;
 105
 106        input_dev->evbit[0] = BIT_MASK(EV_KEY);
 107        input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
 108
 109        error = input_register_device(cam->input);
 110        if (error) {
 111                dev_warn(&dev->dev,
 112                         "Failed to register camera's input device, err: %d\n",
 113                         error);
 114                input_free_device(cam->input);
 115                cam->input = NULL;
 116        }
 117}
 118
 119static void qcm_unregister_input(struct qcm *cam)
 120{
 121        if (cam->input) {
 122                input_unregister_device(cam->input);
 123                cam->input = NULL;
 124        }
 125}
 126
 127static void qcm_report_buttonstat(struct qcm *cam)
 128{
 129        if (cam->input) {
 130                input_report_key(cam->input, KEY_CAMERA, cam->button_sts);
 131                input_sync(cam->input);
 132        }
 133}
 134
 135static void qcm_int_irq(struct urb *urb)
 136{
 137        int ret;
 138        struct uvd *uvd = urb->context;
 139        struct qcm *cam;
 140
 141        if (!CAMERA_IS_OPERATIONAL(uvd))
 142                return;
 143
 144        if (!uvd->streaming)
 145                return;
 146
 147        uvd->stats.urb_count++;
 148
 149        if (urb->status < 0)
 150                uvd->stats.iso_err_count++;
 151        else {
 152                if (urb->actual_length > 0 ) {
 153                        cam = (struct qcm *) uvd->user_data;
 154                        if (cam->button_sts_buf == 0x88)
 155                                cam->button_sts = 0x0;
 156                        else if (cam->button_sts_buf == 0x80)
 157                                cam->button_sts = 0x1;
 158                        qcm_report_buttonstat(cam);
 159                }
 160        }
 161
 162        ret = usb_submit_urb(urb, GFP_ATOMIC);
 163        if (ret < 0)
 164                err("usb_submit_urb error (%d)", ret);
 165}
 166
 167static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd)
 168{
 169        int errflag;
 170        usb_fill_int_urb(cam->button_urb, uvd->dev,
 171                        usb_rcvintpipe(uvd->dev, uvd->video_endp + 1),
 172                        &cam->button_sts_buf,
 173                        1,
 174                        qcm_int_irq,
 175                        uvd, 16);
 176
 177        errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL);
 178        if (errflag)
 179                err ("usb_submit_int ret %d", errflag);
 180        return errflag;
 181}
 182
 183static void qcm_stop_int_data(struct qcm *cam)
 184{
 185        usb_kill_urb(cam->button_urb);
 186}
 187
 188static int qcm_alloc_int_urb(struct qcm *cam)
 189{
 190        cam->button_urb = usb_alloc_urb(0, GFP_KERNEL);
 191
 192        if (!cam->button_urb)
 193                return -ENOMEM;
 194
 195        return 0;
 196}
 197
 198static void qcm_free_int(struct qcm *cam)
 199{
 200        usb_free_urb(cam->button_urb);
 201}
 202#endif /* CONFIG_INPUT */
 203
 204static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
 205{
 206        int ret;
 207
 208        /* we'll wait up to 3 slices but no more */
 209        ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 210                0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 211                reg, 0, &val, 1, 3*HZ);
 212        return ret;
 213}
 214
 215static int qcm_stv_setw(struct usb_device *dev, u16 reg, __le16 val)
 216{
 217        int ret;
 218
 219        /* we'll wait up to 3 slices but no more */
 220        ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 221                0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 222                reg, 0, &val, 2, 3*HZ);
 223        return ret;
 224}
 225
 226static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
 227                                                        __le16 *val)
 228{
 229        int ret;
 230
 231        /* we'll wait up to 3 slices but no more */
 232        ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 233                0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
 234                reg, 0, val, 2, 3*HZ);
 235        return ret;
 236}
 237
 238static int qcm_camera_on(struct uvd *uvd)
 239{
 240        int ret;
 241        CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
 242        return 0;
 243}
 244
 245static int qcm_camera_off(struct uvd *uvd)
 246{
 247        int ret;
 248        CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
 249        return 0;
 250}
 251
 252static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
 253{
 254        unsigned int segment, valsat;
 255        signed int   h = (signed int) hue;
 256        unsigned int s = (sat - 32768) * 2;     /* rescale */
 257        unsigned int v = val;
 258        unsigned int p;
 259
 260        /*
 261        the registers controlling gain are 8 bit of which
 262        we affect only the last 4 bits with our gain.
 263        we know that if saturation is 0, (unsaturated) then
 264        we're grayscale (center axis of the colour cone) so
 265        we set rgb=value. we use a formula obtained from
 266        wikipedia to map the cone to the RGB plane. it's
 267        as follows for the human value case of h=0..360,
 268        s=0..1, v=0..1
 269        h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s)
 270        q = v(1 - f*s) , t = v(1 - (1-f)s)
 271        h_i==0 => r=v , g=t, b=p
 272        h_i==1 => r=q , g=v, b=p
 273        h_i==2 => r=p , g=v, b=t
 274        h_i==3 => r=p , g=q, b=v
 275        h_i==4 => r=t , g=p, b=v
 276        h_i==5 => r=v , g=p, b=q
 277        the bottom side (the point) and the stuff just up
 278        of that is black so we simplify those two cases.
 279        */
 280        if (sat < 32768) {
 281                /* anything less than this is unsaturated */
 282                *r = val;
 283                *g = val;
 284                *b = val;
 285                return;
 286        }
 287        if (val <= (0xFFFF/8)) {
 288                /* anything less than this is black */
 289                *r = 0;
 290                *g = 0;
 291                *b = 0;
 292                return;
 293        }
 294
 295        /* the rest of this code is copying tukkat's
 296        implementation of the hsv2rgb conversion as taken
 297        from qc-usb-messenger code. the 10923 is 0xFFFF/6
 298        to divide the cone into 6 sectors.  */
 299
 300        segment = (h + 10923) & 0xFFFF;
 301        segment = segment*3 >> 16;              /* 0..2: 0=R, 1=G, 2=B */
 302        hue -= segment * 21845;                 /* -10923..10923 */
 303        h = hue;
 304        h *= 3;
 305        valsat = v*s >> 16;                     /* 0..65534 */
 306        p = v - valsat;
 307        if (h >= 0) {
 308                unsigned int t = v - (valsat * (32769 - h) >> 15);
 309                switch (segment) {
 310                case 0: /* R-> */
 311                        *r = v;
 312                        *g = t;
 313                        *b = p;
 314                        break;
 315                case 1: /* G-> */
 316                        *r = p;
 317                        *g = v;
 318                        *b = t;
 319                        break;
 320                case 2: /* B-> */
 321                        *r = t;
 322                        *g = p;
 323                        *b = v;
 324                        break;
 325                }
 326        } else {
 327                unsigned int q = v - (valsat * (32769 + h) >> 15);
 328                switch (segment) {
 329                case 0: /* ->R */
 330                        *r = v;
 331                        *g = p;
 332                        *b = q;
 333                        break;
 334                case 1: /* ->G */
 335                        *r = q;
 336                        *g = v;
 337                        *b = p;
 338                        break;
 339                case 2: /* ->B */
 340                        *r = p;
 341                        *g = q;
 342                        *b = v;
 343                        break;
 344                }
 345        }
 346}
 347
 348static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
 349        u16 saturation, u16 value)
 350{
 351        int ret;
 352        u16 r=0,g=0,b=0;
 353
 354        /* this code is based on qc-usb-messenger */
 355        qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
 356
 357        r >>= 12;
 358        g >>= 12;
 359        b >>= 12;
 360
 361        /* min val is 8 */
 362        r = max((u16) 8, r);
 363        g = max((u16) 8, g);
 364        b = max((u16) 8, b);
 365
 366        r |= 0x30;
 367        g |= 0x30;
 368        b |= 0x30;
 369
 370        /* set the r,g,b gain registers */
 371        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r));
 372        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g));
 373        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b));
 374
 375        /* doing as qc-usb did */
 376        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A));
 377        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01));
 378        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
 379
 380        return 0;
 381}
 382
 383static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
 384{
 385        int ret;
 386        int formedval;
 387
 388        /* calculation was from qc-usb-messenger driver */
 389        formedval = ( exposure >> 12 );
 390
 391        /* max value for formedval is 14 */
 392        formedval = min(formedval, 14);
 393
 394        CHECK_RET(ret, qcm_stv_setb(uvd->dev,
 395                        0x143A, 0xF0 | formedval));
 396        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
 397        return 0;
 398}
 399
 400static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
 401                                        int hue, int colour)
 402{
 403        int ret;
 404        /* brightness is exposure, contrast is gain, colour is saturation */
 405        CHECK_RET(ret,
 406                qcm_sensor_set_exposure(uvd, brightness));
 407        CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
 408
 409        return 0;
 410}
 411
 412static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
 413{
 414        int ret;
 415
 416        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
 417        return 0;
 418}
 419
 420static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
 421{
 422        int ret;
 423        /* some rescaling as done by the qc-usb-messenger code */
 424        if (whiteness > 0xC000)
 425                whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
 426
 427        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D,
 428                                (whiteness >> 8) & 0xFF));
 429        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E,
 430                                (whiteness >> 16) & 0x03));
 431        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
 432
 433        return 0;
 434}
 435
 436static int qcm_sensor_init(struct uvd *uvd)
 437{
 438        struct qcm *cam = (struct qcm *) uvd->user_data;
 439        int ret;
 440        int i;
 441
 442        for (i=0; i < ARRAY_SIZE(regval_table) ; i++) {
 443                CHECK_RET(ret, qcm_stv_setb(uvd->dev,
 444                                        regval_table[i].reg,
 445                                        regval_table[i].val));
 446        }
 447
 448        CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
 449                                cpu_to_le16(ISOC_PACKET_SIZE)));
 450        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
 451        CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143f, 0x01));
 452
 453        CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
 454
 455        CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
 456
 457        CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
 458                        uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
 459
 460        CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
 461        CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
 462
 463        return 0;
 464}
 465
 466static int qcm_set_camera_size(struct uvd *uvd)
 467{
 468        int ret;
 469        struct qcm *cam = (struct qcm *) uvd->user_data;
 470
 471        CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
 472        cam->width = camera_sizes[cam->size].width;
 473        cam->height = camera_sizes[cam->size].height;
 474        uvd->videosize = VIDEOSIZE(cam->width, cam->height);
 475
 476        return 0;
 477}
 478
 479static int qcm_setup_on_open(struct uvd *uvd)
 480{
 481        int ret;
 482
 483        CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
 484                                uvd->vpic.colour, uvd->vpic.contrast));
 485        CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
 486        CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
 487        CHECK_RET(ret, qcm_set_camera_size(uvd));
 488        CHECK_RET(ret, qcm_camera_on(uvd));
 489        return 0;
 490}
 491
 492static void qcm_adjust_picture(struct uvd *uvd)
 493{
 494        int ret;
 495        struct qcm *cam = (struct qcm *) uvd->user_data;
 496
 497        ret = qcm_camera_off(uvd);
 498        if (ret) {
 499                err("can't turn camera off. abandoning pic adjustment");
 500                return;
 501        }
 502
 503        /* if there's been a change in contrast, hue, or
 504        colour then we need to recalculate hsv in order
 505        to update gains */
 506        if ((cam->contrast != uvd->vpic.contrast) ||
 507                (cam->hue != uvd->vpic.hue) ||
 508                (cam->colour != uvd->vpic.colour)) {
 509                cam->contrast = uvd->vpic.contrast;
 510                cam->hue = uvd->vpic.hue;
 511                cam->colour = uvd->vpic.colour;
 512                ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
 513                                                cam->contrast);
 514                if (ret) {
 515                        err("can't set gains. abandoning pic adjustment");
 516                        return;
 517                }
 518        }
 519
 520        if (cam->brightness != uvd->vpic.brightness) {
 521                cam->brightness = uvd->vpic.brightness;
 522                ret = qcm_sensor_set_exposure(uvd, cam->brightness);
 523                if (ret) {
 524                        err("can't set exposure. abandoning pic adjustment");
 525                        return;
 526                }
 527        }
 528
 529        if (cam->whiteness != uvd->vpic.whiteness) {
 530                cam->whiteness = uvd->vpic.whiteness;
 531                qcm_sensor_set_shutter(uvd, cam->whiteness);
 532                if (ret) {
 533                        err("can't set shutter. abandoning pic adjustment");
 534                        return;
 535                }
 536        }
 537
 538        ret = qcm_camera_on(uvd);
 539        if (ret) {
 540                err("can't reenable camera. pic adjustment failed");
 541                return;
 542        }
 543}
 544
 545static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
 546{
 547        int datalen;
 548        int totaldata;
 549        struct framehdr {
 550                __be16 id;
 551                __be16 len;
 552        };
 553        struct framehdr *fhdr;
 554
 555        totaldata = 0;
 556        while (framelen) {
 557                fhdr = (struct framehdr *) cdata;
 558                datalen = be16_to_cpu(fhdr->len);
 559                framelen -= 4;
 560                cdata += 4;
 561
 562                if ((fhdr->id) == cpu_to_be16(0x8001)) {
 563                        RingQueue_Enqueue(&uvd->dp, marker, 4);
 564                        totaldata += 4;
 565                        continue;
 566                }
 567                if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
 568                        RingQueue_Enqueue(&uvd->dp, cdata, datalen);
 569                        totaldata += datalen;
 570                }
 571                framelen -= datalen;
 572                cdata += datalen;
 573        }
 574        return totaldata;
 575}
 576
 577static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
 578{
 579        int totlen;
 580        int i;
 581        unsigned char *cdata;
 582
 583        totlen=0;
 584        for (i = 0; i < dataurb->number_of_packets; i++) {
 585                int n = dataurb->iso_frame_desc[i].actual_length;
 586                int st = dataurb->iso_frame_desc[i].status;
 587
 588                cdata = dataurb->transfer_buffer +
 589                        dataurb->iso_frame_desc[i].offset;
 590
 591                if (st < 0) {
 592                        dev_warn(&uvd->dev->dev,
 593                                 "Data error: packet=%d. len=%d. status=%d.\n",
 594                                 i, n, st);
 595                        uvd->stats.iso_err_count++;
 596                        continue;
 597                }
 598                if (!n)
 599                        continue;
 600
 601                totlen += qcm_process_frame(uvd, cdata, n);
 602        }
 603        return totlen;
 604}
 605
 606static void resubmit_urb(struct uvd *uvd, struct urb *urb)
 607{
 608        int ret;
 609
 610        urb->dev = uvd->dev;
 611        ret = usb_submit_urb(urb, GFP_ATOMIC);
 612        if (ret)
 613                err("usb_submit_urb error (%d)", ret);
 614}
 615
 616static void qcm_isoc_irq(struct urb *urb)
 617{
 618        int len;
 619        struct uvd *uvd = urb->context;
 620
 621        if (!CAMERA_IS_OPERATIONAL(uvd))
 622                return;
 623
 624        if (!uvd->streaming)
 625                return;
 626
 627        uvd->stats.urb_count++;
 628
 629        if (!urb->actual_length) {
 630                resubmit_urb(uvd, urb);
 631                return;
 632        }
 633
 634        len = qcm_compress_iso(uvd, urb);
 635        resubmit_urb(uvd, urb);
 636        uvd->stats.urb_length = len;
 637        uvd->stats.data_count += len;
 638        if (len)
 639                RingQueue_WakeUpInterruptible(&uvd->dp);
 640}
 641
 642static int qcm_start_data(struct uvd *uvd)
 643{
 644        struct qcm *cam = (struct qcm *) uvd->user_data;
 645        int i;
 646        int errflag;
 647        int pktsz;
 648        int err;
 649
 650        pktsz = uvd->iso_packet_len;
 651        if (!CAMERA_IS_OPERATIONAL(uvd)) {
 652                err("Camera is not operational");
 653                return -EFAULT;
 654        }
 655
 656        err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
 657        if (err < 0) {
 658                err("usb_set_interface error");
 659                uvd->last_error = err;
 660                return -EBUSY;
 661        }
 662
 663        for (i=0; i < USBVIDEO_NUMSBUF; i++) {
 664                int j, k;
 665                struct urb *urb = uvd->sbuf[i].urb;
 666                urb->dev = uvd->dev;
 667                urb->context = uvd;
 668                urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
 669                urb->interval = 1;
 670                urb->transfer_flags = URB_ISO_ASAP;
 671                urb->transfer_buffer = uvd->sbuf[i].data;
 672                urb->complete = qcm_isoc_irq;
 673                urb->number_of_packets = FRAMES_PER_DESC;
 674                urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
 675                for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
 676                        urb->iso_frame_desc[j].offset = k;
 677                        urb->iso_frame_desc[j].length = pktsz;
 678                }
 679        }
 680
 681        uvd->streaming = 1;
 682        uvd->curframe = -1;
 683        for (i=0; i < USBVIDEO_NUMSBUF; i++) {
 684                errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
 685                if (errflag)
 686                        err ("usb_submit_isoc(%d) ret %d", i, errflag);
 687        }
 688
 689        CHECK_RET(err, qcm_setup_input_int(cam, uvd));
 690        CHECK_RET(err, qcm_camera_on(uvd));
 691        return 0;
 692}
 693
 694static void qcm_stop_data(struct uvd *uvd)
 695{
 696        struct qcm *cam;
 697        int i, j;
 698        int ret;
 699
 700        if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
 701                return;
 702        cam = (struct qcm *) uvd->user_data;
 703
 704        ret = qcm_camera_off(uvd);
 705        if (ret)
 706                dev_warn(&uvd->dev->dev, "couldn't turn the cam off.\n");
 707
 708        uvd->streaming = 0;
 709
 710        /* Unschedule all of the iso td's */
 711        for (i=0; i < USBVIDEO_NUMSBUF; i++)
 712                usb_kill_urb(uvd->sbuf[i].urb);
 713
 714        qcm_stop_int_data(cam);
 715
 716        if (!uvd->remove_pending) {
 717                /* Set packet size to 0 */
 718                j = usb_set_interface(uvd->dev, uvd->iface,
 719                                        uvd->ifaceAltInactive);
 720                if (j < 0) {
 721                        err("usb_set_interface() error %d.", j);
 722                        uvd->last_error = j;
 723                }
 724        }
 725}
 726
 727static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
 728{
 729        struct qcm *cam = (struct qcm *) uvd->user_data;
 730        int x;
 731        struct rgb *rgbL0;
 732        struct rgb *rgbL1;
 733        struct bayL0 *bayL0;
 734        struct bayL1 *bayL1;
 735        int hor,ver,hordel,verdel;
 736        assert(frame != NULL);
 737
 738        switch (cam->size) {
 739        case SIZE_160X120:
 740                hor = 162; ver = 124; hordel = 1; verdel = 2;
 741                break;
 742        case SIZE_320X240:
 743        default:
 744                hor = 324; ver = 248; hordel = 2; verdel = 4;
 745                break;
 746        }
 747
 748        if (frame->scanstate == ScanState_Scanning) {
 749                while (RingQueue_GetLength(&uvd->dp) >=
 750                         4 + (hor*verdel + hordel)) {
 751                        if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
 752                            (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
 753                            (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
 754                            (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
 755                                frame->curline = 0;
 756                                frame->scanstate = ScanState_Lines;
 757                                frame->frameState = FrameState_Grabbing;
 758                                RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
 759                        /*
 760                        * if we're starting, we need to discard the first
 761                        * 4 lines of y bayer data
 762                        * and the first 2 gr elements of x bayer data
 763                        */
 764                                RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
 765                                                        (hor*verdel + hordel));
 766                                break;
 767                        }
 768                        RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
 769                }
 770        }
 771
 772        if (frame->scanstate == ScanState_Scanning)
 773                return;
 774
 775        /* now we can start processing bayer data so long as we have at least
 776        * 2 lines worth of data. this is the simplest demosaicing method that
 777        * I could think of. I use each 2x2 bayer element without interpolation
 778        * to generate 4 rgb pixels.
 779        */
 780        while ( frame->curline < cam->height &&
 781                (RingQueue_GetLength(&uvd->dp) >= hor*2)) {
 782                /* get 2 lines of bayer for demosaicing
 783                 * into 2 lines of RGB */
 784                RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2);
 785                bayL0 = (struct bayL0 *) cam->scratch;
 786                bayL1 = (struct bayL1 *) (cam->scratch + hor);
 787                /* frame->curline is the rgb y line */
 788                rgbL0 = (struct rgb *)
 789                                ( frame->data + (cam->width*3*frame->curline));
 790                /* w/2 because we're already doing 2 pixels */
 791                rgbL1 = rgbL0 + (cam->width/2);
 792
 793                for (x=0; x < cam->width; x+=2) {
 794                        rgbL0->r = bayL0->r;
 795                        rgbL0->g = bayL0->g;
 796                        rgbL0->b = bayL1->b;
 797
 798                        rgbL0->r2 = bayL0->r;
 799                        rgbL0->g2 = bayL1->g;
 800                        rgbL0->b2 = bayL1->b;
 801
 802                        rgbL1->r = bayL0->r;
 803                        rgbL1->g = bayL1->g;
 804                        rgbL1->b = bayL1->b;
 805
 806                        rgbL1->r2 = bayL0->r;
 807                        rgbL1->g2 = bayL1->g;
 808                        rgbL1->b2 = bayL1->b;
 809
 810                        rgbL0++;
 811                        rgbL1++;
 812
 813                        bayL0++;
 814                        bayL1++;
 815                }
 816
 817                frame->seqRead_Length += cam->width*3*2;
 818                frame->curline += 2;
 819        }
 820        /* See if we filled the frame */
 821        if (frame->curline == cam->height) {
 822                frame->frameState = FrameState_Done_Hold;
 823                frame->curline = 0;
 824                uvd->curframe = -1;
 825                uvd->stats.frame_num++;
 826        }
 827}
 828
 829/* taken from konicawc */
 830static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
 831{
 832        int ret;
 833        int newsize;
 834        int oldsize;
 835        int x = vw->width;
 836        int y = vw->height;
 837        struct qcm *cam = (struct qcm *) uvd->user_data;
 838
 839        if (x > 0 && y > 0) {
 840                DEBUG(2, "trying to find size %d,%d", x, y);
 841                for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
 842                        if ((camera_sizes[newsize].width == x) &&
 843                                (camera_sizes[newsize].height == y))
 844                                break;
 845                }
 846        } else
 847                newsize = cam->size;
 848
 849        if (newsize > MAX_FRAME_SIZE) {
 850                DEBUG(1, "couldn't find size %d,%d", x, y);
 851                return -EINVAL;
 852        }
 853
 854        if (newsize == cam->size) {
 855                DEBUG(1, "Nothing to do");
 856                return 0;
 857        }
 858
 859        qcm_stop_data(uvd);
 860
 861        if (cam->size != newsize) {
 862                oldsize = cam->size;
 863                cam->size = newsize;
 864                ret = qcm_set_camera_size(uvd);
 865                if (ret) {
 866                        err("Couldn't set camera size, err=%d",ret);
 867                        /* restore the original size */
 868                        cam->size = oldsize;
 869                        return ret;
 870                }
 871        }
 872
 873        /* Flush the input queue and clear any current frame in progress */
 874
 875        RingQueue_Flush(&uvd->dp);
 876        if (uvd->curframe != -1) {
 877                uvd->frame[uvd->curframe].curline = 0;
 878                uvd->frame[uvd->curframe].seqRead_Length = 0;
 879                uvd->frame[uvd->curframe].seqRead_Index = 0;
 880        }
 881
 882        CHECK_RET(ret, qcm_start_data(uvd));
 883        return 0;
 884}
 885
 886static int qcm_configure_video(struct uvd *uvd)
 887{
 888        int ret;
 889        memset(&uvd->vpic, 0, sizeof(uvd->vpic));
 890        memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
 891
 892        uvd->vpic.colour = colour;
 893        uvd->vpic.hue = hue;
 894        uvd->vpic.brightness = brightness;
 895        uvd->vpic.contrast = contrast;
 896        uvd->vpic.whiteness = whiteness;
 897        uvd->vpic.depth = 24;
 898        uvd->vpic.palette = VIDEO_PALETTE_RGB24;
 899
 900        memset(&uvd->vcap, 0, sizeof(uvd->vcap));
 901        strcpy(uvd->vcap.name, "QCM USB Camera");
 902        uvd->vcap.type = VID_TYPE_CAPTURE;
 903        uvd->vcap.channels = 1;
 904        uvd->vcap.audios = 0;
 905
 906        uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
 907        uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
 908        uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
 909        uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
 910
 911        memset(&uvd->vchan, 0, sizeof(uvd->vchan));
 912        uvd->vchan.flags = 0 ;
 913        uvd->vchan.tuners = 0;
 914        uvd->vchan.channel = 0;
 915        uvd->vchan.type = VIDEO_TYPE_CAMERA;
 916        strcpy(uvd->vchan.name, "Camera");
 917
 918        CHECK_RET(ret, qcm_sensor_init(uvd));
 919        return 0;
 920}
 921
 922static int qcm_probe(struct usb_interface *intf,
 923                        const struct usb_device_id *devid)
 924{
 925        int err;
 926        struct uvd *uvd;
 927        struct usb_device *dev = interface_to_usbdev(intf);
 928        struct qcm *cam;
 929        size_t buffer_size;
 930        unsigned char video_ep;
 931        struct usb_host_interface *interface;
 932        struct usb_endpoint_descriptor *endpoint;
 933        int i,j;
 934        unsigned int ifacenum, ifacenum_inact=0;
 935        __le16 sensor_id;
 936
 937        /* we don't support multiconfig cams */
 938        if (dev->descriptor.bNumConfigurations != 1)
 939                return -ENODEV;
 940
 941        /* first check for the video interface and not
 942        * the audio interface */
 943        interface = &intf->cur_altsetting[0];
 944        if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
 945                || (interface->desc.bInterfaceSubClass !=
 946                        USB_CLASS_VENDOR_SPEC))
 947                return -ENODEV;
 948
 949        /*
 950        walk through each endpoint in each setting in the interface
 951        stop when we find the one that's an isochronous IN endpoint.
 952        */
 953        for (i=0; i < intf->num_altsetting; i++) {
 954                interface = &intf->cur_altsetting[i];
 955                ifacenum = interface->desc.bAlternateSetting;
 956                /* walk the end points */
 957                for (j=0; j < interface->desc.bNumEndpoints; j++) {
 958                        endpoint = &interface->endpoint[j].desc;
 959
 960                        if (usb_endpoint_dir_out(endpoint))
 961                                continue; /* not input then not good */
 962
 963                        buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 964                        if (!buffer_size) {
 965                                ifacenum_inact = ifacenum;
 966                                continue; /* 0 pkt size is not what we want */
 967                        }
 968
 969                        if (usb_endpoint_xfer_isoc(endpoint)) {
 970                                video_ep = endpoint->bEndpointAddress;
 971                                /* break out of the search */
 972                                goto good_videoep;
 973                        }
 974                }
 975        }
 976        /* failed out since nothing useful was found */
 977        err("No suitable endpoint was found\n");
 978        return -ENODEV;
 979
 980good_videoep:
 981        /* disable isochronous stream before doing anything else */
 982        err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
 983        if (err < 0) {
 984                err("Failed to disable sensor stream");
 985                return -EIO;
 986        }
 987
 988        /*
 989        Check that this is the same unknown sensor that is known to work. This
 990        sensor is suspected to be the ST VV6422C001. I'll check the same value
 991        that the qc-usb driver checks. This value is probably not even the
 992        sensor ID since it matches the USB dev ID. Oh well. If it doesn't
 993        match, it's probably a diff sensor so exit and apologize.
 994        */
 995        err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id);
 996        if (err < 0) {
 997                err("Couldn't read sensor values. Err %d\n",err);
 998                return err;
 999        }
1000        if (sensor_id != cpu_to_le16(0x08F0)) {
1001                err("Sensor ID %x != %x. Unsupported. Sorry\n",
1002                        le16_to_cpu(sensor_id), (0x08F0));
1003                return -ENODEV;
1004        }
1005
1006        uvd = usbvideo_AllocateDevice(cams);
1007        if (!uvd)
1008                return -ENOMEM;
1009
1010        cam = (struct qcm *) uvd->user_data;
1011
1012        /* buf for doing demosaicing */
1013        cam->scratch = kmalloc(324*2, GFP_KERNEL);
1014        if (!cam->scratch) /* uvd freed in dereg */
1015                return -ENOMEM;
1016
1017        /* yes, if we fail after here, cam->scratch gets freed
1018        by qcm_free_uvd */
1019
1020        err = qcm_alloc_int_urb(cam);
1021        if (err < 0)
1022                return err;
1023
1024        /* yes, if we fail after here, int urb gets freed
1025        by qcm_free_uvd */
1026
1027        RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
1028        cam->width = camera_sizes[size].width;
1029        cam->height = camera_sizes[size].height;
1030        cam->size = size;
1031
1032        uvd->debug = debug;
1033        uvd->flags = 0;
1034        uvd->dev = dev;
1035        uvd->iface = intf->altsetting->desc.bInterfaceNumber;
1036        uvd->ifaceAltActive = ifacenum;
1037        uvd->ifaceAltInactive = ifacenum_inact;
1038        uvd->video_endp = video_ep;
1039        uvd->iso_packet_len = buffer_size;
1040        uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
1041        uvd->defaultPalette = VIDEO_PALETTE_RGB24;
1042        uvd->canvas = VIDEOSIZE(320, 240);
1043        uvd->videosize = VIDEOSIZE(cam->width, cam->height);
1044        err = qcm_configure_video(uvd);
1045        if (err) {
1046                err("failed to configure video settings");
1047                return err;
1048        }
1049
1050        err = usbvideo_RegisterVideoDevice(uvd);
1051        if (err) { /* the uvd gets freed in Deregister */
1052                err("usbvideo_RegisterVideoDevice() failed.");
1053                return err;
1054        }
1055
1056        uvd->max_frame_size = (320 * 240 * 3);
1057        qcm_register_input(cam, dev);
1058        usb_set_intfdata(intf, uvd);
1059        return 0;
1060}
1061
1062static void qcm_free_uvd(struct uvd *uvd)
1063{
1064        struct qcm *cam = (struct qcm *) uvd->user_data;
1065
1066        kfree(cam->scratch);
1067        qcm_unregister_input(cam);
1068        qcm_free_int(cam);
1069}
1070
1071static struct usbvideo_cb qcm_driver = {
1072        .probe =                qcm_probe,
1073        .setupOnOpen =          qcm_setup_on_open,
1074        .processData =          qcm_process_isoc,
1075        .setVideoMode =         qcm_set_video_mode,
1076        .startDataPump =        qcm_start_data,
1077        .stopDataPump =         qcm_stop_data,
1078        .adjustPicture =        qcm_adjust_picture,
1079        .userFree =             qcm_free_uvd
1080};
1081
1082static int __init qcm_init(void)
1083{
1084        printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
1085               DRIVER_DESC "\n");
1086
1087        return usbvideo_register(
1088                &cams,
1089                MAX_CAMERAS,
1090                sizeof(struct qcm),
1091                "QCM",
1092                &qcm_driver,
1093                THIS_MODULE,
1094                qcm_table);
1095}
1096
1097static void __exit qcm_exit(void)
1098{
1099        usbvideo_Deregister(&cams);
1100}
1101
1102module_param(size, int, 0);
1103MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240");
1104module_param(colour, int, 0);
1105MODULE_PARM_DESC(colour, "Initial colour");
1106module_param(hue, int, 0);
1107MODULE_PARM_DESC(hue, "Initial hue");
1108module_param(brightness, int, 0);
1109MODULE_PARM_DESC(brightness, "Initial brightness");
1110module_param(contrast, int, 0);
1111MODULE_PARM_DESC(contrast, "Initial contrast");
1112module_param(whiteness, int, 0);
1113MODULE_PARM_DESC(whiteness, "Initial whiteness");
1114
1115#ifdef CONFIG_USB_DEBUG
1116module_param(debug, int, S_IRUGO | S_IWUSR);
1117MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
1118#endif
1119
1120module_init(qcm_init);
1121module_exit(qcm_exit);
1122
1123MODULE_LICENSE("GPL");
1124MODULE_AUTHOR("Jaya Kumar");
1125MODULE_DESCRIPTION("QCM USB Camera");
1126MODULE_SUPPORTED_DEVICE("QCM USB Camera");
1127