linux/drivers/media/platform/omap/omap_vout.c
<<
>>
Prefs
   1/*
   2 * omap_vout.c
   3 *
   4 * Copyright (C) 2005-2010 Texas Instruments.
   5 *
   6 * This file is licensed under the terms of the GNU General Public License
   7 * version 2. This program is licensed "as is" without any warranty of any
   8 * kind, whether express or implied.
   9 *
  10 * Leveraged code from the OMAP2 camera driver
  11 * Video-for-Linux (Version 2) camera capture driver for
  12 * the OMAP24xx camera controller.
  13 *
  14 * Author: Andy Lowe (source@mvista.com)
  15 *
  16 * Copyright (C) 2004 MontaVista Software, Inc.
  17 * Copyright (C) 2010 Texas Instruments.
  18 *
  19 * History:
  20 * 20-APR-2006 Khasim           Modified VRFB based Rotation,
  21 *                              The image data is always read from 0 degree
  22 *                              view and written
  23 *                              to the virtual space of desired rotation angle
  24 * 4-DEC-2006  Jian             Changed to support better memory management
  25 *
  26 * 17-Nov-2008 Hardik           Changed driver to use video_ioctl2
  27 *
  28 * 23-Feb-2010 Vaibhav H        Modified to use new DSS2 interface
  29 *
  30 */
  31
  32#include <linux/init.h>
  33#include <linux/module.h>
  34#include <linux/vmalloc.h>
  35#include <linux/sched.h>
  36#include <linux/types.h>
  37#include <linux/platform_device.h>
  38#include <linux/irq.h>
  39#include <linux/videodev2.h>
  40#include <linux/dma-mapping.h>
  41#include <linux/slab.h>
  42
  43#include <media/videobuf-dma-contig.h>
  44#include <media/v4l2-device.h>
  45#include <media/v4l2-ioctl.h>
  46
  47#include <video/omapvrfb.h>
  48#include <video/omapfb_dss.h>
  49
  50#include "omap_voutlib.h"
  51#include "omap_voutdef.h"
  52#include "omap_vout_vrfb.h"
  53
  54MODULE_AUTHOR("Texas Instruments");
  55MODULE_DESCRIPTION("OMAP Video for Linux Video out driver");
  56MODULE_LICENSE("GPL");
  57
  58/* Driver Configuration macros */
  59#define VOUT_NAME               "omap_vout"
  60
  61enum omap_vout_channels {
  62        OMAP_VIDEO1,
  63        OMAP_VIDEO2,
  64};
  65
  66static struct videobuf_queue_ops video_vbq_ops;
  67/* Variables configurable through module params*/
  68static u32 video1_numbuffers = 3;
  69static u32 video2_numbuffers = 3;
  70static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
  71static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
  72static bool vid1_static_vrfb_alloc;
  73static bool vid2_static_vrfb_alloc;
  74static bool debug;
  75
  76/* Module parameters */
  77module_param(video1_numbuffers, uint, S_IRUGO);
  78MODULE_PARM_DESC(video1_numbuffers,
  79        "Number of buffers to be allocated at init time for Video1 device.");
  80
  81module_param(video2_numbuffers, uint, S_IRUGO);
  82MODULE_PARM_DESC(video2_numbuffers,
  83        "Number of buffers to be allocated at init time for Video2 device.");
  84
  85module_param(video1_bufsize, uint, S_IRUGO);
  86MODULE_PARM_DESC(video1_bufsize,
  87        "Size of the buffer to be allocated for video1 device");
  88
  89module_param(video2_bufsize, uint, S_IRUGO);
  90MODULE_PARM_DESC(video2_bufsize,
  91        "Size of the buffer to be allocated for video2 device");
  92
  93module_param(vid1_static_vrfb_alloc, bool, S_IRUGO);
  94MODULE_PARM_DESC(vid1_static_vrfb_alloc,
  95        "Static allocation of the VRFB buffer for video1 device");
  96
  97module_param(vid2_static_vrfb_alloc, bool, S_IRUGO);
  98MODULE_PARM_DESC(vid2_static_vrfb_alloc,
  99        "Static allocation of the VRFB buffer for video2 device");
 100
 101module_param(debug, bool, S_IRUGO);
 102MODULE_PARM_DESC(debug, "Debug level (0-1)");
 103
 104/* list of image formats supported by OMAP2 video pipelines */
 105static const struct v4l2_fmtdesc omap_formats[] = {
 106        {
 107                /* Note:  V4L2 defines RGB565 as:
 108                 *
 109                 *      Byte 0                    Byte 1
 110                 *      g2 g1 g0 r4 r3 r2 r1 r0   b4 b3 b2 b1 b0 g5 g4 g3
 111                 *
 112                 * We interpret RGB565 as:
 113                 *
 114                 *      Byte 0                    Byte 1
 115                 *      g2 g1 g0 b4 b3 b2 b1 b0   r4 r3 r2 r1 r0 g5 g4 g3
 116                 */
 117                .description = "RGB565, le",
 118                .pixelformat = V4L2_PIX_FMT_RGB565,
 119        },
 120        {
 121                /* Note:  V4L2 defines RGB32 as: RGB-8-8-8-8  we use
 122                 *  this for RGB24 unpack mode, the last 8 bits are ignored
 123                 * */
 124                .description = "RGB32, le",
 125                .pixelformat = V4L2_PIX_FMT_RGB32,
 126        },
 127        {
 128                /* Note:  V4L2 defines RGB24 as: RGB-8-8-8  we use
 129                 *        this for RGB24 packed mode
 130                 *
 131                 */
 132                .description = "RGB24, le",
 133                .pixelformat = V4L2_PIX_FMT_RGB24,
 134        },
 135        {
 136                .description = "YUYV (YUV 4:2:2), packed",
 137                .pixelformat = V4L2_PIX_FMT_YUYV,
 138        },
 139        {
 140                .description = "UYVY, packed",
 141                .pixelformat = V4L2_PIX_FMT_UYVY,
 142        },
 143};
 144
 145#define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats))
 146
 147/*
 148 * Try format
 149 */
 150static int omap_vout_try_format(struct v4l2_pix_format *pix)
 151{
 152        int ifmt, bpp = 0;
 153
 154        pix->height = clamp(pix->height, (u32)VID_MIN_HEIGHT,
 155                                                (u32)VID_MAX_HEIGHT);
 156        pix->width = clamp(pix->width, (u32)VID_MIN_WIDTH, (u32)VID_MAX_WIDTH);
 157
 158        for (ifmt = 0; ifmt < NUM_OUTPUT_FORMATS; ifmt++) {
 159                if (pix->pixelformat == omap_formats[ifmt].pixelformat)
 160                        break;
 161        }
 162
 163        if (ifmt == NUM_OUTPUT_FORMATS)
 164                ifmt = 0;
 165
 166        pix->pixelformat = omap_formats[ifmt].pixelformat;
 167        pix->field = V4L2_FIELD_ANY;
 168
 169        switch (pix->pixelformat) {
 170        case V4L2_PIX_FMT_YUYV:
 171        case V4L2_PIX_FMT_UYVY:
 172        default:
 173                pix->colorspace = V4L2_COLORSPACE_JPEG;
 174                bpp = YUYV_BPP;
 175                break;
 176        case V4L2_PIX_FMT_RGB565:
 177        case V4L2_PIX_FMT_RGB565X:
 178                pix->colorspace = V4L2_COLORSPACE_SRGB;
 179                bpp = RGB565_BPP;
 180                break;
 181        case V4L2_PIX_FMT_RGB24:
 182                pix->colorspace = V4L2_COLORSPACE_SRGB;
 183                bpp = RGB24_BPP;
 184                break;
 185        case V4L2_PIX_FMT_RGB32:
 186        case V4L2_PIX_FMT_BGR32:
 187                pix->colorspace = V4L2_COLORSPACE_SRGB;
 188                bpp = RGB32_BPP;
 189                break;
 190        }
 191        pix->bytesperline = pix->width * bpp;
 192        pix->sizeimage = pix->bytesperline * pix->height;
 193
 194        return bpp;
 195}
 196
 197/*
 198 * omap_vout_get_userptr: Convert user space virtual address to physical
 199 * address.
 200 */
 201static int omap_vout_get_userptr(struct videobuf_buffer *vb, long virtp,
 202                                 u32 *physp)
 203{
 204        struct frame_vector *vec;
 205        int ret;
 206
 207        /* For kernel direct-mapped memory, take the easy way */
 208        if (virtp >= PAGE_OFFSET) {
 209                *physp = virt_to_phys((void *)virtp);
 210                return 0;
 211        }
 212
 213        vec = frame_vector_create(1);
 214        if (!vec)
 215                return -ENOMEM;
 216
 217        ret = get_vaddr_frames(virtp, 1, FOLL_WRITE, vec);
 218        if (ret != 1) {
 219                frame_vector_destroy(vec);
 220                return -EINVAL;
 221        }
 222        *physp = __pfn_to_phys(frame_vector_pfns(vec)[0]);
 223        vb->priv = vec;
 224
 225        return 0;
 226}
 227
 228/*
 229 * Free the V4L2 buffers
 230 */
 231void omap_vout_free_buffers(struct omap_vout_device *vout)
 232{
 233        int i, numbuffers;
 234
 235        /* Allocate memory for the buffers */
 236        numbuffers = (vout->vid) ?  video2_numbuffers : video1_numbuffers;
 237        vout->buffer_size = (vout->vid) ? video2_bufsize : video1_bufsize;
 238
 239        for (i = 0; i < numbuffers; i++) {
 240                omap_vout_free_buffer(vout->buf_virt_addr[i],
 241                                vout->buffer_size);
 242                vout->buf_phy_addr[i] = 0;
 243                vout->buf_virt_addr[i] = 0;
 244        }
 245}
 246
 247/*
 248 * Convert V4L2 rotation to DSS rotation
 249 *      V4L2 understand 0, 90, 180, 270.
 250 *      Convert to 0, 1, 2 and 3 respectively for DSS
 251 */
 252static int v4l2_rot_to_dss_rot(int v4l2_rotation,
 253                        enum dss_rotation *rotation, bool mirror)
 254{
 255        int ret = 0;
 256
 257        switch (v4l2_rotation) {
 258        case 90:
 259                *rotation = dss_rotation_90_degree;
 260                break;
 261        case 180:
 262                *rotation = dss_rotation_180_degree;
 263                break;
 264        case 270:
 265                *rotation = dss_rotation_270_degree;
 266                break;
 267        case 0:
 268                *rotation = dss_rotation_0_degree;
 269                break;
 270        default:
 271                ret = -EINVAL;
 272        }
 273        return ret;
 274}
 275
 276static int omap_vout_calculate_offset(struct omap_vout_device *vout)
 277{
 278        struct omapvideo_info *ovid;
 279        struct v4l2_rect *crop = &vout->crop;
 280        struct v4l2_pix_format *pix = &vout->pix;
 281        int *cropped_offset = &vout->cropped_offset;
 282        int ps = 2, line_length = 0;
 283
 284        ovid = &vout->vid_info;
 285
 286        if (ovid->rotation_type == VOUT_ROT_VRFB) {
 287                omap_vout_calculate_vrfb_offset(vout);
 288        } else {
 289                vout->line_length = line_length = pix->width;
 290
 291                if (V4L2_PIX_FMT_YUYV == pix->pixelformat ||
 292                        V4L2_PIX_FMT_UYVY == pix->pixelformat)
 293                        ps = 2;
 294                else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat)
 295                        ps = 4;
 296                else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat)
 297                        ps = 3;
 298
 299                vout->ps = ps;
 300
 301                *cropped_offset = (line_length * ps) *
 302                        crop->top + crop->left * ps;
 303        }
 304
 305        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s Offset:%x\n",
 306                        __func__, vout->cropped_offset);
 307
 308        return 0;
 309}
 310
 311/*
 312 * Convert V4L2 pixel format to DSS pixel format
 313 */
 314static int video_mode_to_dss_mode(struct omap_vout_device *vout)
 315{
 316        struct omap_overlay *ovl;
 317        struct omapvideo_info *ovid;
 318        struct v4l2_pix_format *pix = &vout->pix;
 319        enum omap_color_mode mode;
 320
 321        ovid = &vout->vid_info;
 322        ovl = ovid->overlays[0];
 323
 324        switch (pix->pixelformat) {
 325        case V4L2_PIX_FMT_YUYV:
 326                mode = OMAP_DSS_COLOR_YUV2;
 327                break;
 328        case V4L2_PIX_FMT_UYVY:
 329                mode = OMAP_DSS_COLOR_UYVY;
 330                break;
 331        case V4L2_PIX_FMT_RGB565:
 332                mode = OMAP_DSS_COLOR_RGB16;
 333                break;
 334        case V4L2_PIX_FMT_RGB24:
 335                mode = OMAP_DSS_COLOR_RGB24P;
 336                break;
 337        case V4L2_PIX_FMT_RGB32:
 338                mode = (ovl->id == OMAP_DSS_VIDEO1) ?
 339                        OMAP_DSS_COLOR_RGB24U : OMAP_DSS_COLOR_ARGB32;
 340                break;
 341        case V4L2_PIX_FMT_BGR32:
 342                mode = OMAP_DSS_COLOR_RGBX32;
 343                break;
 344        default:
 345                mode = -EINVAL;
 346                break;
 347        }
 348        return mode;
 349}
 350
 351/*
 352 * Setup the overlay
 353 */
 354static int omapvid_setup_overlay(struct omap_vout_device *vout,
 355                struct omap_overlay *ovl, int posx, int posy, int outw,
 356                int outh, u32 addr)
 357{
 358        int ret = 0;
 359        struct omap_overlay_info info;
 360        int cropheight, cropwidth, pixwidth;
 361
 362        if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0 &&
 363                        (outw != vout->pix.width || outh != vout->pix.height)) {
 364                ret = -EINVAL;
 365                goto setup_ovl_err;
 366        }
 367
 368        vout->dss_mode = video_mode_to_dss_mode(vout);
 369        if (vout->dss_mode == -EINVAL) {
 370                ret = -EINVAL;
 371                goto setup_ovl_err;
 372        }
 373
 374        /* Setup the input plane parameters according to
 375         * rotation value selected.
 376         */
 377        if (is_rotation_90_or_270(vout)) {
 378                cropheight = vout->crop.width;
 379                cropwidth = vout->crop.height;
 380                pixwidth = vout->pix.height;
 381        } else {
 382                cropheight = vout->crop.height;
 383                cropwidth = vout->crop.width;
 384                pixwidth = vout->pix.width;
 385        }
 386
 387        ovl->get_overlay_info(ovl, &info);
 388        info.paddr = addr;
 389        info.width = cropwidth;
 390        info.height = cropheight;
 391        info.color_mode = vout->dss_mode;
 392        info.mirror = vout->mirror;
 393        info.pos_x = posx;
 394        info.pos_y = posy;
 395        info.out_width = outw;
 396        info.out_height = outh;
 397        info.global_alpha = vout->win.global_alpha;
 398        if (!is_rotation_enabled(vout)) {
 399                info.rotation = 0;
 400                info.rotation_type = OMAP_DSS_ROT_DMA;
 401                info.screen_width = pixwidth;
 402        } else {
 403                info.rotation = vout->rotation;
 404                info.rotation_type = OMAP_DSS_ROT_VRFB;
 405                info.screen_width = 2048;
 406        }
 407
 408        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
 409                "%s enable=%d addr=%pad width=%d\n height=%d color_mode=%d\n"
 410                "rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
 411                "out_height=%d rotation_type=%d screen_width=%d\n", __func__,
 412                ovl->is_enabled(ovl), &info.paddr, info.width, info.height,
 413                info.color_mode, info.rotation, info.mirror, info.pos_x,
 414                info.pos_y, info.out_width, info.out_height, info.rotation_type,
 415                info.screen_width);
 416
 417        ret = ovl->set_overlay_info(ovl, &info);
 418        if (ret)
 419                goto setup_ovl_err;
 420
 421        return 0;
 422
 423setup_ovl_err:
 424        v4l2_warn(&vout->vid_dev->v4l2_dev, "setup_overlay failed\n");
 425        return ret;
 426}
 427
 428/*
 429 * Initialize the overlay structure
 430 */
 431static int omapvid_init(struct omap_vout_device *vout, u32 addr)
 432{
 433        int ret = 0, i;
 434        struct v4l2_window *win;
 435        struct omap_overlay *ovl;
 436        int posx, posy, outw, outh;
 437        struct omap_video_timings *timing;
 438        struct omapvideo_info *ovid = &vout->vid_info;
 439
 440        win = &vout->win;
 441        for (i = 0; i < ovid->num_overlays; i++) {
 442                struct omap_dss_device *dssdev;
 443
 444                ovl = ovid->overlays[i];
 445                dssdev = ovl->get_device(ovl);
 446
 447                if (!dssdev)
 448                        return -EINVAL;
 449
 450                timing = &dssdev->panel.timings;
 451
 452                outw = win->w.width;
 453                outh = win->w.height;
 454                switch (vout->rotation) {
 455                case dss_rotation_90_degree:
 456                        /* Invert the height and width for 90
 457                         * and 270 degree rotation
 458                         */
 459                        swap(outw, outh);
 460                        posy = (timing->y_res - win->w.width) - win->w.left;
 461                        posx = win->w.top;
 462                        break;
 463
 464                case dss_rotation_180_degree:
 465                        posx = (timing->x_res - win->w.width) - win->w.left;
 466                        posy = (timing->y_res - win->w.height) - win->w.top;
 467                        break;
 468
 469                case dss_rotation_270_degree:
 470                        swap(outw, outh);
 471                        posy = win->w.left;
 472                        posx = (timing->x_res - win->w.height) - win->w.top;
 473                        break;
 474
 475                default:
 476                        posx = win->w.left;
 477                        posy = win->w.top;
 478                        break;
 479                }
 480
 481                ret = omapvid_setup_overlay(vout, ovl, posx, posy,
 482                                outw, outh, addr);
 483                if (ret)
 484                        goto omapvid_init_err;
 485        }
 486        return 0;
 487
 488omapvid_init_err:
 489        v4l2_warn(&vout->vid_dev->v4l2_dev, "apply_changes failed\n");
 490        return ret;
 491}
 492
 493/*
 494 * Apply the changes set the go bit of DSS
 495 */
 496static int omapvid_apply_changes(struct omap_vout_device *vout)
 497{
 498        int i;
 499        struct omap_overlay *ovl;
 500        struct omapvideo_info *ovid = &vout->vid_info;
 501
 502        for (i = 0; i < ovid->num_overlays; i++) {
 503                struct omap_dss_device *dssdev;
 504
 505                ovl = ovid->overlays[i];
 506                dssdev = ovl->get_device(ovl);
 507                if (!dssdev)
 508                        return -EINVAL;
 509                ovl->manager->apply(ovl->manager);
 510        }
 511
 512        return 0;
 513}
 514
 515static int omapvid_handle_interlace_display(struct omap_vout_device *vout,
 516                unsigned int irqstatus, struct timeval timevalue)
 517{
 518        u32 fid;
 519
 520        if (vout->first_int) {
 521                vout->first_int = 0;
 522                goto err;
 523        }
 524
 525        if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
 526                fid = 1;
 527        else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
 528                fid = 0;
 529        else
 530                goto err;
 531
 532        vout->field_id ^= 1;
 533        if (fid != vout->field_id) {
 534                if (fid == 0)
 535                        vout->field_id = fid;
 536        } else if (0 == fid) {
 537                if (vout->cur_frm == vout->next_frm)
 538                        goto err;
 539
 540                vout->cur_frm->ts = timevalue;
 541                vout->cur_frm->state = VIDEOBUF_DONE;
 542                wake_up_interruptible(&vout->cur_frm->done);
 543                vout->cur_frm = vout->next_frm;
 544        } else {
 545                if (list_empty(&vout->dma_queue) ||
 546                                (vout->cur_frm != vout->next_frm))
 547                        goto err;
 548        }
 549
 550        return vout->field_id;
 551err:
 552        return 0;
 553}
 554
 555static void omap_vout_isr(void *arg, unsigned int irqstatus)
 556{
 557        int ret, fid, mgr_id;
 558        u32 addr, irq;
 559        struct omap_overlay *ovl;
 560        struct timeval timevalue;
 561        struct omapvideo_info *ovid;
 562        struct omap_dss_device *cur_display;
 563        struct omap_vout_device *vout = (struct omap_vout_device *)arg;
 564
 565        if (!vout->streaming)
 566                return;
 567
 568        ovid = &vout->vid_info;
 569        ovl = ovid->overlays[0];
 570
 571        mgr_id = ovl->manager->id;
 572
 573        /* get the display device attached to the overlay */
 574        cur_display = ovl->get_device(ovl);
 575
 576        if (!cur_display)
 577                return;
 578
 579        spin_lock(&vout->vbq_lock);
 580        v4l2_get_timestamp(&timevalue);
 581
 582        switch (cur_display->type) {
 583        case OMAP_DISPLAY_TYPE_DSI:
 584        case OMAP_DISPLAY_TYPE_DPI:
 585        case OMAP_DISPLAY_TYPE_DVI:
 586                if (mgr_id == OMAP_DSS_CHANNEL_LCD)
 587                        irq = DISPC_IRQ_VSYNC;
 588                else if (mgr_id == OMAP_DSS_CHANNEL_LCD2)
 589                        irq = DISPC_IRQ_VSYNC2;
 590                else
 591                        goto vout_isr_err;
 592
 593                if (!(irqstatus & irq))
 594                        goto vout_isr_err;
 595                break;
 596        case OMAP_DISPLAY_TYPE_VENC:
 597                fid = omapvid_handle_interlace_display(vout, irqstatus,
 598                                timevalue);
 599                if (!fid)
 600                        goto vout_isr_err;
 601                break;
 602        case OMAP_DISPLAY_TYPE_HDMI:
 603                if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
 604                        goto vout_isr_err;
 605                break;
 606        default:
 607                goto vout_isr_err;
 608        }
 609
 610        if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
 611                vout->cur_frm->ts = timevalue;
 612                vout->cur_frm->state = VIDEOBUF_DONE;
 613                wake_up_interruptible(&vout->cur_frm->done);
 614                vout->cur_frm = vout->next_frm;
 615        }
 616
 617        vout->first_int = 0;
 618        if (list_empty(&vout->dma_queue))
 619                goto vout_isr_err;
 620
 621        vout->next_frm = list_entry(vout->dma_queue.next,
 622                        struct videobuf_buffer, queue);
 623        list_del(&vout->next_frm->queue);
 624
 625        vout->next_frm->state = VIDEOBUF_ACTIVE;
 626
 627        addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
 628                + vout->cropped_offset;
 629
 630        /* First save the configuration in ovelray structure */
 631        ret = omapvid_init(vout, addr);
 632        if (ret) {
 633                printk(KERN_ERR VOUT_NAME
 634                        "failed to set overlay info\n");
 635                goto vout_isr_err;
 636        }
 637
 638        /* Enable the pipeline and set the Go bit */
 639        ret = omapvid_apply_changes(vout);
 640        if (ret)
 641                printk(KERN_ERR VOUT_NAME "failed to change mode\n");
 642
 643vout_isr_err:
 644        spin_unlock(&vout->vbq_lock);
 645}
 646
 647/* Video buffer call backs */
 648
 649/*
 650 * Buffer setup function is called by videobuf layer when REQBUF ioctl is
 651 * called. This is used to setup buffers and return size and count of
 652 * buffers allocated. After the call to this buffer, videobuf layer will
 653 * setup buffer queue depending on the size and count of buffers
 654 */
 655static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
 656                          unsigned int *size)
 657{
 658        int startindex = 0, i, j;
 659        u32 phy_addr = 0, virt_addr = 0;
 660        struct omap_vout_device *vout = q->priv_data;
 661        struct omapvideo_info *ovid = &vout->vid_info;
 662        int vid_max_buf_size;
 663
 664        if (!vout)
 665                return -EINVAL;
 666
 667        vid_max_buf_size = vout->vid == OMAP_VIDEO1 ? video1_bufsize :
 668                video2_bufsize;
 669
 670        if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
 671                return -EINVAL;
 672
 673        startindex = (vout->vid == OMAP_VIDEO1) ?
 674                video1_numbuffers : video2_numbuffers;
 675        if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex)
 676                *count = startindex;
 677
 678        if (ovid->rotation_type == VOUT_ROT_VRFB) {
 679                if (omap_vout_vrfb_buffer_setup(vout, count, startindex))
 680                        return -ENOMEM;
 681        }
 682
 683        if (V4L2_MEMORY_MMAP != vout->memory)
 684                return 0;
 685
 686        /* Now allocated the V4L2 buffers */
 687        *size = PAGE_ALIGN(vout->pix.width * vout->pix.height * vout->bpp);
 688        startindex = (vout->vid == OMAP_VIDEO1) ?
 689                video1_numbuffers : video2_numbuffers;
 690
 691        /* Check the size of the buffer */
 692        if (*size > vid_max_buf_size) {
 693                v4l2_err(&vout->vid_dev->v4l2_dev,
 694                                "buffer allocation mismatch [%u] [%u]\n",
 695                                *size, vout->buffer_size);
 696                return -ENOMEM;
 697        }
 698
 699        for (i = startindex; i < *count; i++) {
 700                vout->buffer_size = *size;
 701
 702                virt_addr = omap_vout_alloc_buffer(vout->buffer_size,
 703                                &phy_addr);
 704                if (!virt_addr) {
 705                        if (ovid->rotation_type == VOUT_ROT_NONE)
 706                                break;
 707
 708                        if (!is_rotation_enabled(vout))
 709                                break;
 710
 711                        /* Free the VRFB buffers if no space for V4L2 buffers */
 712                        for (j = i; j < *count; j++) {
 713                                omap_vout_free_buffer(vout->smsshado_virt_addr[j],
 714                                                      vout->smsshado_size);
 715                                vout->smsshado_virt_addr[j] = 0;
 716                                vout->smsshado_phy_addr[j] = 0;
 717                        }
 718                }
 719                vout->buf_virt_addr[i] = virt_addr;
 720                vout->buf_phy_addr[i] = phy_addr;
 721        }
 722        *count = vout->buffer_allocated = i;
 723
 724        return 0;
 725}
 726
 727/*
 728 * Free the V4L2 buffers additionally allocated than default
 729 * number of buffers
 730 */
 731static void omap_vout_free_extra_buffers(struct omap_vout_device *vout)
 732{
 733        int num_buffers = 0, i;
 734
 735        num_buffers = (vout->vid == OMAP_VIDEO1) ?
 736                video1_numbuffers : video2_numbuffers;
 737
 738        for (i = num_buffers; i < vout->buffer_allocated; i++) {
 739                if (vout->buf_virt_addr[i])
 740                        omap_vout_free_buffer(vout->buf_virt_addr[i],
 741                                        vout->buffer_size);
 742
 743                vout->buf_virt_addr[i] = 0;
 744                vout->buf_phy_addr[i] = 0;
 745        }
 746        vout->buffer_allocated = num_buffers;
 747}
 748
 749/*
 750 * This function will be called when VIDIOC_QBUF ioctl is called.
 751 * It prepare buffers before give out for the display. This function
 752 * converts user space virtual address into physical address if userptr memory
 753 * exchange mechanism is used. If rotation is enabled, it copies entire
 754 * buffer into VRFB memory space before giving it to the DSS.
 755 */
 756static int omap_vout_buffer_prepare(struct videobuf_queue *q,
 757                        struct videobuf_buffer *vb,
 758                        enum v4l2_field field)
 759{
 760        struct omap_vout_device *vout = q->priv_data;
 761        struct omapvideo_info *ovid = &vout->vid_info;
 762
 763        if (VIDEOBUF_NEEDS_INIT == vb->state) {
 764                vb->width = vout->pix.width;
 765                vb->height = vout->pix.height;
 766                vb->size = vb->width * vb->height * vout->bpp;
 767                vb->field = field;
 768        }
 769        vb->state = VIDEOBUF_PREPARED;
 770        /* if user pointer memory mechanism is used, get the physical
 771         * address of the buffer
 772         */
 773        if (V4L2_MEMORY_USERPTR == vb->memory) {
 774                int ret;
 775
 776                if (0 == vb->baddr)
 777                        return -EINVAL;
 778                /* Physical address */
 779                ret = omap_vout_get_userptr(vb, vb->baddr,
 780                                (u32 *)&vout->queued_buf_addr[vb->i]);
 781                if (ret < 0)
 782                        return ret;
 783        } else {
 784                unsigned long addr, dma_addr;
 785                unsigned long size;
 786
 787                addr = (unsigned long) vout->buf_virt_addr[vb->i];
 788                size = (unsigned long) vb->size;
 789
 790                dma_addr = dma_map_single(vout->vid_dev->v4l2_dev.dev, (void *) addr,
 791                                size, DMA_TO_DEVICE);
 792                if (dma_mapping_error(vout->vid_dev->v4l2_dev.dev, dma_addr))
 793                        v4l2_err(&vout->vid_dev->v4l2_dev,
 794                                 "dma_map_single failed\n");
 795
 796                vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i];
 797        }
 798
 799        if (ovid->rotation_type == VOUT_ROT_VRFB)
 800                return omap_vout_prepare_vrfb(vout, vb);
 801        else
 802                return 0;
 803}
 804
 805/*
 806 * Buffer queue function will be called from the videobuf layer when _QBUF
 807 * ioctl is called. It is used to enqueue buffer, which is ready to be
 808 * displayed.
 809 */
 810static void omap_vout_buffer_queue(struct videobuf_queue *q,
 811                          struct videobuf_buffer *vb)
 812{
 813        struct omap_vout_device *vout = q->priv_data;
 814
 815        /* Driver is also maintainig a queue. So enqueue buffer in the driver
 816         * queue */
 817        list_add_tail(&vb->queue, &vout->dma_queue);
 818
 819        vb->state = VIDEOBUF_QUEUED;
 820}
 821
 822/*
 823 * Buffer release function is called from videobuf layer to release buffer
 824 * which are already allocated
 825 */
 826static void omap_vout_buffer_release(struct videobuf_queue *q,
 827                            struct videobuf_buffer *vb)
 828{
 829        vb->state = VIDEOBUF_NEEDS_INIT;
 830        if (vb->memory == V4L2_MEMORY_USERPTR && vb->priv) {
 831                struct frame_vector *vec = vb->priv;
 832
 833                put_vaddr_frames(vec);
 834                frame_vector_destroy(vec);
 835        }
 836}
 837
 838/*
 839 *  File operations
 840 */
 841static __poll_t omap_vout_poll(struct file *file,
 842                                   struct poll_table_struct *wait)
 843{
 844        struct omap_vout_device *vout = file->private_data;
 845        struct videobuf_queue *q = &vout->vbq;
 846
 847        return videobuf_poll_stream(file, q, wait);
 848}
 849
 850static void omap_vout_vm_open(struct vm_area_struct *vma)
 851{
 852        struct omap_vout_device *vout = vma->vm_private_data;
 853
 854        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
 855                "vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
 856        vout->mmap_count++;
 857}
 858
 859static void omap_vout_vm_close(struct vm_area_struct *vma)
 860{
 861        struct omap_vout_device *vout = vma->vm_private_data;
 862
 863        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
 864                "vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
 865        vout->mmap_count--;
 866}
 867
 868static const struct vm_operations_struct omap_vout_vm_ops = {
 869        .open   = omap_vout_vm_open,
 870        .close  = omap_vout_vm_close,
 871};
 872
 873static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
 874{
 875        int i;
 876        void *pos;
 877        unsigned long start = vma->vm_start;
 878        unsigned long size = (vma->vm_end - vma->vm_start);
 879        struct omap_vout_device *vout = file->private_data;
 880        struct videobuf_queue *q = &vout->vbq;
 881
 882        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
 883                        " %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__,
 884                        vma->vm_pgoff, vma->vm_start, vma->vm_end);
 885
 886        /* look for the buffer to map */
 887        for (i = 0; i < VIDEO_MAX_FRAME; i++) {
 888                if (NULL == q->bufs[i])
 889                        continue;
 890                if (V4L2_MEMORY_MMAP != q->bufs[i]->memory)
 891                        continue;
 892                if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT))
 893                        break;
 894        }
 895
 896        if (VIDEO_MAX_FRAME == i) {
 897                v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
 898                                "offset invalid [offset=0x%lx]\n",
 899                                (vma->vm_pgoff << PAGE_SHIFT));
 900                return -EINVAL;
 901        }
 902        /* Check the size of the buffer */
 903        if (size > vout->buffer_size) {
 904                v4l2_err(&vout->vid_dev->v4l2_dev,
 905                                "insufficient memory [%lu] [%u]\n",
 906                                size, vout->buffer_size);
 907                return -ENOMEM;
 908        }
 909
 910        q->bufs[i]->baddr = vma->vm_start;
 911
 912        vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 913        vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 914        vma->vm_ops = &omap_vout_vm_ops;
 915        vma->vm_private_data = (void *) vout;
 916        pos = (void *)vout->buf_virt_addr[i];
 917        vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT;
 918        while (size > 0) {
 919                unsigned long pfn;
 920                pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT;
 921                if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
 922                        return -EAGAIN;
 923                start += PAGE_SIZE;
 924                pos += PAGE_SIZE;
 925                size -= PAGE_SIZE;
 926        }
 927        vout->mmap_count++;
 928        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
 929
 930        return 0;
 931}
 932
 933static int omap_vout_release(struct file *file)
 934{
 935        unsigned int ret, i;
 936        struct videobuf_queue *q;
 937        struct omapvideo_info *ovid;
 938        struct omap_vout_device *vout = file->private_data;
 939
 940        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
 941        ovid = &vout->vid_info;
 942
 943        if (!vout)
 944                return 0;
 945
 946        q = &vout->vbq;
 947        /* Disable all the overlay managers connected with this interface */
 948        for (i = 0; i < ovid->num_overlays; i++) {
 949                struct omap_overlay *ovl = ovid->overlays[i];
 950                struct omap_dss_device *dssdev = ovl->get_device(ovl);
 951
 952                if (dssdev)
 953                        ovl->disable(ovl);
 954        }
 955        /* Turn off the pipeline */
 956        ret = omapvid_apply_changes(vout);
 957        if (ret)
 958                v4l2_warn(&vout->vid_dev->v4l2_dev,
 959                                "Unable to apply changes\n");
 960
 961        /* Free all buffers */
 962        omap_vout_free_extra_buffers(vout);
 963
 964        /* Free the VRFB buffers only if they are allocated
 965         * during reqbufs.  Don't free if init time allocated
 966         */
 967        if (ovid->rotation_type == VOUT_ROT_VRFB) {
 968                if (!vout->vrfb_static_allocation)
 969                        omap_vout_free_vrfb_buffers(vout);
 970        }
 971        videobuf_mmap_free(q);
 972
 973        /* Even if apply changes fails we should continue
 974           freeing allocated memory */
 975        if (vout->streaming) {
 976                u32 mask = 0;
 977
 978                mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
 979                        DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_VSYNC2;
 980                omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
 981                vout->streaming = false;
 982
 983                videobuf_streamoff(q);
 984                videobuf_queue_cancel(q);
 985        }
 986
 987        if (vout->mmap_count != 0)
 988                vout->mmap_count = 0;
 989
 990        vout->opened -= 1;
 991        file->private_data = NULL;
 992
 993        if (vout->buffer_allocated)
 994                videobuf_mmap_free(q);
 995
 996        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
 997        return ret;
 998}
 999
1000static int omap_vout_open(struct file *file)
1001{
1002        struct videobuf_queue *q;
1003        struct omap_vout_device *vout = NULL;
1004
1005        vout = video_drvdata(file);
1006
1007        if (vout == NULL)
1008                return -ENODEV;
1009
1010        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
1011
1012        /* for now, we only support single open */
1013        if (vout->opened)
1014                return -EBUSY;
1015
1016        vout->opened += 1;
1017
1018        file->private_data = vout;
1019        vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1020
1021        q = &vout->vbq;
1022        video_vbq_ops.buf_setup = omap_vout_buffer_setup;
1023        video_vbq_ops.buf_prepare = omap_vout_buffer_prepare;
1024        video_vbq_ops.buf_release = omap_vout_buffer_release;
1025        video_vbq_ops.buf_queue = omap_vout_buffer_queue;
1026        spin_lock_init(&vout->vbq_lock);
1027
1028        videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev,
1029                        &vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
1030                        sizeof(struct videobuf_buffer), vout, NULL);
1031
1032        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
1033        return 0;
1034}
1035
1036/*
1037 * V4L2 ioctls
1038 */
1039static int vidioc_querycap(struct file *file, void *fh,
1040                struct v4l2_capability *cap)
1041{
1042        struct omap_vout_device *vout = fh;
1043
1044        strscpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
1045        strscpy(cap->card, vout->vfd->name, sizeof(cap->card));
1046        cap->bus_info[0] = '\0';
1047        cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT |
1048                V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
1049        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1050
1051        return 0;
1052}
1053
1054static int vidioc_enum_fmt_vid_out(struct file *file, void *fh,
1055                        struct v4l2_fmtdesc *fmt)
1056{
1057        int index = fmt->index;
1058
1059        if (index >= NUM_OUTPUT_FORMATS)
1060                return -EINVAL;
1061
1062        fmt->flags = omap_formats[index].flags;
1063        strscpy(fmt->description, omap_formats[index].description,
1064                sizeof(fmt->description));
1065        fmt->pixelformat = omap_formats[index].pixelformat;
1066
1067        return 0;
1068}
1069
1070static int vidioc_g_fmt_vid_out(struct file *file, void *fh,
1071                        struct v4l2_format *f)
1072{
1073        struct omap_vout_device *vout = fh;
1074
1075        f->fmt.pix = vout->pix;
1076        return 0;
1077
1078}
1079
1080static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
1081                        struct v4l2_format *f)
1082{
1083        struct omap_overlay *ovl;
1084        struct omapvideo_info *ovid;
1085        struct omap_video_timings *timing;
1086        struct omap_vout_device *vout = fh;
1087        struct omap_dss_device *dssdev;
1088
1089        ovid = &vout->vid_info;
1090        ovl = ovid->overlays[0];
1091        /* get the display device attached to the overlay */
1092        dssdev = ovl->get_device(ovl);
1093
1094        if (!dssdev)
1095                return -EINVAL;
1096
1097        timing = &dssdev->panel.timings;
1098
1099        vout->fbuf.fmt.height = timing->y_res;
1100        vout->fbuf.fmt.width = timing->x_res;
1101
1102        omap_vout_try_format(&f->fmt.pix);
1103        return 0;
1104}
1105
1106static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
1107                        struct v4l2_format *f)
1108{
1109        int ret, bpp;
1110        struct omap_overlay *ovl;
1111        struct omapvideo_info *ovid;
1112        struct omap_video_timings *timing;
1113        struct omap_vout_device *vout = fh;
1114        struct omap_dss_device *dssdev;
1115
1116        if (vout->streaming)
1117                return -EBUSY;
1118
1119        mutex_lock(&vout->lock);
1120
1121        ovid = &vout->vid_info;
1122        ovl = ovid->overlays[0];
1123        dssdev = ovl->get_device(ovl);
1124
1125        /* get the display device attached to the overlay */
1126        if (!dssdev) {
1127                ret = -EINVAL;
1128                goto s_fmt_vid_out_exit;
1129        }
1130        timing = &dssdev->panel.timings;
1131
1132        /* We dont support RGB24-packed mode if vrfb rotation
1133         * is enabled*/
1134        if ((is_rotation_enabled(vout)) &&
1135                        f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1136                ret = -EINVAL;
1137                goto s_fmt_vid_out_exit;
1138        }
1139
1140        /* get the framebuffer parameters */
1141
1142        if (is_rotation_90_or_270(vout)) {
1143                vout->fbuf.fmt.height = timing->x_res;
1144                vout->fbuf.fmt.width = timing->y_res;
1145        } else {
1146                vout->fbuf.fmt.height = timing->y_res;
1147                vout->fbuf.fmt.width = timing->x_res;
1148        }
1149
1150        /* change to samller size is OK */
1151
1152        bpp = omap_vout_try_format(&f->fmt.pix);
1153        f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp;
1154
1155        /* try & set the new output format */
1156        vout->bpp = bpp;
1157        vout->pix = f->fmt.pix;
1158        vout->vrfb_bpp = 1;
1159
1160        /* If YUYV then vrfb bpp is 2, for  others its 1 */
1161        if (V4L2_PIX_FMT_YUYV == vout->pix.pixelformat ||
1162                        V4L2_PIX_FMT_UYVY == vout->pix.pixelformat)
1163                vout->vrfb_bpp = 2;
1164
1165        /* set default crop and win */
1166        omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win);
1167
1168        ret = 0;
1169
1170s_fmt_vid_out_exit:
1171        mutex_unlock(&vout->lock);
1172        return ret;
1173}
1174
1175static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh,
1176                        struct v4l2_format *f)
1177{
1178        int ret = 0;
1179        struct omap_vout_device *vout = fh;
1180        struct omap_overlay *ovl;
1181        struct omapvideo_info *ovid;
1182        struct v4l2_window *win = &f->fmt.win;
1183
1184        ovid = &vout->vid_info;
1185        ovl = ovid->overlays[0];
1186
1187        ret = omap_vout_try_window(&vout->fbuf, win);
1188
1189        if (!ret) {
1190                if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
1191                        win->global_alpha = 255;
1192                else
1193                        win->global_alpha = f->fmt.win.global_alpha;
1194        }
1195
1196        return ret;
1197}
1198
1199static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh,
1200                        struct v4l2_format *f)
1201{
1202        int ret = 0;
1203        struct omap_overlay *ovl;
1204        struct omapvideo_info *ovid;
1205        struct omap_vout_device *vout = fh;
1206        struct v4l2_window *win = &f->fmt.win;
1207
1208        mutex_lock(&vout->lock);
1209        ovid = &vout->vid_info;
1210        ovl = ovid->overlays[0];
1211
1212        ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win);
1213        if (!ret) {
1214                /* Video1 plane does not support global alpha on OMAP3 */
1215                if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
1216                        vout->win.global_alpha = 255;
1217                else
1218                        vout->win.global_alpha = f->fmt.win.global_alpha;
1219
1220                vout->win.chromakey = f->fmt.win.chromakey;
1221        }
1222        mutex_unlock(&vout->lock);
1223        return ret;
1224}
1225
1226static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh,
1227                        struct v4l2_format *f)
1228{
1229        u32 key_value =  0;
1230        struct omap_overlay *ovl;
1231        struct omapvideo_info *ovid;
1232        struct omap_vout_device *vout = fh;
1233        struct omap_overlay_manager_info info;
1234        struct v4l2_window *win = &f->fmt.win;
1235
1236        ovid = &vout->vid_info;
1237        ovl = ovid->overlays[0];
1238
1239        win->w = vout->win.w;
1240        win->field = vout->win.field;
1241        win->global_alpha = vout->win.global_alpha;
1242
1243        if (ovl->manager && ovl->manager->get_manager_info) {
1244                ovl->manager->get_manager_info(ovl->manager, &info);
1245                key_value = info.trans_key;
1246        }
1247        win->chromakey = key_value;
1248        return 0;
1249}
1250
1251static int vidioc_g_selection(struct file *file, void *fh, struct v4l2_selection *sel)
1252{
1253        struct omap_vout_device *vout = fh;
1254        struct v4l2_pix_format *pix = &vout->pix;
1255
1256        if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1257                return -EINVAL;
1258
1259        switch (sel->target) {
1260        case V4L2_SEL_TGT_CROP:
1261                sel->r = vout->crop;
1262                break;
1263        case V4L2_SEL_TGT_CROP_DEFAULT:
1264                omap_vout_default_crop(&vout->pix, &vout->fbuf, &sel->r);
1265                break;
1266        case V4L2_SEL_TGT_CROP_BOUNDS:
1267                /* Width and height are always even */
1268                sel->r.width = pix->width & ~1;
1269                sel->r.height = pix->height & ~1;
1270                break;
1271        default:
1272                return -EINVAL;
1273        }
1274        return 0;
1275}
1276
1277static int vidioc_s_selection(struct file *file, void *fh, struct v4l2_selection *sel)
1278{
1279        int ret = -EINVAL;
1280        struct omap_vout_device *vout = fh;
1281        struct omapvideo_info *ovid;
1282        struct omap_overlay *ovl;
1283        struct omap_video_timings *timing;
1284        struct omap_dss_device *dssdev;
1285
1286        if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1287                return -EINVAL;
1288
1289        if (sel->target != V4L2_SEL_TGT_CROP)
1290                return -EINVAL;
1291
1292        if (vout->streaming)
1293                return -EBUSY;
1294
1295        mutex_lock(&vout->lock);
1296        ovid = &vout->vid_info;
1297        ovl = ovid->overlays[0];
1298        /* get the display device attached to the overlay */
1299        dssdev = ovl->get_device(ovl);
1300
1301        if (!dssdev) {
1302                ret = -EINVAL;
1303                goto s_crop_err;
1304        }
1305
1306        timing = &dssdev->panel.timings;
1307
1308        if (is_rotation_90_or_270(vout)) {
1309                vout->fbuf.fmt.height = timing->x_res;
1310                vout->fbuf.fmt.width = timing->y_res;
1311        } else {
1312                vout->fbuf.fmt.height = timing->y_res;
1313                vout->fbuf.fmt.width = timing->x_res;
1314        }
1315
1316        ret = omap_vout_new_crop(&vout->pix, &vout->crop, &vout->win,
1317                                 &vout->fbuf, &sel->r);
1318
1319s_crop_err:
1320        mutex_unlock(&vout->lock);
1321        return ret;
1322}
1323
1324static int omap_vout_s_ctrl(struct v4l2_ctrl *ctrl)
1325{
1326        struct omap_vout_device *vout =
1327                container_of(ctrl->handler, struct omap_vout_device, ctrl_handler);
1328        int ret = 0;
1329
1330        switch (ctrl->id) {
1331        case V4L2_CID_ROTATE: {
1332                struct omapvideo_info *ovid;
1333                int rotation = ctrl->val;
1334
1335                ovid = &vout->vid_info;
1336
1337                mutex_lock(&vout->lock);
1338                if (rotation && ovid->rotation_type == VOUT_ROT_NONE) {
1339                        mutex_unlock(&vout->lock);
1340                        ret = -ERANGE;
1341                        break;
1342                }
1343
1344                if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1345                        mutex_unlock(&vout->lock);
1346                        ret = -EINVAL;
1347                        break;
1348                }
1349
1350                if (v4l2_rot_to_dss_rot(rotation, &vout->rotation,
1351                                                        vout->mirror)) {
1352                        mutex_unlock(&vout->lock);
1353                        ret = -EINVAL;
1354                        break;
1355                }
1356                mutex_unlock(&vout->lock);
1357                break;
1358        }
1359        case V4L2_CID_BG_COLOR:
1360        {
1361                struct omap_overlay *ovl;
1362                unsigned int color = ctrl->val;
1363                struct omap_overlay_manager_info info;
1364
1365                ovl = vout->vid_info.overlays[0];
1366
1367                mutex_lock(&vout->lock);
1368                if (!ovl->manager || !ovl->manager->get_manager_info) {
1369                        mutex_unlock(&vout->lock);
1370                        ret = -EINVAL;
1371                        break;
1372                }
1373
1374                ovl->manager->get_manager_info(ovl->manager, &info);
1375                info.default_color = color;
1376                if (ovl->manager->set_manager_info(ovl->manager, &info)) {
1377                        mutex_unlock(&vout->lock);
1378                        ret = -EINVAL;
1379                        break;
1380                }
1381                mutex_unlock(&vout->lock);
1382                break;
1383        }
1384        case V4L2_CID_VFLIP:
1385        {
1386                struct omapvideo_info *ovid;
1387                unsigned int mirror = ctrl->val;
1388
1389                ovid = &vout->vid_info;
1390
1391                mutex_lock(&vout->lock);
1392                if (mirror && ovid->rotation_type == VOUT_ROT_NONE) {
1393                        mutex_unlock(&vout->lock);
1394                        ret = -ERANGE;
1395                        break;
1396                }
1397
1398                if (mirror  && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1399                        mutex_unlock(&vout->lock);
1400                        ret = -EINVAL;
1401                        break;
1402                }
1403                vout->mirror = mirror;
1404                mutex_unlock(&vout->lock);
1405                break;
1406        }
1407        default:
1408                return -EINVAL;
1409        }
1410        return ret;
1411}
1412
1413static const struct v4l2_ctrl_ops omap_vout_ctrl_ops = {
1414        .s_ctrl = omap_vout_s_ctrl,
1415};
1416
1417static int vidioc_reqbufs(struct file *file, void *fh,
1418                        struct v4l2_requestbuffers *req)
1419{
1420        int ret = 0;
1421        unsigned int i, num_buffers = 0;
1422        struct omap_vout_device *vout = fh;
1423        struct videobuf_queue *q = &vout->vbq;
1424
1425        if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1426                return -EINVAL;
1427        /* if memory is not mmp or userptr
1428           return error */
1429        if ((V4L2_MEMORY_MMAP != req->memory) &&
1430                        (V4L2_MEMORY_USERPTR != req->memory))
1431                return -EINVAL;
1432
1433        mutex_lock(&vout->lock);
1434        /* Cannot be requested when streaming is on */
1435        if (vout->streaming) {
1436                ret = -EBUSY;
1437                goto reqbuf_err;
1438        }
1439
1440        /* If buffers are already allocated free them */
1441        if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) {
1442                if (vout->mmap_count) {
1443                        ret = -EBUSY;
1444                        goto reqbuf_err;
1445                }
1446                num_buffers = (vout->vid == OMAP_VIDEO1) ?
1447                        video1_numbuffers : video2_numbuffers;
1448                for (i = num_buffers; i < vout->buffer_allocated; i++) {
1449                        omap_vout_free_buffer(vout->buf_virt_addr[i],
1450                                        vout->buffer_size);
1451                        vout->buf_virt_addr[i] = 0;
1452                        vout->buf_phy_addr[i] = 0;
1453                }
1454                vout->buffer_allocated = num_buffers;
1455                videobuf_mmap_free(q);
1456        } else if (q->bufs[0] && (V4L2_MEMORY_USERPTR == q->bufs[0]->memory)) {
1457                if (vout->buffer_allocated) {
1458                        videobuf_mmap_free(q);
1459                        for (i = 0; i < vout->buffer_allocated; i++) {
1460                                kfree(q->bufs[i]);
1461                                q->bufs[i] = NULL;
1462                        }
1463                        vout->buffer_allocated = 0;
1464                }
1465        }
1466
1467        /*store the memory type in data structure */
1468        vout->memory = req->memory;
1469
1470        INIT_LIST_HEAD(&vout->dma_queue);
1471
1472        /* call videobuf_reqbufs api */
1473        ret = videobuf_reqbufs(q, req);
1474        if (ret < 0)
1475                goto reqbuf_err;
1476
1477        vout->buffer_allocated = req->count;
1478
1479reqbuf_err:
1480        mutex_unlock(&vout->lock);
1481        return ret;
1482}
1483
1484static int vidioc_querybuf(struct file *file, void *fh,
1485                        struct v4l2_buffer *b)
1486{
1487        struct omap_vout_device *vout = fh;
1488
1489        return videobuf_querybuf(&vout->vbq, b);
1490}
1491
1492static int vidioc_qbuf(struct file *file, void *fh,
1493                        struct v4l2_buffer *buffer)
1494{
1495        struct omap_vout_device *vout = fh;
1496        struct videobuf_queue *q = &vout->vbq;
1497
1498        if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) ||
1499                        (buffer->index >= vout->buffer_allocated) ||
1500                        (q->bufs[buffer->index]->memory != buffer->memory)) {
1501                return -EINVAL;
1502        }
1503        if (V4L2_MEMORY_USERPTR == buffer->memory) {
1504                if ((buffer->length < vout->pix.sizeimage) ||
1505                                (0 == buffer->m.userptr)) {
1506                        return -EINVAL;
1507                }
1508        }
1509
1510        if ((is_rotation_enabled(vout)) &&
1511                        vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) {
1512                v4l2_warn(&vout->vid_dev->v4l2_dev,
1513                                "DMA Channel not allocated for Rotation\n");
1514                return -EINVAL;
1515        }
1516
1517        return videobuf_qbuf(q, buffer);
1518}
1519
1520static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1521{
1522        struct omap_vout_device *vout = fh;
1523        struct videobuf_queue *q = &vout->vbq;
1524
1525        int ret;
1526        u32 addr;
1527        unsigned long size;
1528        struct videobuf_buffer *vb;
1529
1530        vb = q->bufs[b->index];
1531
1532        if (!vout->streaming)
1533                return -EINVAL;
1534
1535        if (file->f_flags & O_NONBLOCK)
1536                /* Call videobuf_dqbuf for non blocking mode */
1537                ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1);
1538        else
1539                /* Call videobuf_dqbuf for  blocking mode */
1540                ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
1541
1542        addr = (unsigned long) vout->buf_phy_addr[vb->i];
1543        size = (unsigned long) vb->size;
1544        dma_unmap_single(vout->vid_dev->v4l2_dev.dev,  addr,
1545                                size, DMA_TO_DEVICE);
1546        return ret;
1547}
1548
1549static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1550{
1551        int ret = 0, j;
1552        u32 addr = 0, mask = 0;
1553        struct omap_vout_device *vout = fh;
1554        struct videobuf_queue *q = &vout->vbq;
1555        struct omapvideo_info *ovid = &vout->vid_info;
1556
1557        mutex_lock(&vout->lock);
1558
1559        if (vout->streaming) {
1560                ret = -EBUSY;
1561                goto streamon_err;
1562        }
1563
1564        ret = videobuf_streamon(q);
1565        if (ret)
1566                goto streamon_err;
1567
1568        if (list_empty(&vout->dma_queue)) {
1569                ret = -EIO;
1570                goto streamon_err1;
1571        }
1572
1573        /* Get the next frame from the buffer queue */
1574        vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next,
1575                        struct videobuf_buffer, queue);
1576        /* Remove buffer from the buffer queue */
1577        list_del(&vout->cur_frm->queue);
1578        /* Mark state of the current frame to active */
1579        vout->cur_frm->state = VIDEOBUF_ACTIVE;
1580        /* Initialize field_id and started member */
1581        vout->field_id = 0;
1582
1583        /* set flag here. Next QBUF will start DMA */
1584        vout->streaming = true;
1585
1586        vout->first_int = 1;
1587
1588        if (omap_vout_calculate_offset(vout)) {
1589                ret = -EINVAL;
1590                goto streamon_err1;
1591        }
1592        addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i]
1593                + vout->cropped_offset;
1594
1595        mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
1596                | DISPC_IRQ_VSYNC2;
1597
1598        /* First save the configuration in ovelray structure */
1599        ret = omapvid_init(vout, addr);
1600        if (ret) {
1601                v4l2_err(&vout->vid_dev->v4l2_dev,
1602                                "failed to set overlay info\n");
1603                goto streamon_err1;
1604        }
1605
1606        omap_dispc_register_isr(omap_vout_isr, vout, mask);
1607
1608        /* Enable the pipeline and set the Go bit */
1609        ret = omapvid_apply_changes(vout);
1610        if (ret)
1611                v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
1612
1613        for (j = 0; j < ovid->num_overlays; j++) {
1614                struct omap_overlay *ovl = ovid->overlays[j];
1615                struct omap_dss_device *dssdev = ovl->get_device(ovl);
1616
1617                if (dssdev) {
1618                        ret = ovl->enable(ovl);
1619                        if (ret)
1620                                goto streamon_err1;
1621                }
1622        }
1623
1624        ret = 0;
1625
1626streamon_err1:
1627        if (ret)
1628                ret = videobuf_streamoff(q);
1629streamon_err:
1630        mutex_unlock(&vout->lock);
1631        return ret;
1632}
1633
1634static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1635{
1636        u32 mask = 0;
1637        int ret = 0, j;
1638        struct omap_vout_device *vout = fh;
1639        struct omapvideo_info *ovid = &vout->vid_info;
1640
1641        if (!vout->streaming)
1642                return -EINVAL;
1643
1644        vout->streaming = false;
1645        mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
1646                | DISPC_IRQ_VSYNC2;
1647
1648        omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
1649
1650        for (j = 0; j < ovid->num_overlays; j++) {
1651                struct omap_overlay *ovl = ovid->overlays[j];
1652                struct omap_dss_device *dssdev = ovl->get_device(ovl);
1653
1654                if (dssdev)
1655                        ovl->disable(ovl);
1656        }
1657
1658        /* Turn of the pipeline */
1659        ret = omapvid_apply_changes(vout);
1660        if (ret)
1661                v4l2_err(&vout->vid_dev->v4l2_dev,
1662                         "failed to change mode in streamoff\n");
1663
1664        INIT_LIST_HEAD(&vout->dma_queue);
1665        ret = videobuf_streamoff(&vout->vbq);
1666
1667        return ret;
1668}
1669
1670static int vidioc_s_fbuf(struct file *file, void *fh,
1671                                const struct v4l2_framebuffer *a)
1672{
1673        int enable = 0;
1674        struct omap_overlay *ovl;
1675        struct omapvideo_info *ovid;
1676        struct omap_vout_device *vout = fh;
1677        struct omap_overlay_manager_info info;
1678        enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
1679
1680        ovid = &vout->vid_info;
1681        ovl = ovid->overlays[0];
1682
1683        /* OMAP DSS doesn't support Source and Destination color
1684           key together */
1685        if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) &&
1686                        (a->flags & V4L2_FBUF_FLAG_CHROMAKEY))
1687                return -EINVAL;
1688        /* OMAP DSS Doesn't support the Destination color key
1689           and alpha blending together */
1690        if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY) &&
1691                        (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA))
1692                return -EINVAL;
1693
1694        if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)) {
1695                vout->fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1696                key_type =  OMAP_DSS_COLOR_KEY_VID_SRC;
1697        } else
1698                vout->fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1699
1700        if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) {
1701                vout->fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1702                key_type =  OMAP_DSS_COLOR_KEY_GFX_DST;
1703        } else
1704                vout->fbuf.flags &=  ~V4L2_FBUF_FLAG_CHROMAKEY;
1705
1706        if (a->flags & (V4L2_FBUF_FLAG_CHROMAKEY |
1707                                V4L2_FBUF_FLAG_SRC_CHROMAKEY))
1708                enable = 1;
1709        else
1710                enable = 0;
1711        if (ovl->manager && ovl->manager->get_manager_info &&
1712                        ovl->manager->set_manager_info) {
1713
1714                ovl->manager->get_manager_info(ovl->manager, &info);
1715                info.trans_enabled = enable;
1716                info.trans_key_type = key_type;
1717                info.trans_key = vout->win.chromakey;
1718
1719                if (ovl->manager->set_manager_info(ovl->manager, &info))
1720                        return -EINVAL;
1721        }
1722        if (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) {
1723                vout->fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1724                enable = 1;
1725        } else {
1726                vout->fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA;
1727                enable = 0;
1728        }
1729        if (ovl->manager && ovl->manager->get_manager_info &&
1730                        ovl->manager->set_manager_info) {
1731                ovl->manager->get_manager_info(ovl->manager, &info);
1732                /* enable this only if there is no zorder cap */
1733                if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
1734                        info.partial_alpha_enabled = enable;
1735                if (ovl->manager->set_manager_info(ovl->manager, &info))
1736                        return -EINVAL;
1737        }
1738
1739        return 0;
1740}
1741
1742static int vidioc_g_fbuf(struct file *file, void *fh,
1743                struct v4l2_framebuffer *a)
1744{
1745        struct omap_overlay *ovl;
1746        struct omapvideo_info *ovid;
1747        struct omap_vout_device *vout = fh;
1748        struct omap_overlay_manager_info info;
1749
1750        ovid = &vout->vid_info;
1751        ovl = ovid->overlays[0];
1752
1753        /* The video overlay must stay within the framebuffer and can't be
1754           positioned independently. */
1755        a->flags = V4L2_FBUF_FLAG_OVERLAY;
1756        a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY
1757                | V4L2_FBUF_CAP_SRC_CHROMAKEY;
1758
1759        if (ovl->manager && ovl->manager->get_manager_info) {
1760                ovl->manager->get_manager_info(ovl->manager, &info);
1761                if (info.trans_key_type == OMAP_DSS_COLOR_KEY_VID_SRC)
1762                        a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1763                if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST)
1764                        a->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1765        }
1766        if (ovl->manager && ovl->manager->get_manager_info) {
1767                ovl->manager->get_manager_info(ovl->manager, &info);
1768                if (info.partial_alpha_enabled)
1769                        a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1770        }
1771
1772        return 0;
1773}
1774
1775static const struct v4l2_ioctl_ops vout_ioctl_ops = {
1776        .vidioc_querycap                        = vidioc_querycap,
1777        .vidioc_enum_fmt_vid_out                = vidioc_enum_fmt_vid_out,
1778        .vidioc_g_fmt_vid_out                   = vidioc_g_fmt_vid_out,
1779        .vidioc_try_fmt_vid_out                 = vidioc_try_fmt_vid_out,
1780        .vidioc_s_fmt_vid_out                   = vidioc_s_fmt_vid_out,
1781        .vidioc_s_fbuf                          = vidioc_s_fbuf,
1782        .vidioc_g_fbuf                          = vidioc_g_fbuf,
1783        .vidioc_try_fmt_vid_out_overlay         = vidioc_try_fmt_vid_overlay,
1784        .vidioc_s_fmt_vid_out_overlay           = vidioc_s_fmt_vid_overlay,
1785        .vidioc_g_fmt_vid_out_overlay           = vidioc_g_fmt_vid_overlay,
1786        .vidioc_g_selection                     = vidioc_g_selection,
1787        .vidioc_s_selection                     = vidioc_s_selection,
1788        .vidioc_reqbufs                         = vidioc_reqbufs,
1789        .vidioc_querybuf                        = vidioc_querybuf,
1790        .vidioc_qbuf                            = vidioc_qbuf,
1791        .vidioc_dqbuf                           = vidioc_dqbuf,
1792        .vidioc_streamon                        = vidioc_streamon,
1793        .vidioc_streamoff                       = vidioc_streamoff,
1794};
1795
1796static const struct v4l2_file_operations omap_vout_fops = {
1797        .owner          = THIS_MODULE,
1798        .poll           = omap_vout_poll,
1799        .unlocked_ioctl = video_ioctl2,
1800        .mmap           = omap_vout_mmap,
1801        .open           = omap_vout_open,
1802        .release        = omap_vout_release,
1803};
1804
1805/* Init functions used during driver initialization */
1806/* Initial setup of video_data */
1807static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
1808{
1809        struct video_device *vfd;
1810        struct v4l2_pix_format *pix;
1811        struct omap_overlay *ovl = vout->vid_info.overlays[0];
1812        struct omap_dss_device *display = ovl->get_device(ovl);
1813        struct v4l2_ctrl_handler *hdl;
1814
1815        /* set the default pix */
1816        pix = &vout->pix;
1817
1818        /* Set the default picture of QVGA  */
1819        pix->width = QQVGA_WIDTH;
1820        pix->height = QQVGA_HEIGHT;
1821
1822        /* Default pixel format is RGB 5-6-5 */
1823        pix->pixelformat = V4L2_PIX_FMT_RGB565;
1824        pix->field = V4L2_FIELD_ANY;
1825        pix->bytesperline = pix->width * 2;
1826        pix->sizeimage = pix->bytesperline * pix->height;
1827        pix->colorspace = V4L2_COLORSPACE_JPEG;
1828
1829        vout->bpp = RGB565_BPP;
1830        vout->fbuf.fmt.width  =  display->panel.timings.x_res;
1831        vout->fbuf.fmt.height =  display->panel.timings.y_res;
1832
1833        /* Set the data structures for the overlay parameters*/
1834        vout->win.global_alpha = 255;
1835        vout->fbuf.flags = 0;
1836        vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA |
1837                V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY;
1838        vout->win.chromakey = 0;
1839
1840        omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win);
1841
1842        hdl = &vout->ctrl_handler;
1843        v4l2_ctrl_handler_init(hdl, 3);
1844        v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
1845                          V4L2_CID_ROTATE, 0, 270, 90, 0);
1846        v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
1847                          V4L2_CID_BG_COLOR, 0, 0xffffff, 1, 0);
1848        v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
1849                          V4L2_CID_VFLIP, 0, 1, 1, 0);
1850        if (hdl->error)
1851                return hdl->error;
1852
1853        vout->rotation = 0;
1854        vout->mirror = false;
1855        if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
1856                vout->vrfb_bpp = 2;
1857
1858        /* initialize the video_device struct */
1859        vfd = vout->vfd = video_device_alloc();
1860
1861        if (!vfd) {
1862                printk(KERN_ERR VOUT_NAME
1863                       ": could not allocate video device struct\n");
1864                v4l2_ctrl_handler_free(hdl);
1865                return -ENOMEM;
1866        }
1867        vfd->ctrl_handler = hdl;
1868        vfd->release = video_device_release;
1869        vfd->ioctl_ops = &vout_ioctl_ops;
1870
1871        strscpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
1872
1873        vfd->fops = &omap_vout_fops;
1874        vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
1875        vfd->vfl_dir = VFL_DIR_TX;
1876        mutex_init(&vout->lock);
1877
1878        vfd->minor = -1;
1879        return 0;
1880
1881}
1882
1883/* Setup video buffers */
1884static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
1885                int vid_num)
1886{
1887        u32 numbuffers;
1888        int ret = 0, i;
1889        struct omapvideo_info *ovid;
1890        struct omap_vout_device *vout;
1891        struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1892        struct omap2video_device *vid_dev =
1893                container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
1894
1895        vout = vid_dev->vouts[vid_num];
1896        ovid = &vout->vid_info;
1897
1898        numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers;
1899        vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize;
1900        dev_info(&pdev->dev, "Buffer Size = %d\n", vout->buffer_size);
1901
1902        for (i = 0; i < numbuffers; i++) {
1903                vout->buf_virt_addr[i] =
1904                        omap_vout_alloc_buffer(vout->buffer_size,
1905                                        (u32 *) &vout->buf_phy_addr[i]);
1906                if (!vout->buf_virt_addr[i]) {
1907                        numbuffers = i;
1908                        ret = -ENOMEM;
1909                        goto free_buffers;
1910                }
1911        }
1912
1913        vout->cropped_offset = 0;
1914
1915        if (ovid->rotation_type == VOUT_ROT_VRFB) {
1916                bool static_vrfb_allocation = (vid_num == 0) ?
1917                        vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
1918                ret = omap_vout_setup_vrfb_bufs(pdev, vid_num,
1919                                static_vrfb_allocation);
1920        }
1921
1922        return ret;
1923
1924free_buffers:
1925        for (i = 0; i < numbuffers; i++) {
1926                omap_vout_free_buffer(vout->buf_virt_addr[i],
1927                                                vout->buffer_size);
1928                vout->buf_virt_addr[i] = 0;
1929                vout->buf_phy_addr[i] = 0;
1930        }
1931        return ret;
1932
1933}
1934
1935/* Create video out devices */
1936static int __init omap_vout_create_video_devices(struct platform_device *pdev)
1937{
1938        int ret = 0, k;
1939        struct omap_vout_device *vout;
1940        struct video_device *vfd = NULL;
1941        struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1942        struct omap2video_device *vid_dev = container_of(v4l2_dev,
1943                        struct omap2video_device, v4l2_dev);
1944
1945        for (k = 0; k < pdev->num_resources; k++) {
1946
1947                vout = kzalloc(sizeof(struct omap_vout_device), GFP_KERNEL);
1948                if (!vout) {
1949                        dev_err(&pdev->dev, ": could not allocate memory\n");
1950                        return -ENOMEM;
1951                }
1952
1953                vout->vid = k;
1954                vid_dev->vouts[k] = vout;
1955                vout->vid_dev = vid_dev;
1956                /* Select video2 if only 1 overlay is controlled by V4L2 */
1957                if (pdev->num_resources == 1)
1958                        vout->vid_info.overlays[0] = vid_dev->overlays[k + 2];
1959                else
1960                        /* Else select video1 and video2 one by one. */
1961                        vout->vid_info.overlays[0] = vid_dev->overlays[k + 1];
1962                vout->vid_info.num_overlays = 1;
1963                vout->vid_info.id = k + 1;
1964
1965                /* Set VRFB as rotation_type for omap2 and omap3 */
1966                if (omap_vout_dss_omap24xx() || omap_vout_dss_omap34xx())
1967                        vout->vid_info.rotation_type = VOUT_ROT_VRFB;
1968
1969                /* Setup the default configuration for the video devices
1970                 */
1971                if (omap_vout_setup_video_data(vout) != 0) {
1972                        ret = -ENOMEM;
1973                        goto error;
1974                }
1975
1976                /* Allocate default number of buffers for the video streaming
1977                 * and reserve the VRFB space for rotation
1978                 */
1979                if (omap_vout_setup_video_bufs(pdev, k) != 0) {
1980                        ret = -ENOMEM;
1981                        goto error1;
1982                }
1983
1984                /* Register the Video device with V4L2
1985                 */
1986                vfd = vout->vfd;
1987                if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) {
1988                        dev_err(&pdev->dev,
1989                                ": Could not register Video for Linux device\n");
1990                        vfd->minor = -1;
1991                        ret = -ENODEV;
1992                        goto error2;
1993                }
1994                video_set_drvdata(vfd, vout);
1995
1996                dev_info(&pdev->dev,
1997                         ": registered and initialized video device %d\n",
1998                         vfd->minor);
1999                if (k == (pdev->num_resources - 1))
2000                        return 0;
2001
2002                continue;
2003error2:
2004                if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
2005                        omap_vout_release_vrfb(vout);
2006                omap_vout_free_buffers(vout);
2007error1:
2008                video_device_release(vfd);
2009error:
2010                kfree(vout);
2011                return ret;
2012        }
2013
2014        return -ENODEV;
2015}
2016/* Driver functions */
2017static void omap_vout_cleanup_device(struct omap_vout_device *vout)
2018{
2019        struct video_device *vfd;
2020        struct omapvideo_info *ovid;
2021
2022        if (!vout)
2023                return;
2024
2025        vfd = vout->vfd;
2026        ovid = &vout->vid_info;
2027        if (vfd) {
2028                if (!video_is_registered(vfd)) {
2029                        /*
2030                         * The device was never registered, so release the
2031                         * video_device struct directly.
2032                         */
2033                        video_device_release(vfd);
2034                } else {
2035                        /*
2036                         * The unregister function will release the video_device
2037                         * struct as well as unregistering it.
2038                         */
2039                        video_unregister_device(vfd);
2040                }
2041        }
2042        v4l2_ctrl_handler_free(&vout->ctrl_handler);
2043        if (ovid->rotation_type == VOUT_ROT_VRFB) {
2044                omap_vout_release_vrfb(vout);
2045                /* Free the VRFB buffer if allocated
2046                 * init time
2047                 */
2048                if (vout->vrfb_static_allocation)
2049                        omap_vout_free_vrfb_buffers(vout);
2050        }
2051        omap_vout_free_buffers(vout);
2052
2053        kfree(vout);
2054}
2055
2056static int omap_vout_remove(struct platform_device *pdev)
2057{
2058        int k;
2059        struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2060        struct omap2video_device *vid_dev = container_of(v4l2_dev, struct
2061                        omap2video_device, v4l2_dev);
2062
2063        v4l2_device_unregister(v4l2_dev);
2064        for (k = 0; k < pdev->num_resources; k++)
2065                omap_vout_cleanup_device(vid_dev->vouts[k]);
2066
2067        for (k = 0; k < vid_dev->num_displays; k++) {
2068                if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED)
2069                        vid_dev->displays[k]->driver->disable(vid_dev->displays[k]);
2070
2071                omap_dss_put_device(vid_dev->displays[k]);
2072        }
2073        kfree(vid_dev);
2074        return 0;
2075}
2076
2077static int __init omap_vout_probe(struct platform_device *pdev)
2078{
2079        int ret = 0, i;
2080        struct omap_overlay *ovl;
2081        struct omap_dss_device *dssdev = NULL;
2082        struct omap_dss_device *def_display;
2083        struct omap2video_device *vid_dev = NULL;
2084
2085        if (omapdss_is_initialized() == false)
2086                return -EPROBE_DEFER;
2087
2088        ret = omapdss_compat_init();
2089        if (ret) {
2090                dev_err(&pdev->dev, "failed to init dss\n");
2091                return ret;
2092        }
2093
2094        if (pdev->num_resources == 0) {
2095                dev_err(&pdev->dev, "probed for an unknown device\n");
2096                ret = -ENODEV;
2097                goto err_dss_init;
2098        }
2099
2100        vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL);
2101        if (vid_dev == NULL) {
2102                ret = -ENOMEM;
2103                goto err_dss_init;
2104        }
2105
2106        vid_dev->num_displays = 0;
2107        for_each_dss_dev(dssdev) {
2108                omap_dss_get_device(dssdev);
2109
2110                if (!dssdev->driver) {
2111                        dev_warn(&pdev->dev, "no driver for display: %s\n",
2112                                        dssdev->name);
2113                        omap_dss_put_device(dssdev);
2114                        continue;
2115                }
2116
2117                vid_dev->displays[vid_dev->num_displays++] = dssdev;
2118        }
2119
2120        if (vid_dev->num_displays == 0) {
2121                dev_err(&pdev->dev, "no displays\n");
2122                ret = -EINVAL;
2123                goto probe_err0;
2124        }
2125
2126        vid_dev->num_overlays = omap_dss_get_num_overlays();
2127        for (i = 0; i < vid_dev->num_overlays; i++)
2128                vid_dev->overlays[i] = omap_dss_get_overlay(i);
2129
2130        vid_dev->num_managers = omap_dss_get_num_overlay_managers();
2131        for (i = 0; i < vid_dev->num_managers; i++)
2132                vid_dev->managers[i] = omap_dss_get_overlay_manager(i);
2133
2134        /* Get the Video1 overlay and video2 overlay.
2135         * Setup the Display attached to that overlays
2136         */
2137        for (i = 1; i < vid_dev->num_overlays; i++) {
2138                ovl = omap_dss_get_overlay(i);
2139                dssdev = ovl->get_device(ovl);
2140
2141                if (dssdev) {
2142                        def_display = dssdev;
2143                } else {
2144                        dev_warn(&pdev->dev, "cannot find display\n");
2145                        def_display = NULL;
2146                }
2147                if (def_display) {
2148                        struct omap_dss_driver *dssdrv = def_display->driver;
2149
2150                        ret = dssdrv->enable(def_display);
2151                        if (ret) {
2152                                /* Here we are not considering a error
2153                                 *  as display may be enabled by frame
2154                                 *  buffer driver
2155                                 */
2156                                dev_warn(&pdev->dev,
2157                                        "'%s' Display already enabled\n",
2158                                        def_display->name);
2159                        }
2160                }
2161        }
2162
2163        if (v4l2_device_register(&pdev->dev, &vid_dev->v4l2_dev) < 0) {
2164                dev_err(&pdev->dev, "v4l2_device_register failed\n");
2165                ret = -ENODEV;
2166                goto probe_err1;
2167        }
2168
2169        ret = omap_vout_create_video_devices(pdev);
2170        if (ret)
2171                goto probe_err2;
2172
2173        for (i = 0; i < vid_dev->num_displays; i++) {
2174                struct omap_dss_device *display = vid_dev->displays[i];
2175
2176                if (display->driver->update)
2177                        display->driver->update(display, 0, 0,
2178                                        display->panel.timings.x_res,
2179                                        display->panel.timings.y_res);
2180        }
2181        return 0;
2182
2183probe_err2:
2184        v4l2_device_unregister(&vid_dev->v4l2_dev);
2185probe_err1:
2186        for (i = 1; i < vid_dev->num_overlays; i++) {
2187                def_display = NULL;
2188                ovl = omap_dss_get_overlay(i);
2189                dssdev = ovl->get_device(ovl);
2190
2191                if (dssdev)
2192                        def_display = dssdev;
2193
2194                if (def_display && def_display->driver)
2195                        def_display->driver->disable(def_display);
2196        }
2197probe_err0:
2198        kfree(vid_dev);
2199err_dss_init:
2200        omapdss_compat_uninit();
2201        return ret;
2202}
2203
2204static struct platform_driver omap_vout_driver = {
2205        .driver = {
2206                .name = VOUT_NAME,
2207        },
2208        .remove = omap_vout_remove,
2209};
2210
2211static int __init omap_vout_init(void)
2212{
2213        if (platform_driver_probe(&omap_vout_driver, omap_vout_probe) != 0) {
2214                printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
2215                return -EINVAL;
2216        }
2217        return 0;
2218}
2219
2220static void omap_vout_cleanup(void)
2221{
2222        platform_driver_unregister(&omap_vout_driver);
2223}
2224
2225late_initcall(omap_vout_init);
2226module_exit(omap_vout_cleanup);
2227