linux/drivers/media/video/se401.c
<<
>>
Prefs
   1/*
   2 * Endpoints (formerly known as AOX) se401 USB Camera Driver
   3 *
   4 * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
   5 *
   6 * Still somewhat based on the Linux ov511 driver.
   7 *
   8 * This program is free software; you can redistribute it and/or modify it
   9 * under the terms of the GNU General Public License as published by the
  10 * Free Software Foundation; either version 2 of the License, or (at your
  11 * option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful, but
  14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  15 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16 * for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software Foundation,
  20 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21 *
  22 *
  23 * Thanks to Endpoints Inc. (www.endpoints.com) for making documentation on
  24 * their chipset available and supporting me while writing this driver.
  25 *      - Jeroen Vreeken
  26 */
  27
  28static const char version[] = "0.24";
  29
  30#include <linux/module.h>
  31#include <linux/init.h>
  32#include <linux/vmalloc.h>
  33#include <linux/slab.h>
  34#include <linux/pagemap.h>
  35#include <linux/usb.h>
  36#include "se401.h"
  37
  38static int flickerless;
  39static int video_nr = -1;
  40
  41static struct usb_device_id device_table [] = {
  42        { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
  43        { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
  44        { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
  45        { USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */
  46        { USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */
  47        { }
  48};
  49
  50MODULE_DEVICE_TABLE(usb, device_table);
  51
  52MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
  53MODULE_DESCRIPTION("SE401 USB Camera Driver");
  54MODULE_LICENSE("GPL");
  55module_param(flickerless, int, 0);
  56MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)");
  57module_param(video_nr, int, 0);
  58
  59static struct usb_driver se401_driver;
  60
  61
  62/**********************************************************************
  63 *
  64 * Memory management
  65 *
  66 **********************************************************************/
  67static void *rvmalloc(unsigned long size)
  68{
  69        void *mem;
  70        unsigned long adr;
  71
  72        size = PAGE_ALIGN(size);
  73        mem = vmalloc_32(size);
  74        if (!mem)
  75                return NULL;
  76
  77        memset(mem, 0, size); /* Clear the ram out, no junk to the user */
  78        adr = (unsigned long) mem;
  79        while (size > 0) {
  80                SetPageReserved(vmalloc_to_page((void *)adr));
  81                adr += PAGE_SIZE;
  82                size -= PAGE_SIZE;
  83        }
  84
  85        return mem;
  86}
  87
  88static void rvfree(void *mem, unsigned long size)
  89{
  90        unsigned long adr;
  91
  92        if (!mem)
  93                return;
  94
  95        adr = (unsigned long) mem;
  96        while ((long) size > 0) {
  97                ClearPageReserved(vmalloc_to_page((void *)adr));
  98                adr += PAGE_SIZE;
  99                size -= PAGE_SIZE;
 100        }
 101        vfree(mem);
 102}
 103
 104
 105
 106/****************************************************************************
 107 *
 108 * se401 register read/write functions
 109 *
 110 ***************************************************************************/
 111
 112static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
 113                         unsigned short value, unsigned char *cp, int size)
 114{
 115        return usb_control_msg (
 116                se401->dev,
 117                set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
 118                req,
 119                (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 120                value,
 121                0,
 122                cp,
 123                size,
 124                1000
 125        );
 126}
 127
 128static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
 129                             unsigned short param)
 130{
 131        /* specs say that the selector (address) should go in the value field
 132           and the param in index, but in the logs of the windows driver they do
 133           this the other way around...
 134         */
 135        return usb_control_msg (
 136                se401->dev,
 137                usb_sndctrlpipe(se401->dev, 0),
 138                SE401_REQ_SET_EXT_FEATURE,
 139                USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 140                param,
 141                selector,
 142                NULL,
 143                0,
 144                1000
 145        );
 146}
 147
 148static unsigned short se401_get_feature(struct usb_se401 *se401,
 149                                        unsigned short selector)
 150{
 151        /* For 'set' the selecetor should be in index, not sure if the spec is
 152           wrong here to....
 153         */
 154        unsigned char cp[2];
 155        usb_control_msg (
 156                se401->dev,
 157                usb_rcvctrlpipe(se401->dev, 0),
 158                SE401_REQ_GET_EXT_FEATURE,
 159                USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 160                0,
 161                selector,
 162                cp,
 163                2,
 164                1000
 165        );
 166        return cp[0]+cp[1]*256;
 167}
 168
 169/****************************************************************************
 170 *
 171 * Camera control
 172 *
 173 ***************************************************************************/
 174
 175
 176static int se401_send_pict(struct usb_se401 *se401)
 177{
 178        se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */
 179        se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */
 180        se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */
 181        se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */
 182        se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */
 183        se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */
 184        se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */
 185
 186        return 0;
 187}
 188
 189static void se401_set_exposure(struct usb_se401 *se401, int brightness)
 190{
 191        int integration=brightness<<5;
 192
 193        if (flickerless==50) {
 194                integration=integration-integration%106667;
 195        }
 196        if (flickerless==60) {
 197                integration=integration-integration%88889;
 198        }
 199        se401->brightness=integration>>5;
 200        se401->expose_h=(integration>>16)&0xff;
 201        se401->expose_m=(integration>>8)&0xff;
 202        se401->expose_l=integration&0xff;
 203}
 204
 205static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
 206{
 207        p->brightness=se401->brightness;
 208        if (se401->enhance) {
 209                p->whiteness=32768;
 210        } else {
 211                p->whiteness=0;
 212        }
 213        p->colour=65535;
 214        p->contrast=65535;
 215        p->hue=se401->rgain<<10;
 216        p->palette=se401->palette;
 217        p->depth=3; /* rgb24 */
 218        return 0;
 219}
 220
 221
 222static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
 223{
 224        if (p->palette != VIDEO_PALETTE_RGB24)
 225                return 1;
 226        se401->palette=p->palette;
 227        if (p->hue!=se401->hue) {
 228                se401->rgain= p->hue>>10;
 229                se401->bgain= 0x40-(p->hue>>10);
 230                se401->hue=p->hue;
 231        }
 232        if (p->brightness!=se401->brightness) {
 233                se401_set_exposure(se401, p->brightness);
 234        }
 235        if (p->whiteness>=32768) {
 236                se401->enhance=1;
 237        } else {
 238                se401->enhance=0;
 239        }
 240        se401_send_pict(se401);
 241        se401_send_pict(se401);
 242        return 0;
 243}
 244
 245/*
 246        Hyundai have some really nice docs about this and other sensor related
 247        stuff on their homepage: www.hei.co.kr
 248*/
 249static void se401_auto_resetlevel(struct usb_se401 *se401)
 250{
 251        unsigned int ahrc, alrc;
 252        int oldreset=se401->resetlevel;
 253
 254        /* For some reason this normally read-only register doesn't get reset
 255           to zero after reading them just once...
 256         */
 257        se401_get_feature(se401, HV7131_REG_HIREFNOH);
 258        se401_get_feature(se401, HV7131_REG_HIREFNOL);
 259        se401_get_feature(se401, HV7131_REG_LOREFNOH);
 260        se401_get_feature(se401, HV7131_REG_LOREFNOL);
 261        ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
 262            se401_get_feature(se401, HV7131_REG_HIREFNOL);
 263        alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
 264            se401_get_feature(se401, HV7131_REG_LOREFNOL);
 265
 266        /* Not an exact science, but it seems to work pretty well... */
 267        if (alrc > 10) {
 268                while (alrc>=10 && se401->resetlevel < 63) {
 269                        se401->resetlevel++;
 270                        alrc /=2;
 271                }
 272        } else if (ahrc > 20) {
 273                while (ahrc>=20 && se401->resetlevel > 0) {
 274                        se401->resetlevel--;
 275                        ahrc /=2;
 276                }
 277        }
 278        if (se401->resetlevel!=oldreset)
 279                se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
 280
 281        return;
 282}
 283
 284/* irq handler for snapshot button */
 285static void se401_button_irq(struct urb *urb)
 286{
 287        struct usb_se401 *se401 = urb->context;
 288        int status;
 289
 290        if (!se401->dev) {
 291                dev_info(&urb->dev->dev, "device vapourished\n");
 292                return;
 293        }
 294
 295        switch (urb->status) {
 296        case 0:
 297                /* success */
 298                break;
 299        case -ECONNRESET:
 300        case -ENOENT:
 301        case -ESHUTDOWN:
 302                /* this urb is terminated, clean up */
 303                dbg("%s - urb shutting down with status: %d", __func__, urb->status);
 304                return;
 305        default:
 306                dbg("%s - nonzero urb status received: %d", __func__, urb->status);
 307                goto exit;
 308        }
 309
 310        if (urb->actual_length >=2) {
 311                if (se401->button)
 312                        se401->buttonpressed=1;
 313        }
 314exit:
 315        status = usb_submit_urb (urb, GFP_ATOMIC);
 316        if (status)
 317                err ("%s - usb_submit_urb failed with result %d",
 318                     __func__, status);
 319}
 320
 321static void se401_video_irq(struct urb *urb)
 322{
 323        struct usb_se401 *se401 = urb->context;
 324        int length = urb->actual_length;
 325
 326        /* ohoh... */
 327        if (!se401->streaming)
 328                return;
 329
 330        if (!se401->dev) {
 331                dev_info(&urb->dev->dev, "device vapourished\n");
 332                return;
 333        }
 334
 335        /* 0 sized packets happen if we are to fast, but sometimes the camera
 336           keeps sending them forever...
 337         */
 338        if (length && !urb->status) {
 339                se401->nullpackets=0;
 340                switch(se401->scratch[se401->scratch_next].state) {
 341                        case BUFFER_READY:
 342                        case BUFFER_BUSY: {
 343                                se401->dropped++;
 344                                break;
 345                        }
 346                        case BUFFER_UNUSED: {
 347                                memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length);
 348                                se401->scratch[se401->scratch_next].state=BUFFER_READY;
 349                                se401->scratch[se401->scratch_next].offset=se401->bayeroffset;
 350                                se401->scratch[se401->scratch_next].length=length;
 351                                if (waitqueue_active(&se401->wq)) {
 352                                        wake_up_interruptible(&se401->wq);
 353                                }
 354                                se401->scratch_overflow=0;
 355                                se401->scratch_next++;
 356                                if (se401->scratch_next>=SE401_NUMSCRATCH)
 357                                        se401->scratch_next=0;
 358                                break;
 359                        }
 360                }
 361                se401->bayeroffset+=length;
 362                if (se401->bayeroffset>=se401->cheight*se401->cwidth) {
 363                        se401->bayeroffset=0;
 364                }
 365        } else {
 366                se401->nullpackets++;
 367                if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
 368                        if (waitqueue_active(&se401->wq)) {
 369                                wake_up_interruptible(&se401->wq);
 370                        }
 371                }
 372        }
 373
 374        /* Resubmit urb for new data */
 375        urb->status=0;
 376        urb->dev=se401->dev;
 377        if(usb_submit_urb(urb, GFP_KERNEL))
 378                dev_info(&urb->dev->dev, "urb burned down\n");
 379        return;
 380}
 381
 382static void se401_send_size(struct usb_se401 *se401, int width, int height)
 383{
 384        int i=0;
 385        int mode=0x03; /* No compression */
 386        int sendheight=height;
 387        int sendwidth=width;
 388
 389        /* JangGu compression can only be used with the camera supported sizes,
 390           but bayer seems to work with any size that fits on the sensor.
 391           We check if we can use compression with the current size with either
 392           4 or 16 times subcapturing, if not we use uncompressed bayer data
 393           but this will result in cutouts of the maximum size....
 394         */
 395        while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height))
 396                i++;
 397        while (i<se401->sizes) {
 398                if (se401->width[i]==width*2 && se401->height[i]==height*2) {
 399                        sendheight=se401->height[i];
 400                        sendwidth=se401->width[i];
 401                        mode=0x40;
 402                }
 403                if (se401->width[i]==width*4 && se401->height[i]==height*4) {
 404                        sendheight=se401->height[i];
 405                        sendwidth=se401->width[i];
 406                        mode=0x42;
 407                }
 408                i++;
 409        }
 410
 411        se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0);
 412        se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
 413        se401_set_feature(se401, SE401_OPERATINGMODE, mode);
 414
 415        if (mode==0x03) {
 416                se401->format=FMT_BAYER;
 417        } else {
 418                se401->format=FMT_JANGGU;
 419        }
 420
 421        return;
 422}
 423
 424/*
 425        In this function se401_send_pict is called several times,
 426        for some reason (depending on the state of the sensor and the phase of
 427        the moon :) doing this only in either place doesn't always work...
 428*/
 429static int se401_start_stream(struct usb_se401 *se401)
 430{
 431        struct urb *urb;
 432        int err=0, i;
 433        se401->streaming=1;
 434
 435        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
 436        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
 437
 438        /* Set picture settings */
 439        se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */
 440        se401_send_pict(se401);
 441
 442        se401_send_size(se401, se401->cwidth, se401->cheight);
 443
 444        se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0);
 445
 446        /* Do some memory allocation */
 447        for (i=0; i<SE401_NUMFRAMES; i++) {
 448                se401->frame[i].data=se401->fbuf + i * se401->maxframesize;
 449                se401->frame[i].curpix=0;
 450        }
 451        for (i=0; i<SE401_NUMSBUF; i++) {
 452                se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
 453                if (!se401->sbuf[i].data) {
 454                        for(i = i - 1; i >= 0; i--) {
 455                                kfree(se401->sbuf[i].data);
 456                                se401->sbuf[i].data = NULL;
 457                        }
 458                        return -ENOMEM;
 459                }
 460        }
 461
 462        se401->bayeroffset=0;
 463        se401->scratch_next=0;
 464        se401->scratch_use=0;
 465        se401->scratch_overflow=0;
 466        for (i=0; i<SE401_NUMSCRATCH; i++) {
 467                se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
 468                if (!se401->scratch[i].data) {
 469                        for(i = i - 1; i >= 0; i--) {
 470                                kfree(se401->scratch[i].data);
 471                                se401->scratch[i].data = NULL;
 472                        }
 473                        goto nomem_sbuf;
 474                }
 475                se401->scratch[i].state=BUFFER_UNUSED;
 476        }
 477
 478        for (i=0; i<SE401_NUMSBUF; i++) {
 479                urb=usb_alloc_urb(0, GFP_KERNEL);
 480                if(!urb) {
 481                        for(i = i - 1; i >= 0; i--) {
 482                                usb_kill_urb(se401->urb[i]);
 483                                usb_free_urb(se401->urb[i]);
 484                                se401->urb[i] = NULL;
 485                        }
 486                        goto nomem_scratch;
 487                }
 488
 489                usb_fill_bulk_urb(urb, se401->dev,
 490                        usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
 491                        se401->sbuf[i].data, SE401_PACKETSIZE,
 492                        se401_video_irq,
 493                        se401);
 494
 495                se401->urb[i]=urb;
 496
 497                err=usb_submit_urb(se401->urb[i], GFP_KERNEL);
 498                if(err)
 499                        err("urb burned down");
 500        }
 501
 502        se401->framecount=0;
 503
 504        return 0;
 505
 506 nomem_scratch:
 507        for (i=0; i<SE401_NUMSCRATCH; i++) {
 508                kfree(se401->scratch[i].data);
 509                se401->scratch[i].data = NULL;
 510        }
 511 nomem_sbuf:
 512        for (i=0; i<SE401_NUMSBUF; i++) {
 513                kfree(se401->sbuf[i].data);
 514                se401->sbuf[i].data = NULL;
 515        }
 516        return -ENOMEM;
 517}
 518
 519static int se401_stop_stream(struct usb_se401 *se401)
 520{
 521        int i;
 522
 523        if (!se401->streaming || !se401->dev)
 524                return 1;
 525
 526        se401->streaming=0;
 527
 528        se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
 529
 530        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
 531        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
 532
 533        for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
 534                usb_kill_urb(se401->urb[i]);
 535                usb_free_urb(se401->urb[i]);
 536                se401->urb[i]=NULL;
 537                kfree(se401->sbuf[i].data);
 538        }
 539        for (i=0; i<SE401_NUMSCRATCH; i++) {
 540                kfree(se401->scratch[i].data);
 541                se401->scratch[i].data=NULL;
 542        }
 543
 544        return 0;
 545}
 546
 547static int se401_set_size(struct usb_se401 *se401, int width, int height)
 548{
 549        int wasstreaming=se401->streaming;
 550        /* Check to see if we need to change */
 551        if (se401->cwidth==width && se401->cheight==height)
 552                return 0;
 553
 554        /* Check for a valid mode */
 555        if (!width || !height)
 556                return 1;
 557        if ((width & 1) || (height & 1))
 558                return 1;
 559        if (width>se401->width[se401->sizes-1])
 560                return 1;
 561        if (height>se401->height[se401->sizes-1])
 562                return 1;
 563
 564        /* Stop a current stream and start it again at the new size */
 565        if (wasstreaming)
 566                se401_stop_stream(se401);
 567        se401->cwidth=width;
 568        se401->cheight=height;
 569        if (wasstreaming)
 570                se401_start_stream(se401);
 571        return 0;
 572}
 573
 574
 575/****************************************************************************
 576 *
 577 * Video Decoding
 578 *
 579 ***************************************************************************/
 580
 581/*
 582        This shouldn't really be done in a v4l driver....
 583        But it does make the image look a lot more usable.
 584        Basically it lifts the dark pixels more than the light pixels.
 585*/
 586static inline void enhance_picture(unsigned char *frame, int len)
 587{
 588        while (len--) {
 589                *frame=(((*frame^255)*(*frame^255))/255)^255;
 590                frame++;
 591        }
 592}
 593
 594static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
 595{
 596        struct se401_frame *frame=&se401->frame[se401->curframe];
 597        int linelength=se401->cwidth*3;
 598
 599        if (frame->curlinepix >= linelength) {
 600                frame->curlinepix=0;
 601                frame->curline+=linelength;
 602        }
 603
 604        /* First three are absolute, all others relative.
 605         * Format is rgb from right to left (mirrorred image),
 606         * we flip it to get bgr from left to right. */
 607        if (frame->curlinepix < 3) {
 608                *(frame->curline-frame->curlinepix)=1+data*4;
 609        } else {
 610                *(frame->curline-frame->curlinepix)=
 611                    *(frame->curline-frame->curlinepix+3)+data*4;
 612        }
 613        frame->curlinepix++;
 614}
 615
 616static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength)
 617{
 618        int pos=0;
 619        int vlc_cod=0;
 620        int vlc_size=0;
 621        int vlc_data=0;
 622        int bit_cur;
 623        int bit;
 624        data+=4;
 625        while (pos < packetlength) {
 626                bit_cur=8;
 627                while (bit_cur && bit_exp) {
 628                        bit=((*data)>>(bit_cur-1))&1;
 629                        if (!vlc_cod) {
 630                                if (bit) {
 631                                        vlc_size++;
 632                                } else {
 633                                        if (!vlc_size) {
 634                                                decode_JangGu_integrate(se401, 0);
 635                                        } else {
 636                                                vlc_cod=2;
 637                                                vlc_data=0;
 638                                        }
 639                                }
 640                        } else {
 641                                if (vlc_cod==2) {
 642                                        if (!bit)
 643                                                vlc_data =  -(1<<vlc_size) + 1;
 644                                        vlc_cod--;
 645                                }
 646                                vlc_size--;
 647                                vlc_data+=bit<<vlc_size;
 648                                if (!vlc_size) {
 649                                        decode_JangGu_integrate(se401, vlc_data);
 650                                        vlc_cod=0;
 651                                }
 652                        }
 653                        bit_cur--;
 654                        bit_exp--;
 655                }
 656                pos++;
 657                data++;
 658        }
 659}
 660
 661static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer)
 662{
 663        unsigned char *data=buffer->data;
 664        int len=buffer->length;
 665        int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size;
 666        int datapos=0;
 667
 668        /* New image? */
 669        if (!se401->frame[se401->curframe].curpix) {
 670                se401->frame[se401->curframe].curlinepix=0;
 671                se401->frame[se401->curframe].curline=
 672                    se401->frame[se401->curframe].data+
 673                    se401->cwidth*3-1;
 674                if (se401->frame[se401->curframe].grabstate==FRAME_READY)
 675                        se401->frame[se401->curframe].grabstate=FRAME_GRABBING;
 676                se401->vlcdatapos=0;
 677        }
 678        while (datapos < len) {
 679                size=1024-se401->vlcdatapos;
 680                if (size+datapos > len)
 681                        size=len-datapos;
 682                memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
 683                se401->vlcdatapos+=size;
 684                packetlength=0;
 685                if (se401->vlcdatapos >= 4) {
 686                        bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8);
 687                        pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8);
 688                        frameinfo=se401->vlcdata[0]&0xc0;
 689                        packetlength=((bit_exp+47)>>4)<<1;
 690                        if (packetlength > 1024) {
 691                                se401->vlcdatapos=0;
 692                                datapos=len;
 693                                packetlength=0;
 694                                se401->error++;
 695                                se401->frame[se401->curframe].curpix=0;
 696                        }
 697                }
 698                if (packetlength && se401->vlcdatapos >= packetlength) {
 699                        decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength);
 700                        se401->frame[se401->curframe].curpix+=pix_exp*3;
 701                        datapos+=size-(se401->vlcdatapos-packetlength);
 702                        se401->vlcdatapos=0;
 703                        if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) {
 704                                if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) {
 705                                        if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) {
 706                                                se401->frame[se401->curframe].grabstate=FRAME_DONE;
 707                                                se401->framecount++;
 708                                                se401->readcount++;
 709                                        }
 710                                        if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
 711                                                se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
 712                                        }
 713                                } else {
 714                                        se401->error++;
 715                                }
 716                                se401->frame[se401->curframe].curpix=0;
 717                                datapos=len;
 718                        }
 719                } else {
 720                        datapos+=size;
 721                }
 722        }
 723}
 724
 725static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer)
 726{
 727        unsigned char *data=buffer->data;
 728        int len=buffer->length;
 729        int offset=buffer->offset;
 730        int datasize=se401->cwidth*se401->cheight;
 731        struct se401_frame *frame=&se401->frame[se401->curframe];
 732
 733        unsigned char *framedata=frame->data, *curline, *nextline;
 734        int width=se401->cwidth;
 735        int blineoffset=0, bline;
 736        int linelength=width*3, i;
 737
 738
 739        if (frame->curpix==0) {
 740                if (frame->grabstate==FRAME_READY) {
 741                        frame->grabstate=FRAME_GRABBING;
 742                }
 743                frame->curline=framedata+linelength;
 744                frame->curlinepix=0;
 745        }
 746
 747        if (offset!=frame->curpix) {
 748                /* Regard frame as lost :( */
 749                frame->curpix=0;
 750                se401->error++;
 751                return;
 752        }
 753
 754        /* Check if we have to much data */
 755        if (frame->curpix+len > datasize) {
 756                len=datasize-frame->curpix;
 757        }
 758        if (se401->cheight%4)
 759                blineoffset=1;
 760        bline=frame->curpix/se401->cwidth+blineoffset;
 761
 762        curline=frame->curline;
 763        nextline=curline+linelength;
 764        if (nextline >= framedata+datasize*3)
 765                nextline=curline;
 766        while (len) {
 767                if (frame->curlinepix>=width) {
 768                        frame->curlinepix-=width;
 769                        bline=frame->curpix/width+blineoffset;
 770                        curline+=linelength*2;
 771                        nextline+=linelength*2;
 772                        if (curline >= framedata+datasize*3) {
 773                                frame->curlinepix++;
 774                                curline-=3;
 775                                nextline-=3;
 776                                len--;
 777                                data++;
 778                                frame->curpix++;
 779                        }
 780                        if (nextline >= framedata+datasize*3)
 781                                nextline=curline;
 782                }
 783                if ((bline&1)) {
 784                        if ((frame->curlinepix&1)) {
 785                                *(curline+2)=*data;
 786                                *(curline-1)=*data;
 787                                *(nextline+2)=*data;
 788                                *(nextline-1)=*data;
 789                        } else {
 790                                *(curline+1)=
 791                                        (*(curline+1)+*data)/2;
 792                                *(curline-2)=
 793                                        (*(curline-2)+*data)/2;
 794                                *(nextline+1)=*data;
 795                                *(nextline-2)=*data;
 796                        }
 797                } else {
 798                        if ((frame->curlinepix&1)) {
 799                                *(curline+1)=
 800                                        (*(curline+1)+*data)/2;
 801                                *(curline-2)=
 802                                        (*(curline-2)+*data)/2;
 803                                *(nextline+1)=*data;
 804                                *(nextline-2)=*data;
 805                        } else {
 806                                *curline=*data;
 807                                *(curline-3)=*data;
 808                                *nextline=*data;
 809                                *(nextline-3)=*data;
 810                        }
 811                }
 812                frame->curlinepix++;
 813                curline-=3;
 814                nextline-=3;
 815                len--;
 816                data++;
 817                frame->curpix++;
 818        }
 819        frame->curline=curline;
 820
 821        if (frame->curpix>=datasize) {
 822                /* Fix the top line */
 823                framedata+=linelength;
 824                for (i=0; i<linelength; i++) {
 825                        framedata--;
 826                        *framedata=*(framedata+linelength);
 827                }
 828                /* Fix the left side (green is already present) */
 829                for (i=0; i<se401->cheight; i++) {
 830                        *framedata=*(framedata+3);
 831                        *(framedata+1)=*(framedata+4);
 832                        *(framedata+2)=*(framedata+5);
 833                        framedata+=linelength;
 834                }
 835                frame->curpix=0;
 836                frame->grabstate=FRAME_DONE;
 837                se401->framecount++;
 838                se401->readcount++;
 839                if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
 840                        se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
 841                }
 842        }
 843}
 844
 845static int se401_newframe(struct usb_se401 *se401, int framenr)
 846{
 847        DECLARE_WAITQUEUE(wait, current);
 848        int errors=0;
 849
 850        while (se401->streaming &&
 851            (se401->frame[framenr].grabstate==FRAME_READY ||
 852             se401->frame[framenr].grabstate==FRAME_GRABBING) ) {
 853                if(!se401->frame[framenr].curpix) {
 854                        errors++;
 855                }
 856                wait_interruptible(
 857                    se401->scratch[se401->scratch_use].state!=BUFFER_READY,
 858                    &se401->wq,
 859                    &wait
 860                );
 861                if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
 862                        se401->nullpackets=0;
 863                        dev_info(&se401->dev->dev,
 864                                 "too many null length packets, restarting capture\n");
 865                        se401_stop_stream(se401);
 866                        se401_start_stream(se401);
 867                } else {
 868                        if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) {
 869                                se401->frame[framenr].grabstate=FRAME_ERROR;
 870                                return -EIO;
 871                        }
 872                        se401->scratch[se401->scratch_use].state=BUFFER_BUSY;
 873                        if (se401->format==FMT_JANGGU) {
 874                                decode_JangGu(se401, &se401->scratch[se401->scratch_use]);
 875                        } else {
 876                                decode_bayer(se401, &se401->scratch[se401->scratch_use]);
 877                        }
 878                        se401->scratch[se401->scratch_use].state=BUFFER_UNUSED;
 879                        se401->scratch_use++;
 880                        if (se401->scratch_use>=SE401_NUMSCRATCH)
 881                                se401->scratch_use=0;
 882                        if (errors > SE401_MAX_ERRORS) {
 883                                errors=0;
 884                                dev_info(&se401->dev->dev,
 885                                         "too many errors, restarting capture\n");
 886                                se401_stop_stream(se401);
 887                                se401_start_stream(se401);
 888                        }
 889                }
 890        }
 891
 892        if (se401->frame[framenr].grabstate==FRAME_DONE)
 893                if (se401->enhance)
 894                        enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3);
 895        return 0;
 896}
 897
 898static void usb_se401_remove_disconnected (struct usb_se401 *se401)
 899{
 900        int i;
 901
 902        se401->dev = NULL;
 903
 904        for (i=0; i<SE401_NUMSBUF; i++)
 905                if (se401->urb[i]) {
 906                        usb_kill_urb(se401->urb[i]);
 907                        usb_free_urb(se401->urb[i]);
 908                        se401->urb[i] = NULL;
 909                        kfree(se401->sbuf[i].data);
 910                }
 911        for (i=0; i<SE401_NUMSCRATCH; i++) {
 912                kfree(se401->scratch[i].data);
 913        }
 914        if (se401->inturb) {
 915                usb_kill_urb(se401->inturb);
 916                usb_free_urb(se401->inturb);
 917        }
 918        dev_info(&se401->dev->dev, "%s disconnected", se401->camera_name);
 919
 920        /* Free the memory */
 921        kfree(se401->width);
 922        kfree(se401->height);
 923        kfree(se401);
 924}
 925
 926
 927
 928/****************************************************************************
 929 *
 930 * Video4Linux
 931 *
 932 ***************************************************************************/
 933
 934
 935static int se401_open(struct inode *inode, struct file *file)
 936{
 937        struct video_device *dev = video_devdata(file);
 938        struct usb_se401 *se401 = (struct usb_se401 *)dev;
 939        int err = 0;
 940
 941        lock_kernel();
 942        if (se401->user) {
 943                unlock_kernel();
 944                return -EBUSY;
 945        }
 946        se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
 947        if (se401->fbuf)
 948                file->private_data = dev;
 949        else
 950                err = -ENOMEM;
 951        se401->user = !err;
 952        unlock_kernel();
 953
 954        return err;
 955}
 956
 957static int se401_close(struct inode *inode, struct file *file)
 958{
 959        struct video_device *dev = file->private_data;
 960        struct usb_se401 *se401 = (struct usb_se401 *)dev;
 961        int i;
 962
 963        rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
 964        if (se401->removed) {
 965                dev_info(&se401->dev->dev, "device unregistered\n");
 966                usb_se401_remove_disconnected(se401);
 967        } else {
 968                for (i=0; i<SE401_NUMFRAMES; i++)
 969                        se401->frame[i].grabstate=FRAME_UNUSED;
 970                if (se401->streaming)
 971                        se401_stop_stream(se401);
 972                se401->user=0;
 973        }
 974        file->private_data = NULL;
 975        return 0;
 976}
 977
 978static int se401_do_ioctl(struct inode *inode, struct file *file,
 979                          unsigned int cmd, void *arg)
 980{
 981        struct video_device *vdev = file->private_data;
 982        struct usb_se401 *se401 = (struct usb_se401 *)vdev;
 983
 984        if (!se401->dev)
 985                return -EIO;
 986
 987        switch (cmd) {
 988        case VIDIOCGCAP:
 989        {
 990                struct video_capability *b = arg;
 991                strcpy(b->name, se401->camera_name);
 992                b->type = VID_TYPE_CAPTURE;
 993                b->channels = 1;
 994                b->audios = 0;
 995                b->maxwidth = se401->width[se401->sizes-1];
 996                b->maxheight = se401->height[se401->sizes-1];
 997                b->minwidth = se401->width[0];
 998                b->minheight = se401->height[0];
 999                return 0;
1000        }
1001        case VIDIOCGCHAN:
1002        {
1003                struct video_channel *v = arg;
1004
1005                if (v->channel != 0)
1006                        return -EINVAL;
1007                v->flags = 0;
1008                v->tuners = 0;
1009                v->type = VIDEO_TYPE_CAMERA;
1010                strcpy(v->name, "Camera");
1011                return 0;
1012        }
1013        case VIDIOCSCHAN:
1014        {
1015                struct video_channel *v = arg;
1016
1017                if (v->channel != 0)
1018                        return -EINVAL;
1019                return 0;
1020        }
1021        case VIDIOCGPICT:
1022        {
1023                struct video_picture *p = arg;
1024
1025                se401_get_pict(se401, p);
1026                return 0;
1027        }
1028        case VIDIOCSPICT:
1029        {
1030                struct video_picture *p = arg;
1031
1032                if (se401_set_pict(se401, p))
1033                        return -EINVAL;
1034                return 0;
1035        }
1036        case VIDIOCSWIN:
1037        {
1038                struct video_window *vw = arg;
1039
1040                if (vw->flags)
1041                        return -EINVAL;
1042                if (vw->clipcount)
1043                        return -EINVAL;
1044                if (se401_set_size(se401, vw->width, vw->height))
1045                        return -EINVAL;
1046                return 0;
1047        }
1048        case VIDIOCGWIN:
1049        {
1050                struct video_window *vw = arg;
1051
1052                vw->x = 0;               /* FIXME */
1053                vw->y = 0;
1054                vw->chromakey = 0;
1055                vw->flags = 0;
1056                vw->clipcount = 0;
1057                vw->width = se401->cwidth;
1058                vw->height = se401->cheight;
1059                return 0;
1060        }
1061        case VIDIOCGMBUF:
1062        {
1063                struct video_mbuf *vm = arg;
1064                int i;
1065
1066                memset(vm, 0, sizeof(*vm));
1067                vm->size = SE401_NUMFRAMES * se401->maxframesize;
1068                vm->frames = SE401_NUMFRAMES;
1069                for (i=0; i<SE401_NUMFRAMES; i++)
1070                        vm->offsets[i] = se401->maxframesize * i;
1071                return 0;
1072        }
1073        case VIDIOCMCAPTURE:
1074        {
1075                struct video_mmap *vm = arg;
1076
1077                if (vm->format != VIDEO_PALETTE_RGB24)
1078                        return -EINVAL;
1079                if (vm->frame >= SE401_NUMFRAMES)
1080                        return -EINVAL;
1081                if (se401->frame[vm->frame].grabstate != FRAME_UNUSED)
1082                        return -EBUSY;
1083
1084                /* Is this according to the v4l spec??? */
1085                if (se401_set_size(se401, vm->width, vm->height))
1086                        return -EINVAL;
1087                se401->frame[vm->frame].grabstate=FRAME_READY;
1088
1089                if (!se401->streaming)
1090                        se401_start_stream(se401);
1091
1092                /* Set the picture properties */
1093                if (se401->framecount==0)
1094                        se401_send_pict(se401);
1095                /* Calibrate the reset level after a few frames. */
1096                if (se401->framecount%20==1)
1097                        se401_auto_resetlevel(se401);
1098
1099                return 0;
1100        }
1101        case VIDIOCSYNC:
1102        {
1103                int *frame = arg;
1104                int ret=0;
1105
1106                if(*frame <0 || *frame >= SE401_NUMFRAMES)
1107                        return -EINVAL;
1108
1109                ret=se401_newframe(se401, *frame);
1110                se401->frame[*frame].grabstate=FRAME_UNUSED;
1111                return ret;
1112        }
1113        case VIDIOCGFBUF:
1114        {
1115                struct video_buffer *vb = arg;
1116
1117                memset(vb, 0, sizeof(*vb));
1118                return 0;
1119        }
1120        case VIDIOCKEY:
1121                return 0;
1122        case VIDIOCCAPTURE:
1123                return -EINVAL;
1124        case VIDIOCSFBUF:
1125                return -EINVAL;
1126        case VIDIOCGTUNER:
1127        case VIDIOCSTUNER:
1128                return -EINVAL;
1129        case VIDIOCGFREQ:
1130        case VIDIOCSFREQ:
1131                return -EINVAL;
1132        case VIDIOCGAUDIO:
1133        case VIDIOCSAUDIO:
1134                return -EINVAL;
1135        default:
1136                return -ENOIOCTLCMD;
1137        } /* end switch */
1138
1139        return 0;
1140}
1141
1142static int se401_ioctl(struct inode *inode, struct file *file,
1143                       unsigned int cmd, unsigned long arg)
1144{
1145        return video_usercopy(inode, file, cmd, arg, se401_do_ioctl);
1146}
1147
1148static ssize_t se401_read(struct file *file, char __user *buf,
1149                     size_t count, loff_t *ppos)
1150{
1151        int realcount=count, ret=0;
1152        struct video_device *dev = file->private_data;
1153        struct usb_se401 *se401 = (struct usb_se401 *)dev;
1154
1155
1156        if (se401->dev == NULL)
1157                return -EIO;
1158        if (realcount > se401->cwidth*se401->cheight*3)
1159                realcount=se401->cwidth*se401->cheight*3;
1160
1161        /* Shouldn't happen: */
1162        if (se401->frame[0].grabstate==FRAME_GRABBING)
1163                return -EBUSY;
1164        se401->frame[0].grabstate=FRAME_READY;
1165        se401->frame[1].grabstate=FRAME_UNUSED;
1166        se401->curframe=0;
1167
1168        if (!se401->streaming)
1169                se401_start_stream(se401);
1170
1171        /* Set the picture properties */
1172        if (se401->framecount==0)
1173                se401_send_pict(se401);
1174        /* Calibrate the reset level after a few frames. */
1175        if (se401->framecount%20==1)
1176                se401_auto_resetlevel(se401);
1177
1178        ret=se401_newframe(se401, 0);
1179
1180        se401->frame[0].grabstate=FRAME_UNUSED;
1181        if (ret)
1182                return ret;
1183        if (copy_to_user(buf, se401->frame[0].data, realcount))
1184                return -EFAULT;
1185
1186        return realcount;
1187}
1188
1189static int se401_mmap(struct file *file, struct vm_area_struct *vma)
1190{
1191        struct video_device *dev = file->private_data;
1192        struct usb_se401 *se401 = (struct usb_se401 *)dev;
1193        unsigned long start = vma->vm_start;
1194        unsigned long size  = vma->vm_end-vma->vm_start;
1195        unsigned long page, pos;
1196
1197        mutex_lock(&se401->lock);
1198
1199        if (se401->dev == NULL) {
1200                mutex_unlock(&se401->lock);
1201                return -EIO;
1202        }
1203        if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
1204                mutex_unlock(&se401->lock);
1205                return -EINVAL;
1206        }
1207        pos = (unsigned long)se401->fbuf;
1208        while (size > 0) {
1209                page = vmalloc_to_pfn((void *)pos);
1210                if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1211                        mutex_unlock(&se401->lock);
1212                        return -EAGAIN;
1213                }
1214                start += PAGE_SIZE;
1215                pos += PAGE_SIZE;
1216                if (size > PAGE_SIZE)
1217                        size -= PAGE_SIZE;
1218                else
1219                        size = 0;
1220        }
1221        mutex_unlock(&se401->lock);
1222
1223        return 0;
1224}
1225
1226static const struct file_operations se401_fops = {
1227        .owner =        THIS_MODULE,
1228        .open =         se401_open,
1229        .release =      se401_close,
1230        .read =         se401_read,
1231        .mmap =         se401_mmap,
1232        .ioctl =        se401_ioctl,
1233#ifdef CONFIG_COMPAT
1234        .compat_ioctl = v4l_compat_ioctl32,
1235#endif
1236        .llseek =       no_llseek,
1237};
1238static struct video_device se401_template = {
1239        .name =         "se401 USB camera",
1240        .fops =         &se401_fops,
1241        .release = video_device_release_empty,
1242};
1243
1244
1245
1246/***************************/
1247static int se401_init(struct usb_se401 *se401, int button)
1248{
1249        int i=0, rc;
1250        unsigned char cp[0x40];
1251        char temp[200];
1252
1253        /* led on */
1254        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1255
1256        /* get camera descriptor */
1257        rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp));
1258        if (cp[1]!=0x41) {
1259                err("Wrong descriptor type");
1260                return 1;
1261        }
1262        sprintf (temp, "ExtraFeatures: %d", cp[3]);
1263
1264        se401->sizes=cp[4]+cp[5]*256;
1265        se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1266        if (!se401->width)
1267                return 1;
1268        se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1269        if (!se401->height) {
1270                kfree(se401->width);
1271                return 1;
1272        }
1273        for (i=0; i<se401->sizes; i++) {
1274                    se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
1275                    se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
1276        }
1277        sprintf (temp, "%s Sizes:", temp);
1278        for (i=0; i<se401->sizes; i++) {
1279                sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]);
1280        }
1281        dev_info(&se401->dev->dev, "%s\n", temp);
1282        se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3;
1283
1284        rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
1285        se401->cwidth=cp[0]+cp[1]*256;
1286        rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
1287        se401->cheight=cp[0]+cp[1]*256;
1288
1289        if (!(cp[2] & SE401_FORMAT_BAYER)) {
1290                err("Bayer format not supported!");
1291                return 1;
1292        }
1293        /* set output mode (BAYER) */
1294        se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0);
1295
1296        rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
1297        se401->brightness=cp[0]+cp[1]*256;
1298        /* some default values */
1299        se401->resetlevel=0x2d;
1300        se401->rgain=0x20;
1301        se401->ggain=0x20;
1302        se401->bgain=0x20;
1303        se401_set_exposure(se401, 20000);
1304        se401->palette=VIDEO_PALETTE_RGB24;
1305        se401->enhance=1;
1306        se401->dropped=0;
1307        se401->error=0;
1308        se401->framecount=0;
1309        se401->readcount=0;
1310
1311        /* Start interrupt transfers for snapshot button */
1312        if (button) {
1313                se401->inturb=usb_alloc_urb(0, GFP_KERNEL);
1314                if (!se401->inturb) {
1315                        dev_info(&se401->dev->dev,
1316                                 "Allocation of inturb failed\n");
1317                        return 1;
1318                }
1319                usb_fill_int_urb(se401->inturb, se401->dev,
1320                    usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
1321                    &se401->button, sizeof(se401->button),
1322                    se401_button_irq,
1323                    se401,
1324                    8
1325                );
1326                if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
1327                        dev_info(&se401->dev->dev, "int urb burned down\n");
1328                        return 1;
1329                }
1330        } else
1331                se401->inturb=NULL;
1332
1333        /* Flash the led */
1334        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
1335        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1336        se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
1337        se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
1338
1339        return 0;
1340}
1341
1342static int se401_probe(struct usb_interface *intf,
1343        const struct usb_device_id *id)
1344{
1345        struct usb_device *dev = interface_to_usbdev(intf);
1346        struct usb_interface_descriptor *interface;
1347        struct usb_se401 *se401;
1348        char *camera_name=NULL;
1349        int button=1;
1350
1351        /* We don't handle multi-config cameras */
1352        if (dev->descriptor.bNumConfigurations != 1)
1353                return -ENODEV;
1354
1355        interface = &intf->cur_altsetting->desc;
1356
1357        /* Is it an se401? */
1358        if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
1359            le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
1360                camera_name="Endpoints/Aox SE401";
1361        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
1362            le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
1363                camera_name="Philips PCVC665K";
1364        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1365            le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
1366                camera_name="Kensington VideoCAM 67014";
1367        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1368            le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
1369                camera_name="Kensington VideoCAM 6701(5/7)";
1370        } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1371            le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
1372                camera_name="Kensington VideoCAM 67016";
1373                button=0;
1374        } else
1375                return -ENODEV;
1376
1377        /* Checking vendor/product should be enough, but what the hell */
1378        if (interface->bInterfaceClass != 0x00)
1379                return -ENODEV;
1380        if (interface->bInterfaceSubClass != 0x00)
1381                return -ENODEV;
1382
1383        /* We found one */
1384        dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name);
1385
1386        if ((se401 = kzalloc(sizeof(*se401), GFP_KERNEL)) == NULL) {
1387                err("couldn't kmalloc se401 struct");
1388                return -ENOMEM;
1389        }
1390
1391        se401->dev = dev;
1392        se401->iface = interface->bInterfaceNumber;
1393        se401->camera_name = camera_name;
1394
1395        dev_info(&intf->dev, "firmware version: %02x\n",
1396                 le16_to_cpu(dev->descriptor.bcdDevice) & 255);
1397
1398        if (se401_init(se401, button)) {
1399                kfree(se401);
1400                return -EIO;
1401        }
1402
1403        memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
1404        memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
1405        init_waitqueue_head(&se401->wq);
1406        mutex_init(&se401->lock);
1407        wmb();
1408
1409        if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1410                kfree(se401);
1411                err("video_register_device failed");
1412                return -EIO;
1413        }
1414        dev_info(&intf->dev, "registered new video device: video%d\n",
1415                 se401->vdev.num);
1416
1417        usb_set_intfdata (intf, se401);
1418        return 0;
1419}
1420
1421static void se401_disconnect(struct usb_interface *intf)
1422{
1423        struct usb_se401 *se401 = usb_get_intfdata (intf);
1424
1425        usb_set_intfdata (intf, NULL);
1426        if (se401) {
1427                video_unregister_device(&se401->vdev);
1428                if (!se401->user){
1429                        usb_se401_remove_disconnected(se401);
1430                } else {
1431                        se401->frame[0].grabstate = FRAME_ERROR;
1432                        se401->frame[0].grabstate = FRAME_ERROR;
1433
1434                        se401->streaming = 0;
1435
1436                        wake_up_interruptible(&se401->wq);
1437                        se401->removed = 1;
1438                }
1439        }
1440}
1441
1442static struct usb_driver se401_driver = {
1443        .name           = "se401",
1444        .id_table       = device_table,
1445        .probe          = se401_probe,
1446        .disconnect     = se401_disconnect,
1447};
1448
1449
1450
1451/****************************************************************************
1452 *
1453 *  Module routines
1454 *
1455 ***************************************************************************/
1456
1457static int __init usb_se401_init(void)
1458{
1459        printk(KERN_INFO "SE401 usb camera driver version %s registering\n", version);
1460        if (flickerless)
1461                if (flickerless!=50 && flickerless!=60) {
1462                        printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n");
1463                        return -1;
1464        }
1465        return usb_register(&se401_driver);
1466}
1467
1468static void __exit usb_se401_exit(void)
1469{
1470        usb_deregister(&se401_driver);
1471        printk(KERN_INFO "SE401 driver deregistered\frame");
1472}
1473
1474module_init(usb_se401_init);
1475module_exit(usb_se401_exit);
1476
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.