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