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