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 = kmalloc(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 < 0 || 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
 957        return retval;
 958}
 959
 960static int vidioc_streamoff(struct file *file, void *priv,
 961                                        enum v4l2_buf_type type)
 962{
 963        struct go7007_file *gofh = priv;
 964        struct go7007 *go = gofh->go;
 965
 966        if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 967                return -EINVAL;
 968        mutex_lock(&gofh->lock);
 969        go7007_streamoff(go);
 970        mutex_unlock(&gofh->lock);
 971
 972        return 0;
 973}
 974
 975static int vidioc_queryctrl(struct file *file, void *priv,
 976                           struct v4l2_queryctrl *query)
 977{
 978        struct go7007 *go = ((struct go7007_file *) priv)->go;
 979        int id = query->id;
 980
 981        if (0 == call_all(&go->v4l2_dev, core, queryctrl, query))
 982                return 0;
 983
 984        query->id = id;
 985        return mpeg_query_ctrl(query);
 986}
 987
 988static int vidioc_g_ctrl(struct file *file, void *priv,
 989                                struct v4l2_control *ctrl)
 990{
 991        struct go7007 *go = ((struct go7007_file *) priv)->go;
 992
 993        if (0 == call_all(&go->v4l2_dev, core, g_ctrl, ctrl))
 994                return 0;
 995
 996        return mpeg_g_ctrl(ctrl, go);
 997}
 998
 999static int vidioc_s_ctrl(struct file *file, void *priv,
1000                                struct v4l2_control *ctrl)
1001{
1002        struct go7007 *go = ((struct go7007_file *) priv)->go;
1003
1004        if (0 == call_all(&go->v4l2_dev, core, s_ctrl, ctrl))
1005                return 0;
1006
1007        return mpeg_s_ctrl(ctrl, go);
1008}
1009
1010static int vidioc_g_parm(struct file *filp, void *priv,
1011                struct v4l2_streamparm *parm)
1012{
1013        struct go7007 *go = ((struct go7007_file *) priv)->go;
1014        struct v4l2_fract timeperframe = {
1015                .numerator = 1001 *  go->fps_scale,
1016                .denominator = go->sensor_framerate,
1017        };
1018
1019        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1020                return -EINVAL;
1021
1022        parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
1023        parm->parm.capture.timeperframe = timeperframe;
1024
1025        return 0;
1026}
1027
1028static int vidioc_s_parm(struct file *filp, void *priv,
1029                struct v4l2_streamparm *parm)
1030{
1031        struct go7007 *go = ((struct go7007_file *) priv)->go;
1032        unsigned int n, d;
1033
1034        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1035                return -EINVAL;
1036        if (parm->parm.capture.capturemode != 0)
1037                return -EINVAL;
1038
1039        n = go->sensor_framerate *
1040                parm->parm.capture.timeperframe.numerator;
1041        d = 1001 * parm->parm.capture.timeperframe.denominator;
1042        if (n != 0 && d != 0 && n > d)
1043                go->fps_scale = (n + d/2) / d;
1044        else
1045                go->fps_scale = 1;
1046
1047        return 0;
1048}
1049
1050/* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
1051   its resolution, when the device is not connected to TV.
1052   This is were an API abuse, probably used by the lack of specific IOCTL's to
1053   enumerate it, by the time the driver was written.
1054
1055   However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
1056   and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
1057
1058   The two functions below implement the newer ioctls
1059*/
1060static int vidioc_enum_framesizes(struct file *filp, void *priv,
1061                                  struct v4l2_frmsizeenum *fsize)
1062{
1063        struct go7007 *go = ((struct go7007_file *) priv)->go;
1064
1065        /* Return -EINVAL, if it is a TV board */
1066        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1067            (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1068                return -EINVAL;
1069
1070        if (fsize->index > 0)
1071                return -EINVAL;
1072
1073        fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1074        fsize->discrete.width = go->board_info->sensor_width;
1075        fsize->discrete.height = go->board_info->sensor_height;
1076
1077        return 0;
1078}
1079
1080static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1081                                      struct v4l2_frmivalenum *fival)
1082{
1083        struct go7007 *go = ((struct go7007_file *) priv)->go;
1084
1085        /* Return -EINVAL, if it is a TV board */
1086        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1087            (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1088                return -EINVAL;
1089
1090        if (fival->index > 0)
1091                return -EINVAL;
1092
1093        fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1094        fival->discrete.numerator = 1001;
1095        fival->discrete.denominator = go->board_info->sensor_framerate;
1096
1097        return 0;
1098}
1099
1100static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
1101{
1102        struct go7007 *go = ((struct go7007_file *) priv)->go;
1103
1104        switch (go->standard) {
1105        case GO7007_STD_NTSC:
1106                *std = V4L2_STD_NTSC;
1107                break;
1108        case GO7007_STD_PAL:
1109                *std = V4L2_STD_PAL;
1110                break;
1111        default:
1112                return -EINVAL;
1113        }
1114
1115        return 0;
1116}
1117
1118static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1119{
1120        struct go7007 *go = ((struct go7007_file *) priv)->go;
1121
1122        if (go->streaming)
1123                return -EBUSY;
1124
1125        if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && *std != 0)
1126                return -EINVAL;
1127
1128        if (*std == 0)
1129                return -EINVAL;
1130
1131        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1132                        go->input == go->board_info->num_inputs - 1) {
1133                if (!go->i2c_adapter_online)
1134                        return -EIO;
1135                if (call_all(&go->v4l2_dev, core, s_std, *std) < 0)
1136                        return -EINVAL;
1137        }
1138
1139        if (*std & V4L2_STD_NTSC) {
1140                go->standard = GO7007_STD_NTSC;
1141                go->sensor_framerate = 30000;
1142        } else if (*std & V4L2_STD_PAL) {
1143                go->standard = GO7007_STD_PAL;
1144                go->sensor_framerate = 25025;
1145        } else if (*std & V4L2_STD_SECAM) {
1146                go->standard = GO7007_STD_PAL;
1147                go->sensor_framerate = 25025;
1148        } else
1149                return -EINVAL;
1150
1151        call_all(&go->v4l2_dev, core, s_std, *std);
1152        set_capture_size(go, NULL, 0);
1153
1154        return 0;
1155}
1156
1157static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
1158{
1159        struct go7007 *go = ((struct go7007_file *) priv)->go;
1160
1161        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1162                        go->input == go->board_info->num_inputs - 1) {
1163                if (!go->i2c_adapter_online)
1164                        return -EIO;
1165                return call_all(&go->v4l2_dev, video, querystd, std);
1166        } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1167                *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1168        else
1169                *std = 0;
1170
1171        return 0;
1172}
1173
1174static int vidioc_enum_input(struct file *file, void *priv,
1175                                struct v4l2_input *inp)
1176{
1177        struct go7007 *go = ((struct go7007_file *) priv)->go;
1178
1179        if (inp->index >= go->board_info->num_inputs)
1180                return -EINVAL;
1181
1182        strncpy(inp->name, go->board_info->inputs[inp->index].name,
1183                        sizeof(inp->name));
1184
1185        /* If this board has a tuner, it will be the last input */
1186        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1187                        inp->index == go->board_info->num_inputs - 1)
1188                inp->type = V4L2_INPUT_TYPE_TUNER;
1189        else
1190                inp->type = V4L2_INPUT_TYPE_CAMERA;
1191
1192        inp->audioset = 0;
1193        inp->tuner = 0;
1194        if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1195                inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
1196                                                V4L2_STD_SECAM;
1197        else
1198                inp->std = 0;
1199
1200        return 0;
1201}
1202
1203
1204static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1205{
1206        struct go7007 *go = ((struct go7007_file *) priv)->go;
1207
1208        *input = go->input;
1209
1210        return 0;
1211}
1212
1213static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1214{
1215        struct go7007 *go = ((struct go7007_file *) priv)->go;
1216
1217        if (input >= go->board_info->num_inputs)
1218                return -EINVAL;
1219        if (go->streaming)
1220                return -EBUSY;
1221
1222        go->input = input;
1223
1224        return call_all(&go->v4l2_dev, video, s_routing, input, 0, 0);
1225}
1226
1227static int vidioc_g_tuner(struct file *file, void *priv,
1228                                struct v4l2_tuner *t)
1229{
1230        struct go7007 *go = ((struct go7007_file *) priv)->go;
1231
1232        if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1233                return -EINVAL;
1234        if (t->index != 0)
1235                return -EINVAL;
1236        if (!go->i2c_adapter_online)
1237                return -EIO;
1238
1239        return call_all(&go->v4l2_dev, tuner, g_tuner, t);
1240}
1241
1242static int vidioc_s_tuner(struct file *file, void *priv,
1243                                struct v4l2_tuner *t)
1244{
1245        struct go7007 *go = ((struct go7007_file *) priv)->go;
1246
1247        if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1248                return -EINVAL;
1249        if (t->index != 0)
1250                return -EINVAL;
1251        if (!go->i2c_adapter_online)
1252                return -EIO;
1253
1254        switch (go->board_id) {
1255        case GO7007_BOARDID_PX_TV402U_NA:
1256        case GO7007_BOARDID_PX_TV402U_JP:
1257                /* No selectable options currently */
1258                if (t->audmode != V4L2_TUNER_MODE_STEREO)
1259                        return -EINVAL;
1260                break;
1261        }
1262
1263        return call_all(&go->v4l2_dev, tuner, s_tuner, t);
1264}
1265
1266static int vidioc_g_frequency(struct file *file, void *priv,
1267                                struct v4l2_frequency *f)
1268{
1269        struct go7007 *go = ((struct go7007_file *) priv)->go;
1270
1271        if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1272                return -EINVAL;
1273        if (!go->i2c_adapter_online)
1274                return -EIO;
1275
1276        f->type = V4L2_TUNER_ANALOG_TV;
1277
1278        return call_all(&go->v4l2_dev, tuner, g_frequency, f);
1279}
1280
1281static int vidioc_s_frequency(struct file *file, void *priv,
1282                                struct v4l2_frequency *f)
1283{
1284        struct go7007 *go = ((struct go7007_file *) priv)->go;
1285
1286        if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1287                return -EINVAL;
1288        if (!go->i2c_adapter_online)
1289                return -EIO;
1290
1291        return call_all(&go->v4l2_dev, tuner, s_frequency, f);
1292}
1293
1294static int vidioc_cropcap(struct file *file, void *priv,
1295                                        struct v4l2_cropcap *cropcap)
1296{
1297        struct go7007 *go = ((struct go7007_file *) priv)->go;
1298
1299        if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1300                return -EINVAL;
1301
1302        /* These specify the raw input of the sensor */
1303        switch (go->standard) {
1304        case GO7007_STD_NTSC:
1305                cropcap->bounds.top = 0;
1306                cropcap->bounds.left = 0;
1307                cropcap->bounds.width = 720;
1308                cropcap->bounds.height = 480;
1309                cropcap->defrect.top = 0;
1310                cropcap->defrect.left = 0;
1311                cropcap->defrect.width = 720;
1312                cropcap->defrect.height = 480;
1313                break;
1314        case GO7007_STD_PAL:
1315                cropcap->bounds.top = 0;
1316                cropcap->bounds.left = 0;
1317                cropcap->bounds.width = 720;
1318                cropcap->bounds.height = 576;
1319                cropcap->defrect.top = 0;
1320                cropcap->defrect.left = 0;
1321                cropcap->defrect.width = 720;
1322                cropcap->defrect.height = 576;
1323                break;
1324        case GO7007_STD_OTHER:
1325                cropcap->bounds.top = 0;
1326                cropcap->bounds.left = 0;
1327                cropcap->bounds.width = go->board_info->sensor_width;
1328                cropcap->bounds.height = go->board_info->sensor_height;
1329                cropcap->defrect.top = 0;
1330                cropcap->defrect.left = 0;
1331                cropcap->defrect.width = go->board_info->sensor_width;
1332                cropcap->defrect.height = go->board_info->sensor_height;
1333                break;
1334        }
1335
1336        return 0;
1337}
1338
1339static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1340{
1341        struct go7007 *go = ((struct go7007_file *) priv)->go;
1342
1343        if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1344                return -EINVAL;
1345
1346        crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1347
1348        /* These specify the raw input of the sensor */
1349        switch (go->standard) {
1350        case GO7007_STD_NTSC:
1351                crop->c.top = 0;
1352                crop->c.left = 0;
1353                crop->c.width = 720;
1354                crop->c.height = 480;
1355                break;
1356        case GO7007_STD_PAL:
1357                crop->c.top = 0;
1358                crop->c.left = 0;
1359                crop->c.width = 720;
1360                crop->c.height = 576;
1361                break;
1362        case GO7007_STD_OTHER:
1363                crop->c.top = 0;
1364                crop->c.left = 0;
1365                crop->c.width = go->board_info->sensor_width;
1366                crop->c.height = go->board_info->sensor_height;
1367                break;
1368        }
1369
1370        return 0;
1371}
1372
1373/* FIXME: vidioc_s_crop is not really implemented!!!
1374 */
1375static int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1376{
1377        if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1378                return -EINVAL;
1379
1380        return 0;
1381}
1382
1383static int vidioc_g_jpegcomp(struct file *file, void *priv,
1384                         struct v4l2_jpegcompression *params)
1385{
1386        memset(params, 0, sizeof(*params));
1387        params->quality = 50; /* ?? */
1388        params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
1389                                V4L2_JPEG_MARKER_DQT;
1390
1391        return 0;
1392}
1393
1394static int vidioc_s_jpegcomp(struct file *file, void *priv,
1395                         struct v4l2_jpegcompression *params)
1396{
1397        if (params->quality != 50 ||
1398                        params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
1399                                                V4L2_JPEG_MARKER_DQT))
1400                return -EINVAL;
1401
1402        return 0;
1403}
1404
1405/* FIXME:
1406        Those ioctls are private, and not needed, since several standard
1407        extended controls already provide streaming control.
1408        So, those ioctls should be converted into vidioc_g_ext_ctrls()
1409        and vidioc_s_ext_ctrls()
1410 */
1411
1412#if 0
1413        /* Temporary ioctls for controlling compression characteristics */
1414        case GO7007IOC_S_BITRATE:
1415        {
1416                int *bitrate = arg;
1417
1418                if (go->streaming)
1419                        return -EINVAL;
1420                /* Upper bound is kind of arbitrary here */
1421                if (*bitrate < 64000 || *bitrate > 10000000)
1422                        return -EINVAL;
1423                go->bitrate = *bitrate;
1424                return 0;
1425        }
1426        case GO7007IOC_G_BITRATE:
1427        {
1428                int *bitrate = arg;
1429
1430                *bitrate = go->bitrate;
1431                return 0;
1432        }
1433        case GO7007IOC_S_COMP_PARAMS:
1434        {
1435                struct go7007_comp_params *comp = arg;
1436
1437                if (go->format == GO7007_FORMAT_MJPEG)
1438                        return -EINVAL;
1439                if (comp->gop_size > 0)
1440                        go->gop_size = comp->gop_size;
1441                else
1442                        go->gop_size = go->sensor_framerate / 1000;
1443                if (go->gop_size != 15)
1444                        go->dvd_mode = 0;
1445                /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
1446                if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
1447                        switch (comp->aspect_ratio) {
1448                        case GO7007_ASPECT_RATIO_4_3_NTSC:
1449                        case GO7007_ASPECT_RATIO_4_3_PAL:
1450                                go->aspect_ratio = GO7007_RATIO_4_3;
1451                                break;
1452                        case GO7007_ASPECT_RATIO_16_9_NTSC:
1453                        case GO7007_ASPECT_RATIO_16_9_PAL:
1454                                go->aspect_ratio = GO7007_RATIO_16_9;
1455                                break;
1456                        default:
1457                                go->aspect_ratio = GO7007_RATIO_1_1;
1458                                break;
1459                        }
1460                }
1461                if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
1462                        go->dvd_mode = 0;
1463                        go->seq_header_enable = 0;
1464                } else {
1465                        go->seq_header_enable = 1;
1466                }
1467                /* fall-through */
1468        }
1469        case GO7007IOC_G_COMP_PARAMS:
1470        {
1471                struct go7007_comp_params *comp = arg;
1472
1473                if (go->format == GO7007_FORMAT_MJPEG)
1474                        return -EINVAL;
1475                memset(comp, 0, sizeof(*comp));
1476                comp->gop_size = go->gop_size;
1477                comp->max_b_frames = go->ipb ? 2 : 0;
1478                switch (go->aspect_ratio) {
1479                case GO7007_RATIO_4_3:
1480                        if (go->standard == GO7007_STD_NTSC)
1481                                comp->aspect_ratio =
1482                                        GO7007_ASPECT_RATIO_4_3_NTSC;
1483                        else
1484                                comp->aspect_ratio =
1485                                        GO7007_ASPECT_RATIO_4_3_PAL;
1486                        break;
1487                case GO7007_RATIO_16_9:
1488                        if (go->standard == GO7007_STD_NTSC)
1489                                comp->aspect_ratio =
1490                                        GO7007_ASPECT_RATIO_16_9_NTSC;
1491                        else
1492                                comp->aspect_ratio =
1493                                        GO7007_ASPECT_RATIO_16_9_PAL;
1494                        break;
1495                default:
1496                        comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
1497                        break;
1498                }
1499                if (go->closed_gop)
1500                        comp->flags |= GO7007_COMP_CLOSED_GOP;
1501                if (!go->seq_header_enable)
1502                        comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
1503                return 0;
1504        }
1505        case GO7007IOC_S_MPEG_PARAMS:
1506        {
1507                struct go7007_mpeg_params *mpeg = arg;
1508
1509                if (go->format != GO7007_FORMAT_MPEG1 &&
1510                                go->format != GO7007_FORMAT_MPEG2 &&
1511                                go->format != GO7007_FORMAT_MPEG4)
1512                        return -EINVAL;
1513
1514                if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
1515                        go->format = GO7007_FORMAT_MPEG2;
1516                        go->bitrate = 9800000;
1517                        go->gop_size = 15;
1518                        go->pali = 0x48;
1519                        go->closed_gop = 1;
1520                        go->repeat_seqhead = 0;
1521                        go->seq_header_enable = 1;
1522                        go->gop_header_enable = 1;
1523                        go->dvd_mode = 1;
1524                } else {
1525                        switch (mpeg->mpeg_video_standard) {
1526                        case GO7007_MPEG_VIDEO_MPEG1:
1527                                go->format = GO7007_FORMAT_MPEG1;
1528                                go->pali = 0;
1529                                break;
1530                        case GO7007_MPEG_VIDEO_MPEG2:
1531                                go->format = GO7007_FORMAT_MPEG2;
1532                                if (mpeg->pali >> 24 == 2)
1533                                        go->pali = mpeg->pali & 0xff;
1534                                else
1535                                        go->pali = 0x48;
1536                                break;
1537                        case GO7007_MPEG_VIDEO_MPEG4:
1538                                go->format = GO7007_FORMAT_MPEG4;
1539                                if (mpeg->pali >> 24 == 4)
1540                                        go->pali = mpeg->pali & 0xff;
1541                                else
1542                                        go->pali = 0xf5;
1543                                break;
1544                        default:
1545                                return -EINVAL;
1546                        }
1547                        go->gop_header_enable =
1548                                mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
1549                                ? 0 : 1;
1550                        if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
1551                                go->repeat_seqhead = 1;
1552                        else
1553                                go->repeat_seqhead = 0;
1554                        go->dvd_mode = 0;
1555                }
1556                /* fall-through */
1557        }
1558        case GO7007IOC_G_MPEG_PARAMS:
1559        {
1560                struct go7007_mpeg_params *mpeg = arg;
1561
1562                memset(mpeg, 0, sizeof(*mpeg));
1563                switch (go->format) {
1564                case GO7007_FORMAT_MPEG1:
1565                        mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
1566                        mpeg->pali = 0;
1567                        break;
1568                case GO7007_FORMAT_MPEG2:
1569                        mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
1570                        mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
1571                        break;
1572                case GO7007_FORMAT_MPEG4:
1573                        mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
1574                        mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
1575                        break;
1576                default:
1577                        return -EINVAL;
1578                }
1579                if (!go->gop_header_enable)
1580                        mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
1581                if (go->repeat_seqhead)
1582                        mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
1583                if (go->dvd_mode)
1584                        mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
1585                return 0;
1586        }
1587        case GO7007IOC_S_MD_PARAMS:
1588        {
1589                struct go7007_md_params *mdp = arg;
1590
1591                if (mdp->region > 3)
1592                        return -EINVAL;
1593                if (mdp->trigger > 0) {
1594                        go->modet[mdp->region].pixel_threshold =
1595                                        mdp->pixel_threshold >> 1;
1596                        go->modet[mdp->region].motion_threshold =
1597                                        mdp->motion_threshold >> 1;
1598                        go->modet[mdp->region].mb_threshold =
1599                                        mdp->trigger >> 1;
1600                        go->modet[mdp->region].enable = 1;
1601                } else
1602                        go->modet[mdp->region].enable = 0;
1603                /* fall-through */
1604        }
1605        case GO7007IOC_G_MD_PARAMS:
1606        {
1607                struct go7007_md_params *mdp = arg;
1608                int region = mdp->region;
1609
1610                if (mdp->region > 3)
1611                        return -EINVAL;
1612                memset(mdp, 0, sizeof(struct go7007_md_params));
1613                mdp->region = region;
1614                if (!go->modet[region].enable)
1615                        return 0;
1616                mdp->pixel_threshold =
1617                        (go->modet[region].pixel_threshold << 1) + 1;
1618                mdp->motion_threshold =
1619                        (go->modet[region].motion_threshold << 1) + 1;
1620                mdp->trigger =
1621                        (go->modet[region].mb_threshold << 1) + 1;
1622                return 0;
1623        }
1624        case GO7007IOC_S_MD_REGION:
1625        {
1626                struct go7007_md_region *region = arg;
1627
1628                if (region->region < 1 || region->region > 3)
1629                        return -EINVAL;
1630                return clip_to_modet_map(go, region->region, region->clips);
1631        }
1632#endif
1633
1634static ssize_t go7007_read(struct file *file, char __user *data,
1635                size_t count, loff_t *ppos)
1636{
1637        return -EINVAL;
1638}
1639
1640static void go7007_vm_open(struct vm_area_struct *vma)
1641{
1642        struct go7007_buffer *gobuf = vma->vm_private_data;
1643
1644        ++gobuf->mapped;
1645}
1646
1647static void go7007_vm_close(struct vm_area_struct *vma)
1648{
1649        struct go7007_buffer *gobuf = vma->vm_private_data;
1650        unsigned long flags;
1651
1652        if (--gobuf->mapped == 0) {
1653                spin_lock_irqsave(&gobuf->go->spinlock, flags);
1654                deactivate_buffer(gobuf);
1655                spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
1656        }
1657}
1658
1659/* Copied from videobuf-dma-sg.c */
1660static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1661{
1662        struct page *page;
1663
1664        page = alloc_page(GFP_USER | __GFP_DMA32);
1665        if (!page)
1666                return VM_FAULT_OOM;
1667        clear_user_highpage(page, (unsigned long)vmf->virtual_address);
1668        vmf->page = page;
1669        return 0;
1670}
1671
1672static struct vm_operations_struct go7007_vm_ops = {
1673        .open   = go7007_vm_open,
1674        .close  = go7007_vm_close,
1675        .fault  = go7007_vm_fault,
1676};
1677
1678static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1679{
1680        struct go7007_file *gofh = file->private_data;
1681        unsigned int index;
1682
1683        if (gofh->go->status != STATUS_ONLINE)
1684                return -EIO;
1685        if (!(vma->vm_flags & VM_SHARED))
1686                return -EINVAL; /* only support VM_SHARED mapping */
1687        if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1688                return -EINVAL; /* must map exactly one full buffer */
1689        mutex_lock(&gofh->lock);
1690        index = vma->vm_pgoff / GO7007_BUF_PAGES;
1691        if (index >= gofh->buf_count) {
1692                mutex_unlock(&gofh->lock);
1693                return -EINVAL; /* trying to map beyond requested buffers */
1694        }
1695        if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1696                mutex_unlock(&gofh->lock);
1697                return -EINVAL; /* offset is not aligned on buffer boundary */
1698        }
1699        if (gofh->bufs[index].mapped > 0) {
1700                mutex_unlock(&gofh->lock);
1701                return -EBUSY;
1702        }
1703        gofh->bufs[index].mapped = 1;
1704        gofh->bufs[index].user_addr = vma->vm_start;
1705        vma->vm_ops = &go7007_vm_ops;
1706        vma->vm_flags |= VM_DONTEXPAND;
1707        vma->vm_flags &= ~VM_IO;
1708        vma->vm_private_data = &gofh->bufs[index];
1709        mutex_unlock(&gofh->lock);
1710        return 0;
1711}
1712
1713static unsigned int go7007_poll(struct file *file, poll_table *wait)
1714{
1715        struct go7007_file *gofh = file->private_data;
1716        struct go7007_buffer *gobuf;
1717
1718        if (list_empty(&gofh->go->stream))
1719                return POLLERR;
1720        gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
1721        poll_wait(file, &gofh->go->frame_waitq, wait);
1722        if (gobuf->state == BUF_STATE_DONE)
1723                return POLLIN | POLLRDNORM;
1724        return 0;
1725}
1726
1727static void go7007_vfl_release(struct video_device *vfd)
1728{
1729        struct go7007 *go = video_get_drvdata(vfd);
1730
1731        video_device_release(vfd);
1732        if (--go->ref_count == 0)
1733                kfree(go);
1734}
1735
1736static struct v4l2_file_operations go7007_fops = {
1737        .owner          = THIS_MODULE,
1738        .open           = go7007_open,
1739        .release        = go7007_release,
1740        .ioctl          = video_ioctl2,
1741        .read           = go7007_read,
1742        .mmap           = go7007_mmap,
1743        .poll           = go7007_poll,
1744};
1745
1746static const struct v4l2_ioctl_ops video_ioctl_ops = {
1747        .vidioc_querycap          = vidioc_querycap,
1748        .vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
1749        .vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
1750        .vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
1751        .vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
1752        .vidioc_reqbufs           = vidioc_reqbufs,
1753        .vidioc_querybuf          = vidioc_querybuf,
1754        .vidioc_qbuf              = vidioc_qbuf,
1755        .vidioc_dqbuf             = vidioc_dqbuf,
1756        .vidioc_g_std             = vidioc_g_std,
1757        .vidioc_s_std             = vidioc_s_std,
1758        .vidioc_querystd          = vidioc_querystd,
1759        .vidioc_enum_input        = vidioc_enum_input,
1760        .vidioc_g_input           = vidioc_g_input,
1761        .vidioc_s_input           = vidioc_s_input,
1762        .vidioc_queryctrl         = vidioc_queryctrl,
1763        .vidioc_g_ctrl            = vidioc_g_ctrl,
1764        .vidioc_s_ctrl            = vidioc_s_ctrl,
1765        .vidioc_streamon          = vidioc_streamon,
1766        .vidioc_streamoff         = vidioc_streamoff,
1767        .vidioc_g_tuner           = vidioc_g_tuner,
1768        .vidioc_s_tuner           = vidioc_s_tuner,
1769        .vidioc_g_frequency       = vidioc_g_frequency,
1770        .vidioc_s_frequency       = vidioc_s_frequency,
1771        .vidioc_g_parm            = vidioc_g_parm,
1772        .vidioc_s_parm            = vidioc_s_parm,
1773        .vidioc_enum_framesizes   = vidioc_enum_framesizes,
1774        .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
1775        .vidioc_cropcap           = vidioc_cropcap,
1776        .vidioc_g_crop            = vidioc_g_crop,
1777        .vidioc_s_crop            = vidioc_s_crop,
1778        .vidioc_g_jpegcomp        = vidioc_g_jpegcomp,
1779        .vidioc_s_jpegcomp        = vidioc_s_jpegcomp,
1780};
1781
1782static struct video_device go7007_template = {
1783        .name           = "go7007",
1784        .fops           = &go7007_fops,
1785        .release        = go7007_vfl_release,
1786        .ioctl_ops      = &video_ioctl_ops,
1787        .tvnorms        = V4L2_STD_ALL,
1788        .current_norm   = V4L2_STD_NTSC,
1789};
1790
1791int go7007_v4l2_init(struct go7007 *go)
1792{
1793        int rv;
1794
1795        go->video_dev = video_device_alloc();
1796        if (go->video_dev == NULL)
1797                return -ENOMEM;
1798        *go->video_dev = go7007_template;
1799        go->video_dev->parent = go->dev;
1800        rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
1801        if (rv < 0) {
1802                video_device_release(go->video_dev);
1803                go->video_dev = NULL;
1804                return rv;
1805        }
1806        rv = v4l2_device_register(go->dev, &go->v4l2_dev);
1807        if (rv < 0) {
1808                video_device_release(go->video_dev);
1809                go->video_dev = NULL;
1810                return rv;
1811        }
1812        video_set_drvdata(go->video_dev, go);
1813        ++go->ref_count;
1814        printk(KERN_INFO "%s: registered device %s [v4l2]\n",
1815               go->video_dev->name, video_device_node_name(go->video_dev));
1816
1817        return 0;
1818}
1819
1820void go7007_v4l2_remove(struct go7007 *go)
1821{
1822        unsigned long flags;
1823
1824        mutex_lock(&go->hw_lock);
1825        if (go->streaming) {
1826                go->streaming = 0;
1827                go7007_stream_stop(go);
1828                spin_lock_irqsave(&go->spinlock, flags);
1829                abort_queued(go);
1830                spin_unlock_irqrestore(&go->spinlock, flags);
1831        }
1832        mutex_unlock(&go->hw_lock);
1833        if (go->video_dev)
1834                video_unregister_device(go->video_dev);
1835        v4l2_device_unregister(&go->v4l2_dev);
1836}
1837