linux/drivers/media/video/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/dma-mapping.h>
  39#include <linux/irq.h>
  40#include <linux/videodev2.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 <plat/dma.h>
  48#include <plat/vram.h>
  49#include <plat/vrfb.h>
  50#include <plat/display.h>
  51
  52#include "omap_voutlib.h"
  53#include "omap_voutdef.h"
  54
  55MODULE_AUTHOR("Texas Instruments");
  56MODULE_DESCRIPTION("OMAP Video for Linux Video out driver");
  57MODULE_LICENSE("GPL");
  58
  59
  60/* Driver Configuration macros */
  61#define VOUT_NAME               "omap_vout"
  62
  63enum omap_vout_channels {
  64        OMAP_VIDEO1,
  65        OMAP_VIDEO2,
  66};
  67
  68enum dma_channel_state {
  69        DMA_CHAN_NOT_ALLOTED,
  70        DMA_CHAN_ALLOTED,
  71};
  72
  73#define QQVGA_WIDTH             160
  74#define QQVGA_HEIGHT            120
  75
  76/* Max Resolution supported by the driver */
  77#define VID_MAX_WIDTH           1280    /* Largest width */
  78#define VID_MAX_HEIGHT          720     /* Largest height */
  79
  80/* Mimimum requirement is 2x2 for DSS */
  81#define VID_MIN_WIDTH           2
  82#define VID_MIN_HEIGHT          2
  83
  84/* 2048 x 2048 is max res supported by OMAP display controller */
  85#define MAX_PIXELS_PER_LINE     2048
  86
  87#define VRFB_TX_TIMEOUT         1000
  88#define VRFB_NUM_BUFS           4
  89
  90/* Max buffer size tobe allocated during init */
  91#define OMAP_VOUT_MAX_BUF_SIZE (VID_MAX_WIDTH*VID_MAX_HEIGHT*4)
  92
  93static struct videobuf_queue_ops video_vbq_ops;
  94/* Variables configurable through module params*/
  95static u32 video1_numbuffers = 3;
  96static u32 video2_numbuffers = 3;
  97static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
  98static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
  99static u32 vid1_static_vrfb_alloc;
 100static u32 vid2_static_vrfb_alloc;
 101static int debug;
 102
 103/* Module parameters */
 104module_param(video1_numbuffers, uint, S_IRUGO);
 105MODULE_PARM_DESC(video1_numbuffers,
 106        "Number of buffers to be allocated at init time for Video1 device.");
 107
 108module_param(video2_numbuffers, uint, S_IRUGO);
 109MODULE_PARM_DESC(video2_numbuffers,
 110        "Number of buffers to be allocated at init time for Video2 device.");
 111
 112module_param(video1_bufsize, uint, S_IRUGO);
 113MODULE_PARM_DESC(video1_bufsize,
 114        "Size of the buffer to be allocated for video1 device");
 115
 116module_param(video2_bufsize, uint, S_IRUGO);
 117MODULE_PARM_DESC(video2_bufsize,
 118        "Size of the buffer to be allocated for video2 device");
 119
 120module_param(vid1_static_vrfb_alloc, bool, S_IRUGO);
 121MODULE_PARM_DESC(vid1_static_vrfb_alloc,
 122        "Static allocation of the VRFB buffer for video1 device");
 123
 124module_param(vid2_static_vrfb_alloc, bool, S_IRUGO);
 125MODULE_PARM_DESC(vid2_static_vrfb_alloc,
 126        "Static allocation of the VRFB buffer for video2 device");
 127
 128module_param(debug, bool, S_IRUGO);
 129MODULE_PARM_DESC(debug, "Debug level (0-1)");
 130
 131/* list of image formats supported by OMAP2 video pipelines */
 132const static struct v4l2_fmtdesc omap_formats[] = {
 133        {
 134                /* Note:  V4L2 defines RGB565 as:
 135                 *
 136                 *      Byte 0                    Byte 1
 137                 *      g2 g1 g0 r4 r3 r2 r1 r0   b4 b3 b2 b1 b0 g5 g4 g3
 138                 *
 139                 * We interpret RGB565 as:
 140                 *
 141                 *      Byte 0                    Byte 1
 142                 *      g2 g1 g0 b4 b3 b2 b1 b0   r4 r3 r2 r1 r0 g5 g4 g3
 143                 */
 144                .description = "RGB565, le",
 145                .pixelformat = V4L2_PIX_FMT_RGB565,
 146        },
 147        {
 148                /* Note:  V4L2 defines RGB32 as: RGB-8-8-8-8  we use
 149                 *  this for RGB24 unpack mode, the last 8 bits are ignored
 150                 * */
 151                .description = "RGB32, le",
 152                .pixelformat = V4L2_PIX_FMT_RGB32,
 153        },
 154        {
 155                /* Note:  V4L2 defines RGB24 as: RGB-8-8-8  we use
 156                 *        this for RGB24 packed mode
 157                 *
 158                 */
 159                .description = "RGB24, le",
 160                .pixelformat = V4L2_PIX_FMT_RGB24,
 161        },
 162        {
 163                .description = "YUYV (YUV 4:2:2), packed",
 164                .pixelformat = V4L2_PIX_FMT_YUYV,
 165        },
 166        {
 167                .description = "UYVY, packed",
 168                .pixelformat = V4L2_PIX_FMT_UYVY,
 169        },
 170};
 171
 172#define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats))
 173
 174/*
 175 * Allocate buffers
 176 */
 177static unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr)
 178{
 179        u32 order, size;
 180        unsigned long virt_addr, addr;
 181
 182        size = PAGE_ALIGN(buf_size);
 183        order = get_order(size);
 184        virt_addr = __get_free_pages(GFP_KERNEL | GFP_DMA, order);
 185        addr = virt_addr;
 186
 187        if (virt_addr) {
 188                while (size > 0) {
 189                        SetPageReserved(virt_to_page(addr));
 190                        addr += PAGE_SIZE;
 191                        size -= PAGE_SIZE;
 192                }
 193        }
 194        *phys_addr = (u32) virt_to_phys((void *) virt_addr);
 195        return virt_addr;
 196}
 197
 198/*
 199 * Free buffers
 200 */
 201static void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size)
 202{
 203        u32 order, size;
 204        unsigned long addr = virtaddr;
 205
 206        size = PAGE_ALIGN(buf_size);
 207        order = get_order(size);
 208
 209        while (size > 0) {
 210                ClearPageReserved(virt_to_page(addr));
 211                addr += PAGE_SIZE;
 212                size -= PAGE_SIZE;
 213        }
 214        free_pages((unsigned long) virtaddr, order);
 215}
 216
 217/*
 218 * Function for allocating video buffers
 219 */
 220static int omap_vout_allocate_vrfb_buffers(struct omap_vout_device *vout,
 221                unsigned int *count, int startindex)
 222{
 223        int i, j;
 224
 225        for (i = 0; i < *count; i++) {
 226                if (!vout->smsshado_virt_addr[i]) {
 227                        vout->smsshado_virt_addr[i] =
 228                                omap_vout_alloc_buffer(vout->smsshado_size,
 229                                                &vout->smsshado_phy_addr[i]);
 230                }
 231                if (!vout->smsshado_virt_addr[i] && startindex != -1) {
 232                        if (V4L2_MEMORY_MMAP == vout->memory && i >= startindex)
 233                                break;
 234                }
 235                if (!vout->smsshado_virt_addr[i]) {
 236                        for (j = 0; j < i; j++) {
 237                                omap_vout_free_buffer(
 238                                                vout->smsshado_virt_addr[j],
 239                                                vout->smsshado_size);
 240                                vout->smsshado_virt_addr[j] = 0;
 241                                vout->smsshado_phy_addr[j] = 0;
 242                        }
 243                        *count = 0;
 244                        return -ENOMEM;
 245                }
 246                memset((void *) vout->smsshado_virt_addr[i], 0,
 247                                vout->smsshado_size);
 248        }
 249        return 0;
 250}
 251
 252/*
 253 * Try format
 254 */
 255static int omap_vout_try_format(struct v4l2_pix_format *pix)
 256{
 257        int ifmt, bpp = 0;
 258
 259        pix->height = clamp(pix->height, (u32)VID_MIN_HEIGHT,
 260                                                (u32)VID_MAX_HEIGHT);
 261        pix->width = clamp(pix->width, (u32)VID_MIN_WIDTH, (u32)VID_MAX_WIDTH);
 262
 263        for (ifmt = 0; ifmt < NUM_OUTPUT_FORMATS; ifmt++) {
 264                if (pix->pixelformat == omap_formats[ifmt].pixelformat)
 265                        break;
 266        }
 267
 268        if (ifmt == NUM_OUTPUT_FORMATS)
 269                ifmt = 0;
 270
 271        pix->pixelformat = omap_formats[ifmt].pixelformat;
 272        pix->field = V4L2_FIELD_ANY;
 273        pix->priv = 0;
 274
 275        switch (pix->pixelformat) {
 276        case V4L2_PIX_FMT_YUYV:
 277        case V4L2_PIX_FMT_UYVY:
 278        default:
 279                pix->colorspace = V4L2_COLORSPACE_JPEG;
 280                bpp = YUYV_BPP;
 281                break;
 282        case V4L2_PIX_FMT_RGB565:
 283        case V4L2_PIX_FMT_RGB565X:
 284                pix->colorspace = V4L2_COLORSPACE_SRGB;
 285                bpp = RGB565_BPP;
 286                break;
 287        case V4L2_PIX_FMT_RGB24:
 288                pix->colorspace = V4L2_COLORSPACE_SRGB;
 289                bpp = RGB24_BPP;
 290                break;
 291        case V4L2_PIX_FMT_RGB32:
 292        case V4L2_PIX_FMT_BGR32:
 293                pix->colorspace = V4L2_COLORSPACE_SRGB;
 294                bpp = RGB32_BPP;
 295                break;
 296        }
 297        pix->bytesperline = pix->width * bpp;
 298        pix->sizeimage = pix->bytesperline * pix->height;
 299
 300        return bpp;
 301}
 302
 303/*
 304 * omap_vout_uservirt_to_phys: This inline function is used to convert user
 305 * space virtual address to physical address.
 306 */
 307static u32 omap_vout_uservirt_to_phys(u32 virtp)
 308{
 309        unsigned long physp = 0;
 310        struct vm_area_struct *vma;
 311        struct mm_struct *mm = current->mm;
 312
 313        vma = find_vma(mm, virtp);
 314        /* For kernel direct-mapped memory, take the easy way */
 315        if (virtp >= PAGE_OFFSET) {
 316                physp = virt_to_phys((void *) virtp);
 317        } else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
 318                /* this will catch, kernel-allocated, mmaped-to-usermode
 319                   addresses */
 320                physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
 321        } else {
 322                /* otherwise, use get_user_pages() for general userland pages */
 323                int res, nr_pages = 1;
 324                struct page *pages;
 325                down_read(&current->mm->mmap_sem);
 326
 327                res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
 328                                0, &pages, NULL);
 329                up_read(&current->mm->mmap_sem);
 330
 331                if (res == nr_pages) {
 332                        physp =  __pa(page_address(&pages[0]) +
 333                                        (virtp & ~PAGE_MASK));
 334                } else {
 335                        printk(KERN_WARNING VOUT_NAME
 336                                        "get_user_pages failed\n");
 337                        return 0;
 338                }
 339        }
 340
 341        return physp;
 342}
 343
 344/*
 345 * Wakes up the application once the DMA transfer to VRFB space is completed.
 346 */
 347static void omap_vout_vrfb_dma_tx_callback(int lch, u16 ch_status, void *data)
 348{
 349        struct vid_vrfb_dma *t = (struct vid_vrfb_dma *) data;
 350
 351        t->tx_status = 1;
 352        wake_up_interruptible(&t->wait);
 353}
 354
 355/*
 356 * Release the VRFB context once the module exits
 357 */
 358static void omap_vout_release_vrfb(struct omap_vout_device *vout)
 359{
 360        int i;
 361
 362        for (i = 0; i < VRFB_NUM_BUFS; i++)
 363                omap_vrfb_release_ctx(&vout->vrfb_context[i]);
 364
 365        if (vout->vrfb_dma_tx.req_status == DMA_CHAN_ALLOTED) {
 366                vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
 367                omap_free_dma(vout->vrfb_dma_tx.dma_ch);
 368        }
 369}
 370
 371/*
 372 * Return true if rotation is 90 or 270
 373 */
 374static inline int rotate_90_or_270(const struct omap_vout_device *vout)
 375{
 376        return (vout->rotation == dss_rotation_90_degree ||
 377                        vout->rotation == dss_rotation_270_degree);
 378}
 379
 380/*
 381 * Return true if rotation is enabled
 382 */
 383static inline int rotation_enabled(const struct omap_vout_device *vout)
 384{
 385        return vout->rotation || vout->mirror;
 386}
 387
 388/*
 389 * Reverse the rotation degree if mirroring is enabled
 390 */
 391static inline int calc_rotation(const struct omap_vout_device *vout)
 392{
 393        if (!vout->mirror)
 394                return vout->rotation;
 395
 396        switch (vout->rotation) {
 397        case dss_rotation_90_degree:
 398                return dss_rotation_270_degree;
 399        case dss_rotation_270_degree:
 400                return dss_rotation_90_degree;
 401        case dss_rotation_180_degree:
 402                return dss_rotation_0_degree;
 403        default:
 404                return dss_rotation_180_degree;
 405        }
 406}
 407
 408/*
 409 * Free the V4L2 buffers
 410 */
 411static void omap_vout_free_buffers(struct omap_vout_device *vout)
 412{
 413        int i, numbuffers;
 414
 415        /* Allocate memory for the buffers */
 416        numbuffers = (vout->vid) ?  video2_numbuffers : video1_numbuffers;
 417        vout->buffer_size = (vout->vid) ? video2_bufsize : video1_bufsize;
 418
 419        for (i = 0; i < numbuffers; i++) {
 420                omap_vout_free_buffer(vout->buf_virt_addr[i],
 421                                vout->buffer_size);
 422                vout->buf_phy_addr[i] = 0;
 423                vout->buf_virt_addr[i] = 0;
 424        }
 425}
 426
 427/*
 428 * Free VRFB buffers
 429 */
 430static void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout)
 431{
 432        int j;
 433
 434        for (j = 0; j < VRFB_NUM_BUFS; j++) {
 435                omap_vout_free_buffer(vout->smsshado_virt_addr[j],
 436                                vout->smsshado_size);
 437                vout->smsshado_virt_addr[j] = 0;
 438                vout->smsshado_phy_addr[j] = 0;
 439        }
 440}
 441
 442/*
 443 * Allocate the buffers for the VRFB space.  Data is copied from V4L2
 444 * buffers to the VRFB buffers using the DMA engine.
 445 */
 446static int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
 447                          unsigned int *count, unsigned int startindex)
 448{
 449        int i;
 450        bool yuv_mode;
 451
 452        /* Allocate the VRFB buffers only if the buffers are not
 453         * allocated during init time.
 454         */
 455        if ((rotation_enabled(vout)) && !vout->vrfb_static_allocation)
 456                if (omap_vout_allocate_vrfb_buffers(vout, count, startindex))
 457                        return -ENOMEM;
 458
 459        if (vout->dss_mode == OMAP_DSS_COLOR_YUV2 ||
 460                        vout->dss_mode == OMAP_DSS_COLOR_UYVY)
 461                yuv_mode = true;
 462        else
 463                yuv_mode = false;
 464
 465        for (i = 0; i < *count; i++)
 466                omap_vrfb_setup(&vout->vrfb_context[i],
 467                                vout->smsshado_phy_addr[i], vout->pix.width,
 468                                vout->pix.height, vout->bpp, yuv_mode);
 469
 470        return 0;
 471}
 472
 473/*
 474 * Convert V4L2 rotation to DSS rotation
 475 *      V4L2 understand 0, 90, 180, 270.
 476 *      Convert to 0, 1, 2 and 3 repsectively for DSS
 477 */
 478static int v4l2_rot_to_dss_rot(int v4l2_rotation,
 479                        enum dss_rotation *rotation, bool mirror)
 480{
 481        int ret = 0;
 482
 483        switch (v4l2_rotation) {
 484        case 90:
 485                *rotation = dss_rotation_90_degree;
 486                break;
 487        case 180:
 488                *rotation = dss_rotation_180_degree;
 489                break;
 490        case 270:
 491                *rotation = dss_rotation_270_degree;
 492                break;
 493        case 0:
 494                *rotation = dss_rotation_0_degree;
 495                break;
 496        default:
 497                ret = -EINVAL;
 498        }
 499        return ret;
 500}
 501
 502/*
 503 * Calculate the buffer offsets from which the streaming should
 504 * start. This offset calculation is mainly required because of
 505 * the VRFB 32 pixels alignment with rotation.
 506 */
 507static int omap_vout_calculate_offset(struct omap_vout_device *vout)
 508{
 509        struct omap_overlay *ovl;
 510        enum dss_rotation rotation;
 511        struct omapvideo_info *ovid;
 512        bool mirroring = vout->mirror;
 513        struct omap_dss_device *cur_display;
 514        struct v4l2_rect *crop = &vout->crop;
 515        struct v4l2_pix_format *pix = &vout->pix;
 516        int *cropped_offset = &vout->cropped_offset;
 517        int vr_ps = 1, ps = 2, temp_ps = 2;
 518        int offset = 0, ctop = 0, cleft = 0, line_length = 0;
 519
 520        ovid = &vout->vid_info;
 521        ovl = ovid->overlays[0];
 522        /* get the display device attached to the overlay */
 523        if (!ovl->manager || !ovl->manager->device)
 524                return -1;
 525
 526        cur_display = ovl->manager->device;
 527        rotation = calc_rotation(vout);
 528
 529        if (V4L2_PIX_FMT_YUYV == pix->pixelformat ||
 530                        V4L2_PIX_FMT_UYVY == pix->pixelformat) {
 531                if (rotation_enabled(vout)) {
 532                        /*
 533                         * ps    - Actual pixel size for YUYV/UYVY for
 534                         *         VRFB/Mirroring is 4 bytes
 535                         * vr_ps - Virtually pixel size for YUYV/UYVY is
 536                         *         2 bytes
 537                         */
 538                        ps = 4;
 539                        vr_ps = 2;
 540                } else {
 541                        ps = 2; /* otherwise the pixel size is 2 byte */
 542                }
 543        } else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) {
 544                ps = 4;
 545        } else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) {
 546                ps = 3;
 547        }
 548        vout->ps = ps;
 549        vout->vr_ps = vr_ps;
 550
 551        if (rotation_enabled(vout)) {
 552                line_length = MAX_PIXELS_PER_LINE;
 553                ctop = (pix->height - crop->height) - crop->top;
 554                cleft = (pix->width - crop->width) - crop->left;
 555        } else {
 556                line_length = pix->width;
 557        }
 558        vout->line_length = line_length;
 559        switch (rotation) {
 560        case dss_rotation_90_degree:
 561                offset = vout->vrfb_context[0].yoffset *
 562                        vout->vrfb_context[0].bytespp;
 563                temp_ps = ps / vr_ps;
 564                if (mirroring == 0) {
 565                        *cropped_offset = offset + line_length *
 566                                temp_ps * cleft + crop->top * temp_ps;
 567                } else {
 568                        *cropped_offset = offset + line_length * temp_ps *
 569                                cleft + crop->top * temp_ps + (line_length *
 570                                ((crop->width / (vr_ps)) - 1) * ps);
 571                }
 572                break;
 573        case dss_rotation_180_degree:
 574                offset = ((MAX_PIXELS_PER_LINE * vout->vrfb_context[0].yoffset *
 575                        vout->vrfb_context[0].bytespp) +
 576                        (vout->vrfb_context[0].xoffset *
 577                        vout->vrfb_context[0].bytespp));
 578                if (mirroring == 0) {
 579                        *cropped_offset = offset + (line_length * ps * ctop) +
 580                                (cleft / vr_ps) * ps;
 581
 582                } else {
 583                        *cropped_offset = offset + (line_length * ps * ctop) +
 584                                (cleft / vr_ps) * ps + (line_length *
 585                                (crop->height - 1) * ps);
 586                }
 587                break;
 588        case dss_rotation_270_degree:
 589                offset = MAX_PIXELS_PER_LINE * vout->vrfb_context[0].xoffset *
 590                        vout->vrfb_context[0].bytespp;
 591                temp_ps = ps / vr_ps;
 592                if (mirroring == 0) {
 593                        *cropped_offset = offset + line_length *
 594                            temp_ps * crop->left + ctop * ps;
 595                } else {
 596                        *cropped_offset = offset + line_length *
 597                                temp_ps * crop->left + ctop * ps +
 598                                (line_length * ((crop->width / vr_ps) - 1) *
 599                                 ps);
 600                }
 601                break;
 602        case dss_rotation_0_degree:
 603                if (mirroring == 0) {
 604                        *cropped_offset = (line_length * ps) *
 605                                crop->top + (crop->left / vr_ps) * ps;
 606                } else {
 607                        *cropped_offset = (line_length * ps) *
 608                                crop->top + (crop->left / vr_ps) * ps +
 609                                (line_length * (crop->height - 1) * ps);
 610                }
 611                break;
 612        default:
 613                *cropped_offset = (line_length * ps * crop->top) /
 614                        vr_ps + (crop->left * ps) / vr_ps +
 615                        ((crop->width / vr_ps) - 1) * ps;
 616                break;
 617        }
 618        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s Offset:%x\n",
 619                        __func__, *cropped_offset);
 620        return 0;
 621}
 622
 623/*
 624 * Convert V4L2 pixel format to DSS pixel format
 625 */
 626static int video_mode_to_dss_mode(struct omap_vout_device *vout)
 627{
 628        struct omap_overlay *ovl;
 629        struct omapvideo_info *ovid;
 630        struct v4l2_pix_format *pix = &vout->pix;
 631        enum omap_color_mode mode;
 632
 633        ovid = &vout->vid_info;
 634        ovl = ovid->overlays[0];
 635
 636        switch (pix->pixelformat) {
 637        case 0:
 638                break;
 639        case V4L2_PIX_FMT_YUYV:
 640                mode = OMAP_DSS_COLOR_YUV2;
 641                break;
 642        case V4L2_PIX_FMT_UYVY:
 643                mode = OMAP_DSS_COLOR_UYVY;
 644                break;
 645        case V4L2_PIX_FMT_RGB565:
 646                mode = OMAP_DSS_COLOR_RGB16;
 647                break;
 648        case V4L2_PIX_FMT_RGB24:
 649                mode = OMAP_DSS_COLOR_RGB24P;
 650                break;
 651        case V4L2_PIX_FMT_RGB32:
 652                mode = (ovl->id == OMAP_DSS_VIDEO1) ?
 653                        OMAP_DSS_COLOR_RGB24U : OMAP_DSS_COLOR_ARGB32;
 654                break;
 655        case V4L2_PIX_FMT_BGR32:
 656                mode = OMAP_DSS_COLOR_RGBX32;
 657                break;
 658        default:
 659                mode = -EINVAL;
 660        }
 661        return mode;
 662}
 663
 664/*
 665 * Setup the overlay
 666 */
 667int omapvid_setup_overlay(struct omap_vout_device *vout,
 668                struct omap_overlay *ovl, int posx, int posy, int outw,
 669                int outh, u32 addr)
 670{
 671        int ret = 0;
 672        struct omap_overlay_info info;
 673        int cropheight, cropwidth, pixheight, pixwidth;
 674
 675        if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0 &&
 676                        (outw != vout->pix.width || outh != vout->pix.height)) {
 677                ret = -EINVAL;
 678                goto setup_ovl_err;
 679        }
 680
 681        vout->dss_mode = video_mode_to_dss_mode(vout);
 682        if (vout->dss_mode == -EINVAL) {
 683                ret = -EINVAL;
 684                goto setup_ovl_err;
 685        }
 686
 687        /* Setup the input plane parameters according to
 688         * rotation value selected.
 689         */
 690        if (rotate_90_or_270(vout)) {
 691                cropheight = vout->crop.width;
 692                cropwidth = vout->crop.height;
 693                pixheight = vout->pix.width;
 694                pixwidth = vout->pix.height;
 695        } else {
 696                cropheight = vout->crop.height;
 697                cropwidth = vout->crop.width;
 698                pixheight = vout->pix.height;
 699                pixwidth = vout->pix.width;
 700        }
 701
 702        ovl->get_overlay_info(ovl, &info);
 703        info.paddr = addr;
 704        info.vaddr = NULL;
 705        info.width = cropwidth;
 706        info.height = cropheight;
 707        info.color_mode = vout->dss_mode;
 708        info.mirror = vout->mirror;
 709        info.pos_x = posx;
 710        info.pos_y = posy;
 711        info.out_width = outw;
 712        info.out_height = outh;
 713        info.global_alpha = vout->win.global_alpha;
 714        if (!rotation_enabled(vout)) {
 715                info.rotation = 0;
 716                info.rotation_type = OMAP_DSS_ROT_DMA;
 717                info.screen_width = pixwidth;
 718        } else {
 719                info.rotation = vout->rotation;
 720                info.rotation_type = OMAP_DSS_ROT_VRFB;
 721                info.screen_width = 2048;
 722        }
 723
 724        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
 725                "%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n"
 726                "rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
 727                "out_height=%d rotation_type=%d screen_width=%d\n",
 728                __func__, info.enabled, info.paddr, info.width, info.height,
 729                info.color_mode, info.rotation, info.mirror, info.pos_x,
 730                info.pos_y, info.out_width, info.out_height, info.rotation_type,
 731                info.screen_width);
 732
 733        ret = ovl->set_overlay_info(ovl, &info);
 734        if (ret)
 735                goto setup_ovl_err;
 736
 737        return 0;
 738
 739setup_ovl_err:
 740        v4l2_warn(&vout->vid_dev->v4l2_dev, "setup_overlay failed\n");
 741        return ret;
 742}
 743
 744/*
 745 * Initialize the overlay structure
 746 */
 747int omapvid_init(struct omap_vout_device *vout, u32 addr)
 748{
 749        int ret = 0, i;
 750        struct v4l2_window *win;
 751        struct omap_overlay *ovl;
 752        int posx, posy, outw, outh, temp;
 753        struct omap_video_timings *timing;
 754        struct omapvideo_info *ovid = &vout->vid_info;
 755
 756        win = &vout->win;
 757        for (i = 0; i < ovid->num_overlays; i++) {
 758                ovl = ovid->overlays[i];
 759                if (!ovl->manager || !ovl->manager->device)
 760                        return -EINVAL;
 761
 762                timing = &ovl->manager->device->panel.timings;
 763
 764                outw = win->w.width;
 765                outh = win->w.height;
 766                switch (vout->rotation) {
 767                case dss_rotation_90_degree:
 768                        /* Invert the height and width for 90
 769                         * and 270 degree rotation
 770                         */
 771                        temp = outw;
 772                        outw = outh;
 773                        outh = temp;
 774                        posy = (timing->y_res - win->w.width) - win->w.left;
 775                        posx = win->w.top;
 776                        break;
 777
 778                case dss_rotation_180_degree:
 779                        posx = (timing->x_res - win->w.width) - win->w.left;
 780                        posy = (timing->y_res - win->w.height) - win->w.top;
 781                        break;
 782
 783                case dss_rotation_270_degree:
 784                        temp = outw;
 785                        outw = outh;
 786                        outh = temp;
 787                        posy = win->w.left;
 788                        posx = (timing->x_res - win->w.height) - win->w.top;
 789                        break;
 790
 791                default:
 792                        posx = win->w.left;
 793                        posy = win->w.top;
 794                        break;
 795                }
 796
 797                ret = omapvid_setup_overlay(vout, ovl, posx, posy,
 798                                outw, outh, addr);
 799                if (ret)
 800                        goto omapvid_init_err;
 801        }
 802        return 0;
 803
 804omapvid_init_err:
 805        v4l2_warn(&vout->vid_dev->v4l2_dev, "apply_changes failed\n");
 806        return ret;
 807}
 808
 809/*
 810 * Apply the changes set the go bit of DSS
 811 */
 812int omapvid_apply_changes(struct omap_vout_device *vout)
 813{
 814        int i;
 815        struct omap_overlay *ovl;
 816        struct omapvideo_info *ovid = &vout->vid_info;
 817
 818        for (i = 0; i < ovid->num_overlays; i++) {
 819                ovl = ovid->overlays[i];
 820                if (!ovl->manager || !ovl->manager->device)
 821                        return -EINVAL;
 822                ovl->manager->apply(ovl->manager);
 823        }
 824
 825        return 0;
 826}
 827
 828void omap_vout_isr(void *arg, unsigned int irqstatus)
 829{
 830        int ret;
 831        u32 addr, fid;
 832        struct omap_overlay *ovl;
 833        struct timeval timevalue;
 834        struct omapvideo_info *ovid;
 835        struct omap_dss_device *cur_display;
 836        struct omap_vout_device *vout = (struct omap_vout_device *)arg;
 837
 838        if (!vout->streaming)
 839                return;
 840
 841        ovid = &vout->vid_info;
 842        ovl = ovid->overlays[0];
 843        /* get the display device attached to the overlay */
 844        if (!ovl->manager || !ovl->manager->device)
 845                return;
 846
 847        cur_display = ovl->manager->device;
 848
 849        spin_lock(&vout->vbq_lock);
 850        do_gettimeofday(&timevalue);
 851        if (cur_display->type == OMAP_DISPLAY_TYPE_DPI) {
 852                if (!(irqstatus & DISPC_IRQ_VSYNC))
 853                        goto vout_isr_err;
 854
 855                if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
 856                        vout->cur_frm->ts = timevalue;
 857                        vout->cur_frm->state = VIDEOBUF_DONE;
 858                        wake_up_interruptible(&vout->cur_frm->done);
 859                        vout->cur_frm = vout->next_frm;
 860                }
 861                vout->first_int = 0;
 862                if (list_empty(&vout->dma_queue))
 863                        goto vout_isr_err;
 864
 865                vout->next_frm = list_entry(vout->dma_queue.next,
 866                                struct videobuf_buffer, queue);
 867                list_del(&vout->next_frm->queue);
 868
 869                vout->next_frm->state = VIDEOBUF_ACTIVE;
 870
 871                addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
 872                        + vout->cropped_offset;
 873
 874                /* First save the configuration in ovelray structure */
 875                ret = omapvid_init(vout, addr);
 876                if (ret)
 877                        printk(KERN_ERR VOUT_NAME
 878                                        "failed to set overlay info\n");
 879                /* Enable the pipeline and set the Go bit */
 880                ret = omapvid_apply_changes(vout);
 881                if (ret)
 882                        printk(KERN_ERR VOUT_NAME "failed to change mode\n");
 883        } else {
 884
 885                if (vout->first_int) {
 886                        vout->first_int = 0;
 887                        goto vout_isr_err;
 888                }
 889                if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
 890                        fid = 1;
 891                else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
 892                        fid = 0;
 893                else
 894                        goto vout_isr_err;
 895
 896                vout->field_id ^= 1;
 897                if (fid != vout->field_id) {
 898                        if (0 == fid)
 899                                vout->field_id = fid;
 900
 901                        goto vout_isr_err;
 902                }
 903                if (0 == fid) {
 904                        if (vout->cur_frm == vout->next_frm)
 905                                goto vout_isr_err;
 906
 907                        vout->cur_frm->ts = timevalue;
 908                        vout->cur_frm->state = VIDEOBUF_DONE;
 909                        wake_up_interruptible(&vout->cur_frm->done);
 910                        vout->cur_frm = vout->next_frm;
 911                } else if (1 == fid) {
 912                        if (list_empty(&vout->dma_queue) ||
 913                                        (vout->cur_frm != vout->next_frm))
 914                                goto vout_isr_err;
 915
 916                        vout->next_frm = list_entry(vout->dma_queue.next,
 917                                        struct videobuf_buffer, queue);
 918                        list_del(&vout->next_frm->queue);
 919
 920                        vout->next_frm->state = VIDEOBUF_ACTIVE;
 921                        addr = (unsigned long)
 922                                vout->queued_buf_addr[vout->next_frm->i] +
 923                                vout->cropped_offset;
 924                        /* First save the configuration in ovelray structure */
 925                        ret = omapvid_init(vout, addr);
 926                        if (ret)
 927                                printk(KERN_ERR VOUT_NAME
 928                                                "failed to set overlay info\n");
 929                        /* Enable the pipeline and set the Go bit */
 930                        ret = omapvid_apply_changes(vout);
 931                        if (ret)
 932                                printk(KERN_ERR VOUT_NAME
 933                                                "failed to change mode\n");
 934                }
 935
 936        }
 937
 938vout_isr_err:
 939        spin_unlock(&vout->vbq_lock);
 940}
 941
 942
 943/* Video buffer call backs */
 944
 945/*
 946 * Buffer setup function is called by videobuf layer when REQBUF ioctl is
 947 * called. This is used to setup buffers and return size and count of
 948 * buffers allocated. After the call to this buffer, videobuf layer will
 949 * setup buffer queue depending on the size and count of buffers
 950 */
 951static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
 952                          unsigned int *size)
 953{
 954        int startindex = 0, i, j;
 955        u32 phy_addr = 0, virt_addr = 0;
 956        struct omap_vout_device *vout = q->priv_data;
 957
 958        if (!vout)
 959                return -EINVAL;
 960
 961        if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
 962                return -EINVAL;
 963
 964        startindex = (vout->vid == OMAP_VIDEO1) ?
 965                video1_numbuffers : video2_numbuffers;
 966        if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex)
 967                *count = startindex;
 968
 969        if ((rotation_enabled(vout)) && *count > VRFB_NUM_BUFS)
 970                *count = VRFB_NUM_BUFS;
 971
 972        /* If rotation is enabled, allocate memory for VRFB space also */
 973        if (rotation_enabled(vout))
 974                if (omap_vout_vrfb_buffer_setup(vout, count, startindex))
 975                        return -ENOMEM;
 976
 977        if (V4L2_MEMORY_MMAP != vout->memory)
 978                return 0;
 979
 980        /* Now allocated the V4L2 buffers */
 981        *size = PAGE_ALIGN(vout->pix.width * vout->pix.height * vout->bpp);
 982        startindex = (vout->vid == OMAP_VIDEO1) ?
 983                video1_numbuffers : video2_numbuffers;
 984
 985        for (i = startindex; i < *count; i++) {
 986                vout->buffer_size = *size;
 987
 988                virt_addr = omap_vout_alloc_buffer(vout->buffer_size,
 989                                &phy_addr);
 990                if (!virt_addr) {
 991                        if (!rotation_enabled(vout))
 992                                break;
 993                        /* Free the VRFB buffers if no space for V4L2 buffers */
 994                        for (j = i; j < *count; j++) {
 995                                omap_vout_free_buffer(
 996                                                vout->smsshado_virt_addr[j],
 997                                                vout->smsshado_size);
 998                                vout->smsshado_virt_addr[j] = 0;
 999                                vout->smsshado_phy_addr[j] = 0;
1000                        }
1001                }
1002                vout->buf_virt_addr[i] = virt_addr;
1003                vout->buf_phy_addr[i] = phy_addr;
1004        }
1005        *count = vout->buffer_allocated = i;
1006
1007        return 0;
1008}
1009
1010/*
1011 * Free the V4L2 buffers additionally allocated than default
1012 * number of buffers and free all the VRFB buffers
1013 */
1014static void omap_vout_free_allbuffers(struct omap_vout_device *vout)
1015{
1016        int num_buffers = 0, i;
1017
1018        num_buffers = (vout->vid == OMAP_VIDEO1) ?
1019                video1_numbuffers : video2_numbuffers;
1020
1021        for (i = num_buffers; i < vout->buffer_allocated; i++) {
1022                if (vout->buf_virt_addr[i])
1023                        omap_vout_free_buffer(vout->buf_virt_addr[i],
1024                                        vout->buffer_size);
1025
1026                vout->buf_virt_addr[i] = 0;
1027                vout->buf_phy_addr[i] = 0;
1028        }
1029        /* Free the VRFB buffers only if they are allocated
1030         * during reqbufs.  Don't free if init time allocated
1031         */
1032        if (!vout->vrfb_static_allocation) {
1033                for (i = 0; i < VRFB_NUM_BUFS; i++) {
1034                        if (vout->smsshado_virt_addr[i]) {
1035                                omap_vout_free_buffer(
1036                                                vout->smsshado_virt_addr[i],
1037                                                vout->smsshado_size);
1038                                vout->smsshado_virt_addr[i] = 0;
1039                                vout->smsshado_phy_addr[i] = 0;
1040                        }
1041                }
1042        }
1043        vout->buffer_allocated = num_buffers;
1044}
1045
1046/*
1047 * This function will be called when VIDIOC_QBUF ioctl is called.
1048 * It prepare buffers before give out for the display. This function
1049 * converts user space virtual address into physical address if userptr memory
1050 * exchange mechanism is used. If rotation is enabled, it copies entire
1051 * buffer into VRFB memory space before giving it to the DSS.
1052 */
1053static int omap_vout_buffer_prepare(struct videobuf_queue *q,
1054                            struct videobuf_buffer *vb,
1055                            enum v4l2_field field)
1056{
1057        dma_addr_t dmabuf;
1058        struct vid_vrfb_dma *tx;
1059        enum dss_rotation rotation;
1060        struct omap_vout_device *vout = q->priv_data;
1061        u32 dest_frame_index = 0, src_element_index = 0;
1062        u32 dest_element_index = 0, src_frame_index = 0;
1063        u32 elem_count = 0, frame_count = 0, pixsize = 2;
1064
1065        if (VIDEOBUF_NEEDS_INIT == vb->state) {
1066                vb->width = vout->pix.width;
1067                vb->height = vout->pix.height;
1068                vb->size = vb->width * vb->height * vout->bpp;
1069                vb->field = field;
1070        }
1071        vb->state = VIDEOBUF_PREPARED;
1072        /* if user pointer memory mechanism is used, get the physical
1073         * address of the buffer
1074         */
1075        if (V4L2_MEMORY_USERPTR == vb->memory) {
1076                if (0 == vb->baddr)
1077                        return -EINVAL;
1078                /* Physical address */
1079                vout->queued_buf_addr[vb->i] = (u8 *)
1080                        omap_vout_uservirt_to_phys(vb->baddr);
1081        } else {
1082                vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i];
1083        }
1084
1085        if (!rotation_enabled(vout))
1086                return 0;
1087
1088        dmabuf = vout->buf_phy_addr[vb->i];
1089        /* If rotation is enabled, copy input buffer into VRFB
1090         * memory space using DMA. We are copying input buffer
1091         * into VRFB memory space of desired angle and DSS will
1092         * read image VRFB memory for 0 degree angle
1093         */
1094        pixsize = vout->bpp * vout->vrfb_bpp;
1095        /*
1096         * DMA transfer in double index mode
1097         */
1098
1099        /* Frame index */
1100        dest_frame_index = ((MAX_PIXELS_PER_LINE * pixsize) -
1101                        (vout->pix.width * vout->bpp)) + 1;
1102
1103        /* Source and destination parameters */
1104        src_element_index = 0;
1105        src_frame_index = 0;
1106        dest_element_index = 1;
1107        /* Number of elements per frame */
1108        elem_count = vout->pix.width * vout->bpp;
1109        frame_count = vout->pix.height;
1110        tx = &vout->vrfb_dma_tx;
1111        tx->tx_status = 0;
1112        omap_set_dma_transfer_params(tx->dma_ch, OMAP_DMA_DATA_TYPE_S32,
1113                        (elem_count / 4), frame_count, OMAP_DMA_SYNC_ELEMENT,
1114                        tx->dev_id, 0x0);
1115        /* src_port required only for OMAP1 */
1116        omap_set_dma_src_params(tx->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
1117                        dmabuf, src_element_index, src_frame_index);
1118        /*set dma source burst mode for VRFB */
1119        omap_set_dma_src_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
1120        rotation = calc_rotation(vout);
1121
1122        /* dest_port required only for OMAP1 */
1123        omap_set_dma_dest_params(tx->dma_ch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
1124                        vout->vrfb_context[vb->i].paddr[0], dest_element_index,
1125                        dest_frame_index);
1126        /*set dma dest burst mode for VRFB */
1127        omap_set_dma_dest_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
1128        omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 0x20, 0);
1129
1130        omap_start_dma(tx->dma_ch);
1131        interruptible_sleep_on_timeout(&tx->wait, VRFB_TX_TIMEOUT);
1132
1133        if (tx->tx_status == 0) {
1134                omap_stop_dma(tx->dma_ch);
1135                return -EINVAL;
1136        }
1137        /* Store buffers physical address into an array. Addresses
1138         * from this array will be used to configure DSS */
1139        vout->queued_buf_addr[vb->i] = (u8 *)
1140                vout->vrfb_context[vb->i].paddr[rotation];
1141        return 0;
1142}
1143
1144/*
1145 * Buffer queue funtion will be called from the videobuf layer when _QBUF
1146 * ioctl is called. It is used to enqueue buffer, which is ready to be
1147 * displayed.
1148 */
1149static void omap_vout_buffer_queue(struct videobuf_queue *q,
1150                          struct videobuf_buffer *vb)
1151{
1152        struct omap_vout_device *vout = q->priv_data;
1153
1154        /* Driver is also maintainig a queue. So enqueue buffer in the driver
1155         * queue */
1156        list_add_tail(&vb->queue, &vout->dma_queue);
1157
1158        vb->state = VIDEOBUF_QUEUED;
1159}
1160
1161/*
1162 * Buffer release function is called from videobuf layer to release buffer
1163 * which are already allocated
1164 */
1165static void omap_vout_buffer_release(struct videobuf_queue *q,
1166                            struct videobuf_buffer *vb)
1167{
1168        struct omap_vout_device *vout = q->priv_data;
1169
1170        vb->state = VIDEOBUF_NEEDS_INIT;
1171
1172        if (V4L2_MEMORY_MMAP != vout->memory)
1173                return;
1174}
1175
1176/*
1177 *  File operations
1178 */
1179static void omap_vout_vm_open(struct vm_area_struct *vma)
1180{
1181        struct omap_vout_device *vout = vma->vm_private_data;
1182
1183        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
1184                "vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
1185        vout->mmap_count++;
1186}
1187
1188static void omap_vout_vm_close(struct vm_area_struct *vma)
1189{
1190        struct omap_vout_device *vout = vma->vm_private_data;
1191
1192        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
1193                "vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
1194        vout->mmap_count--;
1195}
1196
1197static struct vm_operations_struct omap_vout_vm_ops = {
1198        .open   = omap_vout_vm_open,
1199        .close  = omap_vout_vm_close,
1200};
1201
1202static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
1203{
1204        int i;
1205        void *pos;
1206        unsigned long start = vma->vm_start;
1207        unsigned long size = (vma->vm_end - vma->vm_start);
1208        struct omap_vout_device *vout = file->private_data;
1209        struct videobuf_queue *q = &vout->vbq;
1210
1211        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
1212                        " %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__,
1213                        vma->vm_pgoff, vma->vm_start, vma->vm_end);
1214
1215        /* look for the buffer to map */
1216        for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1217                if (NULL == q->bufs[i])
1218                        continue;
1219                if (V4L2_MEMORY_MMAP != q->bufs[i]->memory)
1220                        continue;
1221                if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT))
1222                        break;
1223        }
1224
1225        if (VIDEO_MAX_FRAME == i) {
1226                v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
1227                                "offset invalid [offset=0x%lx]\n",
1228                                (vma->vm_pgoff << PAGE_SHIFT));
1229                return -EINVAL;
1230        }
1231        q->bufs[i]->baddr = vma->vm_start;
1232
1233        vma->vm_flags |= VM_RESERVED;
1234        vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
1235        vma->vm_ops = &omap_vout_vm_ops;
1236        vma->vm_private_data = (void *) vout;
1237        pos = (void *)vout->buf_virt_addr[i];
1238        vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT;
1239        while (size > 0) {
1240                unsigned long pfn;
1241                pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT;
1242                if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
1243                        return -EAGAIN;
1244                start += PAGE_SIZE;
1245                pos += PAGE_SIZE;
1246                size -= PAGE_SIZE;
1247        }
1248        vout->mmap_count++;
1249        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
1250
1251        return 0;
1252}
1253
1254static int omap_vout_release(struct file *file)
1255{
1256        unsigned int ret, i;
1257        struct videobuf_queue *q;
1258        struct omapvideo_info *ovid;
1259        struct omap_vout_device *vout = file->private_data;
1260
1261        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
1262        ovid = &vout->vid_info;
1263
1264        if (!vout)
1265                return 0;
1266
1267        q = &vout->vbq;
1268        /* Disable all the overlay managers connected with this interface */
1269        for (i = 0; i < ovid->num_overlays; i++) {
1270                struct omap_overlay *ovl = ovid->overlays[i];
1271                if (ovl->manager && ovl->manager->device) {
1272                        struct omap_overlay_info info;
1273                        ovl->get_overlay_info(ovl, &info);
1274                        info.enabled = 0;
1275                        ovl->set_overlay_info(ovl, &info);
1276                }
1277        }
1278        /* Turn off the pipeline */
1279        ret = omapvid_apply_changes(vout);
1280        if (ret)
1281                v4l2_warn(&vout->vid_dev->v4l2_dev,
1282                                "Unable to apply changes\n");
1283
1284        /* Free all buffers */
1285        omap_vout_free_allbuffers(vout);
1286        videobuf_mmap_free(q);
1287
1288        /* Even if apply changes fails we should continue
1289           freeing allocated memory */
1290        if (vout->streaming) {
1291                u32 mask = 0;
1292
1293                mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
1294                        DISPC_IRQ_EVSYNC_ODD;
1295                omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
1296                vout->streaming = 0;
1297
1298                videobuf_streamoff(q);
1299                videobuf_queue_cancel(q);
1300        }
1301
1302        if (vout->mmap_count != 0)
1303                vout->mmap_count = 0;
1304
1305        vout->opened -= 1;
1306        file->private_data = NULL;
1307
1308        if (vout->buffer_allocated)
1309                videobuf_mmap_free(q);
1310
1311        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
1312        return ret;
1313}
1314
1315static int omap_vout_open(struct file *file)
1316{
1317        struct videobuf_queue *q;
1318        struct omap_vout_device *vout = NULL;
1319
1320        vout = video_drvdata(file);
1321        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
1322
1323        if (vout == NULL)
1324                return -ENODEV;
1325
1326        /* for now, we only support single open */
1327        if (vout->opened)
1328                return -EBUSY;
1329
1330        vout->opened += 1;
1331
1332        file->private_data = vout;
1333        vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1334
1335        q = &vout->vbq;
1336        video_vbq_ops.buf_setup = omap_vout_buffer_setup;
1337        video_vbq_ops.buf_prepare = omap_vout_buffer_prepare;
1338        video_vbq_ops.buf_release = omap_vout_buffer_release;
1339        video_vbq_ops.buf_queue = omap_vout_buffer_queue;
1340        spin_lock_init(&vout->vbq_lock);
1341
1342        videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev,
1343                        &vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
1344                        sizeof(struct videobuf_buffer), vout, NULL);
1345
1346        v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
1347        return 0;
1348}
1349
1350/*
1351 * V4L2 ioctls
1352 */
1353static int vidioc_querycap(struct file *file, void *fh,
1354                struct v4l2_capability *cap)
1355{
1356        struct omap_vout_device *vout = fh;
1357
1358        strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
1359        strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
1360        cap->bus_info[0] = '\0';
1361        cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT;
1362
1363        return 0;
1364}
1365
1366static int vidioc_enum_fmt_vid_out(struct file *file, void *fh,
1367                        struct v4l2_fmtdesc *fmt)
1368{
1369        int index = fmt->index;
1370        enum v4l2_buf_type type = fmt->type;
1371
1372        fmt->index = index;
1373        fmt->type = type;
1374        if (index >= NUM_OUTPUT_FORMATS)
1375                return -EINVAL;
1376
1377        fmt->flags = omap_formats[index].flags;
1378        strlcpy(fmt->description, omap_formats[index].description,
1379                        sizeof(fmt->description));
1380        fmt->pixelformat = omap_formats[index].pixelformat;
1381
1382        return 0;
1383}
1384
1385static int vidioc_g_fmt_vid_out(struct file *file, void *fh,
1386                        struct v4l2_format *f)
1387{
1388        struct omap_vout_device *vout = fh;
1389
1390        f->fmt.pix = vout->pix;
1391        return 0;
1392
1393}
1394
1395static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
1396                        struct v4l2_format *f)
1397{
1398        struct omap_overlay *ovl;
1399        struct omapvideo_info *ovid;
1400        struct omap_video_timings *timing;
1401        struct omap_vout_device *vout = fh;
1402
1403        ovid = &vout->vid_info;
1404        ovl = ovid->overlays[0];
1405
1406        if (!ovl->manager || !ovl->manager->device)
1407                return -EINVAL;
1408        /* get the display device attached to the overlay */
1409        timing = &ovl->manager->device->panel.timings;
1410
1411        vout->fbuf.fmt.height = timing->y_res;
1412        vout->fbuf.fmt.width = timing->x_res;
1413
1414        omap_vout_try_format(&f->fmt.pix);
1415        return 0;
1416}
1417
1418static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
1419                        struct v4l2_format *f)
1420{
1421        int ret, bpp;
1422        struct omap_overlay *ovl;
1423        struct omapvideo_info *ovid;
1424        struct omap_video_timings *timing;
1425        struct omap_vout_device *vout = fh;
1426
1427        if (vout->streaming)
1428                return -EBUSY;
1429
1430        mutex_lock(&vout->lock);
1431
1432        ovid = &vout->vid_info;
1433        ovl = ovid->overlays[0];
1434
1435        /* get the display device attached to the overlay */
1436        if (!ovl->manager || !ovl->manager->device) {
1437                ret = -EINVAL;
1438                goto s_fmt_vid_out_exit;
1439        }
1440        timing = &ovl->manager->device->panel.timings;
1441
1442        /* We dont support RGB24-packed mode if vrfb rotation
1443         * is enabled*/
1444        if ((rotation_enabled(vout)) &&
1445                        f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1446                ret = -EINVAL;
1447                goto s_fmt_vid_out_exit;
1448        }
1449
1450        /* get the framebuffer parameters */
1451
1452        if (rotate_90_or_270(vout)) {
1453                vout->fbuf.fmt.height = timing->x_res;
1454                vout->fbuf.fmt.width = timing->y_res;
1455        } else {
1456                vout->fbuf.fmt.height = timing->y_res;
1457                vout->fbuf.fmt.width = timing->x_res;
1458        }
1459
1460        /* change to samller size is OK */
1461
1462        bpp = omap_vout_try_format(&f->fmt.pix);
1463        f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp;
1464
1465        /* try & set the new output format */
1466        vout->bpp = bpp;
1467        vout->pix = f->fmt.pix;
1468        vout->vrfb_bpp = 1;
1469
1470        /* If YUYV then vrfb bpp is 2, for  others its 1 */
1471        if (V4L2_PIX_FMT_YUYV == vout->pix.pixelformat ||
1472                        V4L2_PIX_FMT_UYVY == vout->pix.pixelformat)
1473                vout->vrfb_bpp = 2;
1474
1475        /* set default crop and win */
1476        omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win);
1477
1478        /* Save the changes in the overlay strcuture */
1479        ret = omapvid_init(vout, 0);
1480        if (ret) {
1481                v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
1482                goto s_fmt_vid_out_exit;
1483        }
1484
1485        ret = 0;
1486
1487s_fmt_vid_out_exit:
1488        mutex_unlock(&vout->lock);
1489        return ret;
1490}
1491
1492static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh,
1493                        struct v4l2_format *f)
1494{
1495        int ret = 0;
1496        struct omap_vout_device *vout = fh;
1497        struct v4l2_window *win = &f->fmt.win;
1498
1499        ret = omap_vout_try_window(&vout->fbuf, win);
1500
1501        if (!ret) {
1502                if (vout->vid == OMAP_VIDEO1)
1503                        win->global_alpha = 255;
1504                else
1505                        win->global_alpha = f->fmt.win.global_alpha;
1506        }
1507
1508        return ret;
1509}
1510
1511static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh,
1512                        struct v4l2_format *f)
1513{
1514        int ret = 0;
1515        struct omap_overlay *ovl;
1516        struct omapvideo_info *ovid;
1517        struct omap_vout_device *vout = fh;
1518        struct v4l2_window *win = &f->fmt.win;
1519
1520        mutex_lock(&vout->lock);
1521        ovid = &vout->vid_info;
1522        ovl = ovid->overlays[0];
1523
1524        ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win);
1525        if (!ret) {
1526                /* Video1 plane does not support global alpha */
1527                if (ovl->id == OMAP_DSS_VIDEO1)
1528                        vout->win.global_alpha = 255;
1529                else
1530                        vout->win.global_alpha = f->fmt.win.global_alpha;
1531
1532                vout->win.chromakey = f->fmt.win.chromakey;
1533        }
1534        mutex_unlock(&vout->lock);
1535        return ret;
1536}
1537
1538static int vidioc_enum_fmt_vid_overlay(struct file *file, void *fh,
1539                        struct v4l2_fmtdesc *fmt)
1540{
1541        int index = fmt->index;
1542        enum v4l2_buf_type type = fmt->type;
1543
1544        fmt->index = index;
1545        fmt->type = type;
1546        if (index >= NUM_OUTPUT_FORMATS)
1547                return -EINVAL;
1548
1549        fmt->flags = omap_formats[index].flags;
1550        strlcpy(fmt->description, omap_formats[index].description,
1551                        sizeof(fmt->description));
1552        fmt->pixelformat = omap_formats[index].pixelformat;
1553        return 0;
1554}
1555
1556static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh,
1557                        struct v4l2_format *f)
1558{
1559        u32 key_value =  0;
1560        struct omap_overlay *ovl;
1561        struct omapvideo_info *ovid;
1562        struct omap_vout_device *vout = fh;
1563        struct omap_overlay_manager_info info;
1564        struct v4l2_window *win = &f->fmt.win;
1565
1566        ovid = &vout->vid_info;
1567        ovl = ovid->overlays[0];
1568
1569        win->w = vout->win.w;
1570        win->field = vout->win.field;
1571        win->global_alpha = vout->win.global_alpha;
1572
1573        if (ovl->manager && ovl->manager->get_manager_info) {
1574                ovl->manager->get_manager_info(ovl->manager, &info);
1575                key_value = info.trans_key;
1576        }
1577        win->chromakey = key_value;
1578        return 0;
1579}
1580
1581static int vidioc_cropcap(struct file *file, void *fh,
1582                struct v4l2_cropcap *cropcap)
1583{
1584        struct omap_vout_device *vout = fh;
1585        struct v4l2_pix_format *pix = &vout->pix;
1586
1587        if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1588                return -EINVAL;
1589
1590        /* Width and height are always even */
1591        cropcap->bounds.width = pix->width & ~1;
1592        cropcap->bounds.height = pix->height & ~1;
1593
1594        omap_vout_default_crop(&vout->pix, &vout->fbuf, &cropcap->defrect);
1595        cropcap->pixelaspect.numerator = 1;
1596        cropcap->pixelaspect.denominator = 1;
1597        return 0;
1598}
1599
1600static int vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
1601{
1602        struct omap_vout_device *vout = fh;
1603
1604        if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1605                return -EINVAL;
1606        crop->c = vout->crop;
1607        return 0;
1608}
1609
1610static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
1611{
1612        int ret = -EINVAL;
1613        struct omap_vout_device *vout = fh;
1614        struct omapvideo_info *ovid;
1615        struct omap_overlay *ovl;
1616        struct omap_video_timings *timing;
1617
1618        if (vout->streaming)
1619                return -EBUSY;
1620
1621        mutex_lock(&vout->lock);
1622        ovid = &vout->vid_info;
1623        ovl = ovid->overlays[0];
1624
1625        if (!ovl->manager || !ovl->manager->device) {
1626                ret = -EINVAL;
1627                goto s_crop_err;
1628        }
1629        /* get the display device attached to the overlay */
1630        timing = &ovl->manager->device->panel.timings;
1631
1632        if (rotate_90_or_270(vout)) {
1633                vout->fbuf.fmt.height = timing->x_res;
1634                vout->fbuf.fmt.width = timing->y_res;
1635        } else {
1636                vout->fbuf.fmt.height = timing->y_res;
1637                vout->fbuf.fmt.width = timing->x_res;
1638        }
1639
1640        if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1641                ret = omap_vout_new_crop(&vout->pix, &vout->crop, &vout->win,
1642                                &vout->fbuf, &crop->c);
1643
1644s_crop_err:
1645        mutex_unlock(&vout->lock);
1646        return ret;
1647}
1648
1649static int vidioc_queryctrl(struct file *file, void *fh,
1650                struct v4l2_queryctrl *ctrl)
1651{
1652        int ret = 0;
1653
1654        switch (ctrl->id) {
1655        case V4L2_CID_ROTATE:
1656                ret = v4l2_ctrl_query_fill(ctrl, 0, 270, 90, 0);
1657                break;
1658        case V4L2_CID_BG_COLOR:
1659                ret = v4l2_ctrl_query_fill(ctrl, 0, 0xFFFFFF, 1, 0);
1660                break;
1661        case V4L2_CID_VFLIP:
1662                ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
1663                break;
1664        default:
1665                ctrl->name[0] = '\0';
1666                ret = -EINVAL;
1667        }
1668        return ret;
1669}
1670
1671static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl)
1672{
1673        int ret = 0;
1674        struct omap_vout_device *vout = fh;
1675
1676        switch (ctrl->id) {
1677        case V4L2_CID_ROTATE:
1678                ctrl->value = vout->control[0].value;
1679                break;
1680        case V4L2_CID_BG_COLOR:
1681        {
1682                struct omap_overlay_manager_info info;
1683                struct omap_overlay *ovl;
1684
1685                ovl = vout->vid_info.overlays[0];
1686                if (!ovl->manager || !ovl->manager->get_manager_info) {
1687                        ret = -EINVAL;
1688                        break;
1689                }
1690
1691                ovl->manager->get_manager_info(ovl->manager, &info);
1692                ctrl->value = info.default_color;
1693                break;
1694        }
1695        case V4L2_CID_VFLIP:
1696                ctrl->value = vout->control[2].value;
1697                break;
1698        default:
1699                ret = -EINVAL;
1700        }
1701        return ret;
1702}
1703
1704static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
1705{
1706        int ret = 0;
1707        struct omap_vout_device *vout = fh;
1708
1709        switch (a->id) {
1710        case V4L2_CID_ROTATE:
1711        {
1712                int rotation = a->value;
1713
1714                mutex_lock(&vout->lock);
1715
1716                if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1717                        mutex_unlock(&vout->lock);
1718                        ret = -EINVAL;
1719                        break;
1720                }
1721
1722                if (v4l2_rot_to_dss_rot(rotation, &vout->rotation,
1723                                                        vout->mirror)) {
1724                        mutex_unlock(&vout->lock);
1725                        ret = -EINVAL;
1726                        break;
1727                }
1728
1729                vout->control[0].value = rotation;
1730                mutex_unlock(&vout->lock);
1731                break;
1732        }
1733        case V4L2_CID_BG_COLOR:
1734        {
1735                struct omap_overlay *ovl;
1736                unsigned int  color = a->value;
1737                struct omap_overlay_manager_info info;
1738
1739                ovl = vout->vid_info.overlays[0];
1740
1741                mutex_lock(&vout->lock);
1742                if (!ovl->manager || !ovl->manager->get_manager_info) {
1743                        mutex_unlock(&vout->lock);
1744                        ret = -EINVAL;
1745                        break;
1746                }
1747
1748                ovl->manager->get_manager_info(ovl->manager, &info);
1749                info.default_color = color;
1750                if (ovl->manager->set_manager_info(ovl->manager, &info)) {
1751                        mutex_unlock(&vout->lock);
1752                        ret = -EINVAL;
1753                        break;
1754                }
1755
1756                vout->control[1].value = color;
1757                mutex_unlock(&vout->lock);
1758                break;
1759        }
1760        case V4L2_CID_VFLIP:
1761        {
1762                struct omap_overlay *ovl;
1763                struct omapvideo_info *ovid;
1764                unsigned int  mirror = a->value;
1765
1766                ovid = &vout->vid_info;
1767                ovl = ovid->overlays[0];
1768
1769                mutex_lock(&vout->lock);
1770
1771                if (mirror  && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1772                        mutex_unlock(&vout->lock);
1773                        ret = -EINVAL;
1774                        break;
1775                }
1776                vout->mirror = mirror;
1777                vout->control[2].value = mirror;
1778                mutex_unlock(&vout->lock);
1779                break;
1780        }
1781        default:
1782                ret = -EINVAL;
1783        }
1784        return ret;
1785}
1786
1787static int vidioc_reqbufs(struct file *file, void *fh,
1788                        struct v4l2_requestbuffers *req)
1789{
1790        int ret = 0;
1791        unsigned int i, num_buffers = 0;
1792        struct omap_vout_device *vout = fh;
1793        struct videobuf_queue *q = &vout->vbq;
1794
1795        if ((req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || (req->count < 0))
1796                return -EINVAL;
1797        /* if memory is not mmp or userptr
1798           return error */
1799        if ((V4L2_MEMORY_MMAP != req->memory) &&
1800                        (V4L2_MEMORY_USERPTR != req->memory))
1801                return -EINVAL;
1802
1803        mutex_lock(&vout->lock);
1804        /* Cannot be requested when streaming is on */
1805        if (vout->streaming) {
1806                ret = -EBUSY;
1807                goto reqbuf_err;
1808        }
1809
1810        /* If buffers are already allocated free them */
1811        if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) {
1812                if (vout->mmap_count) {
1813                        ret = -EBUSY;
1814                        goto reqbuf_err;
1815                }
1816                num_buffers = (vout->vid == OMAP_VIDEO1) ?
1817                        video1_numbuffers : video2_numbuffers;
1818                for (i = num_buffers; i < vout->buffer_allocated; i++) {
1819                        omap_vout_free_buffer(vout->buf_virt_addr[i],
1820                                        vout->buffer_size);
1821                        vout->buf_virt_addr[i] = 0;
1822                        vout->buf_phy_addr[i] = 0;
1823                }
1824                vout->buffer_allocated = num_buffers;
1825                videobuf_mmap_free(q);
1826        } else if (q->bufs[0] && (V4L2_MEMORY_USERPTR == q->bufs[0]->memory)) {
1827                if (vout->buffer_allocated) {
1828                        videobuf_mmap_free(q);
1829                        for (i = 0; i < vout->buffer_allocated; i++) {
1830                                kfree(q->bufs[i]);
1831                                q->bufs[i] = NULL;
1832                        }
1833                        vout->buffer_allocated = 0;
1834                }
1835        }
1836
1837        /*store the memory type in data structure */
1838        vout->memory = req->memory;
1839
1840        INIT_LIST_HEAD(&vout->dma_queue);
1841
1842        /* call videobuf_reqbufs api */
1843        ret = videobuf_reqbufs(q, req);
1844        if (ret < 0)
1845                goto reqbuf_err;
1846
1847        vout->buffer_allocated = req->count;
1848
1849reqbuf_err:
1850        mutex_unlock(&vout->lock);
1851        return ret;
1852}
1853
1854static int vidioc_querybuf(struct file *file, void *fh,
1855                        struct v4l2_buffer *b)
1856{
1857        struct omap_vout_device *vout = fh;
1858
1859        return videobuf_querybuf(&vout->vbq, b);
1860}
1861
1862static int vidioc_qbuf(struct file *file, void *fh,
1863                        struct v4l2_buffer *buffer)
1864{
1865        struct omap_vout_device *vout = fh;
1866        struct videobuf_queue *q = &vout->vbq;
1867
1868        if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) ||
1869                        (buffer->index >= vout->buffer_allocated) ||
1870                        (q->bufs[buffer->index]->memory != buffer->memory)) {
1871                return -EINVAL;
1872        }
1873        if (V4L2_MEMORY_USERPTR == buffer->memory) {
1874                if ((buffer->length < vout->pix.sizeimage) ||
1875                                (0 == buffer->m.userptr)) {
1876                        return -EINVAL;
1877                }
1878        }
1879
1880        if ((rotation_enabled(vout)) &&
1881                        vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) {
1882                v4l2_warn(&vout->vid_dev->v4l2_dev,
1883                                "DMA Channel not allocated for Rotation\n");
1884                return -EINVAL;
1885        }
1886
1887        return videobuf_qbuf(q, buffer);
1888}
1889
1890static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1891{
1892        struct omap_vout_device *vout = fh;
1893        struct videobuf_queue *q = &vout->vbq;
1894
1895        if (!vout->streaming)
1896                return -EINVAL;
1897
1898        if (file->f_flags & O_NONBLOCK)
1899                /* Call videobuf_dqbuf for non blocking mode */
1900                return videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1);
1901        else
1902                /* Call videobuf_dqbuf for  blocking mode */
1903                return videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
1904}
1905
1906static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1907{
1908        int ret = 0, j;
1909        u32 addr = 0, mask = 0;
1910        struct omap_vout_device *vout = fh;
1911        struct videobuf_queue *q = &vout->vbq;
1912        struct omapvideo_info *ovid = &vout->vid_info;
1913
1914        mutex_lock(&vout->lock);
1915
1916        if (vout->streaming) {
1917                ret = -EBUSY;
1918                goto streamon_err;
1919        }
1920
1921        ret = videobuf_streamon(q);
1922        if (ret)
1923                goto streamon_err;
1924
1925        if (list_empty(&vout->dma_queue)) {
1926                ret = -EIO;
1927                goto streamon_err1;
1928        }
1929
1930        /* Get the next frame from the buffer queue */
1931        vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next,
1932                        struct videobuf_buffer, queue);
1933        /* Remove buffer from the buffer queue */
1934        list_del(&vout->cur_frm->queue);
1935        /* Mark state of the current frame to active */
1936        vout->cur_frm->state = VIDEOBUF_ACTIVE;
1937        /* Initialize field_id and started member */
1938        vout->field_id = 0;
1939
1940        /* set flag here. Next QBUF will start DMA */
1941        vout->streaming = 1;
1942
1943        vout->first_int = 1;
1944
1945        if (omap_vout_calculate_offset(vout)) {
1946                ret = -EINVAL;
1947                goto streamon_err1;
1948        }
1949        addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i]
1950                + vout->cropped_offset;
1951
1952        mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
1953
1954        omap_dispc_register_isr(omap_vout_isr, vout, mask);
1955
1956        for (j = 0; j < ovid->num_overlays; j++) {
1957                struct omap_overlay *ovl = ovid->overlays[j];
1958
1959                if (ovl->manager && ovl->manager->device) {
1960                        struct omap_overlay_info info;
1961                        ovl->get_overlay_info(ovl, &info);
1962                        info.enabled = 1;
1963                        info.paddr = addr;
1964                        if (ovl->set_overlay_info(ovl, &info)) {
1965                                ret = -EINVAL;
1966                                goto streamon_err1;
1967                        }
1968                }
1969        }
1970
1971        /* First save the configuration in ovelray structure */
1972        ret = omapvid_init(vout, addr);
1973        if (ret)
1974                v4l2_err(&vout->vid_dev->v4l2_dev,
1975                                "failed to set overlay info\n");
1976        /* Enable the pipeline and set the Go bit */
1977        ret = omapvid_apply_changes(vout);
1978        if (ret)
1979                v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
1980
1981        ret = 0;
1982
1983streamon_err1:
1984        if (ret)
1985                ret = videobuf_streamoff(q);
1986streamon_err:
1987        mutex_unlock(&vout->lock);
1988        return ret;
1989}
1990
1991static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1992{
1993        u32 mask = 0;
1994        int ret = 0, j;
1995        struct omap_vout_device *vout = fh;
1996        struct omapvideo_info *ovid = &vout->vid_info;
1997
1998        if (!vout->streaming)
1999                return -EINVAL;
2000
2001        vout->streaming = 0;
2002        mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
2003
2004        omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
2005
2006        for (j = 0; j < ovid->num_overlays; j++) {
2007                struct omap_overlay *ovl = ovid->overlays[j];
2008
2009                if (ovl->manager && ovl->manager->device) {
2010                        struct omap_overlay_info info;
2011
2012                        ovl->get_overlay_info(ovl, &info);
2013                        info.enabled = 0;
2014                        ret = ovl->set_overlay_info(ovl, &info);
2015                        if (ret)
2016                                v4l2_err(&vout->vid_dev->v4l2_dev,
2017                                "failed to update overlay info in streamoff\n");
2018                }
2019        }
2020
2021        /* Turn of the pipeline */
2022        ret = omapvid_apply_changes(vout);
2023        if (ret)
2024                v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode in"
2025                                " streamoff\n");
2026
2027        INIT_LIST_HEAD(&vout->dma_queue);
2028        ret = videobuf_streamoff(&vout->vbq);
2029
2030        return ret;
2031}
2032
2033static int vidioc_s_fbuf(struct file *file, void *fh,
2034                                struct v4l2_framebuffer *a)
2035{
2036        int enable = 0;
2037        struct omap_overlay *ovl;
2038        struct omapvideo_info *ovid;
2039        struct omap_vout_device *vout = fh;
2040        struct omap_overlay_manager_info info;
2041        enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
2042
2043        ovid = &vout->vid_info;
2044        ovl = ovid->overlays[0];
2045
2046        /* OMAP DSS doesn't support Source and Destination color
2047           key together */
2048        if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) &&
2049                        (a->flags & V4L2_FBUF_FLAG_CHROMAKEY))
2050                return -EINVAL;
2051        /* OMAP DSS Doesn't support the Destination color key
2052           and alpha blending together */
2053        if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY) &&
2054                        (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA))
2055                return -EINVAL;
2056
2057        if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)) {
2058                vout->fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
2059                key_type =  OMAP_DSS_COLOR_KEY_VID_SRC;
2060        } else
2061                vout->fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY;
2062
2063        if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) {
2064                vout->fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
2065                key_type =  OMAP_DSS_COLOR_KEY_GFX_DST;
2066        } else
2067                vout->fbuf.flags &=  ~V4L2_FBUF_FLAG_CHROMAKEY;
2068
2069        if (a->flags & (V4L2_FBUF_FLAG_CHROMAKEY |
2070                                V4L2_FBUF_FLAG_SRC_CHROMAKEY))
2071                enable = 1;
2072        else
2073                enable = 0;
2074        if (ovl->manager && ovl->manager->get_manager_info &&
2075                        ovl->manager->set_manager_info) {
2076
2077                ovl->manager->get_manager_info(ovl->manager, &info);
2078                info.trans_enabled = enable;
2079                info.trans_key_type = key_type;
2080                info.trans_key = vout->win.chromakey;
2081
2082                if (ovl->manager->set_manager_info(ovl->manager, &info))
2083                        return -EINVAL;
2084        }
2085        if (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) {
2086                vout->fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
2087                enable = 1;
2088        } else {
2089                vout->fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA;
2090                enable = 0;
2091        }
2092        if (ovl->manager && ovl->manager->get_manager_info &&
2093                        ovl->manager->set_manager_info) {
2094                ovl->manager->get_manager_info(ovl->manager, &info);
2095                info.alpha_enabled = enable;
2096                if (ovl->manager->set_manager_info(ovl->manager, &info))
2097                        return -EINVAL;
2098        }
2099
2100        return 0;
2101}
2102
2103static int vidioc_g_fbuf(struct file *file, void *fh,
2104                struct v4l2_framebuffer *a)
2105{
2106        struct omap_overlay *ovl;
2107        struct omapvideo_info *ovid;
2108        struct omap_vout_device *vout = fh;
2109        struct omap_overlay_manager_info info;
2110
2111        ovid = &vout->vid_info;
2112        ovl = ovid->overlays[0];
2113
2114        a->flags = 0x0;
2115        a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY
2116                | V4L2_FBUF_CAP_SRC_CHROMAKEY;
2117
2118        if (ovl->manager && ovl->manager->get_manager_info) {
2119                ovl->manager->get_manager_info(ovl->manager, &info);
2120                if (info.trans_key_type == OMAP_DSS_COLOR_KEY_VID_SRC)
2121                        a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
2122                if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST)
2123                        a->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
2124        }
2125        if (ovl->manager && ovl->manager->get_manager_info) {
2126                ovl->manager->get_manager_info(ovl->manager, &info);
2127                if (info.alpha_enabled)
2128                        a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
2129        }
2130
2131        return 0;
2132}
2133
2134static const struct v4l2_ioctl_ops vout_ioctl_ops = {
2135        .vidioc_querycap                        = vidioc_querycap,
2136        .vidioc_enum_fmt_vid_out                = vidioc_enum_fmt_vid_out,
2137        .vidioc_g_fmt_vid_out                   = vidioc_g_fmt_vid_out,
2138        .vidioc_try_fmt_vid_out                 = vidioc_try_fmt_vid_out,
2139        .vidioc_s_fmt_vid_out                   = vidioc_s_fmt_vid_out,
2140        .vidioc_queryctrl                       = vidioc_queryctrl,
2141        .vidioc_g_ctrl                          = vidioc_g_ctrl,
2142        .vidioc_s_fbuf                          = vidioc_s_fbuf,
2143        .vidioc_g_fbuf                          = vidioc_g_fbuf,
2144        .vidioc_s_ctrl                          = vidioc_s_ctrl,
2145        .vidioc_try_fmt_vid_overlay             = vidioc_try_fmt_vid_overlay,
2146        .vidioc_s_fmt_vid_overlay               = vidioc_s_fmt_vid_overlay,
2147        .vidioc_enum_fmt_vid_overlay            = vidioc_enum_fmt_vid_overlay,
2148        .vidioc_g_fmt_vid_overlay               = vidioc_g_fmt_vid_overlay,
2149        .vidioc_cropcap                         = vidioc_cropcap,
2150        .vidioc_g_crop                          = vidioc_g_crop,
2151        .vidioc_s_crop                          = vidioc_s_crop,
2152        .vidioc_reqbufs                         = vidioc_reqbufs,
2153        .vidioc_querybuf                        = vidioc_querybuf,
2154        .vidioc_qbuf                            = vidioc_qbuf,
2155        .vidioc_dqbuf                           = vidioc_dqbuf,
2156        .vidioc_streamon                        = vidioc_streamon,
2157        .vidioc_streamoff                       = vidioc_streamoff,
2158};
2159
2160static const struct v4l2_file_operations omap_vout_fops = {
2161        .owner          = THIS_MODULE,
2162        .unlocked_ioctl = video_ioctl2,
2163        .mmap           = omap_vout_mmap,
2164        .open           = omap_vout_open,
2165        .release        = omap_vout_release,
2166};
2167
2168/* Init functions used during driver initialization */
2169/* Initial setup of video_data */
2170static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
2171{
2172        struct video_device *vfd;
2173        struct v4l2_pix_format *pix;
2174        struct v4l2_control *control;
2175        struct omap_dss_device *display =
2176                vout->vid_info.overlays[0]->manager->device;
2177
2178        /* set the default pix */
2179        pix = &vout->pix;
2180
2181        /* Set the default picture of QVGA  */
2182        pix->width = QQVGA_WIDTH;
2183        pix->height = QQVGA_HEIGHT;
2184
2185        /* Default pixel format is RGB 5-6-5 */
2186        pix->pixelformat = V4L2_PIX_FMT_RGB565;
2187        pix->field = V4L2_FIELD_ANY;
2188        pix->bytesperline = pix->width * 2;
2189        pix->sizeimage = pix->bytesperline * pix->height;
2190        pix->priv = 0;
2191        pix->colorspace = V4L2_COLORSPACE_JPEG;
2192
2193        vout->bpp = RGB565_BPP;
2194        vout->fbuf.fmt.width  =  display->panel.timings.x_res;
2195        vout->fbuf.fmt.height =  display->panel.timings.y_res;
2196
2197        /* Set the data structures for the overlay parameters*/
2198        vout->win.global_alpha = 255;
2199        vout->fbuf.flags = 0;
2200        vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA |
2201                V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY;
2202        vout->win.chromakey = 0;
2203
2204        omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win);
2205
2206        /*Initialize the control variables for
2207          rotation, flipping and background color. */
2208        control = vout->control;
2209        control[0].id = V4L2_CID_ROTATE;
2210        control[0].value = 0;
2211        vout->rotation = 0;
2212        vout->mirror = 0;
2213        vout->control[2].id = V4L2_CID_HFLIP;
2214        vout->control[2].value = 0;
2215        vout->vrfb_bpp = 2;
2216
2217        control[1].id = V4L2_CID_BG_COLOR;
2218        control[1].value = 0;
2219
2220        /* initialize the video_device struct */
2221        vfd = vout->vfd = video_device_alloc();
2222
2223        if (!vfd) {
2224                printk(KERN_ERR VOUT_NAME ": could not allocate"
2225                                " video device struct\n");
2226                return -ENOMEM;
2227        }
2228        vfd->release = video_device_release;
2229        vfd->ioctl_ops = &vout_ioctl_ops;
2230
2231        strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
2232
2233        vfd->fops = &omap_vout_fops;
2234        vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
2235        mutex_init(&vout->lock);
2236
2237        vfd->minor = -1;
2238        return 0;
2239
2240}
2241
2242/* Setup video buffers */
2243static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
2244                int vid_num)
2245{
2246        u32 numbuffers;
2247        int ret = 0, i, j;
2248        int image_width, image_height;
2249        struct video_device *vfd;
2250        struct omap_vout_device *vout;
2251        int static_vrfb_allocation = 0, vrfb_num_bufs = VRFB_NUM_BUFS;
2252        struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2253        struct omap2video_device *vid_dev =
2254                container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
2255
2256        vout = vid_dev->vouts[vid_num];
2257        vfd = vout->vfd;
2258
2259        numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers;
2260        vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize;
2261        dev_info(&pdev->dev, "Buffer Size = %d\n", vout->buffer_size);
2262
2263        for (i = 0; i < numbuffers; i++) {
2264                vout->buf_virt_addr[i] =
2265                        omap_vout_alloc_buffer(vout->buffer_size,
2266                                        (u32 *) &vout->buf_phy_addr[i]);
2267                if (!vout->buf_virt_addr[i]) {
2268                        numbuffers = i;
2269                        ret = -ENOMEM;
2270                        goto free_buffers;
2271                }
2272        }
2273
2274        for (i = 0; i < VRFB_NUM_BUFS; i++) {
2275                if (omap_vrfb_request_ctx(&vout->vrfb_context[i])) {
2276                        dev_info(&pdev->dev, ": VRFB allocation failed\n");
2277                        for (j = 0; j < i; j++)
2278                                omap_vrfb_release_ctx(&vout->vrfb_context[j]);
2279                        ret = -ENOMEM;
2280                        goto free_buffers;
2281                }
2282        }
2283        vout->cropped_offset = 0;
2284
2285        /* Calculate VRFB memory size */
2286        /* allocate for worst case size */
2287        image_width = VID_MAX_WIDTH / TILE_SIZE;
2288        if (VID_MAX_WIDTH % TILE_SIZE)
2289                image_width++;
2290
2291        image_width = image_width * TILE_SIZE;
2292        image_height = VID_MAX_HEIGHT / TILE_SIZE;
2293
2294        if (VID_MAX_HEIGHT % TILE_SIZE)
2295                image_height++;
2296
2297        image_height = image_height * TILE_SIZE;
2298        vout->smsshado_size = PAGE_ALIGN(image_width * image_height * 2 * 2);
2299
2300        /*
2301         * Request and Initialize DMA, for DMA based VRFB transfer
2302         */
2303        vout->vrfb_dma_tx.dev_id = OMAP_DMA_NO_DEVICE;
2304        vout->vrfb_dma_tx.dma_ch = -1;
2305        vout->vrfb_dma_tx.req_status = DMA_CHAN_ALLOTED;
2306        ret = omap_request_dma(vout->vrfb_dma_tx.dev_id, "VRFB DMA TX",
2307                        omap_vout_vrfb_dma_tx_callback,
2308                        (void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch);
2309        if (ret < 0) {
2310                vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
2311                dev_info(&pdev->dev, ": failed to allocate DMA Channel for"
2312                                " video%d\n", vfd->minor);
2313        }
2314        init_waitqueue_head(&vout->vrfb_dma_tx.wait);
2315
2316        /* Allocate VRFB buffers if selected through bootargs */
2317        static_vrfb_allocation = (vid_num == 0) ?
2318                vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
2319
2320        /* statically allocated the VRFB buffer is done through
2321           commands line aruments */
2322        if (static_vrfb_allocation) {
2323                if (omap_vout_allocate_vrfb_buffers(vout, &vrfb_num_bufs, -1)) {
2324                        ret =  -ENOMEM;
2325                        goto release_vrfb_ctx;
2326                }
2327                vout->vrfb_static_allocation = 1;
2328        }
2329        return 0;
2330
2331release_vrfb_ctx:
2332        for (j = 0; j < VRFB_NUM_BUFS; j++)
2333                omap_vrfb_release_ctx(&vout->vrfb_context[j]);
2334
2335free_buffers:
2336        for (i = 0; i < numbuffers; i++) {
2337                omap_vout_free_buffer(vout->buf_virt_addr[i],
2338                                                vout->buffer_size);
2339                vout->buf_virt_addr[i] = 0;
2340                vout->buf_phy_addr[i] = 0;
2341        }
2342        return ret;
2343
2344}
2345
2346/* Create video out devices */
2347static int __init omap_vout_create_video_devices(struct platform_device *pdev)
2348{
2349        int ret = 0, k;
2350        struct omap_vout_device *vout;
2351        struct video_device *vfd = NULL;
2352        struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2353        struct omap2video_device *vid_dev = container_of(v4l2_dev,
2354                        struct omap2video_device, v4l2_dev);
2355
2356        for (k = 0; k < pdev->num_resources; k++) {
2357
2358                vout = kzalloc(sizeof(struct omap_vout_device), GFP_KERNEL);
2359                if (!vout) {
2360                        dev_err(&pdev->dev, ": could not allocate memory\n");
2361                        return -ENOMEM;
2362                }
2363
2364                vout->vid = k;
2365                vid_dev->vouts[k] = vout;
2366                vout->vid_dev = vid_dev;
2367                /* Select video2 if only 1 overlay is controlled by V4L2 */
2368                if (pdev->num_resources == 1)
2369                        vout->vid_info.overlays[0] = vid_dev->overlays[k + 2];
2370                else
2371                        /* Else select video1 and video2 one by one. */
2372                        vout->vid_info.overlays[0] = vid_dev->overlays[k + 1];
2373                vout->vid_info.num_overlays = 1;
2374                vout->vid_info.id = k + 1;
2375
2376                /* Setup the default configuration for the video devices
2377                 */
2378                if (omap_vout_setup_video_data(vout) != 0) {
2379                        ret = -ENOMEM;
2380                        goto error;
2381                }
2382
2383                /* Allocate default number of buffers for the video streaming
2384                 * and reserve the VRFB space for rotation
2385                 */
2386                if (omap_vout_setup_video_bufs(pdev, k) != 0) {
2387                        ret = -ENOMEM;
2388                        goto error1;
2389                }
2390
2391                /* Register the Video device with V4L2
2392                 */
2393                vfd = vout->vfd;
2394                if (video_register_device(vfd, VFL_TYPE_GRABBER, k + 1) < 0) {
2395                        dev_err(&pdev->dev, ": Could not register "
2396                                        "Video for Linux device\n");
2397                        vfd->minor = -1;
2398                        ret = -ENODEV;
2399                        goto error2;
2400                }
2401                video_set_drvdata(vfd, vout);
2402
2403                /* Configure the overlay structure */
2404                ret = omapvid_init(vid_dev->vouts[k], 0);
2405                if (!ret)
2406                        goto success;
2407
2408error2:
2409                omap_vout_release_vrfb(vout);
2410                omap_vout_free_buffers(vout);
2411error1:
2412                video_device_release(vfd);
2413error:
2414                kfree(vout);
2415                return ret;
2416
2417success:
2418                dev_info(&pdev->dev, ": registered and initialized"
2419                                " video device %d\n", vfd->minor);
2420                if (k == (pdev->num_resources - 1))
2421                        return 0;
2422        }
2423
2424        return -ENODEV;
2425}
2426/* Driver functions */
2427static void omap_vout_cleanup_device(struct omap_vout_device *vout)
2428{
2429        struct video_device *vfd;
2430
2431        if (!vout)
2432                return;
2433
2434        vfd = vout->vfd;
2435        if (vfd) {
2436                if (!video_is_registered(vfd)) {
2437                        /*
2438                         * The device was never registered, so release the
2439                         * video_device struct directly.
2440                         */
2441                        video_device_release(vfd);
2442                } else {
2443                        /*
2444                         * The unregister function will release the video_device
2445                         * struct as well as unregistering it.
2446                         */
2447                        video_unregister_device(vfd);
2448                }
2449        }
2450
2451        omap_vout_release_vrfb(vout);
2452        omap_vout_free_buffers(vout);
2453        /* Free the VRFB buffer if allocated
2454         * init time
2455         */
2456        if (vout->vrfb_static_allocation)
2457                omap_vout_free_vrfb_buffers(vout);
2458
2459        kfree(vout);
2460}
2461
2462static int omap_vout_remove(struct platform_device *pdev)
2463{
2464        int k;
2465        struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2466        struct omap2video_device *vid_dev = container_of(v4l2_dev, struct
2467                        omap2video_device, v4l2_dev);
2468
2469        v4l2_device_unregister(v4l2_dev);
2470        for (k = 0; k < pdev->num_resources; k++)
2471                omap_vout_cleanup_device(vid_dev->vouts[k]);
2472
2473        for (k = 0; k < vid_dev->num_displays; k++) {
2474                if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED)
2475                        vid_dev->displays[k]->driver->disable(vid_dev->displays[k]);
2476
2477                omap_dss_put_device(vid_dev->displays[k]);
2478        }
2479        kfree(vid_dev);
2480        return 0;
2481}
2482
2483static int __init omap_vout_probe(struct platform_device *pdev)
2484{
2485        int ret = 0, i;
2486        struct omap_overlay *ovl;
2487        struct omap_dss_device *dssdev = NULL;
2488        struct omap_dss_device *def_display;
2489        struct omap2video_device *vid_dev = NULL;
2490
2491        if (pdev->num_resources == 0) {
2492                dev_err(&pdev->dev, "probed for an unknown device\n");
2493                return -ENODEV;
2494        }
2495
2496        vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL);
2497        if (vid_dev == NULL)
2498                return -ENOMEM;
2499
2500        vid_dev->num_displays = 0;
2501        for_each_dss_dev(dssdev) {
2502                omap_dss_get_device(dssdev);
2503                vid_dev->displays[vid_dev->num_displays++] = dssdev;
2504        }
2505
2506        if (vid_dev->num_displays == 0) {
2507                dev_err(&pdev->dev, "no displays\n");
2508                ret = -EINVAL;
2509                goto probe_err0;
2510        }
2511
2512        vid_dev->num_overlays = omap_dss_get_num_overlays();
2513        for (i = 0; i < vid_dev->num_overlays; i++)
2514                vid_dev->overlays[i] = omap_dss_get_overlay(i);
2515
2516        vid_dev->num_managers = omap_dss_get_num_overlay_managers();
2517        for (i = 0; i < vid_dev->num_managers; i++)
2518                vid_dev->managers[i] = omap_dss_get_overlay_manager(i);
2519
2520        /* Get the Video1 overlay and video2 overlay.
2521         * Setup the Display attached to that overlays
2522         */
2523        for (i = 1; i < vid_dev->num_overlays; i++) {
2524                ovl = omap_dss_get_overlay(i);
2525                if (ovl->manager && ovl->manager->device) {
2526                        def_display = ovl->manager->device;
2527                } else {
2528                        dev_warn(&pdev->dev, "cannot find display\n");
2529                        def_display = NULL;
2530                }
2531                if (def_display) {
2532                        struct omap_dss_driver *dssdrv = def_display->driver;
2533
2534                        ret = dssdrv->enable(def_display);
2535                        if (ret) {
2536                                /* Here we are not considering a error
2537                                 *  as display may be enabled by frame
2538                                 *  buffer driver
2539                                 */
2540                                dev_warn(&pdev->dev,
2541                                        "'%s' Display already enabled\n",
2542                                        def_display->name);
2543                        }
2544                        /* set the update mode */
2545                        if (def_display->caps &
2546                                        OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
2547                                if (dssdrv->enable_te)
2548                                        dssdrv->enable_te(def_display, 0);
2549                                if (dssdrv->set_update_mode)
2550                                        dssdrv->set_update_mode(def_display,
2551                                                        OMAP_DSS_UPDATE_MANUAL);
2552                        } else {
2553                                if (dssdrv->set_update_mode)
2554                                        dssdrv->set_update_mode(def_display,
2555                                                        OMAP_DSS_UPDATE_AUTO);
2556                        }
2557                }
2558        }
2559
2560        if (v4l2_device_register(&pdev->dev, &vid_dev->v4l2_dev) < 0) {
2561                dev_err(&pdev->dev, "v4l2_device_register failed\n");
2562                ret = -ENODEV;
2563                goto probe_err1;
2564        }
2565
2566        ret = omap_vout_create_video_devices(pdev);
2567        if (ret)
2568                goto probe_err2;
2569
2570        for (i = 0; i < vid_dev->num_displays; i++) {
2571                struct omap_dss_device *display = vid_dev->displays[i];
2572
2573                if (display->driver->update)
2574                        display->driver->update(display, 0, 0,
2575                                        display->panel.timings.x_res,
2576                                        display->panel.timings.y_res);
2577        }
2578        return 0;
2579
2580probe_err2:
2581        v4l2_device_unregister(&vid_dev->v4l2_dev);
2582probe_err1:
2583        for (i = 1; i < vid_dev->num_overlays; i++) {
2584                def_display = NULL;
2585                ovl = omap_dss_get_overlay(i);
2586                if (ovl->manager && ovl->manager->device)
2587                        def_display = ovl->manager->device;
2588
2589                if (def_display && def_display->driver)
2590                        def_display->driver->disable(def_display);
2591        }
2592probe_err0:
2593        kfree(vid_dev);
2594        return ret;
2595}
2596
2597static struct platform_driver omap_vout_driver = {
2598        .driver = {
2599                .name = VOUT_NAME,
2600        },
2601        .probe = omap_vout_probe,
2602        .remove = omap_vout_remove,
2603};
2604
2605static int __init omap_vout_init(void)
2606{
2607        if (platform_driver_register(&omap_vout_driver) != 0) {
2608                printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
2609                return -EINVAL;
2610        }
2611        return 0;
2612}
2613
2614static void omap_vout_cleanup(void)
2615{
2616        platform_driver_unregister(&omap_vout_driver);
2617}
2618
2619late_initcall(omap_vout_init);
2620module_exit(omap_vout_cleanup);
2621