linux/drivers/staging/media/go7007/go7007-v4l2.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2005-2006 Micronas USA Inc.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License (Version 2) as
   6 * published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 *
  13 * You should have received a copy of the GNU General Public License
  14 * along with this program; if not, write to the Free Software Foundation,
  15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  16 */
  17
  18#include <linux/module.h>
  19#include <linux/init.h>
  20#include <linux/version.h>
  21#include <linux/delay.h>
  22#include <linux/sched.h>
  23#include <linux/spinlock.h>
  24#include <linux/slab.h>
  25#include <linux/fs.h>
  26#include <linux/unistd.h>
  27#include <linux/time.h>
  28#include <linux/vmalloc.h>
  29#include <linux/pagemap.h>
  30#include <linux/videodev2.h>
  31#include <media/v4l2-common.h>
  32#include <media/v4l2-ioctl.h>
  33#include <media/v4l2-subdev.h>
  34#include <linux/i2c.h>
  35#include <linux/mutex.h>
  36#include <linux/uaccess.h>
  37
  38#include "go7007.h"
  39#include "go7007-priv.h"
  40#include "wis-i2c.h"
  41
  42/* Temporary defines until accepted in v4l-dvb */
  43#ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
  44#define V4L2_MPEG_STREAM_TYPE_MPEG_ELEM   6 /* MPEG elementary stream */
  45#endif
  46#ifndef V4L2_MPEG_VIDEO_ENCODING_MPEG_4
  47#define V4L2_MPEG_VIDEO_ENCODING_MPEG_4   3
  48#endif
  49
  50#define call_all(dev, o, f, args...) \
  51        v4l2_device_call_until_err(dev, 0, o, f, ##args)
  52
  53static void deactivate_buffer(struct go7007_buffer *gobuf)
  54{
  55        int i;
  56
  57        if (gobuf->state != BUF_STATE_IDLE) {
  58                list_del(&gobuf->stream);
  59                gobuf->state = BUF_STATE_IDLE;
  60        }
  61        if (gobuf->page_count > 0) {
  62                for (i = 0; i < gobuf->page_count; ++i)
  63                        page_cache_release(gobuf->pages[i]);
  64                gobuf->page_count = 0;
  65        }
  66}
  67
  68static void abort_queued(struct go7007 *go)
  69{
  70        struct go7007_buffer *gobuf, *next;
  71
  72        list_for_each_entry_safe(gobuf, next, &go->stream, stream) {
  73                deactivate_buffer(gobuf);
  74        }
  75}
  76
  77static int go7007_streamoff(struct go7007 *go)
  78{
  79        unsigned long flags;
  80
  81        mutex_lock(&go->hw_lock);
  82        if (go->streaming) {
  83                go->streaming = 0;
  84                go7007_stream_stop(go);
  85                spin_lock_irqsave(&go->spinlock, flags);
  86                abort_queued(go);
  87                spin_unlock_irqrestore(&go->spinlock, flags);
  88                go7007_reset_encoder(go);
  89        }
  90        mutex_unlock(&go->hw_lock);
  91        return 0;
  92}
  93
  94static int go7007_open(struct file *file)
  95{
  96        struct go7007 *go = video_get_drvdata(video_devdata(file));
  97        struct go7007_file *gofh;
  98
  99        if (go->status != STATUS_ONLINE)
 100                return -EBUSY;
 101        gofh = kzalloc(sizeof(struct go7007_file), GFP_KERNEL);
 102        if (gofh == NULL)
 103                return -ENOMEM;
 104        ++go->ref_count;
 105        gofh->go = go;
 106        mutex_init(&gofh->lock);
 107        gofh->buf_count = 0;
 108        file->private_data = gofh;
 109        return 0;
 110}
 111
 112static int go7007_release(struct file *file)
 113{
 114        struct go7007_file *gofh = file->private_data;
 115        struct go7007 *go = gofh->go;
 116
 117        if (gofh->buf_count > 0) {
 118                go7007_streamoff(go);
 119                go->in_use = 0;
 120                kfree(gofh->bufs);
 121                gofh->buf_count = 0;
 122        }
 123        kfree(gofh);
 124        if (--go->ref_count == 0)
 125                kfree(go);
 126        file->private_data = NULL;
 127        return 0;
 128}
 129
 130static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
 131{
 132        u8 *f = page_address(gobuf->pages[0]);
 133
 134        switch (format) {
 135        case GO7007_FORMAT_MJPEG:
 136                return V4L2_BUF_FLAG_KEYFRAME;
 137        case GO7007_FORMAT_MPEG4:
 138                switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) {
 139                case 0:
 140                        return V4L2_BUF_FLAG_KEYFRAME;
 141                case 1:
 142                        return V4L2_BUF_FLAG_PFRAME;
 143                case 2:
 144                        return V4L2_BUF_FLAG_BFRAME;
 145                default:
 146                        return 0;
 147                }
 148        case GO7007_FORMAT_MPEG1:
 149        case GO7007_FORMAT_MPEG2:
 150                switch ((f[gobuf->frame_offset + 5] >> 3) & 0x7) {
 151                case 1:
 152                        return V4L2_BUF_FLAG_KEYFRAME;
 153                case 2:
 154                        return V4L2_BUF_FLAG_PFRAME;
 155                case 3:
 156                        return V4L2_BUF_FLAG_BFRAME;
 157                default:
 158                        return 0;
 159                }
 160        }
 161
 162        return 0;
 163}
 164
 165static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
 166{
 167        int sensor_height = 0, sensor_width = 0;
 168        int width, height, i;
 169
 170        if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
 171                        fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG &&
 172                        fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG4)
 173                return -EINVAL;
 174
 175        switch (go->standard) {
 176        case GO7007_STD_NTSC:
 177                sensor_width = 720;
 178                sensor_height = 480;
 179                break;
 180        case GO7007_STD_PAL:
 181                sensor_width = 720;
 182                sensor_height = 576;
 183                break;
 184        case GO7007_STD_OTHER:
 185                sensor_width = go->board_info->sensor_width;
 186                sensor_height = go->board_info->sensor_height;
 187                break;
 188        }
 189
 190        if (fmt == NULL) {
 191                width = sensor_width;
 192                height = sensor_height;
 193        } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
 194                if (fmt->fmt.pix.width > sensor_width)
 195                        width = sensor_width;
 196                else if (fmt->fmt.pix.width < 144)
 197                        width = 144;
 198                else
 199                        width = fmt->fmt.pix.width & ~0x0f;
 200
 201                if (fmt->fmt.pix.height > sensor_height)
 202                        height = sensor_height;
 203                else if (fmt->fmt.pix.height < 96)
 204                        height = 96;
 205                else
 206                        height = fmt->fmt.pix.height & ~0x0f;
 207        } else {
 208                int requested_size = fmt->fmt.pix.width * fmt->fmt.pix.height;
 209                int sensor_size = sensor_width * sensor_height;
 210
 211                if (64 * requested_size < 9 * sensor_size) {
 212                        width = sensor_width / 4;
 213                        height = sensor_height / 4;
 214                } else if (64 * requested_size < 36 * sensor_size) {
 215                        width = sensor_width / 2;
 216                        height = sensor_height / 2;
 217                } else {
 218                        width = sensor_width;
 219                        height = sensor_height;
 220                }
 221                width &= ~0xf;
 222                height &= ~0xf;
 223        }
 224
 225        if (fmt != NULL) {
 226                u32 pixelformat = fmt->fmt.pix.pixelformat;
 227
 228                memset(fmt, 0, sizeof(*fmt));
 229                fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 230                fmt->fmt.pix.width = width;
 231                fmt->fmt.pix.height = height;
 232                fmt->fmt.pix.pixelformat = pixelformat;
 233                fmt->fmt.pix.field = V4L2_FIELD_NONE;
 234                fmt->fmt.pix.bytesperline = 0;
 235                fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
 236                fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
 237        }
 238
 239        if (try)
 240                return 0;
 241
 242        go->width = width;
 243        go->height = height;
 244        go->encoder_h_offset = go->board_info->sensor_h_offset;
 245        go->encoder_v_offset = go->board_info->sensor_v_offset;
 246        for (i = 0; i < 4; ++i)
 247                go->modet[i].enable = 0;
 248        for (i = 0; i < 1624; ++i)
 249                go->modet_map[i] = 0;
 250
 251        if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
 252                struct v4l2_mbus_framefmt mbus_fmt;
 253
 254                mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
 255                if (fmt != NULL)
 256                        mbus_fmt.width = fmt->fmt.pix.width;
 257                else
 258                        mbus_fmt.width = width;
 259
 260                if (height > sensor_height / 2) {
 261                        mbus_fmt.height = height / 2;
 262                        go->encoder_v_halve = 0;
 263                } else {
 264                        mbus_fmt.height = height;
 265                        go->encoder_v_halve = 1;
 266                }
 267                call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt);
 268        } else {
 269                if (width <= sensor_width / 4) {
 270                        go->encoder_h_halve = 1;
 271                        go->encoder_v_halve = 1;
 272                        go->encoder_subsample = 1;
 273                } else if (width <= sensor_width / 2) {
 274                        go->encoder_h_halve = 1;
 275                        go->encoder_v_halve = 1;
 276                        go->encoder_subsample = 0;
 277                } else {
 278                        go->encoder_h_halve = 0;
 279                        go->encoder_v_halve = 0;
 280                        go->encoder_subsample = 0;
 281                }
 282        }
 283
 284        if (fmt == NULL)
 285                return 0;
 286
 287        switch (fmt->fmt.pix.pixelformat) {
 288        case V4L2_PIX_FMT_MPEG:
 289                if (go->format == GO7007_FORMAT_MPEG1 ||
 290                                go->format == GO7007_FORMAT_MPEG2 ||
 291                                go->format == GO7007_FORMAT_MPEG4)
 292                        break;
 293                go->format = GO7007_FORMAT_MPEG1;
 294                go->pali = 0;
 295                go->aspect_ratio = GO7007_RATIO_1_1;
 296                go->gop_size = go->sensor_framerate / 1000;
 297                go->ipb = 0;
 298                go->closed_gop = 1;
 299                go->repeat_seqhead = 1;
 300                go->seq_header_enable = 1;
 301                go->gop_header_enable = 1;
 302                go->dvd_mode = 0;
 303                break;
 304        /* Backwards compatibility only! */
 305        case V4L2_PIX_FMT_MPEG4:
 306                if (go->format == GO7007_FORMAT_MPEG4)
 307                        break;
 308                go->format = GO7007_FORMAT_MPEG4;
 309                go->pali = 0xf5;
 310                go->aspect_ratio = GO7007_RATIO_1_1;
 311                go->gop_size = go->sensor_framerate / 1000;
 312                go->ipb = 0;
 313                go->closed_gop = 1;
 314                go->repeat_seqhead = 1;
 315                go->seq_header_enable = 1;
 316                go->gop_header_enable = 1;
 317                go->dvd_mode = 0;
 318                break;
 319        case V4L2_PIX_FMT_MJPEG:
 320                go->format = GO7007_FORMAT_MJPEG;
 321                go->pali = 0;
 322                go->aspect_ratio = GO7007_RATIO_1_1;
 323                go->gop_size = 0;
 324                go->ipb = 0;
 325                go->closed_gop = 0;
 326                go->repeat_seqhead = 0;
 327                go->seq_header_enable = 0;
 328                go->gop_header_enable = 0;
 329                go->dvd_mode = 0;
 330                break;
 331        }
 332        return 0;
 333}
 334
 335#if 0
 336static int clip_to_modet_map(struct go7007 *go, int region,
 337                struct v4l2_clip *clip_list)
 338{
 339        struct v4l2_clip clip, *clip_ptr;
 340        int x, y, mbnum;
 341
 342        /* Check if coordinates are OK and if any macroblocks are already
 343         * used by other regions (besides 0) */
 344        clip_ptr = clip_list;
 345        while (clip_ptr) {
 346                if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
 347                        return -EFAULT;
 348                if (clip.c.left < 0 || (clip.c.left & 0xF) ||
 349                                clip.c.width <= 0 || (clip.c.width & 0xF))
 350                        return -EINVAL;
 351                if (clip.c.left + clip.c.width > go->width)
 352                        return -EINVAL;
 353                if (clip.c.top < 0 || (clip.c.top & 0xF) ||
 354                                clip.c.height <= 0 || (clip.c.height & 0xF))
 355                        return -EINVAL;
 356                if (clip.c.top + clip.c.height > go->height)
 357                        return -EINVAL;
 358                for (y = 0; y < clip.c.height; y += 16)
 359                        for (x = 0; x < clip.c.width; x += 16) {
 360                                mbnum = (go->width >> 4) *
 361                                                ((clip.c.top + y) >> 4) +
 362                                        ((clip.c.left + x) >> 4);
 363                                if (go->modet_map[mbnum] != 0 &&
 364                                                go->modet_map[mbnum] != region)
 365                                        return -EBUSY;
 366                        }
 367                clip_ptr = clip.next;
 368        }
 369
 370        /* Clear old region macroblocks */
 371        for (mbnum = 0; mbnum < 1624; ++mbnum)
 372                if (go->modet_map[mbnum] == region)
 373                        go->modet_map[mbnum] = 0;
 374
 375        /* Claim macroblocks in this list */
 376        clip_ptr = clip_list;
 377        while (clip_ptr) {
 378                if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
 379                        return -EFAULT;
 380                for (y = 0; y < clip.c.height; y += 16)
 381                        for (x = 0; x < clip.c.width; x += 16) {
 382                                mbnum = (go->width >> 4) *
 383                                                ((clip.c.top + y) >> 4) +
 384                                        ((clip.c.left + x) >> 4);
 385                                go->modet_map[mbnum] = region;
 386                        }
 387                clip_ptr = clip.next;
 388        }
 389        return 0;
 390}
 391#endif
 392
 393static int mpeg_query_ctrl(struct v4l2_queryctrl *ctrl)
 394{
 395        static const u32 mpeg_ctrls[] = {
 396                V4L2_CID_MPEG_CLASS,
 397                V4L2_CID_MPEG_STREAM_TYPE,
 398                V4L2_CID_MPEG_VIDEO_ENCODING,
 399                V4L2_CID_MPEG_VIDEO_ASPECT,
 400                V4L2_CID_MPEG_VIDEO_GOP_SIZE,
 401                V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
 402                V4L2_CID_MPEG_VIDEO_BITRATE,
 403                0
 404        };
 405        static const u32 *ctrl_classes[] = {
 406                mpeg_ctrls,
 407                NULL
 408        };
 409
 410        ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
 411
 412        switch (ctrl->id) {
 413        case V4L2_CID_MPEG_CLASS:
 414                return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0);
 415        case V4L2_CID_MPEG_STREAM_TYPE:
 416                return v4l2_ctrl_query_fill(ctrl,
 417                                V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
 418                                V4L2_MPEG_STREAM_TYPE_MPEG_ELEM, 1,
 419                                V4L2_MPEG_STREAM_TYPE_MPEG_ELEM);
 420        case V4L2_CID_MPEG_VIDEO_ENCODING:
 421                return v4l2_ctrl_query_fill(ctrl,
 422                                V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
 423                                V4L2_MPEG_VIDEO_ENCODING_MPEG_4, 1,
 424                                V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
 425        case V4L2_CID_MPEG_VIDEO_ASPECT:
 426                return v4l2_ctrl_query_fill(ctrl,
 427                                V4L2_MPEG_VIDEO_ASPECT_1x1,
 428                                V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
 429                                V4L2_MPEG_VIDEO_ASPECT_1x1);
 430        case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
 431                return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15);
 432        case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
 433                return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
 434        case V4L2_CID_MPEG_VIDEO_BITRATE:
 435                return v4l2_ctrl_query_fill(ctrl,
 436                                64000,
 437                                10000000, 1,
 438                                1500000);
 439        default:
 440                return -EINVAL;
 441        }
 442        return 0;
 443}
 444
 445static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
 446{
 447        /* pretty sure we can't change any of these while streaming */
 448        if (go->streaming)
 449                return -EBUSY;
 450
 451        switch (ctrl->id) {
 452        case V4L2_CID_MPEG_STREAM_TYPE:
 453                switch (ctrl->value) {
 454                case V4L2_MPEG_STREAM_TYPE_MPEG2_DVD:
 455                        go->format = GO7007_FORMAT_MPEG2;
 456                        go->bitrate = 9800000;
 457                        go->gop_size = 15;
 458                        go->pali = 0x48;
 459                        go->closed_gop = 1;
 460                        go->repeat_seqhead = 0;
 461                        go->seq_header_enable = 1;
 462                        go->gop_header_enable = 1;
 463                        go->dvd_mode = 1;
 464                        break;
 465                case V4L2_MPEG_STREAM_TYPE_MPEG_ELEM:
 466                        /* todo: */
 467                        break;
 468                default:
 469                        return -EINVAL;
 470                }
 471                break;
 472        case V4L2_CID_MPEG_VIDEO_ENCODING:
 473                switch (ctrl->value) {
 474                case V4L2_MPEG_VIDEO_ENCODING_MPEG_1:
 475                        go->format = GO7007_FORMAT_MPEG1;
 476                        go->pali = 0;
 477                        break;
 478                case V4L2_MPEG_VIDEO_ENCODING_MPEG_2:
 479                        go->format = GO7007_FORMAT_MPEG2;
 480                        /*if (mpeg->pali >> 24 == 2)
 481                                go->pali = mpeg->pali & 0xff;
 482                        else*/
 483                                go->pali = 0x48;
 484                        break;
 485                case V4L2_MPEG_VIDEO_ENCODING_MPEG_4:
 486                        go->format = GO7007_FORMAT_MPEG4;
 487                        /*if (mpeg->pali >> 24 == 4)
 488                                go->pali = mpeg->pali & 0xff;
 489                        else*/
 490                                go->pali = 0xf5;
 491                        break;
 492                default:
 493                        return -EINVAL;
 494                }
 495                go->gop_header_enable =
 496                        /*mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
 497                        ? 0 :*/ 1;
 498                /*if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
 499                        go->repeat_seqhead = 1;
 500                else*/
 501                        go->repeat_seqhead = 0;
 502                go->dvd_mode = 0;
 503                break;
 504        case V4L2_CID_MPEG_VIDEO_ASPECT:
 505                if (go->format == GO7007_FORMAT_MJPEG)
 506                        return -EINVAL;
 507                switch (ctrl->value) {
 508                case V4L2_MPEG_VIDEO_ASPECT_1x1:
 509                        go->aspect_ratio = GO7007_RATIO_1_1;
 510                        break;
 511                case V4L2_MPEG_VIDEO_ASPECT_4x3:
 512                        go->aspect_ratio = GO7007_RATIO_4_3;
 513                        break;
 514                case V4L2_MPEG_VIDEO_ASPECT_16x9:
 515                        go->aspect_ratio = GO7007_RATIO_16_9;
 516                        break;
 517                case V4L2_MPEG_VIDEO_ASPECT_221x100:
 518                default:
 519                        return -EINVAL;
 520                }
 521                break;
 522        case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
 523                if (ctrl->value < 0 || ctrl->value > 34)
 524                        return -EINVAL;
 525                go->gop_size = ctrl->value;
 526                break;
 527        case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
 528                if (ctrl->value != 0 && ctrl->value != 1)
 529                        return -EINVAL;
 530                go->closed_gop = ctrl->value;
 531                break;
 532        case V4L2_CID_MPEG_VIDEO_BITRATE:
 533                /* Upper bound is kind of arbitrary here */
 534                if (ctrl->value < 64000 || ctrl->value > 10000000)
 535                        return -EINVAL;
 536                go->bitrate = ctrl->value;
 537                break;
 538        default:
 539                return -EINVAL;
 540        }
 541        return 0;
 542}
 543
 544static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
 545{
 546        switch (ctrl->id) {
 547        case V4L2_CID_MPEG_STREAM_TYPE:
 548                if (go->dvd_mode)
 549                        ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
 550                else
 551                        ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG_ELEM;
 552                break;
 553        case V4L2_CID_MPEG_VIDEO_ENCODING:
 554                switch (go->format) {
 555                case GO7007_FORMAT_MPEG1:
 556                        ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
 557                        break;
 558                case GO7007_FORMAT_MPEG2:
 559                        ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
 560                        break;
 561                case GO7007_FORMAT_MPEG4:
 562                        ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4;
 563                        break;
 564                default:
 565                        return -EINVAL;
 566                }
 567                break;
 568        case V4L2_CID_MPEG_VIDEO_ASPECT:
 569                switch (go->aspect_ratio) {
 570                case GO7007_RATIO_1_1:
 571                        ctrl->value = V4L2_MPEG_VIDEO_ASPECT_1x1;
 572                        break;
 573                case GO7007_RATIO_4_3:
 574                        ctrl->value = V4L2_MPEG_VIDEO_ASPECT_4x3;
 575                        break;
 576                case GO7007_RATIO_16_9:
 577                        ctrl->value = V4L2_MPEG_VIDEO_ASPECT_16x9;
 578                        break;
 579                default:
 580                        return -EINVAL;
 581                }
 582                break;
 583        case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
 584                ctrl->value = go->gop_size;
 585                break;
 586        case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
 587                ctrl->value = go->closed_gop;
 588                break;
 589        case V4L2_CID_MPEG_VIDEO_BITRATE:
 590                ctrl->value = go->bitrate;
 591                break;
 592        default:
 593                return -EINVAL;
 594        }
 595        return 0;
 596}
 597
 598static int vidioc_querycap(struct file *file, void  *priv,
 599                                        struct v4l2_capability *cap)
 600{
 601        struct go7007 *go = ((struct go7007_file *) priv)->go;
 602
 603        strlcpy(cap->driver, "go7007", sizeof(cap->driver));
 604        strlcpy(cap->card, go->name, sizeof(cap->card));
 605#if 0
 606        strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
 607#endif
 608
 609        cap->version = KERNEL_VERSION(0, 9, 8);
 610
 611        cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
 612                            V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
 613
 614        if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
 615                cap->capabilities |= V4L2_CAP_TUNER;
 616
 617        return 0;
 618}
 619
 620static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 621                                        struct v4l2_fmtdesc *fmt)
 622{
 623        char *desc = NULL;
 624
 625        switch (fmt->index) {
 626        case 0:
 627                fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
 628                desc = "Motion-JPEG";
 629                break;
 630        case 1:
 631                fmt->pixelformat = V4L2_PIX_FMT_MPEG;
 632                desc = "MPEG1/MPEG2/MPEG4";
 633                break;
 634        default:
 635                return -EINVAL;
 636        }
 637        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 638        fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
 639
 640        strncpy(fmt->description, desc, sizeof(fmt->description));
 641
 642        return 0;
 643}
 644
 645static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 646                                        struct v4l2_format *fmt)
 647{
 648        struct go7007 *go = ((struct go7007_file *) priv)->go;
 649
 650        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 651        fmt->fmt.pix.width = go->width;
 652        fmt->fmt.pix.height = go->height;
 653        fmt->fmt.pix.pixelformat = (go->format == GO7007_FORMAT_MJPEG) ?
 654                                   V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
 655        fmt->fmt.pix.field = V4L2_FIELD_NONE;
 656        fmt->fmt.pix.bytesperline = 0;
 657        fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
 658        fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 659
 660        return 0;
 661}
 662
 663static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 664                        struct v4l2_format *fmt)
 665{
 666        struct go7007 *go = ((struct go7007_file *) priv)->go;
 667
 668        return set_capture_size(go, fmt, 1);
 669}
 670
 671static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 672                        struct v4l2_format *fmt)
 673{
 674        struct go7007 *go = ((struct go7007_file *) priv)->go;
 675
 676        if (go->streaming)
 677                return -EBUSY;
 678
 679        return set_capture_size(go, fmt, 0);
 680}
 681
 682static int vidioc_reqbufs(struct file *file, void *priv,
 683                          struct v4l2_requestbuffers *req)
 684{
 685        struct go7007_file *gofh = priv;
 686        struct go7007 *go = gofh->go;
 687        int retval = -EBUSY;
 688        unsigned int count, i;
 689
 690        if (go->streaming)
 691                return retval;
 692
 693        if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
 694                        req->memory != V4L2_MEMORY_MMAP)
 695                return -EINVAL;
 696
 697        mutex_lock(&gofh->lock);
 698        for (i = 0; i < gofh->buf_count; ++i)
 699                if (gofh->bufs[i].mapped > 0)
 700                        goto unlock_and_return;
 701
 702        mutex_lock(&go->hw_lock);
 703        if (go->in_use > 0 && gofh->buf_count == 0) {
 704                mutex_unlock(&go->hw_lock);
 705                goto unlock_and_return;
 706        }
 707
 708        if (gofh->buf_count > 0)
 709                kfree(gofh->bufs);
 710
 711        retval = -ENOMEM;
 712        count = req->count;
 713        if (count > 0) {
 714                if (count < 2)
 715                        count = 2;
 716                if (count > 32)
 717                        count = 32;
 718
 719                gofh->bufs = kcalloc(count, sizeof(struct go7007_buffer),
 720                                     GFP_KERNEL);
 721
 722                if (!gofh->bufs) {
 723                        mutex_unlock(&go->hw_lock);
 724                        goto unlock_and_return;
 725                }
 726
 727                for (i = 0; i < count; ++i) {
 728                        gofh->bufs[i].go = go;
 729                        gofh->bufs[i].index = i;
 730                        gofh->bufs[i].state = BUF_STATE_IDLE;
 731                        gofh->bufs[i].mapped = 0;
 732                }
 733
 734                go->in_use = 1;
 735        } else {
 736                go->in_use = 0;
 737        }
 738
 739        gofh->buf_count = count;
 740        mutex_unlock(&go->hw_lock);
 741        mutex_unlock(&gofh->lock);
 742
 743        memset(req, 0, sizeof(*req));
 744
 745        req->count = count;
 746        req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 747        req->memory = V4L2_MEMORY_MMAP;
 748
 749        return 0;
 750
 751unlock_and_return:
 752        mutex_unlock(&gofh->lock);
 753        return retval;
 754}
 755
 756static int vidioc_querybuf(struct file *file, void *priv,
 757                           struct v4l2_buffer *buf)
 758{
 759        struct go7007_file *gofh = priv;
 760        int retval = -EINVAL;
 761        unsigned int index;
 762
 763        if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 764                return retval;
 765
 766        index = buf->index;
 767
 768        mutex_lock(&gofh->lock);
 769        if (index >= gofh->buf_count)
 770                goto unlock_and_return;
 771
 772        memset(buf, 0, sizeof(*buf));
 773        buf->index = index;
 774        buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 775
 776        switch (gofh->bufs[index].state) {
 777        case BUF_STATE_QUEUED:
 778                buf->flags = V4L2_BUF_FLAG_QUEUED;
 779                break;
 780        case BUF_STATE_DONE:
 781                buf->flags = V4L2_BUF_FLAG_DONE;
 782                break;
 783        default:
 784                buf->flags = 0;
 785        }
 786
 787        if (gofh->bufs[index].mapped)
 788                buf->flags |= V4L2_BUF_FLAG_MAPPED;
 789        buf->memory = V4L2_MEMORY_MMAP;
 790        buf->m.offset = index * GO7007_BUF_SIZE;
 791        buf->length = GO7007_BUF_SIZE;
 792        mutex_unlock(&gofh->lock);
 793
 794        return 0;
 795
 796unlock_and_return:
 797        mutex_unlock(&gofh->lock);
 798        return retval;
 799}
 800
 801static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 802{
 803        struct go7007_file *gofh = priv;
 804        struct go7007 *go = gofh->go;
 805        struct go7007_buffer *gobuf;
 806        unsigned long flags;
 807        int retval = -EINVAL;
 808        int ret;
 809
 810        if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
 811                        buf->memory != V4L2_MEMORY_MMAP)
 812                return retval;
 813
 814        mutex_lock(&gofh->lock);
 815        if (buf->index >= gofh->buf_count)
 816                goto unlock_and_return;
 817
 818        gobuf = &gofh->bufs[buf->index];
 819        if (!gobuf->mapped)
 820                goto unlock_and_return;
 821
 822        retval = -EBUSY;
 823        if (gobuf->state != BUF_STATE_IDLE)
 824                goto unlock_and_return;
 825
 826        /* offset will be 0 until we really support USERPTR streaming */
 827        gobuf->offset = gobuf->user_addr & ~PAGE_MASK;
 828        gobuf->bytesused = 0;
 829        gobuf->frame_offset = 0;
 830        gobuf->modet_active = 0;
 831        if (gobuf->offset > 0)
 832                gobuf->page_count = GO7007_BUF_PAGES + 1;
 833        else
 834                gobuf->page_count = GO7007_BUF_PAGES;
 835
 836        retval = -ENOMEM;
 837        down_read(&current->mm->mmap_sem);
 838        ret = get_user_pages(current, current->mm,
 839                        gobuf->user_addr & PAGE_MASK, gobuf->page_count,
 840                        1, 1, gobuf->pages, NULL);
 841        up_read(&current->mm->mmap_sem);
 842
 843        if (ret != gobuf->page_count) {
 844                int i;
 845                for (i = 0; i < ret; ++i)
 846                        page_cache_release(gobuf->pages[i]);
 847                gobuf->page_count = 0;
 848                goto unlock_and_return;
 849        }
 850
 851        gobuf->state = BUF_STATE_QUEUED;
 852        spin_lock_irqsave(&go->spinlock, flags);
 853        list_add_tail(&gobuf->stream, &go->stream);
 854        spin_unlock_irqrestore(&go->spinlock, flags);
 855        mutex_unlock(&gofh->lock);
 856
 857        return 0;
 858
 859unlock_and_return:
 860        mutex_unlock(&gofh->lock);
 861        return retval;
 862}
 863
 864
 865static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 866{
 867        struct go7007_file *gofh = priv;
 868        struct go7007 *go = gofh->go;
 869        struct go7007_buffer *gobuf;
 870        int retval = -EINVAL;
 871        unsigned long flags;
 872        u32 frame_type_flag;
 873        DEFINE_WAIT(wait);
 874
 875        if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 876                return retval;
 877        if (buf->memory != V4L2_MEMORY_MMAP)
 878                return retval;
 879
 880        mutex_lock(&gofh->lock);
 881        if (list_empty(&go->stream))
 882                goto unlock_and_return;
 883        gobuf = list_entry(go->stream.next,
 884                        struct go7007_buffer, stream);
 885
 886        retval = -EAGAIN;
 887        if (gobuf->state != BUF_STATE_DONE &&
 888                        !(file->f_flags & O_NONBLOCK)) {
 889                for (;;) {
 890                        prepare_to_wait(&go->frame_waitq, &wait,
 891                                        TASK_INTERRUPTIBLE);
 892                        if (gobuf->state == BUF_STATE_DONE)
 893                                break;
 894                        if (signal_pending(current)) {
 895                                retval = -ERESTARTSYS;
 896                                break;
 897                        }
 898                        schedule();
 899                }
 900                finish_wait(&go->frame_waitq, &wait);
 901        }
 902        if (gobuf->state != BUF_STATE_DONE)
 903                goto unlock_and_return;
 904
 905        spin_lock_irqsave(&go->spinlock, flags);
 906        deactivate_buffer(gobuf);
 907        spin_unlock_irqrestore(&go->spinlock, flags);
 908        frame_type_flag = get_frame_type_flag(gobuf, go->format);
 909        gobuf->state = BUF_STATE_IDLE;
 910
 911        memset(buf, 0, sizeof(*buf));
 912        buf->index = gobuf->index;
 913        buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 914        buf->bytesused = gobuf->bytesused;
 915        buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag;
 916        buf->field = V4L2_FIELD_NONE;
 917        buf->timestamp = gobuf->timestamp;
 918        buf->sequence = gobuf->seq;
 919        buf->memory = V4L2_MEMORY_MMAP;
 920        buf->m.offset = gobuf->index * GO7007_BUF_SIZE;
 921        buf->length = GO7007_BUF_SIZE;
 922        buf->reserved = gobuf->modet_active;
 923
 924        mutex_unlock(&gofh->lock);
 925        return 0;
 926
 927unlock_and_return:
 928        mutex_unlock(&gofh->lock);
 929        return retval;
 930}
 931
 932static int vidioc_streamon(struct file *file, void *priv,
 933                                        enum v4l2_buf_type type)
 934{
 935        struct go7007_file *gofh = priv;
 936        struct go7007 *go = gofh->go;
 937        int retval = 0;
 938
 939        if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 940                return -EINVAL;
 941
 942        mutex_lock(&gofh->lock);
 943        mutex_lock(&go->hw_lock);
 944
 945        if (!go->streaming) {
 946                go->streaming = 1;
 947                go->next_seq = 0;
 948                go->active_buf = NULL;
 949                if (go7007_start_encoder(go) < 0)
 950                        retval = -EIO;
 951                else
 952                        retval = 0;
 953        }
 954        mutex_unlock(&go->hw_lock);
 955        mutex_unlock(&gofh->lock);
 956        call_all(&go->v4l2_dev, video, s_stream, 1);
 957
 958        return retval;
 959}
 960
 961static int vidioc_streamoff(struct file *file, void *priv,
 962                                        enum v4l2_buf_type type)
 963{
 964        struct go7007_file *gofh = priv;
 965        struct go7007 *go = gofh->go;
 966
 967        if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 968                return -EINVAL;
 969        mutex_lock(&gofh->lock);
 970        go7007_streamoff(go);
 971        mutex_unlock(&gofh->lock);
 972        call_all(&go->v4l2_dev, video, s_stream, 0);
 973
 974        return 0;
 975}
 976
 977static int vidioc_queryctrl(struct file *file, void *priv,
 978                           struct v4l2_queryctrl *query)
 979{
 980        struct go7007 *go = ((struct go7007_file *) priv)->go;
 981        int id = query->id;
 982
 983        if (0 == call_all(&go->v4l2_dev, core, queryctrl, query))
 984                return 0;
 985
 986        query->id = id;
 987        return mpeg_query_ctrl(query);
 988}
 989
 990static int vidioc_g_ctrl(struct file *file, void *priv,
 991                                struct v4l2_control *ctrl)
 992{
 993        struct go7007 *go = ((struct go7007_file *) priv)->go;
 994
 995        if (0 == call_all(&go->v4l2_dev, core, g_ctrl, ctrl))
 996                return 0;
 997
 998        return mpeg_g_ctrl(ctrl, go);
 999}
1000
1001static int vidioc_s_ctrl(struct file *file, void *priv,
1002                                struct v4l2_control *ctrl)
1003{
1004        struct go7007 *go = ((struct go7007_file *) priv)->go;
1005
1006        if (0 == call_all(&go->v4l2_dev, core, s_ctrl, ctrl))
1007                return 0;
1008
1009        return mpeg_s_ctrl(ctrl, go);
1010}
1011
1012static int vidioc_g_parm(struct file *filp, void *priv,
1013                struct v4l2_streamparm *parm)
1014{
1015        struct go7007 *go = ((struct go7007_file *) priv)->go;
1016        struct v4l2_fract timeperframe = {
1017                .numerator = 1001 *  go->fps_scale,
1018                .denominator = go->sensor_framerate,
1019        };
1020
1021        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1022                return -EINVAL;
1023
1024        parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
1025        parm->parm.capture.timeperframe = timeperframe;
1026
1027        return 0;
1028}
1029
1030static int vidioc_s_parm(struct file *filp, void *priv,
1031                struct v4l2_streamparm *parm)
1032{
1033        struct go7007 *go = ((struct go7007_file *) priv)->go;
1034        unsigned int n, d;
1035
1036        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1037                return -EINVAL;
1038        if (parm->parm.capture.capturemode != 0)
1039                return -EINVAL;
1040
1041        n = go->sensor_framerate *
1042                parm->parm.capture.timeperframe.numerator;
1043        d = 1001 * parm->parm.capture.timeperframe.denominator;
1044        if (n != 0 && d != 0 && n > d)
1045                go->fps_scale = (n + d/2) / d;
1046        else
1047                go->fps_scale = 1;
1048
1049        return 0;
1050}
1051
1052/* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
1053   its resolution, when the device is not connected to TV.
1054   This is were an API abuse, probably used by the lack of specific IOCTL's to
1055   enumerate it, by the time the driver was written.
1056
1057   However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
1058   and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
1059
1060   The two functions below implement the newer ioctls
1061*/
1062static int vidioc_enum_framesizes(struct file *filp, void *priv,
1063                                  struct v4l2_frmsizeenum *fsize)
1064{
1065        struct go7007 *go = ((struct go7007_file *) priv)->go;
1066
1067        /* Return -EINVAL, if it is a TV board */
1068        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1069            (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1070                return -EINVAL;
1071
1072        if (fsize->index > 0)
1073                return -EINVAL;
1074
1075        fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1076        fsize->discrete.width = go->board_info->sensor_width;
1077        fsize->discrete.height = go->board_info->sensor_height;
1078
1079        return 0;
1080}
1081
1082static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1083                                      struct v4l2_frmivalenum *fival)
1084{
1085        struct go7007 *go = ((struct go7007_file *) priv)->go;
1086
1087        /* Return -EINVAL, if it is a TV board */
1088        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1089            (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1090                return -EINVAL;
1091
1092        if (fival->index > 0)
1093                return -EINVAL;
1094
1095        fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1096        fival->discrete.numerator = 1001;
1097        fival->discrete.denominator = go->board_info->sensor_framerate;
1098
1099        return 0;
1100}
1101
1102static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
1103{
1104        struct go7007 *go = ((struct go7007_file *) priv)->go;
1105
1106        switch (go->standard) {
1107        case GO7007_STD_NTSC:
1108                *std = V4L2_STD_NTSC;
1109                break;
1110        case GO7007_STD_PAL:
1111                *std = V4L2_STD_PAL;
1112                break;
1113        default:
1114                return -EINVAL;
1115        }
1116
1117        return 0;
1118}
1119
1120static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1121{
1122        struct go7007 *go = ((struct go7007_file *) priv)->go;
1123
1124        if (go->streaming)
1125                return -EBUSY;
1126
1127        if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && *std != 0)
1128                return -EINVAL;
1129
1130        if (*std == 0)
1131                return -EINVAL;
1132
1133        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1134                        go->input == go->board_info->num_inputs - 1) {
1135                if (!go->i2c_adapter_online)
1136                        return -EIO;
1137                if (call_all(&go->v4l2_dev, core, s_std, *std) < 0)
1138                        return -EINVAL;
1139        }
1140
1141        if (*std & V4L2_STD_NTSC) {
1142                go->standard = GO7007_STD_NTSC;
1143                go->sensor_framerate = 30000;
1144        } else if (*std & V4L2_STD_PAL) {
1145                go->standard = GO7007_STD_PAL;
1146                go->sensor_framerate = 25025;
1147        } else if (*std & V4L2_STD_SECAM) {
1148                go->standard = GO7007_STD_PAL;
1149                go->sensor_framerate = 25025;
1150        } else
1151                return -EINVAL;
1152
1153        call_all(&go->v4l2_dev, core, s_std, *std);
1154        set_capture_size(go, NULL, 0);
1155
1156        return 0;
1157}
1158
1159static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
1160{
1161        struct go7007 *go = ((struct go7007_file *) priv)->go;
1162
1163        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1164                        go->input == go->board_info->num_inputs - 1) {
1165                if (!go->i2c_adapter_online)
1166                        return -EIO;
1167                return call_all(&go->v4l2_dev, video, querystd, std);
1168        } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1169                *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1170        else
1171                *std = 0;
1172
1173        return 0;
1174}
1175
1176static int vidioc_enum_input(struct file *file, void *priv,
1177                                struct v4l2_input *inp)
1178{
1179        struct go7007 *go = ((struct go7007_file *) priv)->go;
1180
1181        if (inp->index >= go->board_info->num_inputs)
1182                return -EINVAL;
1183
1184        strncpy(inp->name, go->board_info->inputs[inp->index].name,
1185                        sizeof(inp->name));
1186
1187        /* If this board has a tuner, it will be the last input */
1188        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1189                        inp->index == go->board_info->num_inputs - 1)
1190                inp->type = V4L2_INPUT_TYPE_TUNER;
1191        else
1192                inp->type = V4L2_INPUT_TYPE_CAMERA;
1193
1194        inp->audioset = 0;
1195        inp->tuner = 0;
1196        if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1197                inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
1198                                                V4L2_STD_SECAM;
1199        else
1200                inp->std = 0;
1201
1202        return 0;
1203}
1204
1205
1206static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1207{
1208        struct go7007 *go = ((struct go7007_file *) priv)->go;
1209
1210        *input = go->input;
1211
1212        return 0;
1213}
1214
1215static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1216{
1217        struct go7007 *go = ((struct go7007_file *) priv)->go;
1218
1219        if (input >= go->board_info->num_inputs)
1220                return -EINVAL;
1221        if (go->streaming)
1222                return -EBUSY;
1223
1224        go->input = input;
1225
1226        return call_all(&go->v4l2_dev, video, s_routing, input, 0, 0);
1227}
1228
1229static int vidioc_g_tuner(struct file *file, void *priv,
1230                                struct v4l2_tuner *t)
1231{
1232        struct go7007 *go = ((struct go7007_file *) priv)->go;
1233
1234        if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1235                return -EINVAL;
1236        if (t->index != 0)
1237                return -EINVAL;
1238        if (!go->i2c_adapter_online)
1239                return -EIO;
1240
1241        return call_all(&go->v4l2_dev, tuner, g_tuner, t);
1242}
1243
1244static int vidioc_s_tuner(struct file *file, void *priv,
1245                                struct v4l2_tuner *t)
1246{
1247        struct go7007 *go = ((struct go7007_file *) priv)->go;
1248
1249        if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1250                return -EINVAL;
1251        if (t->index != 0)
1252                return -EINVAL;
1253        if (!go->i2c_adapter_online)
1254                return -EIO;
1255
1256        switch (go->board_id) {
1257        case GO7007_BOARDID_PX_TV402U_NA:
1258        case GO7007_BOARDID_PX_TV402U_JP:
1259                /* No selectable options currently */
1260                if (t->audmode != V4L2_TUNER_MODE_STEREO)
1261                        return -EINVAL;
1262                break;
1263        }
1264
1265        return call_all(&go->v4l2_dev, tuner, s_tuner, t);
1266}
1267
1268static int vidioc_g_frequency(struct file *file, void *priv,
1269                                struct v4l2_frequency *f)
1270{
1271        struct go7007 *go = ((struct go7007_file *) priv)->go;
1272
1273        if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1274                return -EINVAL;
1275        if (!go->i2c_adapter_online)
1276                return -EIO;
1277
1278        f->type = V4L2_TUNER_ANALOG_TV;
1279
1280        return call_all(&go->v4l2_dev, tuner, g_frequency, f);
1281}
1282
1283static int vidioc_s_frequency(struct file *file, void *priv,
1284                                struct v4l2_frequency *f)
1285{
1286        struct go7007 *go = ((struct go7007_file *) priv)->go;
1287
1288        if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1289                return -EINVAL;
1290        if (!go->i2c_adapter_online)
1291                return -EIO;
1292
1293        return call_all(&go->v4l2_dev, tuner, s_frequency, f);
1294}
1295
1296static int vidioc_cropcap(struct file *file, void *priv,
1297                                        struct v4l2_cropcap *cropcap)
1298{
1299        struct go7007 *go = ((struct go7007_file *) priv)->go;
1300
1301        if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1302                return -EINVAL;
1303
1304        /* These specify the raw input of the sensor */
1305        switch (go->standard) {
1306        case GO7007_STD_NTSC:
1307                cropcap->bounds.top = 0;
1308                cropcap->bounds.left = 0;
1309                cropcap->bounds.width = 720;
1310                cropcap->bounds.height = 480;
1311                cropcap->defrect.top = 0;
1312                cropcap->defrect.left = 0;
1313                cropcap->defrect.width = 720;
1314                cropcap->defrect.height = 480;
1315                break;
1316        case GO7007_STD_PAL:
1317                cropcap->bounds.top = 0;
1318                cropcap->bounds.left = 0;
1319                cropcap->bounds.width = 720;
1320                cropcap->bounds.height = 576;
1321                cropcap->defrect.top = 0;
1322                cropcap->defrect.left = 0;
1323                cropcap->defrect.width = 720;
1324                cropcap->defrect.height = 576;
1325                break;
1326        case GO7007_STD_OTHER:
1327                cropcap->bounds.top = 0;
1328                cropcap->bounds.left = 0;
1329                cropcap->bounds.width = go->board_info->sensor_width;
1330                cropcap->bounds.height = go->board_info->sensor_height;
1331                cropcap->defrect.top = 0;
1332                cropcap->defrect.left = 0;
1333                cropcap->defrect.width = go->board_info->sensor_width;
1334                cropcap->defrect.height = go->board_info->sensor_height;
1335                break;
1336        }
1337
1338        return 0;
1339}
1340
1341static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1342{
1343        struct go7007 *go = ((struct go7007_file *) priv)->go;
1344
1345        if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1346                return -EINVAL;
1347
1348        crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1349
1350        /* These specify the raw input of the sensor */
1351        switch (go->standard) {
1352        case GO7007_STD_NTSC:
1353                crop->c.top = 0;
1354                crop->c.left = 0;
1355                crop->c.width = 720;
1356                crop->c.height = 480;
1357                break;
1358        case GO7007_STD_PAL:
1359                crop->c.top = 0;
1360                crop->c.left = 0;
1361                crop->c.width = 720;
1362                crop->c.height = 576;
1363                break;
1364        case GO7007_STD_OTHER:
1365                crop->c.top = 0;
1366                crop->c.left = 0;
1367                crop->c.width = go->board_info->sensor_width;
1368                crop->c.height = go->board_info->sensor_height;
1369                break;
1370        }
1371
1372        return 0;
1373}
1374
1375/* FIXME: vidioc_s_crop is not really implemented!!!
1376 */
1377static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop)
1378{
1379        if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1380                return -EINVAL;
1381
1382        return 0;
1383}
1384
1385static int vidioc_g_jpegcomp(struct file *file, void *priv,
1386                         struct v4l2_jpegcompression *params)
1387{
1388        memset(params, 0, sizeof(*params));
1389        params->quality = 50; /* ?? */
1390        params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
1391                                V4L2_JPEG_MARKER_DQT;
1392
1393        return 0;
1394}
1395
1396static int vidioc_s_jpegcomp(struct file *file, void *priv,
1397                         const struct v4l2_jpegcompression *params)
1398{
1399        if (params->quality != 50 ||
1400                        params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
1401                                                V4L2_JPEG_MARKER_DQT))
1402                return -EINVAL;
1403
1404        return 0;
1405}
1406
1407/* FIXME:
1408        Those ioctls are private, and not needed, since several standard
1409        extended controls already provide streaming control.
1410        So, those ioctls should be converted into vidioc_g_ext_ctrls()
1411        and vidioc_s_ext_ctrls()
1412 */
1413
1414#if 0
1415        /* Temporary ioctls for controlling compression characteristics */
1416        case GO7007IOC_S_BITRATE:
1417        {
1418                int *bitrate = arg;
1419
1420                if (go->streaming)
1421                        return -EINVAL;
1422                /* Upper bound is kind of arbitrary here */
1423                if (*bitrate < 64000 || *bitrate > 10000000)
1424                        return -EINVAL;
1425                go->bitrate = *bitrate;
1426                return 0;
1427        }
1428        case GO7007IOC_G_BITRATE:
1429        {
1430                int *bitrate = arg;
1431
1432                *bitrate = go->bitrate;
1433                return 0;
1434        }
1435        case GO7007IOC_S_COMP_PARAMS:
1436        {
1437                struct go7007_comp_params *comp = arg;
1438
1439                if (go->format == GO7007_FORMAT_MJPEG)
1440                        return -EINVAL;
1441                if (comp->gop_size > 0)
1442                        go->gop_size = comp->gop_size;
1443                else
1444                        go->gop_size = go->sensor_framerate / 1000;
1445                if (go->gop_size != 15)
1446                        go->dvd_mode = 0;
1447                /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
1448                if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
1449                        switch (comp->aspect_ratio) {
1450                        case GO7007_ASPECT_RATIO_4_3_NTSC:
1451                        case GO7007_ASPECT_RATIO_4_3_PAL:
1452                                go->aspect_ratio = GO7007_RATIO_4_3;
1453                                break;
1454                        case GO7007_ASPECT_RATIO_16_9_NTSC:
1455                        case GO7007_ASPECT_RATIO_16_9_PAL:
1456                                go->aspect_ratio = GO7007_RATIO_16_9;
1457                                break;
1458                        default:
1459                                go->aspect_ratio = GO7007_RATIO_1_1;
1460                                break;
1461                        }
1462                }
1463                if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
1464                        go->dvd_mode = 0;
1465                        go->seq_header_enable = 0;
1466                } else {
1467                        go->seq_header_enable = 1;
1468                }
1469                /* fall-through */
1470        }
1471        case GO7007IOC_G_COMP_PARAMS:
1472        {
1473                struct go7007_comp_params *comp = arg;
1474
1475                if (go->format == GO7007_FORMAT_MJPEG)
1476                        return -EINVAL;
1477                memset(comp, 0, sizeof(*comp));
1478                comp->gop_size = go->gop_size;
1479                comp->max_b_frames = go->ipb ? 2 : 0;
1480                switch (go->aspect_ratio) {
1481                case GO7007_RATIO_4_3:
1482                        if (go->standard == GO7007_STD_NTSC)
1483                                comp->aspect_ratio =
1484                                        GO7007_ASPECT_RATIO_4_3_NTSC;
1485                        else
1486                                comp->aspect_ratio =
1487                                        GO7007_ASPECT_RATIO_4_3_PAL;
1488                        break;
1489                case GO7007_RATIO_16_9:
1490                        if (go->standard == GO7007_STD_NTSC)
1491                                comp->aspect_ratio =
1492                                        GO7007_ASPECT_RATIO_16_9_NTSC;
1493                        else
1494                                comp->aspect_ratio =
1495                                        GO7007_ASPECT_RATIO_16_9_PAL;
1496                        break;
1497                default:
1498                        comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
1499                        break;
1500                }
1501                if (go->closed_gop)
1502                        comp->flags |= GO7007_COMP_CLOSED_GOP;
1503                if (!go->seq_header_enable)
1504                        comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
1505                return 0;
1506        }
1507        case GO7007IOC_S_MPEG_PARAMS:
1508        {
1509                struct go7007_mpeg_params *mpeg = arg;
1510
1511                if (go->format != GO7007_FORMAT_MPEG1 &&
1512                                go->format != GO7007_FORMAT_MPEG2 &&
1513                                go->format != GO7007_FORMAT_MPEG4)
1514                        return -EINVAL;
1515
1516                if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
1517                        go->format = GO7007_FORMAT_MPEG2;
1518                        go->bitrate = 9800000;
1519                        go->gop_size = 15;
1520                        go->pali = 0x48;
1521                        go->closed_gop = 1;
1522                        go->repeat_seqhead = 0;
1523                        go->seq_header_enable = 1;
1524                        go->gop_header_enable = 1;
1525                        go->dvd_mode = 1;
1526                } else {
1527                        switch (mpeg->mpeg_video_standard) {
1528                        case GO7007_MPEG_VIDEO_MPEG1:
1529                                go->format = GO7007_FORMAT_MPEG1;
1530                                go->pali = 0;
1531                                break;
1532                        case GO7007_MPEG_VIDEO_MPEG2:
1533                                go->format = GO7007_FORMAT_MPEG2;
1534                                if (mpeg->pali >> 24 == 2)
1535                                        go->pali = mpeg->pali & 0xff;
1536                                else
1537                                        go->pali = 0x48;
1538                                break;
1539                        case GO7007_MPEG_VIDEO_MPEG4:
1540                                go->format = GO7007_FORMAT_MPEG4;
1541                                if (mpeg->pali >> 24 == 4)
1542                                        go->pali = mpeg->pali & 0xff;
1543                                else
1544                                        go->pali = 0xf5;
1545                                break;
1546                        default:
1547                                return -EINVAL;
1548                        }
1549                        go->gop_header_enable =
1550                                mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
1551                                ? 0 : 1;
1552                        if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
1553                                go->repeat_seqhead = 1;
1554                        else
1555                                go->repeat_seqhead = 0;
1556                        go->dvd_mode = 0;
1557                }
1558                /* fall-through */
1559        }
1560        case GO7007IOC_G_MPEG_PARAMS:
1561        {
1562                struct go7007_mpeg_params *mpeg = arg;
1563
1564                memset(mpeg, 0, sizeof(*mpeg));
1565                switch (go->format) {
1566                case GO7007_FORMAT_MPEG1:
1567                        mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
1568                        mpeg->pali = 0;
1569                        break;
1570                case GO7007_FORMAT_MPEG2:
1571                        mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
1572                        mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
1573                        break;
1574                case GO7007_FORMAT_MPEG4:
1575                        mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
1576                        mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
1577                        break;
1578                default:
1579                        return -EINVAL;
1580                }
1581                if (!go->gop_header_enable)
1582                        mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
1583                if (go->repeat_seqhead)
1584                        mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
1585                if (go->dvd_mode)
1586                        mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
1587                return 0;
1588        }
1589        case GO7007IOC_S_MD_PARAMS:
1590        {
1591                struct go7007_md_params *mdp = arg;
1592
1593                if (mdp->region > 3)
1594                        return -EINVAL;
1595                if (mdp->trigger > 0) {
1596                        go->modet[mdp->region].pixel_threshold =
1597                                        mdp->pixel_threshold >> 1;
1598                        go->modet[mdp->region].motion_threshold =
1599                                        mdp->motion_threshold >> 1;
1600                        go->modet[mdp->region].mb_threshold =
1601                                        mdp->trigger >> 1;
1602                        go->modet[mdp->region].enable = 1;
1603                } else
1604                        go->modet[mdp->region].enable = 0;
1605                /* fall-through */
1606        }
1607        case GO7007IOC_G_MD_PARAMS:
1608        {
1609                struct go7007_md_params *mdp = arg;
1610                int region = mdp->region;
1611
1612                if (mdp->region > 3)
1613                        return -EINVAL;
1614                memset(mdp, 0, sizeof(struct go7007_md_params));
1615                mdp->region = region;
1616                if (!go->modet[region].enable)
1617                        return 0;
1618                mdp->pixel_threshold =
1619                        (go->modet[region].pixel_threshold << 1) + 1;
1620                mdp->motion_threshold =
1621                        (go->modet[region].motion_threshold << 1) + 1;
1622                mdp->trigger =
1623                        (go->modet[region].mb_threshold << 1) + 1;
1624                return 0;
1625        }
1626        case GO7007IOC_S_MD_REGION:
1627        {
1628                struct go7007_md_region *region = arg;
1629
1630                if (region->region < 1 || region->region > 3)
1631                        return -EINVAL;
1632                return clip_to_modet_map(go, region->region, region->clips);
1633        }
1634#endif
1635
1636static ssize_t go7007_read(struct file *file, char __user *data,
1637                size_t count, loff_t *ppos)
1638{
1639        return -EINVAL;
1640}
1641
1642static void go7007_vm_open(struct vm_area_struct *vma)
1643{
1644        struct go7007_buffer *gobuf = vma->vm_private_data;
1645
1646        ++gobuf->mapped;
1647}
1648
1649static void go7007_vm_close(struct vm_area_struct *vma)
1650{
1651        struct go7007_buffer *gobuf = vma->vm_private_data;
1652        unsigned long flags;
1653
1654        if (--gobuf->mapped == 0) {
1655                spin_lock_irqsave(&gobuf->go->spinlock, flags);
1656                deactivate_buffer(gobuf);
1657                spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
1658        }
1659}
1660
1661/* Copied from videobuf-dma-sg.c */
1662static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1663{
1664        struct page *page;
1665
1666        page = alloc_page(GFP_USER | __GFP_DMA32);
1667        if (!page)
1668                return VM_FAULT_OOM;
1669        clear_user_highpage(page, (unsigned long)vmf->virtual_address);
1670        vmf->page = page;
1671        return 0;
1672}
1673
1674static struct vm_operations_struct go7007_vm_ops = {
1675        .open   = go7007_vm_open,
1676        .close  = go7007_vm_close,
1677        .fault  = go7007_vm_fault,
1678};
1679
1680static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1681{
1682        struct go7007_file *gofh = file->private_data;
1683        unsigned int index;
1684
1685        if (gofh->go->status != STATUS_ONLINE)
1686                return -EIO;
1687        if (!(vma->vm_flags & VM_SHARED))
1688                return -EINVAL; /* only support VM_SHARED mapping */
1689        if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1690                return -EINVAL; /* must map exactly one full buffer */
1691        mutex_lock(&gofh->lock);
1692        index = vma->vm_pgoff / GO7007_BUF_PAGES;
1693        if (index >= gofh->buf_count) {
1694                mutex_unlock(&gofh->lock);
1695                return -EINVAL; /* trying to map beyond requested buffers */
1696        }
1697        if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1698                mutex_unlock(&gofh->lock);
1699                return -EINVAL; /* offset is not aligned on buffer boundary */
1700        }
1701        if (gofh->bufs[index].mapped > 0) {
1702                mutex_unlock(&gofh->lock);
1703                return -EBUSY;
1704        }
1705        gofh->bufs[index].mapped = 1;
1706        gofh->bufs[index].user_addr = vma->vm_start;
1707        vma->vm_ops = &go7007_vm_ops;
1708        vma->vm_flags |= VM_DONTEXPAND;
1709        vma->vm_flags &= ~VM_IO;
1710        vma->vm_private_data = &gofh->bufs[index];
1711        mutex_unlock(&gofh->lock);
1712        return 0;
1713}
1714
1715static unsigned int go7007_poll(struct file *file, poll_table *wait)
1716{
1717        struct go7007_file *gofh = file->private_data;
1718        struct go7007_buffer *gobuf;
1719
1720        if (list_empty(&gofh->go->stream))
1721                return POLLERR;
1722        gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
1723        poll_wait(file, &gofh->go->frame_waitq, wait);
1724        if (gobuf->state == BUF_STATE_DONE)
1725                return POLLIN | POLLRDNORM;
1726        return 0;
1727}
1728
1729static void go7007_vfl_release(struct video_device *vfd)
1730{
1731        struct go7007 *go = video_get_drvdata(vfd);
1732
1733        video_device_release(vfd);
1734        if (--go->ref_count == 0)
1735                kfree(go);
1736}
1737
1738static struct v4l2_file_operations go7007_fops = {
1739        .owner          = THIS_MODULE,
1740        .open           = go7007_open,
1741        .release        = go7007_release,
1742        .ioctl          = video_ioctl2,
1743        .read           = go7007_read,
1744        .mmap           = go7007_mmap,
1745        .poll           = go7007_poll,
1746};
1747
1748static const struct v4l2_ioctl_ops video_ioctl_ops = {
1749        .vidioc_querycap          = vidioc_querycap,
1750        .vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
1751        .vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
1752        .vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
1753        .vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
1754        .vidioc_reqbufs           = vidioc_reqbufs,
1755        .vidioc_querybuf          = vidioc_querybuf,
1756        .vidioc_qbuf              = vidioc_qbuf,
1757        .vidioc_dqbuf             = vidioc_dqbuf,
1758        .vidioc_g_std             = vidioc_g_std,
1759        .vidioc_s_std             = vidioc_s_std,
1760        .vidioc_querystd          = vidioc_querystd,
1761        .vidioc_enum_input        = vidioc_enum_input,
1762        .vidioc_g_input           = vidioc_g_input,
1763        .vidioc_s_input           = vidioc_s_input,
1764        .vidioc_queryctrl         = vidioc_queryctrl,
1765        .vidioc_g_ctrl            = vidioc_g_ctrl,
1766        .vidioc_s_ctrl            = vidioc_s_ctrl,
1767        .vidioc_streamon          = vidioc_streamon,
1768        .vidioc_streamoff         = vidioc_streamoff,
1769        .vidioc_g_tuner           = vidioc_g_tuner,
1770        .vidioc_s_tuner           = vidioc_s_tuner,
1771        .vidioc_g_frequency       = vidioc_g_frequency,
1772        .vidioc_s_frequency       = vidioc_s_frequency,
1773        .vidioc_g_parm            = vidioc_g_parm,
1774        .vidioc_s_parm            = vidioc_s_parm,
1775        .vidioc_enum_framesizes   = vidioc_enum_framesizes,
1776        .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
1777        .vidioc_cropcap           = vidioc_cropcap,
1778        .vidioc_g_crop            = vidioc_g_crop,
1779        .vidioc_s_crop            = vidioc_s_crop,
1780        .vidioc_g_jpegcomp        = vidioc_g_jpegcomp,
1781        .vidioc_s_jpegcomp        = vidioc_s_jpegcomp,
1782};
1783
1784static struct video_device go7007_template = {
1785        .name           = "go7007",
1786        .fops           = &go7007_fops,
1787        .release        = go7007_vfl_release,
1788        .ioctl_ops      = &video_ioctl_ops,
1789        .tvnorms        = V4L2_STD_ALL,
1790        .current_norm   = V4L2_STD_NTSC,
1791};
1792
1793int go7007_v4l2_init(struct go7007 *go)
1794{
1795        int rv;
1796
1797        go->video_dev = video_device_alloc();
1798        if (go->video_dev == NULL)
1799                return -ENOMEM;
1800        *go->video_dev = go7007_template;
1801        go->video_dev->parent = go->dev;
1802        rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
1803        if (rv < 0) {
1804                video_device_release(go->video_dev);
1805                go->video_dev = NULL;
1806                return rv;
1807        }
1808        rv = v4l2_device_register(go->dev, &go->v4l2_dev);
1809        if (rv < 0) {
1810                video_device_release(go->video_dev);
1811                go->video_dev = NULL;
1812                return rv;
1813        }
1814        video_set_drvdata(go->video_dev, go);
1815        ++go->ref_count;
1816        dev_info(go->dev, "registered device %s [v4l2]\n",
1817                 video_device_node_name(go->video_dev));
1818
1819        return 0;
1820}
1821
1822void go7007_v4l2_remove(struct go7007 *go)
1823{
1824        unsigned long flags;
1825
1826        mutex_lock(&go->hw_lock);
1827        if (go->streaming) {
1828                go->streaming = 0;
1829                go7007_stream_stop(go);
1830                spin_lock_irqsave(&go->spinlock, flags);
1831                abort_queued(go);
1832                spin_unlock_irqrestore(&go->spinlock, flags);
1833        }
1834        mutex_unlock(&go->hw_lock);
1835        if (go->video_dev)
1836                video_unregister_device(go->video_dev);
1837        if (go->status != STATUS_SHUTDOWN)
1838                v4l2_device_unregister(&go->v4l2_dev);
1839}
1840