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/delay.h>
  21#include <linux/sched.h>
  22#include <linux/spinlock.h>
  23#include <linux/slab.h>
  24#include <linux/fs.h>
  25#include <linux/unistd.h>
  26#include <linux/time.h>
  27#include <linux/vmalloc.h>
  28#include <linux/pagemap.h>
  29#include <linux/i2c.h>
  30#include <linux/mutex.h>
  31#include <linux/uaccess.h>
  32#include <linux/videodev2.h>
  33#include <media/v4l2-common.h>
  34#include <media/v4l2-ioctl.h>
  35#include <media/v4l2-subdev.h>
  36#include <media/v4l2-event.h>
  37#include <media/videobuf2-vmalloc.h>
  38#include <media/saa7115.h>
  39
  40#include "go7007.h"
  41#include "go7007-priv.h"
  42
  43#define call_all(dev, o, f, args...) \
  44        v4l2_device_call_until_err(dev, 0, o, f, ##args)
  45
  46static bool valid_pixelformat(u32 pixelformat)
  47{
  48        switch (pixelformat) {
  49        case V4L2_PIX_FMT_MJPEG:
  50        case V4L2_PIX_FMT_MPEG1:
  51        case V4L2_PIX_FMT_MPEG2:
  52        case V4L2_PIX_FMT_MPEG4:
  53                return true;
  54        default:
  55                return false;
  56        }
  57}
  58
  59static u32 get_frame_type_flag(struct go7007_buffer *vb, int format)
  60{
  61        u8 *ptr = vb2_plane_vaddr(&vb->vb, 0);
  62
  63        switch (format) {
  64        case V4L2_PIX_FMT_MJPEG:
  65                return V4L2_BUF_FLAG_KEYFRAME;
  66        case V4L2_PIX_FMT_MPEG4:
  67                switch ((ptr[vb->frame_offset + 4] >> 6) & 0x3) {
  68                case 0:
  69                        return V4L2_BUF_FLAG_KEYFRAME;
  70                case 1:
  71                        return V4L2_BUF_FLAG_PFRAME;
  72                case 2:
  73                        return V4L2_BUF_FLAG_BFRAME;
  74                default:
  75                        return 0;
  76                }
  77        case V4L2_PIX_FMT_MPEG1:
  78        case V4L2_PIX_FMT_MPEG2:
  79                switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) {
  80                case 1:
  81                        return V4L2_BUF_FLAG_KEYFRAME;
  82                case 2:
  83                        return V4L2_BUF_FLAG_PFRAME;
  84                case 3:
  85                        return V4L2_BUF_FLAG_BFRAME;
  86                default:
  87                        return 0;
  88                }
  89        }
  90
  91        return 0;
  92}
  93
  94static void get_resolution(struct go7007 *go, int *width, int *height)
  95{
  96        switch (go->standard) {
  97        case GO7007_STD_NTSC:
  98                *width = 720;
  99                *height = 480;
 100                break;
 101        case GO7007_STD_PAL:
 102                *width = 720;
 103                *height = 576;
 104                break;
 105        case GO7007_STD_OTHER:
 106        default:
 107                *width = go->board_info->sensor_width;
 108                *height = go->board_info->sensor_height;
 109                break;
 110        }
 111}
 112
 113static void set_formatting(struct go7007 *go)
 114{
 115        if (go->format == V4L2_PIX_FMT_MJPEG) {
 116                go->pali = 0;
 117                go->aspect_ratio = GO7007_RATIO_1_1;
 118                go->gop_size = 0;
 119                go->ipb = 0;
 120                go->closed_gop = 0;
 121                go->repeat_seqhead = 0;
 122                go->seq_header_enable = 0;
 123                go->gop_header_enable = 0;
 124                go->dvd_mode = 0;
 125                return;
 126        }
 127
 128        switch (go->format) {
 129        case V4L2_PIX_FMT_MPEG1:
 130                go->pali = 0;
 131                break;
 132        default:
 133        case V4L2_PIX_FMT_MPEG2:
 134                go->pali = 0x48;
 135                break;
 136        case V4L2_PIX_FMT_MPEG4:
 137                /* For future reference: this is the list of MPEG4
 138                 * profiles that are available, although they are
 139                 * untested:
 140                 *
 141                 * Profile              pali
 142                 * --------------       ----
 143                 * PROFILE_S_L0         0x08
 144                 * PROFILE_S_L1         0x01
 145                 * PROFILE_S_L2         0x02
 146                 * PROFILE_S_L3         0x03
 147                 * PROFILE_ARTS_L1      0x91
 148                 * PROFILE_ARTS_L2      0x92
 149                 * PROFILE_ARTS_L3      0x93
 150                 * PROFILE_ARTS_L4      0x94
 151                 * PROFILE_AS_L0        0xf0
 152                 * PROFILE_AS_L1        0xf1
 153                 * PROFILE_AS_L2        0xf2
 154                 * PROFILE_AS_L3        0xf3
 155                 * PROFILE_AS_L4        0xf4
 156                 * PROFILE_AS_L5        0xf5
 157                 */
 158                go->pali = 0xf5;
 159                break;
 160        }
 161        go->gop_size = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_size);
 162        go->closed_gop = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_closure);
 163        go->ipb = v4l2_ctrl_g_ctrl(go->mpeg_video_b_frames) != 0;
 164        go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate);
 165        go->repeat_seqhead = v4l2_ctrl_g_ctrl(go->mpeg_video_rep_seqheader);
 166        go->gop_header_enable = 1;
 167        go->dvd_mode = 0;
 168        if (go->format == V4L2_PIX_FMT_MPEG2)
 169                go->dvd_mode =
 170                        go->bitrate == 9800000 &&
 171                        go->gop_size == 15 &&
 172                        go->ipb == 0 &&
 173                        go->repeat_seqhead == 1 &&
 174                        go->closed_gop;
 175
 176        switch (v4l2_ctrl_g_ctrl(go->mpeg_video_aspect_ratio)) {
 177        default:
 178        case V4L2_MPEG_VIDEO_ASPECT_1x1:
 179                go->aspect_ratio = GO7007_RATIO_1_1;
 180                break;
 181        case V4L2_MPEG_VIDEO_ASPECT_4x3:
 182                go->aspect_ratio = GO7007_RATIO_4_3;
 183                break;
 184        case V4L2_MPEG_VIDEO_ASPECT_16x9:
 185                go->aspect_ratio = GO7007_RATIO_16_9;
 186                break;
 187        }
 188}
 189
 190static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
 191{
 192        int sensor_height = 0, sensor_width = 0;
 193        int width, height, i;
 194
 195        if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
 196                return -EINVAL;
 197
 198        get_resolution(go, &sensor_width, &sensor_height);
 199
 200        if (fmt == NULL) {
 201                width = sensor_width;
 202                height = sensor_height;
 203        } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
 204                if (fmt->fmt.pix.width > sensor_width)
 205                        width = sensor_width;
 206                else if (fmt->fmt.pix.width < 144)
 207                        width = 144;
 208                else
 209                        width = fmt->fmt.pix.width & ~0x0f;
 210
 211                if (fmt->fmt.pix.height > sensor_height)
 212                        height = sensor_height;
 213                else if (fmt->fmt.pix.height < 96)
 214                        height = 96;
 215                else
 216                        height = fmt->fmt.pix.height & ~0x0f;
 217        } else {
 218                width = fmt->fmt.pix.width;
 219
 220                if (width <= sensor_width / 4) {
 221                        width = sensor_width / 4;
 222                        height = sensor_height / 4;
 223                } else if (width <= sensor_width / 2) {
 224                        width = sensor_width / 2;
 225                        height = sensor_height / 2;
 226                } else {
 227                        width = sensor_width;
 228                        height = sensor_height;
 229                }
 230                width &= ~0xf;
 231                height &= ~0xf;
 232        }
 233
 234        if (fmt != NULL) {
 235                u32 pixelformat = fmt->fmt.pix.pixelformat;
 236
 237                memset(fmt, 0, sizeof(*fmt));
 238                fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 239                fmt->fmt.pix.width = width;
 240                fmt->fmt.pix.height = height;
 241                fmt->fmt.pix.pixelformat = pixelformat;
 242                fmt->fmt.pix.field = V4L2_FIELD_NONE;
 243                fmt->fmt.pix.bytesperline = 0;
 244                fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
 245                fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 246        }
 247
 248        if (try)
 249                return 0;
 250
 251        if (fmt)
 252                go->format = fmt->fmt.pix.pixelformat;
 253        go->width = width;
 254        go->height = height;
 255        go->encoder_h_offset = go->board_info->sensor_h_offset;
 256        go->encoder_v_offset = go->board_info->sensor_v_offset;
 257        for (i = 0; i < 4; ++i)
 258                go->modet[i].enable = 0;
 259        for (i = 0; i < 1624; ++i)
 260                go->modet_map[i] = 0;
 261
 262        if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
 263                struct v4l2_mbus_framefmt mbus_fmt;
 264
 265                mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
 266                mbus_fmt.width = fmt ? fmt->fmt.pix.width : width;
 267                mbus_fmt.height = height;
 268                go->encoder_h_halve = 0;
 269                go->encoder_v_halve = 0;
 270                go->encoder_subsample = 0;
 271                call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt);
 272        } else {
 273                if (width <= sensor_width / 4) {
 274                        go->encoder_h_halve = 1;
 275                        go->encoder_v_halve = 1;
 276                        go->encoder_subsample = 1;
 277                } else if (width <= sensor_width / 2) {
 278                        go->encoder_h_halve = 1;
 279                        go->encoder_v_halve = 1;
 280                        go->encoder_subsample = 0;
 281                } else {
 282                        go->encoder_h_halve = 0;
 283                        go->encoder_v_halve = 0;
 284                        go->encoder_subsample = 0;
 285                }
 286        }
 287        return 0;
 288}
 289
 290#if 0
 291static int clip_to_modet_map(struct go7007 *go, int region,
 292                struct v4l2_clip *clip_list)
 293{
 294        struct v4l2_clip clip, *clip_ptr;
 295        int x, y, mbnum;
 296
 297        /* Check if coordinates are OK and if any macroblocks are already
 298         * used by other regions (besides 0) */
 299        clip_ptr = clip_list;
 300        while (clip_ptr) {
 301                if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
 302                        return -EFAULT;
 303                if (clip.c.left < 0 || (clip.c.left & 0xF) ||
 304                                clip.c.width <= 0 || (clip.c.width & 0xF))
 305                        return -EINVAL;
 306                if (clip.c.left + clip.c.width > go->width)
 307                        return -EINVAL;
 308                if (clip.c.top < 0 || (clip.c.top & 0xF) ||
 309                                clip.c.height <= 0 || (clip.c.height & 0xF))
 310                        return -EINVAL;
 311                if (clip.c.top + clip.c.height > go->height)
 312                        return -EINVAL;
 313                for (y = 0; y < clip.c.height; y += 16)
 314                        for (x = 0; x < clip.c.width; x += 16) {
 315                                mbnum = (go->width >> 4) *
 316                                                ((clip.c.top + y) >> 4) +
 317                                        ((clip.c.left + x) >> 4);
 318                                if (go->modet_map[mbnum] != 0 &&
 319                                                go->modet_map[mbnum] != region)
 320                                        return -EBUSY;
 321                        }
 322                clip_ptr = clip.next;
 323        }
 324
 325        /* Clear old region macroblocks */
 326        for (mbnum = 0; mbnum < 1624; ++mbnum)
 327                if (go->modet_map[mbnum] == region)
 328                        go->modet_map[mbnum] = 0;
 329
 330        /* Claim macroblocks in this list */
 331        clip_ptr = clip_list;
 332        while (clip_ptr) {
 333                if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
 334                        return -EFAULT;
 335                for (y = 0; y < clip.c.height; y += 16)
 336                        for (x = 0; x < clip.c.width; x += 16) {
 337                                mbnum = (go->width >> 4) *
 338                                                ((clip.c.top + y) >> 4) +
 339                                        ((clip.c.left + x) >> 4);
 340                                go->modet_map[mbnum] = region;
 341                        }
 342                clip_ptr = clip.next;
 343        }
 344        return 0;
 345}
 346#endif
 347
 348static int vidioc_querycap(struct file *file, void  *priv,
 349                                        struct v4l2_capability *cap)
 350{
 351        struct go7007 *go = video_drvdata(file);
 352
 353        strlcpy(cap->driver, "go7007", sizeof(cap->driver));
 354        strlcpy(cap->card, go->name, sizeof(cap->card));
 355        strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
 356
 357        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
 358                                V4L2_CAP_STREAMING;
 359
 360        if (go->board_info->num_aud_inputs)
 361                cap->device_caps |= V4L2_CAP_AUDIO;
 362        if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
 363                cap->device_caps |= V4L2_CAP_TUNER;
 364        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 365        return 0;
 366}
 367
 368static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 369                                        struct v4l2_fmtdesc *fmt)
 370{
 371        char *desc = NULL;
 372
 373        switch (fmt->index) {
 374        case 0:
 375                fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
 376                desc = "Motion JPEG";
 377                break;
 378        case 1:
 379                fmt->pixelformat = V4L2_PIX_FMT_MPEG1;
 380                desc = "MPEG-1 ES";
 381                break;
 382        case 2:
 383                fmt->pixelformat = V4L2_PIX_FMT_MPEG2;
 384                desc = "MPEG-2 ES";
 385                break;
 386        case 3:
 387                fmt->pixelformat = V4L2_PIX_FMT_MPEG4;
 388                desc = "MPEG-4 ES";
 389                break;
 390        default:
 391                return -EINVAL;
 392        }
 393        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 394        fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
 395
 396        strncpy(fmt->description, desc, sizeof(fmt->description));
 397
 398        return 0;
 399}
 400
 401static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 402                                        struct v4l2_format *fmt)
 403{
 404        struct go7007 *go = video_drvdata(file);
 405
 406        fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 407        fmt->fmt.pix.width = go->width;
 408        fmt->fmt.pix.height = go->height;
 409        fmt->fmt.pix.pixelformat = go->format;
 410        fmt->fmt.pix.field = V4L2_FIELD_NONE;
 411        fmt->fmt.pix.bytesperline = 0;
 412        fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
 413        fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 414
 415        return 0;
 416}
 417
 418static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 419                        struct v4l2_format *fmt)
 420{
 421        struct go7007 *go = video_drvdata(file);
 422
 423        return set_capture_size(go, fmt, 1);
 424}
 425
 426static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 427                        struct v4l2_format *fmt)
 428{
 429        struct go7007 *go = video_drvdata(file);
 430
 431        if (vb2_is_busy(&go->vidq))
 432                return -EBUSY;
 433
 434        return set_capture_size(go, fmt, 0);
 435}
 436
 437static int go7007_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
 438                unsigned int *num_buffers, unsigned int *num_planes,
 439                unsigned int sizes[], void *alloc_ctxs[])
 440{
 441        sizes[0] = GO7007_BUF_SIZE;
 442        *num_planes = 1;
 443
 444        if (*num_buffers < 2)
 445                *num_buffers = 2;
 446
 447        return 0;
 448}
 449
 450static void go7007_buf_queue(struct vb2_buffer *vb)
 451{
 452        struct vb2_queue *vq = vb->vb2_queue;
 453        struct go7007 *go = vb2_get_drv_priv(vq);
 454        struct go7007_buffer *go7007_vb =
 455                container_of(vb, struct go7007_buffer, vb);
 456        unsigned long flags;
 457
 458        spin_lock_irqsave(&go->spinlock, flags);
 459        list_add_tail(&go7007_vb->list, &go->vidq_active);
 460        spin_unlock_irqrestore(&go->spinlock, flags);
 461}
 462
 463static int go7007_buf_prepare(struct vb2_buffer *vb)
 464{
 465        struct go7007_buffer *go7007_vb =
 466                container_of(vb, struct go7007_buffer, vb);
 467
 468        go7007_vb->modet_active = 0;
 469        go7007_vb->frame_offset = 0;
 470        vb->v4l2_planes[0].bytesused = 0;
 471        return 0;
 472}
 473
 474static int go7007_buf_finish(struct vb2_buffer *vb)
 475{
 476        struct vb2_queue *vq = vb->vb2_queue;
 477        struct go7007 *go = vb2_get_drv_priv(vq);
 478        struct go7007_buffer *go7007_vb =
 479                container_of(vb, struct go7007_buffer, vb);
 480        u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format);
 481        struct v4l2_buffer *buf = &vb->v4l2_buf;
 482
 483        buf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
 484                        V4L2_BUF_FLAG_PFRAME);
 485        buf->flags |= frame_type_flag;
 486        buf->field = V4L2_FIELD_NONE;
 487        return 0;
 488}
 489
 490static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
 491{
 492        struct go7007 *go = vb2_get_drv_priv(q);
 493        int ret;
 494
 495        set_formatting(go);
 496        mutex_lock(&go->hw_lock);
 497        go->next_seq = 0;
 498        go->active_buf = NULL;
 499        q->streaming = 1;
 500        if (go7007_start_encoder(go) < 0)
 501                ret = -EIO;
 502        else
 503                ret = 0;
 504        mutex_unlock(&go->hw_lock);
 505        if (ret) {
 506                q->streaming = 0;
 507                return ret;
 508        }
 509        call_all(&go->v4l2_dev, video, s_stream, 1);
 510        v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
 511        v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
 512        v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
 513        v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
 514        /* Turn on Capture LED */
 515        if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
 516                go7007_write_addr(go, 0x3c82, 0x0005);
 517        return ret;
 518}
 519
 520static int go7007_stop_streaming(struct vb2_queue *q)
 521{
 522        struct go7007 *go = vb2_get_drv_priv(q);
 523        unsigned long flags;
 524
 525        q->streaming = 0;
 526        go7007_stream_stop(go);
 527        mutex_lock(&go->hw_lock);
 528        go7007_reset_encoder(go);
 529        mutex_unlock(&go->hw_lock);
 530        call_all(&go->v4l2_dev, video, s_stream, 0);
 531
 532        spin_lock_irqsave(&go->spinlock, flags);
 533        INIT_LIST_HEAD(&go->vidq_active);
 534        spin_unlock_irqrestore(&go->spinlock, flags);
 535        v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
 536        v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
 537        v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
 538        v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
 539        /* Turn on Capture LED */
 540        if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
 541                go7007_write_addr(go, 0x3c82, 0x000d);
 542        return 0;
 543}
 544
 545static struct vb2_ops go7007_video_qops = {
 546        .queue_setup    = go7007_queue_setup,
 547        .buf_queue      = go7007_buf_queue,
 548        .buf_prepare    = go7007_buf_prepare,
 549        .buf_finish     = go7007_buf_finish,
 550        .start_streaming = go7007_start_streaming,
 551        .stop_streaming = go7007_stop_streaming,
 552        .wait_prepare   = vb2_ops_wait_prepare,
 553        .wait_finish    = vb2_ops_wait_finish,
 554};
 555
 556static int vidioc_g_parm(struct file *filp, void *priv,
 557                struct v4l2_streamparm *parm)
 558{
 559        struct go7007 *go = video_drvdata(filp);
 560        struct v4l2_fract timeperframe = {
 561                .numerator = 1001 *  go->fps_scale,
 562                .denominator = go->sensor_framerate,
 563        };
 564
 565        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 566                return -EINVAL;
 567
 568        parm->parm.capture.readbuffers = 2;
 569        parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
 570        parm->parm.capture.timeperframe = timeperframe;
 571
 572        return 0;
 573}
 574
 575static int vidioc_s_parm(struct file *filp, void *priv,
 576                struct v4l2_streamparm *parm)
 577{
 578        struct go7007 *go = video_drvdata(filp);
 579        unsigned int n, d;
 580
 581        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 582                return -EINVAL;
 583
 584        n = go->sensor_framerate *
 585                parm->parm.capture.timeperframe.numerator;
 586        d = 1001 * parm->parm.capture.timeperframe.denominator;
 587        if (n != 0 && d != 0 && n > d)
 588                go->fps_scale = (n + d/2) / d;
 589        else
 590                go->fps_scale = 1;
 591
 592        return vidioc_g_parm(filp, priv, parm);
 593}
 594
 595/* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
 596   its resolution, when the device is not connected to TV.
 597   This is were an API abuse, probably used by the lack of specific IOCTL's to
 598   enumerate it, by the time the driver was written.
 599
 600   However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
 601   and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
 602
 603   The two functions below implement the newer ioctls
 604*/
 605static int vidioc_enum_framesizes(struct file *filp, void *priv,
 606                                  struct v4l2_frmsizeenum *fsize)
 607{
 608        struct go7007 *go = video_drvdata(filp);
 609        int width, height;
 610
 611        if (fsize->index > 2)
 612                return -EINVAL;
 613
 614        if (!valid_pixelformat(fsize->pixel_format))
 615                return -EINVAL;
 616
 617        get_resolution(go, &width, &height);
 618        fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
 619        fsize->discrete.width = (width >> fsize->index) & ~0xf;
 620        fsize->discrete.height = (height >> fsize->index) & ~0xf;
 621        return 0;
 622}
 623
 624static int vidioc_enum_frameintervals(struct file *filp, void *priv,
 625                                      struct v4l2_frmivalenum *fival)
 626{
 627        struct go7007 *go = video_drvdata(filp);
 628        int width, height;
 629        int i;
 630
 631        if (fival->index > 4)
 632                return -EINVAL;
 633
 634        if (!valid_pixelformat(fival->pixel_format))
 635                return -EINVAL;
 636
 637        if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
 638                get_resolution(go, &width, &height);
 639                for (i = 0; i <= 2; i++)
 640                        if (fival->width == ((width >> i) & ~0xf) &&
 641                            fival->height == ((height >> i) & ~0xf))
 642                                break;
 643                if (i > 2)
 644                        return -EINVAL;
 645        }
 646        fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
 647        fival->discrete.numerator = 1001 * (fival->index + 1);
 648        fival->discrete.denominator = go->sensor_framerate;
 649        return 0;
 650}
 651
 652static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
 653{
 654        struct go7007 *go = video_drvdata(file);
 655
 656        *std = go->std;
 657        return 0;
 658}
 659
 660static int go7007_s_std(struct go7007 *go)
 661{
 662        if (go->std & V4L2_STD_625_50) {
 663                go->standard = GO7007_STD_PAL;
 664                go->sensor_framerate = 25025;
 665        } else {
 666                go->standard = GO7007_STD_NTSC;
 667                go->sensor_framerate = 30000;
 668        }
 669
 670        call_all(&go->v4l2_dev, core, s_std, go->std);
 671        set_capture_size(go, NULL, 0);
 672        return 0;
 673}
 674
 675static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
 676{
 677        struct go7007 *go = video_drvdata(file);
 678
 679        if (vb2_is_busy(&go->vidq))
 680                return -EBUSY;
 681
 682        go->std = std;
 683
 684        return go7007_s_std(go);
 685}
 686
 687static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
 688{
 689        struct go7007 *go = video_drvdata(file);
 690
 691        return call_all(&go->v4l2_dev, video, querystd, std);
 692}
 693
 694static int vidioc_enum_input(struct file *file, void *priv,
 695                                struct v4l2_input *inp)
 696{
 697        struct go7007 *go = video_drvdata(file);
 698
 699        if (inp->index >= go->board_info->num_inputs)
 700                return -EINVAL;
 701
 702        strncpy(inp->name, go->board_info->inputs[inp->index].name,
 703                        sizeof(inp->name));
 704
 705        /* If this board has a tuner, it will be the first input */
 706        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
 707                        inp->index == 0)
 708                inp->type = V4L2_INPUT_TYPE_TUNER;
 709        else
 710                inp->type = V4L2_INPUT_TYPE_CAMERA;
 711
 712        if (go->board_info->num_aud_inputs)
 713                inp->audioset = (1 << go->board_info->num_aud_inputs) - 1;
 714        else
 715                inp->audioset = 0;
 716        inp->tuner = 0;
 717        if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
 718                inp->std = video_devdata(file)->tvnorms;
 719        else
 720                inp->std = 0;
 721
 722        return 0;
 723}
 724
 725
 726static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
 727{
 728        struct go7007 *go = video_drvdata(file);
 729
 730        *input = go->input;
 731
 732        return 0;
 733}
 734
 735static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
 736{
 737        struct go7007 *go = video_drvdata(file);
 738
 739        if (a->index >= go->board_info->num_aud_inputs)
 740                return -EINVAL;
 741        strlcpy(a->name, go->board_info->aud_inputs[a->index].name, sizeof(a->name));
 742        a->capability = V4L2_AUDCAP_STEREO;
 743        return 0;
 744}
 745
 746static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
 747{
 748        struct go7007 *go = video_drvdata(file);
 749
 750        a->index = go->aud_input;
 751        strlcpy(a->name, go->board_info->aud_inputs[go->aud_input].name, sizeof(a->name));
 752        a->capability = V4L2_AUDCAP_STEREO;
 753        return 0;
 754}
 755
 756static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
 757{
 758        struct go7007 *go = video_drvdata(file);
 759
 760        if (a->index >= go->board_info->num_aud_inputs)
 761                return -EINVAL;
 762        go->aud_input = a->index;
 763        v4l2_subdev_call(go->sd_audio, audio, s_routing,
 764                        go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0);
 765        return 0;
 766}
 767
 768static void go7007_s_input(struct go7007 *go)
 769{
 770        unsigned int input = go->input;
 771
 772        v4l2_subdev_call(go->sd_video, video, s_routing,
 773                        go->board_info->inputs[input].video_input, 0,
 774                        go->board_info->video_config);
 775        if (go->board_info->num_aud_inputs) {
 776                int aud_input = go->board_info->inputs[input].audio_index;
 777
 778                v4l2_subdev_call(go->sd_audio, audio, s_routing,
 779                        go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
 780                go->aud_input = aud_input;
 781        }
 782}
 783
 784static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
 785{
 786        struct go7007 *go = video_drvdata(file);
 787
 788        if (input >= go->board_info->num_inputs)
 789                return -EINVAL;
 790        if (vb2_is_busy(&go->vidq))
 791                return -EBUSY;
 792
 793        go->input = input;
 794        go7007_s_input(go);
 795
 796        return 0;
 797}
 798
 799static int vidioc_g_tuner(struct file *file, void *priv,
 800                                struct v4l2_tuner *t)
 801{
 802        struct go7007 *go = video_drvdata(file);
 803
 804        if (t->index != 0)
 805                return -EINVAL;
 806
 807        strlcpy(t->name, "Tuner", sizeof(t->name));
 808        return call_all(&go->v4l2_dev, tuner, g_tuner, t);
 809}
 810
 811static int vidioc_s_tuner(struct file *file, void *priv,
 812                                const struct v4l2_tuner *t)
 813{
 814        struct go7007 *go = video_drvdata(file);
 815
 816        if (t->index != 0)
 817                return -EINVAL;
 818
 819        return call_all(&go->v4l2_dev, tuner, s_tuner, t);
 820}
 821
 822static int vidioc_g_frequency(struct file *file, void *priv,
 823                                struct v4l2_frequency *f)
 824{
 825        struct go7007 *go = video_drvdata(file);
 826
 827        if (f->tuner)
 828                return -EINVAL;
 829
 830        return call_all(&go->v4l2_dev, tuner, g_frequency, f);
 831}
 832
 833static int vidioc_s_frequency(struct file *file, void *priv,
 834                                const struct v4l2_frequency *f)
 835{
 836        struct go7007 *go = video_drvdata(file);
 837
 838        if (f->tuner)
 839                return -EINVAL;
 840
 841        return call_all(&go->v4l2_dev, tuner, s_frequency, f);
 842}
 843
 844static int vidioc_log_status(struct file *file, void *priv)
 845{
 846        struct go7007 *go = video_drvdata(file);
 847
 848        v4l2_ctrl_log_status(file, priv);
 849        return call_all(&go->v4l2_dev, core, log_status);
 850}
 851
 852/* FIXME:
 853        Those ioctls are private, and not needed, since several standard
 854        extended controls already provide streaming control.
 855        So, those ioctls should be converted into vidioc_g_ext_ctrls()
 856        and vidioc_s_ext_ctrls()
 857 */
 858
 859#if 0
 860        case GO7007IOC_S_MD_PARAMS:
 861        {
 862                struct go7007_md_params *mdp = arg;
 863
 864                if (mdp->region > 3)
 865                        return -EINVAL;
 866                if (mdp->trigger > 0) {
 867                        go->modet[mdp->region].pixel_threshold =
 868                                        mdp->pixel_threshold >> 1;
 869                        go->modet[mdp->region].motion_threshold =
 870                                        mdp->motion_threshold >> 1;
 871                        go->modet[mdp->region].mb_threshold =
 872                                        mdp->trigger >> 1;
 873                        go->modet[mdp->region].enable = 1;
 874                } else
 875                        go->modet[mdp->region].enable = 0;
 876                /* fall-through */
 877        }
 878        case GO7007IOC_S_MD_REGION:
 879        {
 880                struct go7007_md_region *region = arg;
 881
 882                if (region->region < 1 || region->region > 3)
 883                        return -EINVAL;
 884                return clip_to_modet_map(go, region->region, region->clips);
 885        }
 886#endif
 887
 888static struct v4l2_file_operations go7007_fops = {
 889        .owner          = THIS_MODULE,
 890        .open           = v4l2_fh_open,
 891        .release        = vb2_fop_release,
 892        .unlocked_ioctl = video_ioctl2,
 893        .read           = vb2_fop_read,
 894        .mmap           = vb2_fop_mmap,
 895        .poll           = vb2_fop_poll,
 896};
 897
 898static const struct v4l2_ioctl_ops video_ioctl_ops = {
 899        .vidioc_querycap          = vidioc_querycap,
 900        .vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
 901        .vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
 902        .vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
 903        .vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
 904        .vidioc_reqbufs           = vb2_ioctl_reqbufs,
 905        .vidioc_querybuf          = vb2_ioctl_querybuf,
 906        .vidioc_qbuf              = vb2_ioctl_qbuf,
 907        .vidioc_dqbuf             = vb2_ioctl_dqbuf,
 908        .vidioc_g_std             = vidioc_g_std,
 909        .vidioc_s_std             = vidioc_s_std,
 910        .vidioc_querystd          = vidioc_querystd,
 911        .vidioc_enum_input        = vidioc_enum_input,
 912        .vidioc_g_input           = vidioc_g_input,
 913        .vidioc_s_input           = vidioc_s_input,
 914        .vidioc_enumaudio         = vidioc_enumaudio,
 915        .vidioc_g_audio           = vidioc_g_audio,
 916        .vidioc_s_audio           = vidioc_s_audio,
 917        .vidioc_streamon          = vb2_ioctl_streamon,
 918        .vidioc_streamoff         = vb2_ioctl_streamoff,
 919        .vidioc_g_tuner           = vidioc_g_tuner,
 920        .vidioc_s_tuner           = vidioc_s_tuner,
 921        .vidioc_g_frequency       = vidioc_g_frequency,
 922        .vidioc_s_frequency       = vidioc_s_frequency,
 923        .vidioc_g_parm            = vidioc_g_parm,
 924        .vidioc_s_parm            = vidioc_s_parm,
 925        .vidioc_enum_framesizes   = vidioc_enum_framesizes,
 926        .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
 927        .vidioc_log_status        = vidioc_log_status,
 928        .vidioc_subscribe_event   = v4l2_ctrl_subscribe_event,
 929        .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 930};
 931
 932static struct video_device go7007_template = {
 933        .name           = "go7007",
 934        .fops           = &go7007_fops,
 935        .release        = video_device_release_empty,
 936        .ioctl_ops      = &video_ioctl_ops,
 937        .tvnorms        = V4L2_STD_ALL,
 938};
 939
 940int go7007_v4l2_ctrl_init(struct go7007 *go)
 941{
 942        struct v4l2_ctrl_handler *hdl = &go->hdl;
 943        struct v4l2_ctrl *ctrl;
 944
 945        v4l2_ctrl_handler_init(hdl, 13);
 946        go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
 947                        V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
 948        go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
 949                        V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
 950        go->mpeg_video_bitrate = v4l2_ctrl_new_std(hdl, NULL,
 951                        V4L2_CID_MPEG_VIDEO_BITRATE,
 952                        64000, 10000000, 1, 9800000);
 953        go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
 954                        V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
 955        go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
 956                        V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
 957
 958        go->mpeg_video_aspect_ratio = v4l2_ctrl_new_std_menu(hdl, NULL,
 959                        V4L2_CID_MPEG_VIDEO_ASPECT,
 960                        V4L2_MPEG_VIDEO_ASPECT_16x9, 0,
 961                        V4L2_MPEG_VIDEO_ASPECT_1x1);
 962        ctrl = v4l2_ctrl_new_std(hdl, NULL,
 963                        V4L2_CID_JPEG_ACTIVE_MARKER, 0,
 964                        V4L2_JPEG_ACTIVE_MARKER_DQT | V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
 965                        V4L2_JPEG_ACTIVE_MARKER_DQT | V4L2_JPEG_ACTIVE_MARKER_DHT);
 966        if (ctrl)
 967                ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 968        if (hdl->error) {
 969                int rv = hdl->error;
 970
 971                v4l2_err(&go->v4l2_dev, "Could not register controls\n");
 972                return rv;
 973        }
 974        go->v4l2_dev.ctrl_handler = hdl;
 975        return 0;
 976}
 977
 978int go7007_v4l2_init(struct go7007 *go)
 979{
 980        struct video_device *vdev = &go->vdev;
 981        int rv;
 982
 983        mutex_init(&go->serialize_lock);
 984        mutex_init(&go->queue_lock);
 985
 986        INIT_LIST_HEAD(&go->vidq_active);
 987        go->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 988        go->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
 989        go->vidq.ops = &go7007_video_qops;
 990        go->vidq.mem_ops = &vb2_vmalloc_memops;
 991        go->vidq.drv_priv = go;
 992        go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
 993        go->vidq.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 994        go->vidq.lock = &go->queue_lock;
 995        rv = vb2_queue_init(&go->vidq);
 996        if (rv)
 997                return rv;
 998        *vdev = go7007_template;
 999        vdev->lock = &go->serialize_lock;
1000        vdev->queue = &go->vidq;
1001        set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
1002        video_set_drvdata(vdev, go);
1003        vdev->v4l2_dev = &go->v4l2_dev;
1004        if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd))
1005                v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
1006        if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
1007                v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY);
1008                v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY);
1009                v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER);
1010                v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER);
1011        } else {
1012                struct v4l2_frequency f = {
1013                        .type = V4L2_TUNER_ANALOG_TV,
1014                        .frequency = 980,
1015                };
1016
1017                call_all(&go->v4l2_dev, tuner, s_frequency, &f);
1018        }
1019        if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
1020                v4l2_disable_ioctl(vdev, VIDIOC_G_STD);
1021                v4l2_disable_ioctl(vdev, VIDIOC_S_STD);
1022                vdev->tvnorms = 0;
1023        }
1024        if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
1025                v4l2_disable_ioctl(vdev, VIDIOC_ENUM_FRAMESIZES);
1026        if (go->board_info->num_aud_inputs == 0) {
1027                v4l2_disable_ioctl(vdev, VIDIOC_G_AUDIO);
1028                v4l2_disable_ioctl(vdev, VIDIOC_S_AUDIO);
1029                v4l2_disable_ioctl(vdev, VIDIOC_ENUMAUDIO);
1030        }
1031        /* Setup correct crystal frequency on this board */
1032        if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
1033                v4l2_subdev_call(go->sd_video, video, s_crystal_freq,
1034                                SAA7115_FREQ_24_576_MHZ,
1035                                SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC |
1036                                SAA7115_FREQ_FL_DOUBLE_ASCLK);
1037        go7007_s_input(go);
1038        if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1039                go7007_s_std(go);
1040        rv = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1041        if (rv < 0)
1042                return rv;
1043        dev_info(go->dev, "registered device %s [v4l2]\n",
1044                 video_device_node_name(vdev));
1045
1046        return 0;
1047}
1048
1049void go7007_v4l2_remove(struct go7007 *go)
1050{
1051        v4l2_ctrl_handler_free(&go->hdl);
1052}
1053