linux/drivers/media/video/cpia2/cpia2_v4l.c
<<
>>
Prefs
   1/****************************************************************************
   2 *
   3 *  Filename: cpia2_v4l.c
   4 *
   5 *  Copyright 2001, STMicrolectronics, Inc.
   6 *      Contact:  steve.miller@st.com
   7 *  Copyright 2001,2005, Scott J. Bertin <scottbertin@yahoo.com>
   8 *
   9 *  Description:
  10 *     This is a USB driver for CPia2 based video cameras.
  11 *     The infrastructure of this driver is based on the cpia usb driver by
  12 *     Jochen Scharrlach and Johannes Erdfeldt.
  13 *
  14 *  This program is free software; you can redistribute it and/or modify
  15 *  it under the terms of the GNU General Public License as published by
  16 *  the Free Software Foundation; either version 2 of the License, or
  17 *  (at your option) any later version.
  18 *
  19 *  This program is distributed in the hope that it will be useful,
  20 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22 *  GNU General Public License for more details.
  23 *
  24 *  You should have received a copy of the GNU General Public License
  25 *  along with this program; if not, write to the Free Software
  26 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27 *
  28 *  Stripped of 2.4 stuff ready for main kernel submit by
  29 *              Alan Cox <alan@lxorguk.ukuu.org.uk>
  30 ****************************************************************************/
  31
  32#include <linux/version.h>
  33
  34
  35#include <linux/module.h>
  36#include <linux/time.h>
  37#include <linux/sched.h>
  38#include <linux/slab.h>
  39#include <linux/init.h>
  40#include <linux/videodev2.h>
  41#include <linux/stringify.h>
  42#include <media/v4l2-ioctl.h>
  43
  44#include "cpia2.h"
  45#include "cpia2dev.h"
  46
  47static int video_nr = -1;
  48module_param(video_nr, int, 0);
  49MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)");
  50
  51static int buffer_size = 68*1024;
  52module_param(buffer_size, int, 0);
  53MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)");
  54
  55static int num_buffers = 3;
  56module_param(num_buffers, int, 0);
  57MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-"
  58                 __stringify(VIDEO_MAX_FRAME) ", default 3)");
  59
  60static int alternate = DEFAULT_ALT;
  61module_param(alternate, int, 0);
  62MODULE_PARM_DESC(alternate, "USB Alternate (" __stringify(USBIF_ISO_1) "-"
  63                 __stringify(USBIF_ISO_6) ", default "
  64                 __stringify(DEFAULT_ALT) ")");
  65
  66static int flicker_freq = 60;
  67module_param(flicker_freq, int, 0);
  68MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" __stringify(50) "or"
  69                 __stringify(60) ", default "
  70                 __stringify(60) ")");
  71
  72static int flicker_mode = NEVER_FLICKER;
  73module_param(flicker_mode, int, 0);
  74MODULE_PARM_DESC(flicker_mode,
  75                 "Flicker supression (" __stringify(NEVER_FLICKER) "or"
  76                 __stringify(ANTI_FLICKER_ON) ", default "
  77                 __stringify(NEVER_FLICKER) ")");
  78
  79MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>");
  80MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras");
  81MODULE_SUPPORTED_DEVICE("video");
  82MODULE_LICENSE("GPL");
  83
  84#define ABOUT "V4L-Driver for Vision CPiA2 based cameras"
  85
  86struct control_menu_info {
  87        int value;
  88        char name[32];
  89};
  90
  91static struct control_menu_info framerate_controls[] =
  92{
  93        { CPIA2_VP_FRAMERATE_6_25, "6.25 fps" },
  94        { CPIA2_VP_FRAMERATE_7_5,  "7.5 fps"  },
  95        { CPIA2_VP_FRAMERATE_12_5, "12.5 fps" },
  96        { CPIA2_VP_FRAMERATE_15,   "15 fps"   },
  97        { CPIA2_VP_FRAMERATE_25,   "25 fps"   },
  98        { CPIA2_VP_FRAMERATE_30,   "30 fps"   },
  99};
 100#define NUM_FRAMERATE_CONTROLS (ARRAY_SIZE(framerate_controls))
 101
 102static struct control_menu_info flicker_controls[] =
 103{
 104        { NEVER_FLICKER, "Off" },
 105        { FLICKER_50,    "50 Hz" },
 106        { FLICKER_60,    "60 Hz"  },
 107};
 108#define NUM_FLICKER_CONTROLS (ARRAY_SIZE(flicker_controls))
 109
 110static struct control_menu_info lights_controls[] =
 111{
 112        { 0,   "Off" },
 113        { 64,  "Top" },
 114        { 128, "Bottom"  },
 115        { 192, "Both"  },
 116};
 117#define NUM_LIGHTS_CONTROLS (ARRAY_SIZE(lights_controls))
 118#define GPIO_LIGHTS_MASK 192
 119
 120static struct v4l2_queryctrl controls[] = {
 121        {
 122                .id            = V4L2_CID_BRIGHTNESS,
 123                .type          = V4L2_CTRL_TYPE_INTEGER,
 124                .name          = "Brightness",
 125                .minimum       = 0,
 126                .maximum       = 255,
 127                .step          = 1,
 128                .default_value = DEFAULT_BRIGHTNESS,
 129        },
 130        {
 131                .id            = V4L2_CID_CONTRAST,
 132                .type          = V4L2_CTRL_TYPE_INTEGER,
 133                .name          = "Contrast",
 134                .minimum       = 0,
 135                .maximum       = 255,
 136                .step          = 1,
 137                .default_value = DEFAULT_CONTRAST,
 138        },
 139        {
 140                .id            = V4L2_CID_SATURATION,
 141                .type          = V4L2_CTRL_TYPE_INTEGER,
 142                .name          = "Saturation",
 143                .minimum       = 0,
 144                .maximum       = 255,
 145                .step          = 1,
 146                .default_value = DEFAULT_SATURATION,
 147        },
 148        {
 149                .id            = V4L2_CID_HFLIP,
 150                .type          = V4L2_CTRL_TYPE_BOOLEAN,
 151                .name          = "Mirror Horizontally",
 152                .minimum       = 0,
 153                .maximum       = 1,
 154                .step          = 1,
 155                .default_value = 0,
 156        },
 157        {
 158                .id            = V4L2_CID_VFLIP,
 159                .type          = V4L2_CTRL_TYPE_BOOLEAN,
 160                .name          = "Flip Vertically",
 161                .minimum       = 0,
 162                .maximum       = 1,
 163                .step          = 1,
 164                .default_value = 0,
 165        },
 166        {
 167                .id            = CPIA2_CID_TARGET_KB,
 168                .type          = V4L2_CTRL_TYPE_INTEGER,
 169                .name          = "Target KB",
 170                .minimum       = 0,
 171                .maximum       = 255,
 172                .step          = 1,
 173                .default_value = DEFAULT_TARGET_KB,
 174        },
 175        {
 176                .id            = CPIA2_CID_GPIO,
 177                .type          = V4L2_CTRL_TYPE_INTEGER,
 178                .name          = "GPIO",
 179                .minimum       = 0,
 180                .maximum       = 255,
 181                .step          = 1,
 182                .default_value = 0,
 183        },
 184        {
 185                .id            = CPIA2_CID_FLICKER_MODE,
 186                .type          = V4L2_CTRL_TYPE_MENU,
 187                .name          = "Flicker Reduction",
 188                .minimum       = 0,
 189                .maximum       = NUM_FLICKER_CONTROLS-1,
 190                .step          = 1,
 191                .default_value = 0,
 192        },
 193        {
 194                .id            = CPIA2_CID_FRAMERATE,
 195                .type          = V4L2_CTRL_TYPE_MENU,
 196                .name          = "Framerate",
 197                .minimum       = 0,
 198                .maximum       = NUM_FRAMERATE_CONTROLS-1,
 199                .step          = 1,
 200                .default_value = NUM_FRAMERATE_CONTROLS-1,
 201        },
 202        {
 203                .id            = CPIA2_CID_USB_ALT,
 204                .type          = V4L2_CTRL_TYPE_INTEGER,
 205                .name          = "USB Alternate",
 206                .minimum       = USBIF_ISO_1,
 207                .maximum       = USBIF_ISO_6,
 208                .step          = 1,
 209                .default_value = DEFAULT_ALT,
 210        },
 211        {
 212                .id            = CPIA2_CID_LIGHTS,
 213                .type          = V4L2_CTRL_TYPE_MENU,
 214                .name          = "Lights",
 215                .minimum       = 0,
 216                .maximum       = NUM_LIGHTS_CONTROLS-1,
 217                .step          = 1,
 218                .default_value = 0,
 219        },
 220        {
 221                .id            = CPIA2_CID_RESET_CAMERA,
 222                .type          = V4L2_CTRL_TYPE_BUTTON,
 223                .name          = "Reset Camera",
 224                .minimum       = 0,
 225                .maximum       = 0,
 226                .step          = 0,
 227                .default_value = 0,
 228        },
 229};
 230#define NUM_CONTROLS (ARRAY_SIZE(controls))
 231
 232
 233/******************************************************************************
 234 *
 235 *  cpia2_open
 236 *
 237 *****************************************************************************/
 238static int cpia2_open(struct file *file)
 239{
 240        struct camera_data *cam = video_drvdata(file);
 241        struct cpia2_fh *fh;
 242
 243        if (!cam) {
 244                ERR("Internal error, camera_data not found!\n");
 245                return -ENODEV;
 246        }
 247
 248        if (!cam->present)
 249                return -ENODEV;
 250
 251        if (cam->open_count == 0) {
 252                if (cpia2_allocate_buffers(cam))
 253                        return -ENOMEM;
 254
 255                /* reset the camera */
 256                if (cpia2_reset_camera(cam) < 0)
 257                        return -EIO;
 258
 259                cam->APP_len = 0;
 260                cam->COM_len = 0;
 261        }
 262
 263        fh = kmalloc(sizeof(*fh), GFP_KERNEL);
 264        if (!fh)
 265                return -ENOMEM;
 266        file->private_data = fh;
 267        fh->prio = V4L2_PRIORITY_UNSET;
 268        v4l2_prio_open(&cam->prio, &fh->prio);
 269        fh->mmapped = 0;
 270
 271        ++cam->open_count;
 272
 273        cpia2_dbg_dump_registers(cam);
 274        return 0;
 275}
 276
 277/******************************************************************************
 278 *
 279 *  cpia2_close
 280 *
 281 *****************************************************************************/
 282static int cpia2_close(struct file *file)
 283{
 284        struct video_device *dev = video_devdata(file);
 285        struct camera_data *cam = video_get_drvdata(dev);
 286        struct cpia2_fh *fh = file->private_data;
 287
 288        if (cam->present &&
 289            (cam->open_count == 1 || fh->prio == V4L2_PRIORITY_RECORD)) {
 290                cpia2_usb_stream_stop(cam);
 291
 292                if (cam->open_count == 1) {
 293                        /* save camera state for later open */
 294                        cpia2_save_camera_state(cam);
 295
 296                        cpia2_set_low_power(cam);
 297                        cpia2_free_buffers(cam);
 298                }
 299        }
 300
 301        if (fh->mmapped)
 302                cam->mmapped = 0;
 303        v4l2_prio_close(&cam->prio, fh->prio);
 304        file->private_data = NULL;
 305        kfree(fh);
 306
 307        if (--cam->open_count == 0) {
 308                cpia2_free_buffers(cam);
 309                if (!cam->present) {
 310                        video_unregister_device(dev);
 311                        kfree(cam);
 312                        return 0;
 313                }
 314        }
 315
 316        return 0;
 317}
 318
 319/******************************************************************************
 320 *
 321 *  cpia2_v4l_read
 322 *
 323 *****************************************************************************/
 324static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count,
 325                              loff_t *off)
 326{
 327        struct camera_data *cam = video_drvdata(file);
 328        int noblock = file->f_flags&O_NONBLOCK;
 329
 330        struct cpia2_fh *fh = file->private_data;
 331
 332        if(!cam)
 333                return -EINVAL;
 334
 335        /* Priority check */
 336        if(fh->prio != V4L2_PRIORITY_RECORD) {
 337                return -EBUSY;
 338        }
 339
 340        return cpia2_read(cam, buf, count, noblock);
 341}
 342
 343
 344/******************************************************************************
 345 *
 346 *  cpia2_v4l_poll
 347 *
 348 *****************************************************************************/
 349static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait)
 350{
 351        struct camera_data *cam = video_drvdata(filp);
 352        struct cpia2_fh *fh = filp->private_data;
 353
 354        if(!cam)
 355                return POLLERR;
 356
 357        /* Priority check */
 358        if(fh->prio != V4L2_PRIORITY_RECORD) {
 359                return POLLERR;
 360        }
 361
 362        return cpia2_poll(cam, filp, wait);
 363}
 364
 365
 366static int sync(struct camera_data *cam, int frame_nr)
 367{
 368        struct framebuf *frame = &cam->buffers[frame_nr];
 369
 370        while (1) {
 371                if (frame->status == FRAME_READY)
 372                        return 0;
 373
 374                if (!cam->streaming) {
 375                        frame->status = FRAME_READY;
 376                        frame->length = 0;
 377                        return 0;
 378                }
 379
 380                mutex_unlock(&cam->v4l2_lock);
 381                wait_event_interruptible(cam->wq_stream,
 382                                         !cam->streaming ||
 383                                         frame->status == FRAME_READY);
 384                mutex_lock(&cam->v4l2_lock);
 385                if (signal_pending(current))
 386                        return -ERESTARTSYS;
 387                if(!cam->present)
 388                        return -ENOTTY;
 389        }
 390}
 391
 392/******************************************************************************
 393 *
 394 *  ioctl_set_gpio
 395 *
 396 *****************************************************************************/
 397
 398static int ioctl_set_gpio(void *arg, struct camera_data *cam)
 399{
 400        __u32 gpio_val;
 401
 402        gpio_val = *(__u32*) arg;
 403
 404        if (gpio_val &~ 0xFFU)
 405                return -EINVAL;
 406
 407        return cpia2_set_gpio(cam, (unsigned char)gpio_val);
 408}
 409
 410/******************************************************************************
 411 *
 412 *  ioctl_querycap
 413 *
 414 *  V4L2 device capabilities
 415 *
 416 *****************************************************************************/
 417
 418static int ioctl_querycap(void *arg, struct camera_data *cam)
 419{
 420        struct v4l2_capability *vc = arg;
 421
 422        memset(vc, 0, sizeof(*vc));
 423        strcpy(vc->driver, "cpia2");
 424
 425        if (cam->params.pnp_id.product == 0x151)
 426                strcpy(vc->card, "QX5 Microscope");
 427        else
 428                strcpy(vc->card, "CPiA2 Camera");
 429        switch (cam->params.pnp_id.device_type) {
 430        case DEVICE_STV_672:
 431                strcat(vc->card, " (672/");
 432                break;
 433        case DEVICE_STV_676:
 434                strcat(vc->card, " (676/");
 435                break;
 436        default:
 437                strcat(vc->card, " (???/");
 438                break;
 439        }
 440        switch (cam->params.version.sensor_flags) {
 441        case CPIA2_VP_SENSOR_FLAGS_404:
 442                strcat(vc->card, "404)");
 443                break;
 444        case CPIA2_VP_SENSOR_FLAGS_407:
 445                strcat(vc->card, "407)");
 446                break;
 447        case CPIA2_VP_SENSOR_FLAGS_409:
 448                strcat(vc->card, "409)");
 449                break;
 450        case CPIA2_VP_SENSOR_FLAGS_410:
 451                strcat(vc->card, "410)");
 452                break;
 453        case CPIA2_VP_SENSOR_FLAGS_500:
 454                strcat(vc->card, "500)");
 455                break;
 456        default:
 457                strcat(vc->card, "???)");
 458                break;
 459        }
 460
 461        if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0)
 462                memset(vc->bus_info,0, sizeof(vc->bus_info));
 463
 464        vc->version = KERNEL_VERSION(CPIA2_MAJ_VER, CPIA2_MIN_VER,
 465                                     CPIA2_PATCH_VER);
 466
 467        vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
 468                           V4L2_CAP_READWRITE |
 469                           V4L2_CAP_STREAMING;
 470
 471        return 0;
 472}
 473
 474/******************************************************************************
 475 *
 476 *  ioctl_input
 477 *
 478 *  V4L2 input get/set/enumerate
 479 *
 480 *****************************************************************************/
 481
 482static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam)
 483{
 484        struct v4l2_input *i = arg;
 485
 486        if(ioclt_nr  != VIDIOC_G_INPUT) {
 487                if (i->index != 0)
 488                       return -EINVAL;
 489        }
 490
 491        memset(i, 0, sizeof(*i));
 492        strcpy(i->name, "Camera");
 493        i->type = V4L2_INPUT_TYPE_CAMERA;
 494
 495        return 0;
 496}
 497
 498/******************************************************************************
 499 *
 500 *  ioctl_enum_fmt
 501 *
 502 *  V4L2 format enumerate
 503 *
 504 *****************************************************************************/
 505
 506static int ioctl_enum_fmt(void *arg,struct camera_data *cam)
 507{
 508        struct v4l2_fmtdesc *f = arg;
 509        int index = f->index;
 510
 511        if (index < 0 || index > 1)
 512               return -EINVAL;
 513
 514        memset(f, 0, sizeof(*f));
 515        f->index = index;
 516        f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 517        f->flags = V4L2_FMT_FLAG_COMPRESSED;
 518        switch(index) {
 519        case 0:
 520                strcpy(f->description, "MJPEG");
 521                f->pixelformat = V4L2_PIX_FMT_MJPEG;
 522                break;
 523        case 1:
 524                strcpy(f->description, "JPEG");
 525                f->pixelformat = V4L2_PIX_FMT_JPEG;
 526                break;
 527        default:
 528                return -EINVAL;
 529        }
 530
 531        return 0;
 532}
 533
 534/******************************************************************************
 535 *
 536 *  ioctl_try_fmt
 537 *
 538 *  V4L2 format try
 539 *
 540 *****************************************************************************/
 541
 542static int ioctl_try_fmt(void *arg,struct camera_data *cam)
 543{
 544        struct v4l2_format *f = arg;
 545
 546        if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 547               return -EINVAL;
 548
 549        if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
 550            f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
 551               return -EINVAL;
 552
 553        f->fmt.pix.field = V4L2_FIELD_NONE;
 554        f->fmt.pix.bytesperline = 0;
 555        f->fmt.pix.sizeimage = cam->frame_size;
 556        f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
 557        f->fmt.pix.priv = 0;
 558
 559        switch (cpia2_match_video_size(f->fmt.pix.width, f->fmt.pix.height)) {
 560        case VIDEOSIZE_VGA:
 561                f->fmt.pix.width = 640;
 562                f->fmt.pix.height = 480;
 563                break;
 564        case VIDEOSIZE_CIF:
 565                f->fmt.pix.width = 352;
 566                f->fmt.pix.height = 288;
 567                break;
 568        case VIDEOSIZE_QVGA:
 569                f->fmt.pix.width = 320;
 570                f->fmt.pix.height = 240;
 571                break;
 572        case VIDEOSIZE_288_216:
 573                f->fmt.pix.width = 288;
 574                f->fmt.pix.height = 216;
 575                break;
 576        case VIDEOSIZE_256_192:
 577                f->fmt.pix.width = 256;
 578                f->fmt.pix.height = 192;
 579                break;
 580        case VIDEOSIZE_224_168:
 581                f->fmt.pix.width = 224;
 582                f->fmt.pix.height = 168;
 583                break;
 584        case VIDEOSIZE_192_144:
 585                f->fmt.pix.width = 192;
 586                f->fmt.pix.height = 144;
 587                break;
 588        case VIDEOSIZE_QCIF:
 589        default:
 590                f->fmt.pix.width = 176;
 591                f->fmt.pix.height = 144;
 592                break;
 593        }
 594
 595        return 0;
 596}
 597
 598/******************************************************************************
 599 *
 600 *  ioctl_set_fmt
 601 *
 602 *  V4L2 format set
 603 *
 604 *****************************************************************************/
 605
 606static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh)
 607{
 608        struct v4l2_format *f = arg;
 609        int err, frame;
 610
 611        err = ioctl_try_fmt(arg, cam);
 612        if(err != 0)
 613                return err;
 614
 615        /* Ensure that only this process can change the format. */
 616        err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD);
 617        if(err != 0) {
 618                return err;
 619        }
 620
 621        cam->pixelformat = f->fmt.pix.pixelformat;
 622
 623        /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle
 624         * the missing Huffman table properly. */
 625        cam->params.compression.inhibit_htables = 0;
 626                /*f->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG;*/
 627
 628        /* we set the video window to something smaller or equal to what
 629         * is requested by the user???
 630         */
 631        DBG("Requested width = %d, height = %d\n",
 632            f->fmt.pix.width, f->fmt.pix.height);
 633        if (f->fmt.pix.width != cam->width ||
 634            f->fmt.pix.height != cam->height) {
 635                cam->width = f->fmt.pix.width;
 636                cam->height = f->fmt.pix.height;
 637                cam->params.roi.width = f->fmt.pix.width;
 638                cam->params.roi.height = f->fmt.pix.height;
 639                cpia2_set_format(cam);
 640        }
 641
 642        for (frame = 0; frame < cam->num_frames; ++frame) {
 643                if (cam->buffers[frame].status == FRAME_READING)
 644                        if ((err = sync(cam, frame)) < 0)
 645                                return err;
 646
 647                cam->buffers[frame].status = FRAME_EMPTY;
 648        }
 649
 650        return 0;
 651}
 652
 653/******************************************************************************
 654 *
 655 *  ioctl_get_fmt
 656 *
 657 *  V4L2 format get
 658 *
 659 *****************************************************************************/
 660
 661static int ioctl_get_fmt(void *arg,struct camera_data *cam)
 662{
 663        struct v4l2_format *f = arg;
 664
 665        if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 666               return -EINVAL;
 667
 668        f->fmt.pix.width = cam->width;
 669        f->fmt.pix.height = cam->height;
 670        f->fmt.pix.pixelformat = cam->pixelformat;
 671        f->fmt.pix.field = V4L2_FIELD_NONE;
 672        f->fmt.pix.bytesperline = 0;
 673        f->fmt.pix.sizeimage = cam->frame_size;
 674        f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
 675        f->fmt.pix.priv = 0;
 676
 677        return 0;
 678}
 679
 680/******************************************************************************
 681 *
 682 *  ioctl_cropcap
 683 *
 684 *  V4L2 query cropping capabilities
 685 *  NOTE: cropping is currently disabled
 686 *
 687 *****************************************************************************/
 688
 689static int ioctl_cropcap(void *arg,struct camera_data *cam)
 690{
 691        struct v4l2_cropcap *c = arg;
 692
 693        if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 694               return -EINVAL;
 695
 696        c->bounds.left = 0;
 697        c->bounds.top = 0;
 698        c->bounds.width = cam->width;
 699        c->bounds.height = cam->height;
 700        c->defrect.left = 0;
 701        c->defrect.top = 0;
 702        c->defrect.width = cam->width;
 703        c->defrect.height = cam->height;
 704        c->pixelaspect.numerator = 1;
 705        c->pixelaspect.denominator = 1;
 706
 707        return 0;
 708}
 709
 710/******************************************************************************
 711 *
 712 *  ioctl_queryctrl
 713 *
 714 *  V4L2 query possible control variables
 715 *
 716 *****************************************************************************/
 717
 718static int ioctl_queryctrl(void *arg,struct camera_data *cam)
 719{
 720        struct v4l2_queryctrl *c = arg;
 721        int i;
 722
 723        for(i=0; i<NUM_CONTROLS; ++i) {
 724                if(c->id == controls[i].id) {
 725                        memcpy(c, controls+i, sizeof(*c));
 726                        break;
 727                }
 728        }
 729
 730        if(i == NUM_CONTROLS)
 731                return -EINVAL;
 732
 733        /* Some devices have additional limitations */
 734        switch(c->id) {
 735        case V4L2_CID_BRIGHTNESS:
 736                /***
 737                 * Don't let the register be set to zero - bug in VP4
 738                 * flash of full brightness
 739                 ***/
 740                if (cam->params.pnp_id.device_type == DEVICE_STV_672)
 741                        c->minimum = 1;
 742                break;
 743        case V4L2_CID_VFLIP:
 744                // VP5 Only
 745                if(cam->params.pnp_id.device_type == DEVICE_STV_672)
 746                        c->flags |= V4L2_CTRL_FLAG_DISABLED;
 747                break;
 748        case CPIA2_CID_FRAMERATE:
 749                if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
 750                   cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
 751                        // Maximum 15fps
 752                        for(i=0; i<c->maximum; ++i) {
 753                                if(framerate_controls[i].value ==
 754                                   CPIA2_VP_FRAMERATE_15) {
 755                                        c->maximum = i;
 756                                        c->default_value = i;
 757                                }
 758                        }
 759                }
 760                break;
 761        case CPIA2_CID_FLICKER_MODE:
 762                // Flicker control only valid for 672.
 763                if(cam->params.pnp_id.device_type != DEVICE_STV_672)
 764                        c->flags |= V4L2_CTRL_FLAG_DISABLED;
 765                break;
 766        case CPIA2_CID_LIGHTS:
 767                // Light control only valid for the QX5 Microscope.
 768                if(cam->params.pnp_id.product != 0x151)
 769                        c->flags |= V4L2_CTRL_FLAG_DISABLED;
 770                break;
 771        default:
 772                break;
 773        }
 774
 775        return 0;
 776}
 777
 778/******************************************************************************
 779 *
 780 *  ioctl_querymenu
 781 *
 782 *  V4L2 query possible control variables
 783 *
 784 *****************************************************************************/
 785
 786static int ioctl_querymenu(void *arg,struct camera_data *cam)
 787{
 788        struct v4l2_querymenu *m = arg;
 789
 790        memset(m->name, 0, sizeof(m->name));
 791        m->reserved = 0;
 792
 793        switch(m->id) {
 794        case CPIA2_CID_FLICKER_MODE:
 795                if (m->index >= NUM_FLICKER_CONTROLS)
 796                        return -EINVAL;
 797
 798                strcpy(m->name, flicker_controls[m->index].name);
 799                break;
 800        case CPIA2_CID_FRAMERATE:
 801            {
 802                int maximum = NUM_FRAMERATE_CONTROLS - 1;
 803                if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
 804                   cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
 805                        // Maximum 15fps
 806                        int i;
 807                        for(i=0; i<maximum; ++i) {
 808                                if(framerate_controls[i].value ==
 809                                   CPIA2_VP_FRAMERATE_15)
 810                                        maximum = i;
 811                        }
 812                }
 813                if (m->index > maximum)
 814                        return -EINVAL;
 815
 816                strcpy(m->name, framerate_controls[m->index].name);
 817                break;
 818            }
 819        case CPIA2_CID_LIGHTS:
 820                if (m->index >= NUM_LIGHTS_CONTROLS)
 821                        return -EINVAL;
 822
 823                strcpy(m->name, lights_controls[m->index].name);
 824                break;
 825        default:
 826                return -EINVAL;
 827        }
 828
 829        return 0;
 830}
 831
 832/******************************************************************************
 833 *
 834 *  ioctl_g_ctrl
 835 *
 836 *  V4L2 get the value of a control variable
 837 *
 838 *****************************************************************************/
 839
 840static int ioctl_g_ctrl(void *arg,struct camera_data *cam)
 841{
 842        struct v4l2_control *c = arg;
 843
 844        switch(c->id) {
 845        case V4L2_CID_BRIGHTNESS:
 846                cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS,
 847                                 TRANSFER_READ, 0);
 848                c->value = cam->params.color_params.brightness;
 849                break;
 850        case V4L2_CID_CONTRAST:
 851                cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST,
 852                                 TRANSFER_READ, 0);
 853                c->value = cam->params.color_params.contrast;
 854                break;
 855        case V4L2_CID_SATURATION:
 856                cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION,
 857                                 TRANSFER_READ, 0);
 858                c->value = cam->params.color_params.saturation;
 859                break;
 860        case V4L2_CID_HFLIP:
 861                cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS,
 862                                 TRANSFER_READ, 0);
 863                c->value = (cam->params.vp_params.user_effects &
 864                            CPIA2_VP_USER_EFFECTS_MIRROR) != 0;
 865                break;
 866        case V4L2_CID_VFLIP:
 867                cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS,
 868                                 TRANSFER_READ, 0);
 869                c->value = (cam->params.vp_params.user_effects &
 870                            CPIA2_VP_USER_EFFECTS_FLIP) != 0;
 871                break;
 872        case CPIA2_CID_TARGET_KB:
 873                c->value = cam->params.vc_params.target_kb;
 874                break;
 875        case CPIA2_CID_GPIO:
 876                cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA,
 877                                 TRANSFER_READ, 0);
 878                c->value = cam->params.vp_params.gpio_data;
 879                break;
 880        case CPIA2_CID_FLICKER_MODE:
 881        {
 882                int i, mode;
 883                cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES,
 884                                 TRANSFER_READ, 0);
 885                if(cam->params.flicker_control.cam_register &
 886                   CPIA2_VP_FLICKER_MODES_NEVER_FLICKER) {
 887                        mode = NEVER_FLICKER;
 888                } else {
 889                    if(cam->params.flicker_control.cam_register &
 890                       CPIA2_VP_FLICKER_MODES_50HZ) {
 891                        mode = FLICKER_50;
 892                    } else {
 893                        mode = FLICKER_60;
 894                    }
 895                }
 896                for(i=0; i<NUM_FLICKER_CONTROLS; i++) {
 897                        if(flicker_controls[i].value == mode) {
 898                                c->value = i;
 899                                break;
 900                        }
 901                }
 902                if(i == NUM_FLICKER_CONTROLS)
 903                        return -EINVAL;
 904                break;
 905        }
 906        case CPIA2_CID_FRAMERATE:
 907        {
 908                int maximum = NUM_FRAMERATE_CONTROLS - 1;
 909                int i;
 910                for(i=0; i<= maximum; i++) {
 911                        if(cam->params.vp_params.frame_rate ==
 912                           framerate_controls[i].value)
 913                                break;
 914                }
 915                if(i > maximum)
 916                        return -EINVAL;
 917                c->value = i;
 918                break;
 919        }
 920        case CPIA2_CID_USB_ALT:
 921                c->value = cam->params.camera_state.stream_mode;
 922                break;
 923        case CPIA2_CID_LIGHTS:
 924        {
 925                int i;
 926                cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA,
 927                                 TRANSFER_READ, 0);
 928                for(i=0; i<NUM_LIGHTS_CONTROLS; i++) {
 929                        if((cam->params.vp_params.gpio_data&GPIO_LIGHTS_MASK) ==
 930                           lights_controls[i].value) {
 931                                break;
 932                        }
 933                }
 934                if(i == NUM_LIGHTS_CONTROLS)
 935                        return -EINVAL;
 936                c->value = i;
 937                break;
 938        }
 939        case CPIA2_CID_RESET_CAMERA:
 940                return -EINVAL;
 941        default:
 942                return -EINVAL;
 943        }
 944
 945        DBG("Get control id:%d, value:%d\n", c->id, c->value);
 946
 947        return 0;
 948}
 949
 950/******************************************************************************
 951 *
 952 *  ioctl_s_ctrl
 953 *
 954 *  V4L2 set the value of a control variable
 955 *
 956 *****************************************************************************/
 957
 958static int ioctl_s_ctrl(void *arg,struct camera_data *cam)
 959{
 960        struct v4l2_control *c = arg;
 961        int i;
 962        int retval = 0;
 963
 964        DBG("Set control id:%d, value:%d\n", c->id, c->value);
 965
 966        /* Check that the value is in range */
 967        for(i=0; i<NUM_CONTROLS; i++) {
 968                if(c->id == controls[i].id) {
 969                        if(c->value < controls[i].minimum ||
 970                           c->value > controls[i].maximum) {
 971                                return -EINVAL;
 972                        }
 973                        break;
 974                }
 975        }
 976        if(i == NUM_CONTROLS)
 977                return -EINVAL;
 978
 979        switch(c->id) {
 980        case V4L2_CID_BRIGHTNESS:
 981                cpia2_set_brightness(cam, c->value);
 982                break;
 983        case V4L2_CID_CONTRAST:
 984                cpia2_set_contrast(cam, c->value);
 985                break;
 986        case V4L2_CID_SATURATION:
 987                cpia2_set_saturation(cam, c->value);
 988                break;
 989        case V4L2_CID_HFLIP:
 990                cpia2_set_property_mirror(cam, c->value);
 991                break;
 992        case V4L2_CID_VFLIP:
 993                cpia2_set_property_flip(cam, c->value);
 994                break;
 995        case CPIA2_CID_TARGET_KB:
 996                retval = cpia2_set_target_kb(cam, c->value);
 997                break;
 998        case CPIA2_CID_GPIO:
 999                retval = cpia2_set_gpio(cam, c->value);
1000                break;
1001        case CPIA2_CID_FLICKER_MODE:
1002                retval = cpia2_set_flicker_mode(cam,
1003                                              flicker_controls[c->value].value);
1004                break;
1005        case CPIA2_CID_FRAMERATE:
1006                retval = cpia2_set_fps(cam, framerate_controls[c->value].value);
1007                break;
1008        case CPIA2_CID_USB_ALT:
1009                retval = cpia2_usb_change_streaming_alternate(cam, c->value);
1010                break;
1011        case CPIA2_CID_LIGHTS:
1012                retval = cpia2_set_gpio(cam, lights_controls[c->value].value);
1013                break;
1014        case CPIA2_CID_RESET_CAMERA:
1015                cpia2_usb_stream_pause(cam);
1016                cpia2_reset_camera(cam);
1017                cpia2_usb_stream_resume(cam);
1018                break;
1019        default:
1020                retval = -EINVAL;
1021        }
1022
1023        return retval;
1024}
1025
1026/******************************************************************************
1027 *
1028 *  ioctl_g_jpegcomp
1029 *
1030 *  V4L2 get the JPEG compression parameters
1031 *
1032 *****************************************************************************/
1033
1034static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam)
1035{
1036        struct v4l2_jpegcompression *parms = arg;
1037
1038        memset(parms, 0, sizeof(*parms));
1039
1040        parms->quality = 80; // TODO: Can this be made meaningful?
1041
1042        parms->jpeg_markers = V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI;
1043        if(!cam->params.compression.inhibit_htables) {
1044                parms->jpeg_markers |= V4L2_JPEG_MARKER_DHT;
1045        }
1046
1047        parms->APPn = cam->APPn;
1048        parms->APP_len = cam->APP_len;
1049        if(cam->APP_len > 0) {
1050                memcpy(parms->APP_data, cam->APP_data, cam->APP_len);
1051                parms->jpeg_markers |= V4L2_JPEG_MARKER_APP;
1052        }
1053
1054        parms->COM_len = cam->COM_len;
1055        if(cam->COM_len > 0) {
1056                memcpy(parms->COM_data, cam->COM_data, cam->COM_len);
1057                parms->jpeg_markers |= JPEG_MARKER_COM;
1058        }
1059
1060        DBG("G_JPEGCOMP APP_len:%d COM_len:%d\n",
1061            parms->APP_len, parms->COM_len);
1062
1063        return 0;
1064}
1065
1066/******************************************************************************
1067 *
1068 *  ioctl_s_jpegcomp
1069 *
1070 *  V4L2 set the JPEG compression parameters
1071 *  NOTE: quality and some jpeg_markers are ignored.
1072 *
1073 *****************************************************************************/
1074
1075static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam)
1076{
1077        struct v4l2_jpegcompression *parms = arg;
1078
1079        DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n",
1080            parms->APP_len, parms->COM_len);
1081
1082        cam->params.compression.inhibit_htables =
1083                !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT);
1084
1085        if(parms->APP_len != 0) {
1086                if(parms->APP_len > 0 &&
1087                   parms->APP_len <= sizeof(cam->APP_data) &&
1088                   parms->APPn >= 0 && parms->APPn <= 15) {
1089                        cam->APPn = parms->APPn;
1090                        cam->APP_len = parms->APP_len;
1091                        memcpy(cam->APP_data, parms->APP_data, parms->APP_len);
1092                } else {
1093                        LOG("Bad APPn Params n=%d len=%d\n",
1094                            parms->APPn, parms->APP_len);
1095                        return -EINVAL;
1096                }
1097        } else {
1098                cam->APP_len = 0;
1099        }
1100
1101        if(parms->COM_len != 0) {
1102                if(parms->COM_len > 0 &&
1103                   parms->COM_len <= sizeof(cam->COM_data)) {
1104                        cam->COM_len = parms->COM_len;
1105                        memcpy(cam->COM_data, parms->COM_data, parms->COM_len);
1106                } else {
1107                        LOG("Bad COM_len=%d\n", parms->COM_len);
1108                        return -EINVAL;
1109                }
1110        }
1111
1112        return 0;
1113}
1114
1115/******************************************************************************
1116 *
1117 *  ioctl_reqbufs
1118 *
1119 *  V4L2 Initiate memory mapping.
1120 *  NOTE: The user's request is ignored. For now the buffers are fixed.
1121 *
1122 *****************************************************************************/
1123
1124static int ioctl_reqbufs(void *arg,struct camera_data *cam)
1125{
1126        struct v4l2_requestbuffers *req = arg;
1127
1128        if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1129           req->memory != V4L2_MEMORY_MMAP)
1130                return -EINVAL;
1131
1132        DBG("REQBUFS requested:%d returning:%d\n", req->count, cam->num_frames);
1133        req->count = cam->num_frames;
1134        memset(&req->reserved, 0, sizeof(req->reserved));
1135
1136        return 0;
1137}
1138
1139/******************************************************************************
1140 *
1141 *  ioctl_querybuf
1142 *
1143 *  V4L2 Query memory buffer status.
1144 *
1145 *****************************************************************************/
1146
1147static int ioctl_querybuf(void *arg,struct camera_data *cam)
1148{
1149        struct v4l2_buffer *buf = arg;
1150
1151        if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1152           buf->index > cam->num_frames)
1153                return -EINVAL;
1154
1155        buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
1156        buf->length = cam->frame_size;
1157
1158        buf->memory = V4L2_MEMORY_MMAP;
1159
1160        if(cam->mmapped)
1161                buf->flags = V4L2_BUF_FLAG_MAPPED;
1162        else
1163                buf->flags = 0;
1164
1165        switch (cam->buffers[buf->index].status) {
1166        case FRAME_EMPTY:
1167        case FRAME_ERROR:
1168        case FRAME_READING:
1169                buf->bytesused = 0;
1170                buf->flags = V4L2_BUF_FLAG_QUEUED;
1171                break;
1172        case FRAME_READY:
1173                buf->bytesused = cam->buffers[buf->index].length;
1174                buf->timestamp = cam->buffers[buf->index].timestamp;
1175                buf->sequence = cam->buffers[buf->index].seq;
1176                buf->flags = V4L2_BUF_FLAG_DONE;
1177                break;
1178        }
1179
1180        DBG("QUERYBUF index:%d offset:%d flags:%d seq:%d bytesused:%d\n",
1181             buf->index, buf->m.offset, buf->flags, buf->sequence,
1182             buf->bytesused);
1183
1184        return 0;
1185}
1186
1187/******************************************************************************
1188 *
1189 *  ioctl_qbuf
1190 *
1191 *  V4L2 User is freeing buffer
1192 *
1193 *****************************************************************************/
1194
1195static int ioctl_qbuf(void *arg,struct camera_data *cam)
1196{
1197        struct v4l2_buffer *buf = arg;
1198
1199        if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1200           buf->memory != V4L2_MEMORY_MMAP ||
1201           buf->index > cam->num_frames)
1202                return -EINVAL;
1203
1204        DBG("QBUF #%d\n", buf->index);
1205
1206        if(cam->buffers[buf->index].status == FRAME_READY)
1207                cam->buffers[buf->index].status = FRAME_EMPTY;
1208
1209        return 0;
1210}
1211
1212/******************************************************************************
1213 *
1214 *  find_earliest_filled_buffer
1215 *
1216 *  Helper for ioctl_dqbuf. Find the next ready buffer.
1217 *
1218 *****************************************************************************/
1219
1220static int find_earliest_filled_buffer(struct camera_data *cam)
1221{
1222        int i;
1223        int found = -1;
1224        for (i=0; i<cam->num_frames; i++) {
1225                if(cam->buffers[i].status == FRAME_READY) {
1226                        if(found < 0) {
1227                                found = i;
1228                        } else {
1229                                /* find which buffer is earlier */
1230                                struct timeval *tv1, *tv2;
1231                                tv1 = &cam->buffers[i].timestamp;
1232                                tv2 = &cam->buffers[found].timestamp;
1233                                if(tv1->tv_sec < tv2->tv_sec ||
1234                                   (tv1->tv_sec == tv2->tv_sec &&
1235                                    tv1->tv_usec < tv2->tv_usec))
1236                                        found = i;
1237                        }
1238                }
1239        }
1240        return found;
1241}
1242
1243/******************************************************************************
1244 *
1245 *  ioctl_dqbuf
1246 *
1247 *  V4L2 User is asking for a filled buffer.
1248 *
1249 *****************************************************************************/
1250
1251static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
1252{
1253        struct v4l2_buffer *buf = arg;
1254        int frame;
1255
1256        if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1257           buf->memory != V4L2_MEMORY_MMAP)
1258                return -EINVAL;
1259
1260        frame = find_earliest_filled_buffer(cam);
1261
1262        if(frame < 0 && file->f_flags&O_NONBLOCK)
1263                return -EAGAIN;
1264
1265        if(frame < 0) {
1266                /* Wait for a frame to become available */
1267                struct framebuf *cb=cam->curbuff;
1268                mutex_unlock(&cam->v4l2_lock);
1269                wait_event_interruptible(cam->wq_stream,
1270                                         !cam->present ||
1271                                         (cb=cam->curbuff)->status == FRAME_READY);
1272                mutex_lock(&cam->v4l2_lock);
1273                if (signal_pending(current))
1274                        return -ERESTARTSYS;
1275                if(!cam->present)
1276                        return -ENOTTY;
1277                frame = cb->num;
1278        }
1279
1280
1281        buf->index = frame;
1282        buf->bytesused = cam->buffers[buf->index].length;
1283        buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
1284        buf->field = V4L2_FIELD_NONE;
1285        buf->timestamp = cam->buffers[buf->index].timestamp;
1286        buf->sequence = cam->buffers[buf->index].seq;
1287        buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
1288        buf->length = cam->frame_size;
1289        buf->input = 0;
1290        buf->reserved = 0;
1291        memset(&buf->timecode, 0, sizeof(buf->timecode));
1292
1293        DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index,
1294            cam->buffers[buf->index].status, buf->sequence, buf->bytesused);
1295
1296        return 0;
1297}
1298
1299/******************************************************************************
1300 *
1301 *  cpia2_ioctl
1302 *
1303 *****************************************************************************/
1304static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1305{
1306        struct camera_data *cam = video_drvdata(file);
1307        long retval = 0;
1308
1309        if (!cam)
1310                return -ENOTTY;
1311
1312        if (!cam->present)
1313                return -ENODEV;
1314
1315        /* Priority check */
1316        switch (cmd) {
1317        case VIDIOC_S_FMT:
1318        {
1319                struct cpia2_fh *fh = file->private_data;
1320                retval = v4l2_prio_check(&cam->prio, fh->prio);
1321                if (retval)
1322                        return retval;
1323                break;
1324        }
1325        default:
1326                break;
1327        }
1328
1329        switch (cmd) {
1330        /* CPIA2 extension to Video4Linux API */
1331        case CPIA2_IOC_SET_GPIO:
1332                retval = ioctl_set_gpio(arg, cam);
1333                break;
1334        case VIDIOC_QUERYCAP:
1335                retval = ioctl_querycap(arg,cam);
1336                break;
1337
1338        case VIDIOC_ENUMINPUT:
1339        case VIDIOC_G_INPUT:
1340        case VIDIOC_S_INPUT:
1341                retval = ioctl_input(cmd, arg, cam);
1342                break;
1343
1344        case VIDIOC_ENUM_FMT:
1345                retval = ioctl_enum_fmt(arg,cam);
1346                break;
1347        case VIDIOC_TRY_FMT:
1348                retval = ioctl_try_fmt(arg,cam);
1349                break;
1350        case VIDIOC_G_FMT:
1351                retval = ioctl_get_fmt(arg,cam);
1352                break;
1353        case VIDIOC_S_FMT:
1354                retval = ioctl_set_fmt(arg,cam,file->private_data);
1355                break;
1356
1357        case VIDIOC_CROPCAP:
1358                retval = ioctl_cropcap(arg,cam);
1359                break;
1360        case VIDIOC_G_CROP:
1361        case VIDIOC_S_CROP:
1362                // TODO: I think cropping can be implemented - SJB
1363                retval = -EINVAL;
1364                break;
1365
1366        case VIDIOC_QUERYCTRL:
1367                retval = ioctl_queryctrl(arg,cam);
1368                break;
1369        case VIDIOC_QUERYMENU:
1370                retval = ioctl_querymenu(arg,cam);
1371                break;
1372        case VIDIOC_G_CTRL:
1373                retval = ioctl_g_ctrl(arg,cam);
1374                break;
1375        case VIDIOC_S_CTRL:
1376                retval = ioctl_s_ctrl(arg,cam);
1377                break;
1378
1379        case VIDIOC_G_JPEGCOMP:
1380                retval = ioctl_g_jpegcomp(arg,cam);
1381                break;
1382        case VIDIOC_S_JPEGCOMP:
1383                retval = ioctl_s_jpegcomp(arg,cam);
1384                break;
1385
1386        case VIDIOC_G_PRIORITY:
1387        {
1388                struct cpia2_fh *fh = file->private_data;
1389                *(enum v4l2_priority*)arg = fh->prio;
1390                break;
1391        }
1392        case VIDIOC_S_PRIORITY:
1393        {
1394                struct cpia2_fh *fh = file->private_data;
1395                enum v4l2_priority prio;
1396                prio = *(enum v4l2_priority*)arg;
1397                if(cam->streaming &&
1398                   prio != fh->prio &&
1399                   fh->prio == V4L2_PRIORITY_RECORD) {
1400                        /* Can't drop record priority while streaming */
1401                        retval = -EBUSY;
1402                } else if(prio == V4L2_PRIORITY_RECORD &&
1403                   prio != fh->prio &&
1404                   v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) {
1405                        /* Only one program can record at a time */
1406                        retval = -EBUSY;
1407                } else {
1408                        retval = v4l2_prio_change(&cam->prio, &fh->prio, prio);
1409                }
1410                break;
1411        }
1412
1413        case VIDIOC_REQBUFS:
1414                retval = ioctl_reqbufs(arg,cam);
1415                break;
1416        case VIDIOC_QUERYBUF:
1417                retval = ioctl_querybuf(arg,cam);
1418                break;
1419        case VIDIOC_QBUF:
1420                retval = ioctl_qbuf(arg,cam);
1421                break;
1422        case VIDIOC_DQBUF:
1423                retval = ioctl_dqbuf(arg,cam,file);
1424                break;
1425        case VIDIOC_STREAMON:
1426        {
1427                int type;
1428                DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming);
1429                type = *(int*)arg;
1430                if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1431                        retval = -EINVAL;
1432
1433                if(!cam->streaming) {
1434                        retval = cpia2_usb_stream_start(cam,
1435                                          cam->params.camera_state.stream_mode);
1436                } else {
1437                        retval = -EINVAL;
1438                }
1439
1440                break;
1441        }
1442        case VIDIOC_STREAMOFF:
1443        {
1444                int type;
1445                DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming);
1446                type = *(int*)arg;
1447                if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1448                        retval = -EINVAL;
1449
1450                if(cam->streaming) {
1451                        retval = cpia2_usb_stream_stop(cam);
1452                } else {
1453                        retval = -EINVAL;
1454                }
1455
1456                break;
1457        }
1458
1459        case VIDIOC_ENUMOUTPUT:
1460        case VIDIOC_G_OUTPUT:
1461        case VIDIOC_S_OUTPUT:
1462        case VIDIOC_G_MODULATOR:
1463        case VIDIOC_S_MODULATOR:
1464
1465        case VIDIOC_ENUMAUDIO:
1466        case VIDIOC_G_AUDIO:
1467        case VIDIOC_S_AUDIO:
1468
1469        case VIDIOC_ENUMAUDOUT:
1470        case VIDIOC_G_AUDOUT:
1471        case VIDIOC_S_AUDOUT:
1472
1473        case VIDIOC_ENUMSTD:
1474        case VIDIOC_QUERYSTD:
1475        case VIDIOC_G_STD:
1476        case VIDIOC_S_STD:
1477
1478        case VIDIOC_G_TUNER:
1479        case VIDIOC_S_TUNER:
1480        case VIDIOC_G_FREQUENCY:
1481        case VIDIOC_S_FREQUENCY:
1482
1483        case VIDIOC_OVERLAY:
1484        case VIDIOC_G_FBUF:
1485        case VIDIOC_S_FBUF:
1486
1487        case VIDIOC_G_PARM:
1488        case VIDIOC_S_PARM:
1489                retval = -EINVAL;
1490                break;
1491        default:
1492                retval = -ENOIOCTLCMD;
1493                break;
1494        }
1495
1496        return retval;
1497}
1498
1499static long cpia2_ioctl(struct file *file,
1500                       unsigned int cmd, unsigned long arg)
1501{
1502        return video_usercopy(file, cmd, arg, cpia2_do_ioctl);
1503}
1504
1505/******************************************************************************
1506 *
1507 *  cpia2_mmap
1508 *
1509 *****************************************************************************/
1510static int cpia2_mmap(struct file *file, struct vm_area_struct *area)
1511{
1512        struct camera_data *cam = video_drvdata(file);
1513        int retval;
1514
1515        /* Priority check */
1516        struct cpia2_fh *fh = file->private_data;
1517        if(fh->prio != V4L2_PRIORITY_RECORD) {
1518                return -EBUSY;
1519        }
1520
1521        retval = cpia2_remap_buffer(cam, area);
1522
1523        if(!retval)
1524                fh->mmapped = 1;
1525        return retval;
1526}
1527
1528/******************************************************************************
1529 *
1530 *  reset_camera_struct_v4l
1531 *
1532 *  Sets all values to the defaults
1533 *****************************************************************************/
1534static void reset_camera_struct_v4l(struct camera_data *cam)
1535{
1536        cam->width = cam->params.roi.width;
1537        cam->height = cam->params.roi.height;
1538
1539        cam->frame_size = buffer_size;
1540        cam->num_frames = num_buffers;
1541
1542        /* FlickerModes */
1543        cam->params.flicker_control.flicker_mode_req = flicker_mode;
1544        cam->params.flicker_control.mains_frequency = flicker_freq;
1545
1546        /* streamMode */
1547        cam->params.camera_state.stream_mode = alternate;
1548
1549        cam->pixelformat = V4L2_PIX_FMT_JPEG;
1550        v4l2_prio_init(&cam->prio);
1551}
1552
1553/***
1554 * The v4l video device structure initialized for this device
1555 ***/
1556static const struct v4l2_file_operations cpia2_fops = {
1557        .owner          = THIS_MODULE,
1558        .open           = cpia2_open,
1559        .release        = cpia2_close,
1560        .read           = cpia2_v4l_read,
1561        .poll           = cpia2_v4l_poll,
1562        .unlocked_ioctl = cpia2_ioctl,
1563        .mmap           = cpia2_mmap,
1564};
1565
1566static struct video_device cpia2_template = {
1567        /* I could not find any place for the old .initialize initializer?? */
1568        .name =         "CPiA2 Camera",
1569        .fops =         &cpia2_fops,
1570        .release =      video_device_release,
1571};
1572
1573/******************************************************************************
1574 *
1575 *  cpia2_register_camera
1576 *
1577 *****************************************************************************/
1578int cpia2_register_camera(struct camera_data *cam)
1579{
1580        cam->vdev = video_device_alloc();
1581        if(!cam->vdev)
1582                return -ENOMEM;
1583
1584        memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template));
1585        video_set_drvdata(cam->vdev, cam);
1586        cam->vdev->lock = &cam->v4l2_lock;
1587
1588        reset_camera_struct_v4l(cam);
1589
1590        /* register v4l device */
1591        if (video_register_device(cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1592                ERR("video_register_device failed\n");
1593                video_device_release(cam->vdev);
1594                return -ENODEV;
1595        }
1596
1597        return 0;
1598}
1599
1600/******************************************************************************
1601 *
1602 *  cpia2_unregister_camera
1603 *
1604 *****************************************************************************/
1605void cpia2_unregister_camera(struct camera_data *cam)
1606{
1607        if (!cam->open_count) {
1608                video_unregister_device(cam->vdev);
1609        } else {
1610                LOG("%s removed while open, deferring "
1611                    "video_unregister_device\n",
1612                    video_device_node_name(cam->vdev));
1613        }
1614}
1615
1616/******************************************************************************
1617 *
1618 *  check_parameters
1619 *
1620 *  Make sure that all user-supplied parameters are sensible
1621 *****************************************************************************/
1622static void __init check_parameters(void)
1623{
1624        if(buffer_size < PAGE_SIZE) {
1625                buffer_size = PAGE_SIZE;
1626                LOG("buffer_size too small, setting to %d\n", buffer_size);
1627        } else if(buffer_size > 1024*1024) {
1628                /* arbitrary upper limiit */
1629                buffer_size = 1024*1024;
1630                LOG("buffer_size ridiculously large, setting to %d\n",
1631                    buffer_size);
1632        } else {
1633                buffer_size += PAGE_SIZE-1;
1634                buffer_size &= ~(PAGE_SIZE-1);
1635        }
1636
1637        if(num_buffers < 1) {
1638                num_buffers = 1;
1639                LOG("num_buffers too small, setting to %d\n", num_buffers);
1640        } else if(num_buffers > VIDEO_MAX_FRAME) {
1641                num_buffers = VIDEO_MAX_FRAME;
1642                LOG("num_buffers too large, setting to %d\n", num_buffers);
1643        }
1644
1645        if(alternate < USBIF_ISO_1 || alternate > USBIF_ISO_6) {
1646                alternate = DEFAULT_ALT;
1647                LOG("alternate specified is invalid, using %d\n", alternate);
1648        }
1649
1650        if (flicker_mode != NEVER_FLICKER && flicker_mode != ANTI_FLICKER_ON) {
1651                flicker_mode = NEVER_FLICKER;
1652                LOG("Flicker mode specified is invalid, using %d\n",
1653                    flicker_mode);
1654        }
1655
1656        if (flicker_freq != FLICKER_50 && flicker_freq != FLICKER_60) {
1657                flicker_freq = FLICKER_60;
1658                LOG("Flicker mode specified is invalid, using %d\n",
1659                    flicker_freq);
1660        }
1661
1662        if(video_nr < -1 || video_nr > 64) {
1663                video_nr = -1;
1664                LOG("invalid video_nr specified, must be -1 to 64\n");
1665        }
1666
1667        DBG("Using %d buffers, each %d bytes, alternate=%d\n",
1668            num_buffers, buffer_size, alternate);
1669}
1670
1671/************   Module Stuff ***************/
1672
1673
1674/******************************************************************************
1675 *
1676 * cpia2_init/module_init
1677 *
1678 *****************************************************************************/
1679static int __init cpia2_init(void)
1680{
1681        LOG("%s v%d.%d.%d\n",
1682            ABOUT, CPIA2_MAJ_VER, CPIA2_MIN_VER, CPIA2_PATCH_VER);
1683        check_parameters();
1684        cpia2_usb_init();
1685        return 0;
1686}
1687
1688
1689/******************************************************************************
1690 *
1691 * cpia2_exit/module_exit
1692 *
1693 *****************************************************************************/
1694static void __exit cpia2_exit(void)
1695{
1696        cpia2_usb_cleanup();
1697        schedule_timeout(2 * HZ);
1698}
1699
1700module_init(cpia2_init);
1701module_exit(cpia2_exit);
1702
1703