linux/drivers/media/platform/vivid/vivid-vid-out.c
<<
>>
Prefs
   1/*
   2 * vivid-vid-out.c - video output support functions.
   3 *
   4 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
   5 *
   6 * This program is free software; you may redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; version 2 of the License.
   9 *
  10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  11 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  12 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  13 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  14 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  15 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  16 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  17 * SOFTWARE.
  18 */
  19
  20#include <linux/errno.h>
  21#include <linux/kernel.h>
  22#include <linux/sched.h>
  23#include <linux/videodev2.h>
  24#include <linux/v4l2-dv-timings.h>
  25#include <media/v4l2-common.h>
  26#include <media/v4l2-event.h>
  27#include <media/v4l2-dv-timings.h>
  28
  29#include "vivid-core.h"
  30#include "vivid-vid-common.h"
  31#include "vivid-kthread-out.h"
  32#include "vivid-vid-out.h"
  33
  34static int vid_out_queue_setup(struct vb2_queue *vq, const void *parg,
  35                       unsigned *nbuffers, unsigned *nplanes,
  36                       unsigned sizes[], void *alloc_ctxs[])
  37{
  38        const struct v4l2_format *fmt = parg;
  39        struct vivid_dev *dev = vb2_get_drv_priv(vq);
  40        const struct vivid_fmt *vfmt = dev->fmt_out;
  41        unsigned planes = vfmt->buffers;
  42        unsigned h = dev->fmt_out_rect.height;
  43        unsigned size = dev->bytesperline_out[0] * h;
  44        unsigned p;
  45
  46        for (p = vfmt->buffers; p < vfmt->planes; p++)
  47                size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p];
  48
  49        if (dev->field_out == V4L2_FIELD_ALTERNATE) {
  50                /*
  51                 * You cannot use write() with FIELD_ALTERNATE since the field
  52                 * information (TOP/BOTTOM) cannot be passed to the kernel.
  53                 */
  54                if (vb2_fileio_is_active(vq))
  55                        return -EINVAL;
  56        }
  57
  58        if (dev->queue_setup_error) {
  59                /*
  60                 * Error injection: test what happens if queue_setup() returns
  61                 * an error.
  62                 */
  63                dev->queue_setup_error = false;
  64                return -EINVAL;
  65        }
  66
  67        if (fmt) {
  68                const struct v4l2_pix_format_mplane *mp;
  69                struct v4l2_format mp_fmt;
  70
  71                if (!V4L2_TYPE_IS_MULTIPLANAR(fmt->type)) {
  72                        fmt_sp2mp(fmt, &mp_fmt);
  73                        fmt = &mp_fmt;
  74                }
  75                mp = &fmt->fmt.pix_mp;
  76                /*
  77                 * Check if the number of planes in the specified format match
  78                 * the number of planes in the current format. You can't mix that.
  79                 */
  80                if (mp->num_planes != planes)
  81                        return -EINVAL;
  82                sizes[0] = mp->plane_fmt[0].sizeimage;
  83                if (sizes[0] < size)
  84                        return -EINVAL;
  85                for (p = 1; p < planes; p++) {
  86                        sizes[p] = mp->plane_fmt[p].sizeimage;
  87                        if (sizes[p] < dev->bytesperline_out[p] * h)
  88                                return -EINVAL;
  89                }
  90        } else {
  91                for (p = 0; p < planes; p++)
  92                        sizes[p] = p ? dev->bytesperline_out[p] * h : size;
  93        }
  94
  95        if (vq->num_buffers + *nbuffers < 2)
  96                *nbuffers = 2 - vq->num_buffers;
  97
  98        *nplanes = planes;
  99
 100        /*
 101         * videobuf2-vmalloc allocator is context-less so no need to set
 102         * alloc_ctxs array.
 103         */
 104
 105        dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
 106        for (p = 0; p < planes; p++)
 107                dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
 108        return 0;
 109}
 110
 111static int vid_out_buf_prepare(struct vb2_buffer *vb)
 112{
 113        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 114        struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 115        unsigned long size;
 116        unsigned planes;
 117        unsigned p;
 118
 119        dprintk(dev, 1, "%s\n", __func__);
 120
 121        if (WARN_ON(NULL == dev->fmt_out))
 122                return -EINVAL;
 123
 124        planes = dev->fmt_out->planes;
 125
 126        if (dev->buf_prepare_error) {
 127                /*
 128                 * Error injection: test what happens if buf_prepare() returns
 129                 * an error.
 130                 */
 131                dev->buf_prepare_error = false;
 132                return -EINVAL;
 133        }
 134
 135        if (dev->field_out != V4L2_FIELD_ALTERNATE)
 136                vbuf->field = dev->field_out;
 137        else if (vbuf->field != V4L2_FIELD_TOP &&
 138                 vbuf->field != V4L2_FIELD_BOTTOM)
 139                return -EINVAL;
 140
 141        for (p = 0; p < planes; p++) {
 142                size = dev->bytesperline_out[p] * dev->fmt_out_rect.height +
 143                        vb->planes[p].data_offset;
 144
 145                if (vb2_get_plane_payload(vb, p) < size) {
 146                        dprintk(dev, 1, "%s the payload is too small for plane %u (%lu < %lu)\n",
 147                                        __func__, p, vb2_get_plane_payload(vb, p), size);
 148                        return -EINVAL;
 149                }
 150        }
 151
 152        return 0;
 153}
 154
 155static void vid_out_buf_queue(struct vb2_buffer *vb)
 156{
 157        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 158        struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 159        struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
 160
 161        dprintk(dev, 1, "%s\n", __func__);
 162
 163        spin_lock(&dev->slock);
 164        list_add_tail(&buf->list, &dev->vid_out_active);
 165        spin_unlock(&dev->slock);
 166}
 167
 168static int vid_out_start_streaming(struct vb2_queue *vq, unsigned count)
 169{
 170        struct vivid_dev *dev = vb2_get_drv_priv(vq);
 171        int err;
 172
 173        if (vb2_is_streaming(&dev->vb_vid_cap_q))
 174                dev->can_loop_video = vivid_vid_can_loop(dev);
 175
 176        if (dev->kthread_vid_out)
 177                return 0;
 178
 179        dev->vid_out_seq_count = 0;
 180        dprintk(dev, 1, "%s\n", __func__);
 181        if (dev->start_streaming_error) {
 182                dev->start_streaming_error = false;
 183                err = -EINVAL;
 184        } else {
 185                err = vivid_start_generating_vid_out(dev, &dev->vid_out_streaming);
 186        }
 187        if (err) {
 188                struct vivid_buffer *buf, *tmp;
 189
 190                list_for_each_entry_safe(buf, tmp, &dev->vid_out_active, list) {
 191                        list_del(&buf->list);
 192                        vb2_buffer_done(&buf->vb.vb2_buf,
 193                                        VB2_BUF_STATE_QUEUED);
 194                }
 195        }
 196        return err;
 197}
 198
 199/* abort streaming and wait for last buffer */
 200static void vid_out_stop_streaming(struct vb2_queue *vq)
 201{
 202        struct vivid_dev *dev = vb2_get_drv_priv(vq);
 203
 204        dprintk(dev, 1, "%s\n", __func__);
 205        vivid_stop_generating_vid_out(dev, &dev->vid_out_streaming);
 206        dev->can_loop_video = false;
 207}
 208
 209const struct vb2_ops vivid_vid_out_qops = {
 210        .queue_setup            = vid_out_queue_setup,
 211        .buf_prepare            = vid_out_buf_prepare,
 212        .buf_queue              = vid_out_buf_queue,
 213        .start_streaming        = vid_out_start_streaming,
 214        .stop_streaming         = vid_out_stop_streaming,
 215        .wait_prepare           = vb2_ops_wait_prepare,
 216        .wait_finish            = vb2_ops_wait_finish,
 217};
 218
 219/*
 220 * Called whenever the format has to be reset which can occur when
 221 * changing outputs, standard, timings, etc.
 222 */
 223void vivid_update_format_out(struct vivid_dev *dev)
 224{
 225        struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
 226        unsigned size, p;
 227
 228        switch (dev->output_type[dev->output]) {
 229        case SVID:
 230        default:
 231                dev->field_out = dev->tv_field_out;
 232                dev->sink_rect.width = 720;
 233                if (dev->std_out & V4L2_STD_525_60) {
 234                        dev->sink_rect.height = 480;
 235                        dev->timeperframe_vid_out = (struct v4l2_fract) { 1001, 30000 };
 236                        dev->service_set_out = V4L2_SLICED_CAPTION_525;
 237                } else {
 238                        dev->sink_rect.height = 576;
 239                        dev->timeperframe_vid_out = (struct v4l2_fract) { 1000, 25000 };
 240                        dev->service_set_out = V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
 241                }
 242                dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
 243                break;
 244        case HDMI:
 245                dev->sink_rect.width = bt->width;
 246                dev->sink_rect.height = bt->height;
 247                size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt);
 248                dev->timeperframe_vid_out = (struct v4l2_fract) {
 249                        size / 100, (u32)bt->pixelclock / 100
 250                };
 251                if (bt->interlaced)
 252                        dev->field_out = V4L2_FIELD_ALTERNATE;
 253                else
 254                        dev->field_out = V4L2_FIELD_NONE;
 255                if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
 256                        if (bt->width == 720 && bt->height <= 576)
 257                                dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
 258                        else
 259                                dev->colorspace_out = V4L2_COLORSPACE_REC709;
 260                } else {
 261                        dev->colorspace_out = V4L2_COLORSPACE_SRGB;
 262                }
 263                break;
 264        }
 265        dev->xfer_func_out = V4L2_XFER_FUNC_DEFAULT;
 266        dev->ycbcr_enc_out = V4L2_YCBCR_ENC_DEFAULT;
 267        dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
 268        dev->compose_out = dev->sink_rect;
 269        dev->compose_bounds_out = dev->sink_rect;
 270        dev->crop_out = dev->compose_out;
 271        if (V4L2_FIELD_HAS_T_OR_B(dev->field_out))
 272                dev->crop_out.height /= 2;
 273        dev->fmt_out_rect = dev->crop_out;
 274        for (p = 0; p < dev->fmt_out->planes; p++)
 275                dev->bytesperline_out[p] =
 276                        (dev->sink_rect.width * dev->fmt_out->bit_depth[p]) / 8;
 277}
 278
 279/* Map the field to something that is valid for the current output */
 280static enum v4l2_field vivid_field_out(struct vivid_dev *dev, enum v4l2_field field)
 281{
 282        if (vivid_is_svid_out(dev)) {
 283                switch (field) {
 284                case V4L2_FIELD_INTERLACED_TB:
 285                case V4L2_FIELD_INTERLACED_BT:
 286                case V4L2_FIELD_SEQ_TB:
 287                case V4L2_FIELD_SEQ_BT:
 288                case V4L2_FIELD_ALTERNATE:
 289                        return field;
 290                case V4L2_FIELD_INTERLACED:
 291                default:
 292                        return V4L2_FIELD_INTERLACED;
 293                }
 294        }
 295        if (vivid_is_hdmi_out(dev))
 296                return dev->dv_timings_out.bt.interlaced ? V4L2_FIELD_ALTERNATE :
 297                                                       V4L2_FIELD_NONE;
 298        return V4L2_FIELD_NONE;
 299}
 300
 301static enum tpg_pixel_aspect vivid_get_pixel_aspect(const struct vivid_dev *dev)
 302{
 303        if (vivid_is_svid_out(dev))
 304                return (dev->std_out & V4L2_STD_525_60) ?
 305                        TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;
 306
 307        if (vivid_is_hdmi_out(dev) &&
 308            dev->sink_rect.width == 720 && dev->sink_rect.height <= 576)
 309                return dev->sink_rect.height == 480 ?
 310                        TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL;
 311
 312        return TPG_PIXEL_ASPECT_SQUARE;
 313}
 314
 315int vivid_g_fmt_vid_out(struct file *file, void *priv,
 316                                        struct v4l2_format *f)
 317{
 318        struct vivid_dev *dev = video_drvdata(file);
 319        struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
 320        const struct vivid_fmt *fmt = dev->fmt_out;
 321        unsigned p;
 322
 323        mp->width        = dev->fmt_out_rect.width;
 324        mp->height       = dev->fmt_out_rect.height;
 325        mp->field        = dev->field_out;
 326        mp->pixelformat  = fmt->fourcc;
 327        mp->colorspace   = dev->colorspace_out;
 328        mp->xfer_func    = dev->xfer_func_out;
 329        mp->ycbcr_enc    = dev->ycbcr_enc_out;
 330        mp->quantization = dev->quantization_out;
 331        mp->num_planes = fmt->buffers;
 332        for (p = 0; p < mp->num_planes; p++) {
 333                mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p];
 334                mp->plane_fmt[p].sizeimage =
 335                        mp->plane_fmt[p].bytesperline * mp->height;
 336        }
 337        for (p = fmt->buffers; p < fmt->planes; p++) {
 338                unsigned stride = dev->bytesperline_out[p];
 339
 340                mp->plane_fmt[0].sizeimage +=
 341                        (stride * mp->height) / fmt->vdownsampling[p];
 342        }
 343        return 0;
 344}
 345
 346int vivid_try_fmt_vid_out(struct file *file, void *priv,
 347                        struct v4l2_format *f)
 348{
 349        struct vivid_dev *dev = video_drvdata(file);
 350        struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
 351        struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
 352        struct v4l2_plane_pix_format *pfmt = mp->plane_fmt;
 353        const struct vivid_fmt *fmt;
 354        unsigned bytesperline, max_bpl;
 355        unsigned factor = 1;
 356        unsigned w, h;
 357        unsigned p;
 358
 359        fmt = vivid_get_format(dev, mp->pixelformat);
 360        if (!fmt) {
 361                dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n",
 362                        mp->pixelformat);
 363                mp->pixelformat = V4L2_PIX_FMT_YUYV;
 364                fmt = vivid_get_format(dev, mp->pixelformat);
 365        }
 366
 367        mp->field = vivid_field_out(dev, mp->field);
 368        if (vivid_is_svid_out(dev)) {
 369                w = 720;
 370                h = (dev->std_out & V4L2_STD_525_60) ? 480 : 576;
 371        } else {
 372                w = dev->sink_rect.width;
 373                h = dev->sink_rect.height;
 374        }
 375        if (V4L2_FIELD_HAS_T_OR_B(mp->field))
 376                factor = 2;
 377        if (!dev->has_scaler_out && !dev->has_crop_out && !dev->has_compose_out) {
 378                mp->width = w;
 379                mp->height = h / factor;
 380        } else {
 381                struct v4l2_rect r = { 0, 0, mp->width, mp->height * factor };
 382
 383                rect_set_min_size(&r, &vivid_min_rect);
 384                rect_set_max_size(&r, &vivid_max_rect);
 385                if (dev->has_scaler_out && !dev->has_crop_out) {
 386                        struct v4l2_rect max_r = { 0, 0, MAX_ZOOM * w, MAX_ZOOM * h };
 387
 388                        rect_set_max_size(&r, &max_r);
 389                } else if (!dev->has_scaler_out && dev->has_compose_out && !dev->has_crop_out) {
 390                        rect_set_max_size(&r, &dev->sink_rect);
 391                } else if (!dev->has_scaler_out && !dev->has_compose_out) {
 392                        rect_set_min_size(&r, &dev->sink_rect);
 393                }
 394                mp->width = r.width;
 395                mp->height = r.height / factor;
 396        }
 397
 398        /* This driver supports custom bytesperline values */
 399
 400        /* Calculate the minimum supported bytesperline value */
 401        bytesperline = (mp->width * fmt->bit_depth[0]) >> 3;
 402        /* Calculate the maximum supported bytesperline value */
 403        max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[0]) >> 3;
 404        mp->num_planes = fmt->buffers;
 405        for (p = 0; p < mp->num_planes; p++) {
 406                if (pfmt[p].bytesperline > max_bpl)
 407                        pfmt[p].bytesperline = max_bpl;
 408                if (pfmt[p].bytesperline < bytesperline)
 409                        pfmt[p].bytesperline = bytesperline;
 410                pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height;
 411                memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
 412        }
 413        for (p = fmt->buffers; p < fmt->planes; p++)
 414                pfmt[0].sizeimage += (pfmt[0].bytesperline * fmt->bit_depth[p]) /
 415                                     (fmt->bit_depth[0] * fmt->vdownsampling[p]);
 416        mp->xfer_func = V4L2_XFER_FUNC_DEFAULT;
 417        mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
 418        mp->quantization = V4L2_QUANTIZATION_DEFAULT;
 419        if (vivid_is_svid_out(dev)) {
 420                mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
 421        } else if (dev->dvi_d_out || !(bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
 422                mp->colorspace = V4L2_COLORSPACE_SRGB;
 423                if (dev->dvi_d_out)
 424                        mp->quantization = V4L2_QUANTIZATION_LIM_RANGE;
 425        } else if (bt->width == 720 && bt->height <= 576) {
 426                mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
 427        } else if (mp->colorspace != V4L2_COLORSPACE_SMPTE170M &&
 428                   mp->colorspace != V4L2_COLORSPACE_REC709 &&
 429                   mp->colorspace != V4L2_COLORSPACE_ADOBERGB &&
 430                   mp->colorspace != V4L2_COLORSPACE_BT2020 &&
 431                   mp->colorspace != V4L2_COLORSPACE_SRGB) {
 432                mp->colorspace = V4L2_COLORSPACE_REC709;
 433        }
 434        memset(mp->reserved, 0, sizeof(mp->reserved));
 435        return 0;
 436}
 437
 438int vivid_s_fmt_vid_out(struct file *file, void *priv,
 439                                        struct v4l2_format *f)
 440{
 441        struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
 442        struct vivid_dev *dev = video_drvdata(file);
 443        struct v4l2_rect *crop = &dev->crop_out;
 444        struct v4l2_rect *compose = &dev->compose_out;
 445        struct vb2_queue *q = &dev->vb_vid_out_q;
 446        int ret = vivid_try_fmt_vid_out(file, priv, f);
 447        unsigned factor = 1;
 448        unsigned p;
 449
 450        if (ret < 0)
 451                return ret;
 452
 453        if (vb2_is_busy(q) &&
 454            (vivid_is_svid_out(dev) ||
 455             mp->width != dev->fmt_out_rect.width ||
 456             mp->height != dev->fmt_out_rect.height ||
 457             mp->pixelformat != dev->fmt_out->fourcc ||
 458             mp->field != dev->field_out)) {
 459                dprintk(dev, 1, "%s device busy\n", __func__);
 460                return -EBUSY;
 461        }
 462
 463        /*
 464         * Allow for changing the colorspace on the fly. Useful for testing
 465         * purposes, and it is something that HDMI transmitters are able
 466         * to do.
 467         */
 468        if (vb2_is_busy(q))
 469                goto set_colorspace;
 470
 471        dev->fmt_out = vivid_get_format(dev, mp->pixelformat);
 472        if (V4L2_FIELD_HAS_T_OR_B(mp->field))
 473                factor = 2;
 474
 475        if (dev->has_scaler_out || dev->has_crop_out || dev->has_compose_out) {
 476                struct v4l2_rect r = { 0, 0, mp->width, mp->height };
 477
 478                if (dev->has_scaler_out) {
 479                        if (dev->has_crop_out)
 480                                rect_map_inside(crop, &r);
 481                        else
 482                                *crop = r;
 483                        if (dev->has_compose_out && !dev->has_crop_out) {
 484                                struct v4l2_rect min_r = {
 485                                        0, 0,
 486                                        r.width / MAX_ZOOM,
 487                                        factor * r.height / MAX_ZOOM
 488                                };
 489                                struct v4l2_rect max_r = {
 490                                        0, 0,
 491                                        r.width * MAX_ZOOM,
 492                                        factor * r.height * MAX_ZOOM
 493                                };
 494
 495                                rect_set_min_size(compose, &min_r);
 496                                rect_set_max_size(compose, &max_r);
 497                                rect_map_inside(compose, &dev->compose_bounds_out);
 498                        } else if (dev->has_compose_out) {
 499                                struct v4l2_rect min_r = {
 500                                        0, 0,
 501                                        crop->width / MAX_ZOOM,
 502                                        factor * crop->height / MAX_ZOOM
 503                                };
 504                                struct v4l2_rect max_r = {
 505                                        0, 0,
 506                                        crop->width * MAX_ZOOM,
 507                                        factor * crop->height * MAX_ZOOM
 508                                };
 509
 510                                rect_set_min_size(compose, &min_r);
 511                                rect_set_max_size(compose, &max_r);
 512                                rect_map_inside(compose, &dev->compose_bounds_out);
 513                        }
 514                } else if (dev->has_compose_out && !dev->has_crop_out) {
 515                        rect_set_size_to(crop, &r);
 516                        r.height *= factor;
 517                        rect_set_size_to(compose, &r);
 518                        rect_map_inside(compose, &dev->compose_bounds_out);
 519                } else if (!dev->has_compose_out) {
 520                        rect_map_inside(crop, &r);
 521                        r.height /= factor;
 522                        rect_set_size_to(compose, &r);
 523                } else {
 524                        r.height *= factor;
 525                        rect_set_max_size(compose, &r);
 526                        rect_map_inside(compose, &dev->compose_bounds_out);
 527                        crop->top *= factor;
 528                        crop->height *= factor;
 529                        rect_set_size_to(crop, compose);
 530                        rect_map_inside(crop, &r);
 531                        crop->top /= factor;
 532                        crop->height /= factor;
 533                }
 534        } else {
 535                struct v4l2_rect r = { 0, 0, mp->width, mp->height };
 536
 537                rect_set_size_to(crop, &r);
 538                r.height /= factor;
 539                rect_set_size_to(compose, &r);
 540        }
 541
 542        dev->fmt_out_rect.width = mp->width;
 543        dev->fmt_out_rect.height = mp->height;
 544        for (p = 0; p < mp->num_planes; p++)
 545                dev->bytesperline_out[p] = mp->plane_fmt[p].bytesperline;
 546        for (p = dev->fmt_out->buffers; p < dev->fmt_out->planes; p++)
 547                dev->bytesperline_out[p] =
 548                        (dev->bytesperline_out[0] * dev->fmt_out->bit_depth[p]) /
 549                        dev->fmt_out->bit_depth[0];
 550        dev->field_out = mp->field;
 551        if (vivid_is_svid_out(dev))
 552                dev->tv_field_out = mp->field;
 553
 554set_colorspace:
 555        dev->colorspace_out = mp->colorspace;
 556        dev->xfer_func_out = mp->xfer_func;
 557        dev->ycbcr_enc_out = mp->ycbcr_enc;
 558        dev->quantization_out = mp->quantization;
 559        if (dev->loop_video) {
 560                vivid_send_source_change(dev, SVID);
 561                vivid_send_source_change(dev, HDMI);
 562        }
 563        return 0;
 564}
 565
 566int vidioc_g_fmt_vid_out_mplane(struct file *file, void *priv,
 567                                        struct v4l2_format *f)
 568{
 569        struct vivid_dev *dev = video_drvdata(file);
 570
 571        if (!dev->multiplanar)
 572                return -ENOTTY;
 573        return vivid_g_fmt_vid_out(file, priv, f);
 574}
 575
 576int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
 577                        struct v4l2_format *f)
 578{
 579        struct vivid_dev *dev = video_drvdata(file);
 580
 581        if (!dev->multiplanar)
 582                return -ENOTTY;
 583        return vivid_try_fmt_vid_out(file, priv, f);
 584}
 585
 586int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv,
 587                        struct v4l2_format *f)
 588{
 589        struct vivid_dev *dev = video_drvdata(file);
 590
 591        if (!dev->multiplanar)
 592                return -ENOTTY;
 593        return vivid_s_fmt_vid_out(file, priv, f);
 594}
 595
 596int vidioc_g_fmt_vid_out(struct file *file, void *priv,
 597                                        struct v4l2_format *f)
 598{
 599        struct vivid_dev *dev = video_drvdata(file);
 600
 601        if (dev->multiplanar)
 602                return -ENOTTY;
 603        return fmt_sp2mp_func(file, priv, f, vivid_g_fmt_vid_out);
 604}
 605
 606int vidioc_try_fmt_vid_out(struct file *file, void *priv,
 607                        struct v4l2_format *f)
 608{
 609        struct vivid_dev *dev = video_drvdata(file);
 610
 611        if (dev->multiplanar)
 612                return -ENOTTY;
 613        return fmt_sp2mp_func(file, priv, f, vivid_try_fmt_vid_out);
 614}
 615
 616int vidioc_s_fmt_vid_out(struct file *file, void *priv,
 617                        struct v4l2_format *f)
 618{
 619        struct vivid_dev *dev = video_drvdata(file);
 620
 621        if (dev->multiplanar)
 622                return -ENOTTY;
 623        return fmt_sp2mp_func(file, priv, f, vivid_s_fmt_vid_out);
 624}
 625
 626int vivid_vid_out_g_selection(struct file *file, void *priv,
 627                              struct v4l2_selection *sel)
 628{
 629        struct vivid_dev *dev = video_drvdata(file);
 630
 631        if (!dev->has_crop_out && !dev->has_compose_out)
 632                return -ENOTTY;
 633        if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
 634                return -EINVAL;
 635
 636        sel->r.left = sel->r.top = 0;
 637        switch (sel->target) {
 638        case V4L2_SEL_TGT_CROP:
 639                if (!dev->has_crop_out)
 640                        return -EINVAL;
 641                sel->r = dev->crop_out;
 642                break;
 643        case V4L2_SEL_TGT_CROP_DEFAULT:
 644                if (!dev->has_crop_out)
 645                        return -EINVAL;
 646                sel->r = dev->fmt_out_rect;
 647                break;
 648        case V4L2_SEL_TGT_CROP_BOUNDS:
 649                if (!dev->has_crop_out)
 650                        return -EINVAL;
 651                sel->r = vivid_max_rect;
 652                break;
 653        case V4L2_SEL_TGT_COMPOSE:
 654                if (!dev->has_compose_out)
 655                        return -EINVAL;
 656                sel->r = dev->compose_out;
 657                break;
 658        case V4L2_SEL_TGT_COMPOSE_DEFAULT:
 659        case V4L2_SEL_TGT_COMPOSE_BOUNDS:
 660                if (!dev->has_compose_out)
 661                        return -EINVAL;
 662                sel->r = dev->sink_rect;
 663                break;
 664        default:
 665                return -EINVAL;
 666        }
 667        return 0;
 668}
 669
 670int vivid_vid_out_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
 671{
 672        struct vivid_dev *dev = video_drvdata(file);
 673        struct v4l2_rect *crop = &dev->crop_out;
 674        struct v4l2_rect *compose = &dev->compose_out;
 675        unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_out) ? 2 : 1;
 676        int ret;
 677
 678        if (!dev->has_crop_out && !dev->has_compose_out)
 679                return -ENOTTY;
 680        if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
 681                return -EINVAL;
 682
 683        switch (s->target) {
 684        case V4L2_SEL_TGT_CROP:
 685                if (!dev->has_crop_out)
 686                        return -EINVAL;
 687                ret = vivid_vid_adjust_sel(s->flags, &s->r);
 688                if (ret)
 689                        return ret;
 690                rect_set_min_size(&s->r, &vivid_min_rect);
 691                rect_set_max_size(&s->r, &dev->fmt_out_rect);
 692                if (dev->has_scaler_out) {
 693                        struct v4l2_rect max_rect = {
 694                                0, 0,
 695                                dev->sink_rect.width * MAX_ZOOM,
 696                                (dev->sink_rect.height / factor) * MAX_ZOOM
 697                        };
 698
 699                        rect_set_max_size(&s->r, &max_rect);
 700                        if (dev->has_compose_out) {
 701                                struct v4l2_rect min_rect = {
 702                                        0, 0,
 703                                        s->r.width / MAX_ZOOM,
 704                                        (s->r.height * factor) / MAX_ZOOM
 705                                };
 706                                struct v4l2_rect max_rect = {
 707                                        0, 0,
 708                                        s->r.width * MAX_ZOOM,
 709                                        (s->r.height * factor) * MAX_ZOOM
 710                                };
 711
 712                                rect_set_min_size(compose, &min_rect);
 713                                rect_set_max_size(compose, &max_rect);
 714                                rect_map_inside(compose, &dev->compose_bounds_out);
 715                        }
 716                } else if (dev->has_compose_out) {
 717                        s->r.top *= factor;
 718                        s->r.height *= factor;
 719                        rect_set_max_size(&s->r, &dev->sink_rect);
 720                        rect_set_size_to(compose, &s->r);
 721                        rect_map_inside(compose, &dev->compose_bounds_out);
 722                        s->r.top /= factor;
 723                        s->r.height /= factor;
 724                } else {
 725                        rect_set_size_to(&s->r, &dev->sink_rect);
 726                        s->r.height /= factor;
 727                }
 728                rect_map_inside(&s->r, &dev->fmt_out_rect);
 729                *crop = s->r;
 730                break;
 731        case V4L2_SEL_TGT_COMPOSE:
 732                if (!dev->has_compose_out)
 733                        return -EINVAL;
 734                ret = vivid_vid_adjust_sel(s->flags, &s->r);
 735                if (ret)
 736                        return ret;
 737                rect_set_min_size(&s->r, &vivid_min_rect);
 738                rect_set_max_size(&s->r, &dev->sink_rect);
 739                rect_map_inside(&s->r, &dev->compose_bounds_out);
 740                s->r.top /= factor;
 741                s->r.height /= factor;
 742                if (dev->has_scaler_out) {
 743                        struct v4l2_rect fmt = dev->fmt_out_rect;
 744                        struct v4l2_rect max_rect = {
 745                                0, 0,
 746                                s->r.width * MAX_ZOOM,
 747                                s->r.height * MAX_ZOOM
 748                        };
 749                        struct v4l2_rect min_rect = {
 750                                0, 0,
 751                                s->r.width / MAX_ZOOM,
 752                                s->r.height / MAX_ZOOM
 753                        };
 754
 755                        rect_set_min_size(&fmt, &min_rect);
 756                        if (!dev->has_crop_out)
 757                                rect_set_max_size(&fmt, &max_rect);
 758                        if (!rect_same_size(&dev->fmt_out_rect, &fmt) &&
 759                            vb2_is_busy(&dev->vb_vid_out_q))
 760                                return -EBUSY;
 761                        if (dev->has_crop_out) {
 762                                rect_set_min_size(crop, &min_rect);
 763                                rect_set_max_size(crop, &max_rect);
 764                        }
 765                        dev->fmt_out_rect = fmt;
 766                } else if (dev->has_crop_out) {
 767                        struct v4l2_rect fmt = dev->fmt_out_rect;
 768
 769                        rect_set_min_size(&fmt, &s->r);
 770                        if (!rect_same_size(&dev->fmt_out_rect, &fmt) &&
 771                            vb2_is_busy(&dev->vb_vid_out_q))
 772                                return -EBUSY;
 773                        dev->fmt_out_rect = fmt;
 774                        rect_set_size_to(crop, &s->r);
 775                        rect_map_inside(crop, &dev->fmt_out_rect);
 776                } else {
 777                        if (!rect_same_size(&s->r, &dev->fmt_out_rect) &&
 778                            vb2_is_busy(&dev->vb_vid_out_q))
 779                                return -EBUSY;
 780                        rect_set_size_to(&dev->fmt_out_rect, &s->r);
 781                        rect_set_size_to(crop, &s->r);
 782                        crop->height /= factor;
 783                        rect_map_inside(crop, &dev->fmt_out_rect);
 784                }
 785                s->r.top *= factor;
 786                s->r.height *= factor;
 787                if (dev->bitmap_out && (compose->width != s->r.width ||
 788                                        compose->height != s->r.height)) {
 789                        kfree(dev->bitmap_out);
 790                        dev->bitmap_out = NULL;
 791                }
 792                *compose = s->r;
 793                break;
 794        default:
 795                return -EINVAL;
 796        }
 797
 798        return 0;
 799}
 800
 801int vivid_vid_out_cropcap(struct file *file, void *priv,
 802                              struct v4l2_cropcap *cap)
 803{
 804        struct vivid_dev *dev = video_drvdata(file);
 805
 806        if (cap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
 807                return -EINVAL;
 808
 809        switch (vivid_get_pixel_aspect(dev)) {
 810        case TPG_PIXEL_ASPECT_NTSC:
 811                cap->pixelaspect.numerator = 11;
 812                cap->pixelaspect.denominator = 10;
 813                break;
 814        case TPG_PIXEL_ASPECT_PAL:
 815                cap->pixelaspect.numerator = 54;
 816                cap->pixelaspect.denominator = 59;
 817                break;
 818        case TPG_PIXEL_ASPECT_SQUARE:
 819                cap->pixelaspect.numerator = 1;
 820                cap->pixelaspect.denominator = 1;
 821                break;
 822        }
 823        return 0;
 824}
 825
 826int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv,
 827                                        struct v4l2_format *f)
 828{
 829        struct vivid_dev *dev = video_drvdata(file);
 830        const struct v4l2_rect *compose = &dev->compose_out;
 831        struct v4l2_window *win = &f->fmt.win;
 832        unsigned clipcount = win->clipcount;
 833
 834        if (!dev->has_fb)
 835                return -EINVAL;
 836        win->w.top = dev->overlay_out_top;
 837        win->w.left = dev->overlay_out_left;
 838        win->w.width = compose->width;
 839        win->w.height = compose->height;
 840        win->clipcount = dev->clipcount_out;
 841        win->field = V4L2_FIELD_ANY;
 842        win->chromakey = dev->chromakey_out;
 843        win->global_alpha = dev->global_alpha_out;
 844        if (clipcount > dev->clipcount_out)
 845                clipcount = dev->clipcount_out;
 846        if (dev->bitmap_out == NULL)
 847                win->bitmap = NULL;
 848        else if (win->bitmap) {
 849                if (copy_to_user(win->bitmap, dev->bitmap_out,
 850                    ((dev->compose_out.width + 7) / 8) * dev->compose_out.height))
 851                        return -EFAULT;
 852        }
 853        if (clipcount && win->clips) {
 854                if (copy_to_user(win->clips, dev->clips_out,
 855                                 clipcount * sizeof(dev->clips_out[0])))
 856                        return -EFAULT;
 857        }
 858        return 0;
 859}
 860
 861int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv,
 862                                        struct v4l2_format *f)
 863{
 864        struct vivid_dev *dev = video_drvdata(file);
 865        const struct v4l2_rect *compose = &dev->compose_out;
 866        struct v4l2_window *win = &f->fmt.win;
 867        int i, j;
 868
 869        if (!dev->has_fb)
 870                return -EINVAL;
 871        win->w.left = clamp_t(int, win->w.left,
 872                              -dev->display_width, dev->display_width);
 873        win->w.top = clamp_t(int, win->w.top,
 874                             -dev->display_height, dev->display_height);
 875        win->w.width = compose->width;
 876        win->w.height = compose->height;
 877        /*
 878         * It makes no sense for an OSD to overlay only top or bottom fields,
 879         * so always set this to ANY.
 880         */
 881        win->field = V4L2_FIELD_ANY;
 882        if (win->clipcount && !win->clips)
 883                win->clipcount = 0;
 884        if (win->clipcount > MAX_CLIPS)
 885                win->clipcount = MAX_CLIPS;
 886        if (win->clipcount) {
 887                if (copy_from_user(dev->try_clips_out, win->clips,
 888                                   win->clipcount * sizeof(dev->clips_out[0])))
 889                        return -EFAULT;
 890                for (i = 0; i < win->clipcount; i++) {
 891                        struct v4l2_rect *r = &dev->try_clips_out[i].c;
 892
 893                        r->top = clamp_t(s32, r->top, 0, dev->display_height - 1);
 894                        r->height = clamp_t(s32, r->height, 1, dev->display_height - r->top);
 895                        r->left = clamp_t(u32, r->left, 0, dev->display_width - 1);
 896                        r->width = clamp_t(u32, r->width, 1, dev->display_width - r->left);
 897                }
 898                /*
 899                 * Yeah, so sue me, it's an O(n^2) algorithm. But n is a small
 900                 * number and it's typically a one-time deal.
 901                 */
 902                for (i = 0; i < win->clipcount - 1; i++) {
 903                        struct v4l2_rect *r1 = &dev->try_clips_out[i].c;
 904
 905                        for (j = i + 1; j < win->clipcount; j++) {
 906                                struct v4l2_rect *r2 = &dev->try_clips_out[j].c;
 907
 908                                if (rect_overlap(r1, r2))
 909                                        return -EINVAL;
 910                        }
 911                }
 912                if (copy_to_user(win->clips, dev->try_clips_out,
 913                                 win->clipcount * sizeof(dev->clips_out[0])))
 914                        return -EFAULT;
 915        }
 916        return 0;
 917}
 918
 919int vidioc_s_fmt_vid_out_overlay(struct file *file, void *priv,
 920                                        struct v4l2_format *f)
 921{
 922        struct vivid_dev *dev = video_drvdata(file);
 923        const struct v4l2_rect *compose = &dev->compose_out;
 924        struct v4l2_window *win = &f->fmt.win;
 925        int ret = vidioc_try_fmt_vid_out_overlay(file, priv, f);
 926        unsigned bitmap_size = ((compose->width + 7) / 8) * compose->height;
 927        unsigned clips_size = win->clipcount * sizeof(dev->clips_out[0]);
 928        void *new_bitmap = NULL;
 929
 930        if (ret)
 931                return ret;
 932
 933        if (win->bitmap) {
 934                new_bitmap = memdup_user(win->bitmap, bitmap_size);
 935
 936                if (IS_ERR(new_bitmap))
 937                        return PTR_ERR(new_bitmap);
 938        }
 939
 940        dev->overlay_out_top = win->w.top;
 941        dev->overlay_out_left = win->w.left;
 942        kfree(dev->bitmap_out);
 943        dev->bitmap_out = new_bitmap;
 944        dev->clipcount_out = win->clipcount;
 945        if (dev->clipcount_out)
 946                memcpy(dev->clips_out, dev->try_clips_out, clips_size);
 947        dev->chromakey_out = win->chromakey;
 948        dev->global_alpha_out = win->global_alpha;
 949        return ret;
 950}
 951
 952int vivid_vid_out_overlay(struct file *file, void *fh, unsigned i)
 953{
 954        struct vivid_dev *dev = video_drvdata(file);
 955
 956        if (i && !dev->fmt_out->can_do_overlay) {
 957                dprintk(dev, 1, "unsupported output format for output overlay\n");
 958                return -EINVAL;
 959        }
 960
 961        dev->overlay_out_enabled = i;
 962        return 0;
 963}
 964
 965int vivid_vid_out_g_fbuf(struct file *file, void *fh,
 966                                struct v4l2_framebuffer *a)
 967{
 968        struct vivid_dev *dev = video_drvdata(file);
 969
 970        a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY |
 971                        V4L2_FBUF_CAP_BITMAP_CLIPPING |
 972                        V4L2_FBUF_CAP_LIST_CLIPPING |
 973                        V4L2_FBUF_CAP_CHROMAKEY |
 974                        V4L2_FBUF_CAP_SRC_CHROMAKEY |
 975                        V4L2_FBUF_CAP_GLOBAL_ALPHA |
 976                        V4L2_FBUF_CAP_LOCAL_ALPHA |
 977                        V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
 978        a->flags = V4L2_FBUF_FLAG_OVERLAY | dev->fbuf_out_flags;
 979        a->base = (void *)dev->video_pbase;
 980        a->fmt.width = dev->display_width;
 981        a->fmt.height = dev->display_height;
 982        if (dev->fb_defined.green.length == 5)
 983                a->fmt.pixelformat = V4L2_PIX_FMT_ARGB555;
 984        else
 985                a->fmt.pixelformat = V4L2_PIX_FMT_RGB565;
 986        a->fmt.bytesperline = dev->display_byte_stride;
 987        a->fmt.sizeimage = a->fmt.height * a->fmt.bytesperline;
 988        a->fmt.field = V4L2_FIELD_NONE;
 989        a->fmt.colorspace = V4L2_COLORSPACE_SRGB;
 990        a->fmt.priv = 0;
 991        return 0;
 992}
 993
 994int vivid_vid_out_s_fbuf(struct file *file, void *fh,
 995                                const struct v4l2_framebuffer *a)
 996{
 997        struct vivid_dev *dev = video_drvdata(file);
 998        const unsigned chroma_flags = V4L2_FBUF_FLAG_CHROMAKEY |
 999                                      V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1000        const unsigned alpha_flags = V4L2_FBUF_FLAG_GLOBAL_ALPHA |
1001                                     V4L2_FBUF_FLAG_LOCAL_ALPHA |
1002                                     V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
1003
1004
1005        if ((a->flags & chroma_flags) == chroma_flags)
1006                return -EINVAL;
1007        switch (a->flags & alpha_flags) {
1008        case 0:
1009        case V4L2_FBUF_FLAG_GLOBAL_ALPHA:
1010        case V4L2_FBUF_FLAG_LOCAL_ALPHA:
1011        case V4L2_FBUF_FLAG_LOCAL_INV_ALPHA:
1012                break;
1013        default:
1014                return -EINVAL;
1015        }
1016        dev->fbuf_out_flags &= ~(chroma_flags | alpha_flags);
1017        dev->fbuf_out_flags = a->flags & (chroma_flags | alpha_flags);
1018        return 0;
1019}
1020
1021static const struct v4l2_audioout vivid_audio_outputs[] = {
1022        { 0, "Line-Out 1" },
1023        { 1, "Line-Out 2" },
1024};
1025
1026int vidioc_enum_output(struct file *file, void *priv,
1027                                struct v4l2_output *out)
1028{
1029        struct vivid_dev *dev = video_drvdata(file);
1030
1031        if (out->index >= dev->num_outputs)
1032                return -EINVAL;
1033
1034        out->type = V4L2_OUTPUT_TYPE_ANALOG;
1035        switch (dev->output_type[out->index]) {
1036        case SVID:
1037                snprintf(out->name, sizeof(out->name), "S-Video %u",
1038                                dev->output_name_counter[out->index]);
1039                out->std = V4L2_STD_ALL;
1040                if (dev->has_audio_outputs)
1041                        out->audioset = (1 << ARRAY_SIZE(vivid_audio_outputs)) - 1;
1042                out->capabilities = V4L2_OUT_CAP_STD;
1043                break;
1044        case HDMI:
1045                snprintf(out->name, sizeof(out->name), "HDMI %u",
1046                                dev->output_name_counter[out->index]);
1047                out->capabilities = V4L2_OUT_CAP_DV_TIMINGS;
1048                break;
1049        }
1050        return 0;
1051}
1052
1053int vidioc_g_output(struct file *file, void *priv, unsigned *o)
1054{
1055        struct vivid_dev *dev = video_drvdata(file);
1056
1057        *o = dev->output;
1058        return 0;
1059}
1060
1061int vidioc_s_output(struct file *file, void *priv, unsigned o)
1062{
1063        struct vivid_dev *dev = video_drvdata(file);
1064
1065        if (o >= dev->num_outputs)
1066                return -EINVAL;
1067
1068        if (o == dev->output)
1069                return 0;
1070
1071        if (vb2_is_busy(&dev->vb_vid_out_q) || vb2_is_busy(&dev->vb_vbi_out_q))
1072                return -EBUSY;
1073
1074        dev->output = o;
1075        dev->tv_audio_output = 0;
1076        if (dev->output_type[o] == SVID)
1077                dev->vid_out_dev.tvnorms = V4L2_STD_ALL;
1078        else
1079                dev->vid_out_dev.tvnorms = 0;
1080
1081        dev->vbi_out_dev.tvnorms = dev->vid_out_dev.tvnorms;
1082        vivid_update_format_out(dev);
1083        return 0;
1084}
1085
1086int vidioc_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vout)
1087{
1088        if (vout->index >= ARRAY_SIZE(vivid_audio_outputs))
1089                return -EINVAL;
1090        *vout = vivid_audio_outputs[vout->index];
1091        return 0;
1092}
1093
1094int vidioc_g_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
1095{
1096        struct vivid_dev *dev = video_drvdata(file);
1097
1098        if (!vivid_is_svid_out(dev))
1099                return -EINVAL;
1100        *vout = vivid_audio_outputs[dev->tv_audio_output];
1101        return 0;
1102}
1103
1104int vidioc_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
1105{
1106        struct vivid_dev *dev = video_drvdata(file);
1107
1108        if (!vivid_is_svid_out(dev))
1109                return -EINVAL;
1110        if (vout->index >= ARRAY_SIZE(vivid_audio_outputs))
1111                return -EINVAL;
1112        dev->tv_audio_output = vout->index;
1113        return 0;
1114}
1115
1116int vivid_vid_out_s_std(struct file *file, void *priv, v4l2_std_id id)
1117{
1118        struct vivid_dev *dev = video_drvdata(file);
1119
1120        if (!vivid_is_svid_out(dev))
1121                return -ENODATA;
1122        if (dev->std_out == id)
1123                return 0;
1124        if (vb2_is_busy(&dev->vb_vid_out_q) || vb2_is_busy(&dev->vb_vbi_out_q))
1125                return -EBUSY;
1126        dev->std_out = id;
1127        vivid_update_format_out(dev);
1128        return 0;
1129}
1130
1131static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
1132{
1133        struct v4l2_bt_timings *bt = &timings->bt;
1134
1135        if ((bt->standards & (V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF)) &&
1136            v4l2_valid_dv_timings(timings, &vivid_dv_timings_cap, NULL, NULL))
1137                return true;
1138
1139        return false;
1140}
1141
1142int vivid_vid_out_s_dv_timings(struct file *file, void *_fh,
1143                                    struct v4l2_dv_timings *timings)
1144{
1145        struct vivid_dev *dev = video_drvdata(file);
1146        if (!vivid_is_hdmi_out(dev))
1147                return -ENODATA;
1148        if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap,
1149                                0, NULL, NULL) &&
1150            !valid_cvt_gtf_timings(timings))
1151                return -EINVAL;
1152        if (v4l2_match_dv_timings(timings, &dev->dv_timings_out, 0))
1153                return 0;
1154        if (vb2_is_busy(&dev->vb_vid_out_q))
1155                return -EBUSY;
1156        dev->dv_timings_out = *timings;
1157        vivid_update_format_out(dev);
1158        return 0;
1159}
1160
1161int vivid_vid_out_g_parm(struct file *file, void *priv,
1162                          struct v4l2_streamparm *parm)
1163{
1164        struct vivid_dev *dev = video_drvdata(file);
1165
1166        if (parm->type != (dev->multiplanar ?
1167                           V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
1168                           V4L2_BUF_TYPE_VIDEO_OUTPUT))
1169                return -EINVAL;
1170
1171        parm->parm.output.capability   = V4L2_CAP_TIMEPERFRAME;
1172        parm->parm.output.timeperframe = dev->timeperframe_vid_out;
1173        parm->parm.output.writebuffers  = 1;
1174
1175        return 0;
1176}
1177
1178int vidioc_subscribe_event(struct v4l2_fh *fh,
1179                        const struct v4l2_event_subscription *sub)
1180{
1181        switch (sub->type) {
1182        case V4L2_EVENT_CTRL:
1183                return v4l2_ctrl_subscribe_event(fh, sub);
1184        case V4L2_EVENT_SOURCE_CHANGE:
1185                if (fh->vdev->vfl_dir == VFL_DIR_RX)
1186                        return v4l2_src_change_event_subscribe(fh, sub);
1187                break;
1188        default:
1189                break;
1190        }
1191        return -EINVAL;
1192}
1193