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