Linux Audio

Check our new training course

Loading...
   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 <plat/dma.h>
  48#include <plat/vrfb.h>
  49#include <video/omapdss.h>
  50
  51#include "omap_voutlib.h"
  52#include "omap_voutdef.h"
  53#include "omap_vout_vrfb.h"
  54
  55MODULE_AUTHOR("Texas Instruments");
  56MODULE_DESCRIPTION("OMAP Video for Linux Video out driver");
  57MODULE_LICENSE("GPL");
  58
  59/* Driver Configuration macros */
  60#define VOUT_NAME		"omap_vout"
  61
  62enum omap_vout_channels {
  63	OMAP_VIDEO1,
  64	OMAP_VIDEO2,
  65};
  66
  67static struct videobuf_queue_ops video_vbq_ops;
  68/* Variables configurable through module params*/
  69static u32 video1_numbuffers = 3;
  70static u32 video2_numbuffers = 3;
  71static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
  72static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
  73static bool vid1_static_vrfb_alloc;
  74static bool vid2_static_vrfb_alloc;
  75static bool debug;
  76
  77/* Module parameters */
  78module_param(video1_numbuffers, uint, S_IRUGO);
  79MODULE_PARM_DESC(video1_numbuffers,
  80	"Number of buffers to be allocated at init time for Video1 device.");
  81
  82module_param(video2_numbuffers, uint, S_IRUGO);
  83MODULE_PARM_DESC(video2_numbuffers,
  84	"Number of buffers to be allocated at init time for Video2 device.");
  85
  86module_param(video1_bufsize, uint, S_IRUGO);
  87MODULE_PARM_DESC(video1_bufsize,
  88	"Size of the buffer to be allocated for video1 device");
  89
  90module_param(video2_bufsize, uint, S_IRUGO);
  91MODULE_PARM_DESC(video2_bufsize,
  92	"Size of the buffer to be allocated for video2 device");
  93
  94module_param(vid1_static_vrfb_alloc, bool, S_IRUGO);
  95MODULE_PARM_DESC(vid1_static_vrfb_alloc,
  96	"Static allocation of the VRFB buffer for video1 device");
  97
  98module_param(vid2_static_vrfb_alloc, bool, S_IRUGO);
  99MODULE_PARM_DESC(vid2_static_vrfb_alloc,
 100	"Static allocation of the VRFB buffer for video2 device");
 101
 102module_param(debug, bool, S_IRUGO);
 103MODULE_PARM_DESC(debug, "Debug level (0-1)");
 104
 105/* list of image formats supported by OMAP2 video pipelines */
 106static const struct v4l2_fmtdesc omap_formats[] = {
 107	{
 108		/* Note:  V4L2 defines RGB565 as:
 109		 *
 110		 *      Byte 0                    Byte 1
 111		 *      g2 g1 g0 r4 r3 r2 r1 r0   b4 b3 b2 b1 b0 g5 g4 g3
 112		 *
 113		 * We interpret RGB565 as:
 114		 *
 115		 *      Byte 0                    Byte 1
 116		 *      g2 g1 g0 b4 b3 b2 b1 b0   r4 r3 r2 r1 r0 g5 g4 g3
 117		 */
 118		.description = "RGB565, le",
 119		.pixelformat = V4L2_PIX_FMT_RGB565,
 120	},
 121	{
 122		/* Note:  V4L2 defines RGB32 as: RGB-8-8-8-8  we use
 123		 *  this for RGB24 unpack mode, the last 8 bits are ignored
 124		 * */
 125		.description = "RGB32, le",
 126		.pixelformat = V4L2_PIX_FMT_RGB32,
 127	},
 128	{
 129		/* Note:  V4L2 defines RGB24 as: RGB-8-8-8  we use
 130		 *        this for RGB24 packed mode
 131		 *
 132		 */
 133		.description = "RGB24, le",
 134		.pixelformat = V4L2_PIX_FMT_RGB24,
 135	},
 136	{
 137		.description = "YUYV (YUV 4:2:2), packed",
 138		.pixelformat = V4L2_PIX_FMT_YUYV,
 139	},
 140	{
 141		.description = "UYVY, packed",
 142		.pixelformat = V4L2_PIX_FMT_UYVY,
 143	},
 144};
 145
 146#define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats))
 147
 148/*
 149 * Try format
 150 */
 151static int omap_vout_try_format(struct v4l2_pix_format *pix)
 152{
 153	int ifmt, bpp = 0;
 154
 155	pix->height = clamp(pix->height, (u32)VID_MIN_HEIGHT,
 156						(u32)VID_MAX_HEIGHT);
 157	pix->width = clamp(pix->width, (u32)VID_MIN_WIDTH, (u32)VID_MAX_WIDTH);
 158
 159	for (ifmt = 0; ifmt < NUM_OUTPUT_FORMATS; ifmt++) {
 160		if (pix->pixelformat == omap_formats[ifmt].pixelformat)
 161			break;
 162	}
 163
 164	if (ifmt == NUM_OUTPUT_FORMATS)
 165		ifmt = 0;
 166
 167	pix->pixelformat = omap_formats[ifmt].pixelformat;
 168	pix->field = V4L2_FIELD_ANY;
 169	pix->priv = 0;
 170
 171	switch (pix->pixelformat) {
 172	case V4L2_PIX_FMT_YUYV:
 173	case V4L2_PIX_FMT_UYVY:
 174	default:
 175		pix->colorspace = V4L2_COLORSPACE_JPEG;
 176		bpp = YUYV_BPP;
 177		break;
 178	case V4L2_PIX_FMT_RGB565:
 179	case V4L2_PIX_FMT_RGB565X:
 180		pix->colorspace = V4L2_COLORSPACE_SRGB;
 181		bpp = RGB565_BPP;
 182		break;
 183	case V4L2_PIX_FMT_RGB24:
 184		pix->colorspace = V4L2_COLORSPACE_SRGB;
 185		bpp = RGB24_BPP;
 186		break;
 187	case V4L2_PIX_FMT_RGB32:
 188	case V4L2_PIX_FMT_BGR32:
 189		pix->colorspace = V4L2_COLORSPACE_SRGB;
 190		bpp = RGB32_BPP;
 191		break;
 192	}
 193	pix->bytesperline = pix->width * bpp;
 194	pix->sizeimage = pix->bytesperline * pix->height;
 195
 196	return bpp;
 197}
 198
 199/*
 200 * omap_vout_uservirt_to_phys: This inline function is used to convert user
 201 * space virtual address to physical address.
 202 */
 203static u32 omap_vout_uservirt_to_phys(u32 virtp)
 204{
 205	unsigned long physp = 0;
 206	struct vm_area_struct *vma;
 207	struct mm_struct *mm = current->mm;
 208
 209	vma = find_vma(mm, virtp);
 210	/* For kernel direct-mapped memory, take the easy way */
 211	if (virtp >= PAGE_OFFSET) {
 212		physp = virt_to_phys((void *) virtp);
 213	} else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
 214		/* this will catch, kernel-allocated, mmaped-to-usermode
 215		   addresses */
 216		physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
 217	} else {
 218		/* otherwise, use get_user_pages() for general userland pages */
 219		int res, nr_pages = 1;
 220		struct page *pages;
 221		down_read(&current->mm->mmap_sem);
 222
 223		res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
 224				0, &pages, NULL);
 225		up_read(&current->mm->mmap_sem);
 226
 227		if (res == nr_pages) {
 228			physp =  __pa(page_address(&pages[0]) +
 229					(virtp & ~PAGE_MASK));
 230		} else {
 231			printk(KERN_WARNING VOUT_NAME
 232					"get_user_pages failed\n");
 233			return 0;
 234		}
 235	}
 236
 237	return physp;
 238}
 239
 240/*
 241 * Free the V4L2 buffers
 242 */
 243void omap_vout_free_buffers(struct omap_vout_device *vout)
 244{
 245	int i, numbuffers;
 246
 247	/* Allocate memory for the buffers */
 248	numbuffers = (vout->vid) ?  video2_numbuffers : video1_numbuffers;
 249	vout->buffer_size = (vout->vid) ? video2_bufsize : video1_bufsize;
 250
 251	for (i = 0; i < numbuffers; i++) {
 252		omap_vout_free_buffer(vout->buf_virt_addr[i],
 253				vout->buffer_size);
 254		vout->buf_phy_addr[i] = 0;
 255		vout->buf_virt_addr[i] = 0;
 256	}
 257}
 258
 259/*
 260 * Convert V4L2 rotation to DSS rotation
 261 *	V4L2 understand 0, 90, 180, 270.
 262 *	Convert to 0, 1, 2 and 3 respectively for DSS
 263 */
 264static int v4l2_rot_to_dss_rot(int v4l2_rotation,
 265			enum dss_rotation *rotation, bool mirror)
 266{
 267	int ret = 0;
 268
 269	switch (v4l2_rotation) {
 270	case 90:
 271		*rotation = dss_rotation_90_degree;
 272		break;
 273	case 180:
 274		*rotation = dss_rotation_180_degree;
 275		break;
 276	case 270:
 277		*rotation = dss_rotation_270_degree;
 278		break;
 279	case 0:
 280		*rotation = dss_rotation_0_degree;
 281		break;
 282	default:
 283		ret = -EINVAL;
 284	}
 285	return ret;
 286}
 287
 288static int omap_vout_calculate_offset(struct omap_vout_device *vout)
 289{
 290	struct omapvideo_info *ovid;
 291	struct v4l2_rect *crop = &vout->crop;
 292	struct v4l2_pix_format *pix = &vout->pix;
 293	int *cropped_offset = &vout->cropped_offset;
 294	int ps = 2, line_length = 0;
 295
 296	ovid = &vout->vid_info;
 297
 298	if (ovid->rotation_type == VOUT_ROT_VRFB) {
 299		omap_vout_calculate_vrfb_offset(vout);
 300	} else {
 301		vout->line_length = line_length = pix->width;
 302
 303		if (V4L2_PIX_FMT_YUYV == pix->pixelformat ||
 304			V4L2_PIX_FMT_UYVY == pix->pixelformat)
 305			ps = 2;
 306		else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat)
 307			ps = 4;
 308		else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat)
 309			ps = 3;
 310
 311		vout->ps = ps;
 312
 313		*cropped_offset = (line_length * ps) *
 314			crop->top + crop->left * ps;
 315	}
 316
 317	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s Offset:%x\n",
 318			__func__, vout->cropped_offset);
 319
 320	return 0;
 321}
 322
 323/*
 324 * Convert V4L2 pixel format to DSS pixel format
 325 */
 326static int video_mode_to_dss_mode(struct omap_vout_device *vout)
 327{
 328	struct omap_overlay *ovl;
 329	struct omapvideo_info *ovid;
 330	struct v4l2_pix_format *pix = &vout->pix;
 331	enum omap_color_mode mode;
 332
 333	ovid = &vout->vid_info;
 334	ovl = ovid->overlays[0];
 335
 336	switch (pix->pixelformat) {
 337	case 0:
 338		break;
 339	case V4L2_PIX_FMT_YUYV:
 340		mode = OMAP_DSS_COLOR_YUV2;
 341		break;
 342	case V4L2_PIX_FMT_UYVY:
 343		mode = OMAP_DSS_COLOR_UYVY;
 344		break;
 345	case V4L2_PIX_FMT_RGB565:
 346		mode = OMAP_DSS_COLOR_RGB16;
 347		break;
 348	case V4L2_PIX_FMT_RGB24:
 349		mode = OMAP_DSS_COLOR_RGB24P;
 350		break;
 351	case V4L2_PIX_FMT_RGB32:
 352		mode = (ovl->id == OMAP_DSS_VIDEO1) ?
 353			OMAP_DSS_COLOR_RGB24U : OMAP_DSS_COLOR_ARGB32;
 354		break;
 355	case V4L2_PIX_FMT_BGR32:
 356		mode = OMAP_DSS_COLOR_RGBX32;
 357		break;
 358	default:
 359		mode = -EINVAL;
 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		ovl = ovid->overlays[i];
 458		if (!ovl->manager || !ovl->manager->device)
 459			return -EINVAL;
 460
 461		timing = &ovl->manager->device->panel.timings;
 462
 463		outw = win->w.width;
 464		outh = win->w.height;
 465		switch (vout->rotation) {
 466		case dss_rotation_90_degree:
 467			/* Invert the height and width for 90
 468			 * and 270 degree rotation
 469			 */
 470			temp = outw;
 471			outw = outh;
 472			outh = temp;
 473			posy = (timing->y_res - win->w.width) - win->w.left;
 474			posx = win->w.top;
 475			break;
 476
 477		case dss_rotation_180_degree:
 478			posx = (timing->x_res - win->w.width) - win->w.left;
 479			posy = (timing->y_res - win->w.height) - win->w.top;
 480			break;
 481
 482		case dss_rotation_270_degree:
 483			temp = outw;
 484			outw = outh;
 485			outh = temp;
 486			posy = win->w.left;
 487			posx = (timing->x_res - win->w.height) - win->w.top;
 488			break;
 489
 490		default:
 491			posx = win->w.left;
 492			posy = win->w.top;
 493			break;
 494		}
 495
 496		ret = omapvid_setup_overlay(vout, ovl, posx, posy,
 497				outw, outh, addr);
 498		if (ret)
 499			goto omapvid_init_err;
 500	}
 501	return 0;
 502
 503omapvid_init_err:
 504	v4l2_warn(&vout->vid_dev->v4l2_dev, "apply_changes failed\n");
 505	return ret;
 506}
 507
 508/*
 509 * Apply the changes set the go bit of DSS
 510 */
 511static int omapvid_apply_changes(struct omap_vout_device *vout)
 512{
 513	int i;
 514	struct omap_overlay *ovl;
 515	struct omapvideo_info *ovid = &vout->vid_info;
 516
 517	for (i = 0; i < ovid->num_overlays; i++) {
 518		ovl = ovid->overlays[i];
 519		if (!ovl->manager || !ovl->manager->device)
 520			return -EINVAL;
 521		ovl->manager->apply(ovl->manager);
 522	}
 523
 524	return 0;
 525}
 526
 527static int omapvid_handle_interlace_display(struct omap_vout_device *vout,
 528		unsigned int irqstatus, struct timeval timevalue)
 529{
 530	u32 fid;
 531
 532	if (vout->first_int) {
 533		vout->first_int = 0;
 534		goto err;
 535	}
 536
 537	if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
 538		fid = 1;
 539	else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
 540		fid = 0;
 541	else
 542		goto err;
 543
 544	vout->field_id ^= 1;
 545	if (fid != vout->field_id) {
 546		if (fid == 0)
 547			vout->field_id = fid;
 548	} else if (0 == fid) {
 549		if (vout->cur_frm == vout->next_frm)
 550			goto err;
 551
 552		vout->cur_frm->ts = timevalue;
 553		vout->cur_frm->state = VIDEOBUF_DONE;
 554		wake_up_interruptible(&vout->cur_frm->done);
 555		vout->cur_frm = vout->next_frm;
 556	} else {
 557		if (list_empty(&vout->dma_queue) ||
 558				(vout->cur_frm != vout->next_frm))
 559			goto err;
 560	}
 561
 562	return vout->field_id;
 563err:
 564	return 0;
 565}
 566
 567static void omap_vout_isr(void *arg, unsigned int irqstatus)
 568{
 569	int ret, fid, mgr_id;
 570	u32 addr, irq;
 571	struct omap_overlay *ovl;
 572	struct timeval timevalue;
 573	struct omapvideo_info *ovid;
 574	struct omap_dss_device *cur_display;
 575	struct omap_vout_device *vout = (struct omap_vout_device *)arg;
 576
 577	if (!vout->streaming)
 578		return;
 579
 580	ovid = &vout->vid_info;
 581	ovl = ovid->overlays[0];
 582	/* get the display device attached to the overlay */
 583	if (!ovl->manager || !ovl->manager->device)
 584		return;
 585
 586	mgr_id = ovl->manager->id;
 587	cur_display = ovl->manager->device;
 588
 589	spin_lock(&vout->vbq_lock);
 590	do_gettimeofday(&timevalue);
 591
 592	switch (cur_display->type) {
 593	case OMAP_DISPLAY_TYPE_DSI:
 594	case OMAP_DISPLAY_TYPE_DPI:
 595		if (mgr_id == OMAP_DSS_CHANNEL_LCD)
 596			irq = DISPC_IRQ_VSYNC;
 597		else if (mgr_id == OMAP_DSS_CHANNEL_LCD2)
 598			irq = DISPC_IRQ_VSYNC2;
 599		else
 600			goto vout_isr_err;
 601
 602		if (!(irqstatus & irq))
 603			goto vout_isr_err;
 604		break;
 605	case OMAP_DISPLAY_TYPE_VENC:
 606		fid = omapvid_handle_interlace_display(vout, irqstatus,
 607				timevalue);
 608		if (!fid)
 609			goto vout_isr_err;
 610		break;
 611	case OMAP_DISPLAY_TYPE_HDMI:
 612		if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
 613			goto vout_isr_err;
 614		break;
 615	default:
 616		goto vout_isr_err;
 617	}
 618
 619	if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
 620		vout->cur_frm->ts = timevalue;
 621		vout->cur_frm->state = VIDEOBUF_DONE;
 622		wake_up_interruptible(&vout->cur_frm->done);
 623		vout->cur_frm = vout->next_frm;
 624	}
 625
 626	vout->first_int = 0;
 627	if (list_empty(&vout->dma_queue))
 628		goto vout_isr_err;
 629
 630	vout->next_frm = list_entry(vout->dma_queue.next,
 631			struct videobuf_buffer, queue);
 632	list_del(&vout->next_frm->queue);
 633
 634	vout->next_frm->state = VIDEOBUF_ACTIVE;
 635
 636	addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
 637		+ vout->cropped_offset;
 638
 639	/* First save the configuration in ovelray structure */
 640	ret = omapvid_init(vout, addr);
 641	if (ret)
 642		printk(KERN_ERR VOUT_NAME
 643			"failed to set overlay info\n");
 644	/* Enable the pipeline and set the Go bit */
 645	ret = omapvid_apply_changes(vout);
 646	if (ret)
 647		printk(KERN_ERR VOUT_NAME "failed to change mode\n");
 648
 649vout_isr_err:
 650	spin_unlock(&vout->vbq_lock);
 651}
 652
 653/* Video buffer call backs */
 654
 655/*
 656 * Buffer setup function is called by videobuf layer when REQBUF ioctl is
 657 * called. This is used to setup buffers and return size and count of
 658 * buffers allocated. After the call to this buffer, videobuf layer will
 659 * setup buffer queue depending on the size and count of buffers
 660 */
 661static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
 662			  unsigned int *size)
 663{
 664	int startindex = 0, i, j;
 665	u32 phy_addr = 0, virt_addr = 0;
 666	struct omap_vout_device *vout = q->priv_data;
 667	struct omapvideo_info *ovid = &vout->vid_info;
 668	int vid_max_buf_size;
 669
 670	if (!vout)
 671		return -EINVAL;
 672
 673	vid_max_buf_size = vout->vid == OMAP_VIDEO1 ? video1_bufsize :
 674		video2_bufsize;
 675
 676	if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
 677		return -EINVAL;
 678
 679	startindex = (vout->vid == OMAP_VIDEO1) ?
 680		video1_numbuffers : video2_numbuffers;
 681	if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex)
 682		*count = startindex;
 683
 684	if (ovid->rotation_type == VOUT_ROT_VRFB) {
 685		if (omap_vout_vrfb_buffer_setup(vout, count, startindex))
 686			return -ENOMEM;
 687	}
 688
 689	if (V4L2_MEMORY_MMAP != vout->memory)
 690		return 0;
 691
 692	/* Now allocated the V4L2 buffers */
 693	*size = PAGE_ALIGN(vout->pix.width * vout->pix.height * vout->bpp);
 694	startindex = (vout->vid == OMAP_VIDEO1) ?
 695		video1_numbuffers : video2_numbuffers;
 696
 697	/* Check the size of the buffer */
 698	if (*size > vid_max_buf_size) {
 699		v4l2_err(&vout->vid_dev->v4l2_dev,
 700				"buffer allocation mismatch [%u] [%u]\n",
 701				*size, vout->buffer_size);
 702		return -ENOMEM;
 703	}
 704
 705	for (i = startindex; i < *count; i++) {
 706		vout->buffer_size = *size;
 707
 708		virt_addr = omap_vout_alloc_buffer(vout->buffer_size,
 709				&phy_addr);
 710		if (!virt_addr) {
 711			if (ovid->rotation_type == VOUT_ROT_NONE) {
 712				break;
 713			} else {
 714				if (!is_rotation_enabled(vout))
 715					break;
 716			/* Free the VRFB buffers if no space for V4L2 buffers */
 717			for (j = i; j < *count; j++) {
 718				omap_vout_free_buffer(
 719						vout->smsshado_virt_addr[j],
 720						vout->smsshado_size);
 721				vout->smsshado_virt_addr[j] = 0;
 722				vout->smsshado_phy_addr[j] = 0;
 723				}
 724			}
 725		}
 726		vout->buf_virt_addr[i] = virt_addr;
 727		vout->buf_phy_addr[i] = phy_addr;
 728	}
 729	*count = vout->buffer_allocated = i;
 730
 731	return 0;
 732}
 733
 734/*
 735 * Free the V4L2 buffers additionally allocated than default
 736 * number of buffers
 737 */
 738static void omap_vout_free_extra_buffers(struct omap_vout_device *vout)
 739{
 740	int num_buffers = 0, i;
 741
 742	num_buffers = (vout->vid == OMAP_VIDEO1) ?
 743		video1_numbuffers : video2_numbuffers;
 744
 745	for (i = num_buffers; i < vout->buffer_allocated; i++) {
 746		if (vout->buf_virt_addr[i])
 747			omap_vout_free_buffer(vout->buf_virt_addr[i],
 748					vout->buffer_size);
 749
 750		vout->buf_virt_addr[i] = 0;
 751		vout->buf_phy_addr[i] = 0;
 752	}
 753	vout->buffer_allocated = num_buffers;
 754}
 755
 756/*
 757 * This function will be called when VIDIOC_QBUF ioctl is called.
 758 * It prepare buffers before give out for the display. This function
 759 * converts user space virtual address into physical address if userptr memory
 760 * exchange mechanism is used. If rotation is enabled, it copies entire
 761 * buffer into VRFB memory space before giving it to the DSS.
 762 */
 763static int omap_vout_buffer_prepare(struct videobuf_queue *q,
 764			struct videobuf_buffer *vb,
 765			enum v4l2_field field)
 766{
 767	struct omap_vout_device *vout = q->priv_data;
 768	struct omapvideo_info *ovid = &vout->vid_info;
 769
 770	if (VIDEOBUF_NEEDS_INIT == vb->state) {
 771		vb->width = vout->pix.width;
 772		vb->height = vout->pix.height;
 773		vb->size = vb->width * vb->height * vout->bpp;
 774		vb->field = field;
 775	}
 776	vb->state = VIDEOBUF_PREPARED;
 777	/* if user pointer memory mechanism is used, get the physical
 778	 * address of the buffer
 779	 */
 780	if (V4L2_MEMORY_USERPTR == vb->memory) {
 781		if (0 == vb->baddr)
 782			return -EINVAL;
 783		/* Physical address */
 784		vout->queued_buf_addr[vb->i] = (u8 *)
 785			omap_vout_uservirt_to_phys(vb->baddr);
 786	} else {
 787		u32 addr, dma_addr;
 788		unsigned long size;
 789
 790		addr = (unsigned long) vout->buf_virt_addr[vb->i];
 791		size = (unsigned long) vb->size;
 792
 793		dma_addr = dma_map_single(vout->vid_dev->v4l2_dev.dev, (void *) addr,
 794				size, DMA_TO_DEVICE);
 795		if (dma_mapping_error(vout->vid_dev->v4l2_dev.dev, dma_addr))
 796			v4l2_err(&vout->vid_dev->v4l2_dev, "dma_map_single failed\n");
 797
 798		vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i];
 799	}
 800
 801	if (ovid->rotation_type == VOUT_ROT_VRFB)
 802		return omap_vout_prepare_vrfb(vout, vb);
 803	else
 804		return 0;
 805}
 806
 807/*
 808 * Buffer queue function will be called from the videobuf layer when _QBUF
 809 * ioctl is called. It is used to enqueue buffer, which is ready to be
 810 * displayed.
 811 */
 812static void omap_vout_buffer_queue(struct videobuf_queue *q,
 813			  struct videobuf_buffer *vb)
 814{
 815	struct omap_vout_device *vout = q->priv_data;
 816
 817	/* Driver is also maintainig a queue. So enqueue buffer in the driver
 818	 * queue */
 819	list_add_tail(&vb->queue, &vout->dma_queue);
 820
 821	vb->state = VIDEOBUF_QUEUED;
 822}
 823
 824/*
 825 * Buffer release function is called from videobuf layer to release buffer
 826 * which are already allocated
 827 */
 828static void omap_vout_buffer_release(struct videobuf_queue *q,
 829			    struct videobuf_buffer *vb)
 830{
 831	struct omap_vout_device *vout = q->priv_data;
 832
 833	vb->state = VIDEOBUF_NEEDS_INIT;
 834
 835	if (V4L2_MEMORY_MMAP != vout->memory)
 836		return;
 837}
 838
 839/*
 840 *  File operations
 841 */
 842static unsigned int omap_vout_poll(struct file *file,
 843				   struct poll_table_struct *wait)
 844{
 845	struct omap_vout_device *vout = file->private_data;
 846	struct videobuf_queue *q = &vout->vbq;
 847
 848	return videobuf_poll_stream(file, q, wait);
 849}
 850
 851static void omap_vout_vm_open(struct vm_area_struct *vma)
 852{
 853	struct omap_vout_device *vout = vma->vm_private_data;
 854
 855	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
 856		"vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
 857	vout->mmap_count++;
 858}
 859
 860static void omap_vout_vm_close(struct vm_area_struct *vma)
 861{
 862	struct omap_vout_device *vout = vma->vm_private_data;
 863
 864	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
 865		"vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
 866	vout->mmap_count--;
 867}
 868
 869static struct vm_operations_struct omap_vout_vm_ops = {
 870	.open	= omap_vout_vm_open,
 871	.close	= omap_vout_vm_close,
 872};
 873
 874static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
 875{
 876	int i;
 877	void *pos;
 878	unsigned long start = vma->vm_start;
 879	unsigned long size = (vma->vm_end - vma->vm_start);
 880	struct omap_vout_device *vout = file->private_data;
 881	struct videobuf_queue *q = &vout->vbq;
 882
 883	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
 884			" %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__,
 885			vma->vm_pgoff, vma->vm_start, vma->vm_end);
 886
 887	/* look for the buffer to map */
 888	for (i = 0; i < VIDEO_MAX_FRAME; i++) {
 889		if (NULL == q->bufs[i])
 890			continue;
 891		if (V4L2_MEMORY_MMAP != q->bufs[i]->memory)
 892			continue;
 893		if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT))
 894			break;
 895	}
 896
 897	if (VIDEO_MAX_FRAME == i) {
 898		v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
 899				"offset invalid [offset=0x%lx]\n",
 900				(vma->vm_pgoff << PAGE_SHIFT));
 901		return -EINVAL;
 902	}
 903	/* Check the size of the buffer */
 904	if (size > vout->buffer_size) {
 905		v4l2_err(&vout->vid_dev->v4l2_dev,
 906				"insufficient memory [%lu] [%u]\n",
 907				size, vout->buffer_size);
 908		return -ENOMEM;
 909	}
 910
 911	q->bufs[i]->baddr = vma->vm_start;
 912
 913	vma->vm_flags |= VM_RESERVED;
 914	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 915	vma->vm_ops = &omap_vout_vm_ops;
 916	vma->vm_private_data = (void *) vout;
 917	pos = (void *)vout->buf_virt_addr[i];
 918	vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT;
 919	while (size > 0) {
 920		unsigned long pfn;
 921		pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT;
 922		if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
 923			return -EAGAIN;
 924		start += PAGE_SIZE;
 925		pos += PAGE_SIZE;
 926		size -= PAGE_SIZE;
 927	}
 928	vout->mmap_count++;
 929	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
 930
 931	return 0;
 932}
 933
 934static int omap_vout_release(struct file *file)
 935{
 936	unsigned int ret, i;
 937	struct videobuf_queue *q;
 938	struct omapvideo_info *ovid;
 939	struct omap_vout_device *vout = file->private_data;
 940
 941	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
 942	ovid = &vout->vid_info;
 943
 944	if (!vout)
 945		return 0;
 946
 947	q = &vout->vbq;
 948	/* Disable all the overlay managers connected with this interface */
 949	for (i = 0; i < ovid->num_overlays; i++) {
 950		struct omap_overlay *ovl = ovid->overlays[i];
 951		if (ovl->manager && ovl->manager->device)
 952			ovl->disable(ovl);
 953	}
 954	/* Turn off the pipeline */
 955	ret = omapvid_apply_changes(vout);
 956	if (ret)
 957		v4l2_warn(&vout->vid_dev->v4l2_dev,
 958				"Unable to apply changes\n");
 959
 960	/* Free all buffers */
 961	omap_vout_free_extra_buffers(vout);
 962
 963	/* Free the VRFB buffers only if they are allocated
 964	 * during reqbufs.  Don't free if init time allocated
 965	 */
 966	if (ovid->rotation_type == VOUT_ROT_VRFB) {
 967		if (!vout->vrfb_static_allocation)
 968			omap_vout_free_vrfb_buffers(vout);
 969	}
 970	videobuf_mmap_free(q);
 971
 972	/* Even if apply changes fails we should continue
 973	   freeing allocated memory */
 974	if (vout->streaming) {
 975		u32 mask = 0;
 976
 977		mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
 978			DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_VSYNC2;
 979		omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
 980		vout->streaming = 0;
 981
 982		videobuf_streamoff(q);
 983		videobuf_queue_cancel(q);
 984	}
 985
 986	if (vout->mmap_count != 0)
 987		vout->mmap_count = 0;
 988
 989	vout->opened -= 1;
 990	file->private_data = NULL;
 991
 992	if (vout->buffer_allocated)
 993		videobuf_mmap_free(q);
 994
 995	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
 996	return ret;
 997}
 998
 999static int omap_vout_open(struct file *file)
1000{
1001	struct videobuf_queue *q;
1002	struct omap_vout_device *vout = NULL;
1003
1004	vout = video_drvdata(file);
1005	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
1006
1007	if (vout == NULL)
1008		return -ENODEV;
1009
1010	/* for now, we only support single open */
1011	if (vout->opened)
1012		return -EBUSY;
1013
1014	vout->opened += 1;
1015
1016	file->private_data = vout;
1017	vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1018
1019	q = &vout->vbq;
1020	video_vbq_ops.buf_setup = omap_vout_buffer_setup;
1021	video_vbq_ops.buf_prepare = omap_vout_buffer_prepare;
1022	video_vbq_ops.buf_release = omap_vout_buffer_release;
1023	video_vbq_ops.buf_queue = omap_vout_buffer_queue;
1024	spin_lock_init(&vout->vbq_lock);
1025
1026	videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev,
1027			&vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
1028			sizeof(struct videobuf_buffer), vout, NULL);
1029
1030	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
1031	return 0;
1032}
1033
1034/*
1035 * V4L2 ioctls
1036 */
1037static int vidioc_querycap(struct file *file, void *fh,
1038		struct v4l2_capability *cap)
1039{
1040	struct omap_vout_device *vout = fh;
1041
1042	strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
1043	strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
1044	cap->bus_info[0] = '\0';
1045	cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT |
1046		V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
1047
1048	return 0;
1049}
1050
1051static int vidioc_enum_fmt_vid_out(struct file *file, void *fh,
1052			struct v4l2_fmtdesc *fmt)
1053{
1054	int index = fmt->index;
1055
1056	if (index >= NUM_OUTPUT_FORMATS)
1057		return -EINVAL;
1058
1059	fmt->flags = omap_formats[index].flags;
1060	strlcpy(fmt->description, omap_formats[index].description,
1061			sizeof(fmt->description));
1062	fmt->pixelformat = omap_formats[index].pixelformat;
1063
1064	return 0;
1065}
1066
1067static int vidioc_g_fmt_vid_out(struct file *file, void *fh,
1068			struct v4l2_format *f)
1069{
1070	struct omap_vout_device *vout = fh;
1071
1072	f->fmt.pix = vout->pix;
1073	return 0;
1074
1075}
1076
1077static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
1078			struct v4l2_format *f)
1079{
1080	struct omap_overlay *ovl;
1081	struct omapvideo_info *ovid;
1082	struct omap_video_timings *timing;
1083	struct omap_vout_device *vout = fh;
1084
1085	ovid = &vout->vid_info;
1086	ovl = ovid->overlays[0];
1087
1088	if (!ovl->manager || !ovl->manager->device)
1089		return -EINVAL;
1090	/* get the display device attached to the overlay */
1091	timing = &ovl->manager->device->panel.timings;
1092
1093	vout->fbuf.fmt.height = timing->y_res;
1094	vout->fbuf.fmt.width = timing->x_res;
1095
1096	omap_vout_try_format(&f->fmt.pix);
1097	return 0;
1098}
1099
1100static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
1101			struct v4l2_format *f)
1102{
1103	int ret, bpp;
1104	struct omap_overlay *ovl;
1105	struct omapvideo_info *ovid;
1106	struct omap_video_timings *timing;
1107	struct omap_vout_device *vout = fh;
1108
1109	if (vout->streaming)
1110		return -EBUSY;
1111
1112	mutex_lock(&vout->lock);
1113
1114	ovid = &vout->vid_info;
1115	ovl = ovid->overlays[0];
1116
1117	/* get the display device attached to the overlay */
1118	if (!ovl->manager || !ovl->manager->device) {
1119		ret = -EINVAL;
1120		goto s_fmt_vid_out_exit;
1121	}
1122	timing = &ovl->manager->device->panel.timings;
1123
1124	/* We dont support RGB24-packed mode if vrfb rotation
1125	 * is enabled*/
1126	if ((is_rotation_enabled(vout)) &&
1127			f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1128		ret = -EINVAL;
1129		goto s_fmt_vid_out_exit;
1130	}
1131
1132	/* get the framebuffer parameters */
1133
1134	if (is_rotation_90_or_270(vout)) {
1135		vout->fbuf.fmt.height = timing->x_res;
1136		vout->fbuf.fmt.width = timing->y_res;
1137	} else {
1138		vout->fbuf.fmt.height = timing->y_res;
1139		vout->fbuf.fmt.width = timing->x_res;
1140	}
1141
1142	/* change to samller size is OK */
1143
1144	bpp = omap_vout_try_format(&f->fmt.pix);
1145	f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp;
1146
1147	/* try & set the new output format */
1148	vout->bpp = bpp;
1149	vout->pix = f->fmt.pix;
1150	vout->vrfb_bpp = 1;
1151
1152	/* If YUYV then vrfb bpp is 2, for  others its 1 */
1153	if (V4L2_PIX_FMT_YUYV == vout->pix.pixelformat ||
1154			V4L2_PIX_FMT_UYVY == vout->pix.pixelformat)
1155		vout->vrfb_bpp = 2;
1156
1157	/* set default crop and win */
1158	omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win);
1159
1160	/* Save the changes in the overlay strcuture */
1161	ret = omapvid_init(vout, 0);
1162	if (ret) {
1163		v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
1164		goto s_fmt_vid_out_exit;
1165	}
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_enum_fmt_vid_overlay(struct file *file, void *fh,
1226			struct v4l2_fmtdesc *fmt)
1227{
1228	int index = fmt->index;
1229
1230	if (index >= NUM_OUTPUT_FORMATS)
1231		return -EINVAL;
1232
1233	fmt->flags = omap_formats[index].flags;
1234	strlcpy(fmt->description, omap_formats[index].description,
1235			sizeof(fmt->description));
1236	fmt->pixelformat = omap_formats[index].pixelformat;
1237	return 0;
1238}
1239
1240static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh,
1241			struct v4l2_format *f)
1242{
1243	u32 key_value =  0;
1244	struct omap_overlay *ovl;
1245	struct omapvideo_info *ovid;
1246	struct omap_vout_device *vout = fh;
1247	struct omap_overlay_manager_info info;
1248	struct v4l2_window *win = &f->fmt.win;
1249
1250	ovid = &vout->vid_info;
1251	ovl = ovid->overlays[0];
1252
1253	win->w = vout->win.w;
1254	win->field = vout->win.field;
1255	win->global_alpha = vout->win.global_alpha;
1256
1257	if (ovl->manager && ovl->manager->get_manager_info) {
1258		ovl->manager->get_manager_info(ovl->manager, &info);
1259		key_value = info.trans_key;
1260	}
1261	win->chromakey = key_value;
1262	return 0;
1263}
1264
1265static int vidioc_cropcap(struct file *file, void *fh,
1266		struct v4l2_cropcap *cropcap)
1267{
1268	struct omap_vout_device *vout = fh;
1269	struct v4l2_pix_format *pix = &vout->pix;
1270
1271	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1272		return -EINVAL;
1273
1274	/* Width and height are always even */
1275	cropcap->bounds.width = pix->width & ~1;
1276	cropcap->bounds.height = pix->height & ~1;
1277
1278	omap_vout_default_crop(&vout->pix, &vout->fbuf, &cropcap->defrect);
1279	cropcap->pixelaspect.numerator = 1;
1280	cropcap->pixelaspect.denominator = 1;
1281	return 0;
1282}
1283
1284static int vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
1285{
1286	struct omap_vout_device *vout = fh;
1287
1288	if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1289		return -EINVAL;
1290	crop->c = vout->crop;
1291	return 0;
1292}
1293
1294static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
1295{
1296	int ret = -EINVAL;
1297	struct omap_vout_device *vout = fh;
1298	struct omapvideo_info *ovid;
1299	struct omap_overlay *ovl;
1300	struct omap_video_timings *timing;
1301
1302	if (vout->streaming)
1303		return -EBUSY;
1304
1305	mutex_lock(&vout->lock);
1306	ovid = &vout->vid_info;
1307	ovl = ovid->overlays[0];
1308
1309	if (!ovl->manager || !ovl->manager->device) {
1310		ret = -EINVAL;
1311		goto s_crop_err;
1312	}
1313	/* get the display device attached to the overlay */
1314	timing = &ovl->manager->device->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	omap_dispc_register_isr(omap_vout_isr, vout, mask);
1666
1667	for (j = 0; j < ovid->num_overlays; j++) {
1668		struct omap_overlay *ovl = ovid->overlays[j];
1669
1670		if (ovl->manager && ovl->manager->device) {
1671			struct omap_overlay_info info;
1672			ovl->get_overlay_info(ovl, &info);
1673			info.paddr = addr;
1674			if (ovl->set_overlay_info(ovl, &info)) {
1675				ret = -EINVAL;
1676				goto streamon_err1;
1677			}
1678		}
1679	}
1680
1681	/* First save the configuration in ovelray structure */
1682	ret = omapvid_init(vout, addr);
1683	if (ret)
1684		v4l2_err(&vout->vid_dev->v4l2_dev,
1685				"failed to set overlay info\n");
1686	/* Enable the pipeline and set the Go bit */
1687	ret = omapvid_apply_changes(vout);
1688	if (ret)
1689		v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
1690
1691	for (j = 0; j < ovid->num_overlays; j++) {
1692		struct omap_overlay *ovl = ovid->overlays[j];
1693
1694		if (ovl->manager && ovl->manager->device) {
1695			ret = ovl->enable(ovl);
1696			if (ret)
1697				goto streamon_err1;
1698		}
1699	}
1700
1701	ret = 0;
1702
1703streamon_err1:
1704	if (ret)
1705		ret = videobuf_streamoff(q);
1706streamon_err:
1707	mutex_unlock(&vout->lock);
1708	return ret;
1709}
1710
1711static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1712{
1713	u32 mask = 0;
1714	int ret = 0, j;
1715	struct omap_vout_device *vout = fh;
1716	struct omapvideo_info *ovid = &vout->vid_info;
1717
1718	if (!vout->streaming)
1719		return -EINVAL;
1720
1721	vout->streaming = 0;
1722	mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
1723		| DISPC_IRQ_VSYNC2;
1724
1725	omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
1726
1727	for (j = 0; j < ovid->num_overlays; j++) {
1728		struct omap_overlay *ovl = ovid->overlays[j];
1729
1730		if (ovl->manager && ovl->manager->device)
1731			ovl->disable(ovl);
1732	}
1733
1734	/* Turn of the pipeline */
1735	ret = omapvid_apply_changes(vout);
1736	if (ret)
1737		v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode in"
1738				" streamoff\n");
1739
1740	INIT_LIST_HEAD(&vout->dma_queue);
1741	ret = videobuf_streamoff(&vout->vbq);
1742
1743	return ret;
1744}
1745
1746static int vidioc_s_fbuf(struct file *file, void *fh,
1747				struct v4l2_framebuffer *a)
1748{
1749	int enable = 0;
1750	struct omap_overlay *ovl;
1751	struct omapvideo_info *ovid;
1752	struct omap_vout_device *vout = fh;
1753	struct omap_overlay_manager_info info;
1754	enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
1755
1756	ovid = &vout->vid_info;
1757	ovl = ovid->overlays[0];
1758
1759	/* OMAP DSS doesn't support Source and Destination color
1760	   key together */
1761	if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) &&
1762			(a->flags & V4L2_FBUF_FLAG_CHROMAKEY))
1763		return -EINVAL;
1764	/* OMAP DSS Doesn't support the Destination color key
1765	   and alpha blending together */
1766	if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY) &&
1767			(a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA))
1768		return -EINVAL;
1769
1770	if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)) {
1771		vout->fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1772		key_type =  OMAP_DSS_COLOR_KEY_VID_SRC;
1773	} else
1774		vout->fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1775
1776	if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) {
1777		vout->fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1778		key_type =  OMAP_DSS_COLOR_KEY_GFX_DST;
1779	} else
1780		vout->fbuf.flags &=  ~V4L2_FBUF_FLAG_CHROMAKEY;
1781
1782	if (a->flags & (V4L2_FBUF_FLAG_CHROMAKEY |
1783				V4L2_FBUF_FLAG_SRC_CHROMAKEY))
1784		enable = 1;
1785	else
1786		enable = 0;
1787	if (ovl->manager && ovl->manager->get_manager_info &&
1788			ovl->manager->set_manager_info) {
1789
1790		ovl->manager->get_manager_info(ovl->manager, &info);
1791		info.trans_enabled = enable;
1792		info.trans_key_type = key_type;
1793		info.trans_key = vout->win.chromakey;
1794
1795		if (ovl->manager->set_manager_info(ovl->manager, &info))
1796			return -EINVAL;
1797	}
1798	if (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) {
1799		vout->fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1800		enable = 1;
1801	} else {
1802		vout->fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA;
1803		enable = 0;
1804	}
1805	if (ovl->manager && ovl->manager->get_manager_info &&
1806			ovl->manager->set_manager_info) {
1807		ovl->manager->get_manager_info(ovl->manager, &info);
1808		/* enable this only if there is no zorder cap */
1809		if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
1810			info.partial_alpha_enabled = enable;
1811		if (ovl->manager->set_manager_info(ovl->manager, &info))
1812			return -EINVAL;
1813	}
1814
1815	return 0;
1816}
1817
1818static int vidioc_g_fbuf(struct file *file, void *fh,
1819		struct v4l2_framebuffer *a)
1820{
1821	struct omap_overlay *ovl;
1822	struct omapvideo_info *ovid;
1823	struct omap_vout_device *vout = fh;
1824	struct omap_overlay_manager_info info;
1825
1826	ovid = &vout->vid_info;
1827	ovl = ovid->overlays[0];
1828
1829	/* The video overlay must stay within the framebuffer and can't be
1830	   positioned independently. */
1831	a->flags = V4L2_FBUF_FLAG_OVERLAY;
1832	a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY
1833		| V4L2_FBUF_CAP_SRC_CHROMAKEY;
1834
1835	if (ovl->manager && ovl->manager->get_manager_info) {
1836		ovl->manager->get_manager_info(ovl->manager, &info);
1837		if (info.trans_key_type == OMAP_DSS_COLOR_KEY_VID_SRC)
1838			a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1839		if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST)
1840			a->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1841	}
1842	if (ovl->manager && ovl->manager->get_manager_info) {
1843		ovl->manager->get_manager_info(ovl->manager, &info);
1844		if (info.partial_alpha_enabled)
1845			a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1846	}
1847
1848	return 0;
1849}
1850
1851static const struct v4l2_ioctl_ops vout_ioctl_ops = {
1852	.vidioc_querycap      			= vidioc_querycap,
1853	.vidioc_enum_fmt_vid_out 		= vidioc_enum_fmt_vid_out,
1854	.vidioc_g_fmt_vid_out			= vidioc_g_fmt_vid_out,
1855	.vidioc_try_fmt_vid_out			= vidioc_try_fmt_vid_out,
1856	.vidioc_s_fmt_vid_out			= vidioc_s_fmt_vid_out,
1857	.vidioc_queryctrl    			= vidioc_queryctrl,
1858	.vidioc_g_ctrl       			= vidioc_g_ctrl,
1859	.vidioc_s_fbuf				= vidioc_s_fbuf,
1860	.vidioc_g_fbuf				= vidioc_g_fbuf,
1861	.vidioc_s_ctrl       			= vidioc_s_ctrl,
1862	.vidioc_try_fmt_vid_overlay 		= vidioc_try_fmt_vid_overlay,
1863	.vidioc_s_fmt_vid_overlay		= vidioc_s_fmt_vid_overlay,
1864	.vidioc_enum_fmt_vid_overlay		= vidioc_enum_fmt_vid_overlay,
1865	.vidioc_g_fmt_vid_overlay		= vidioc_g_fmt_vid_overlay,
1866	.vidioc_cropcap				= vidioc_cropcap,
1867	.vidioc_g_crop				= vidioc_g_crop,
1868	.vidioc_s_crop				= vidioc_s_crop,
1869	.vidioc_reqbufs				= vidioc_reqbufs,
1870	.vidioc_querybuf			= vidioc_querybuf,
1871	.vidioc_qbuf				= vidioc_qbuf,
1872	.vidioc_dqbuf				= vidioc_dqbuf,
1873	.vidioc_streamon			= vidioc_streamon,
1874	.vidioc_streamoff			= vidioc_streamoff,
1875};
1876
1877static const struct v4l2_file_operations omap_vout_fops = {
1878	.owner 		= THIS_MODULE,
1879	.poll		= omap_vout_poll,
1880	.unlocked_ioctl	= video_ioctl2,
1881	.mmap 		= omap_vout_mmap,
1882	.open 		= omap_vout_open,
1883	.release 	= omap_vout_release,
1884};
1885
1886/* Init functions used during driver initialization */
1887/* Initial setup of video_data */
1888static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
1889{
1890	struct video_device *vfd;
1891	struct v4l2_pix_format *pix;
1892	struct v4l2_control *control;
1893	struct omap_dss_device *display =
1894		vout->vid_info.overlays[0]->manager->device;
1895
1896	/* set the default pix */
1897	pix = &vout->pix;
1898
1899	/* Set the default picture of QVGA  */
1900	pix->width = QQVGA_WIDTH;
1901	pix->height = QQVGA_HEIGHT;
1902
1903	/* Default pixel format is RGB 5-6-5 */
1904	pix->pixelformat = V4L2_PIX_FMT_RGB565;
1905	pix->field = V4L2_FIELD_ANY;
1906	pix->bytesperline = pix->width * 2;
1907	pix->sizeimage = pix->bytesperline * pix->height;
1908	pix->priv = 0;
1909	pix->colorspace = V4L2_COLORSPACE_JPEG;
1910
1911	vout->bpp = RGB565_BPP;
1912	vout->fbuf.fmt.width  =  display->panel.timings.x_res;
1913	vout->fbuf.fmt.height =  display->panel.timings.y_res;
1914
1915	/* Set the data structures for the overlay parameters*/
1916	vout->win.global_alpha = 255;
1917	vout->fbuf.flags = 0;
1918	vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA |
1919		V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY;
1920	vout->win.chromakey = 0;
1921
1922	omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win);
1923
1924	/*Initialize the control variables for
1925	  rotation, flipping and background color. */
1926	control = vout->control;
1927	control[0].id = V4L2_CID_ROTATE;
1928	control[0].value = 0;
1929	vout->rotation = 0;
1930	vout->mirror = 0;
1931	vout->control[2].id = V4L2_CID_HFLIP;
1932	vout->control[2].value = 0;
1933	if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
1934		vout->vrfb_bpp = 2;
1935
1936	control[1].id = V4L2_CID_BG_COLOR;
1937	control[1].value = 0;
1938
1939	/* initialize the video_device struct */
1940	vfd = vout->vfd = video_device_alloc();
1941
1942	if (!vfd) {
1943		printk(KERN_ERR VOUT_NAME ": could not allocate"
1944				" video device struct\n");
1945		return -ENOMEM;
1946	}
1947	vfd->release = video_device_release;
1948	vfd->ioctl_ops = &vout_ioctl_ops;
1949
1950	strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
1951
1952	vfd->fops = &omap_vout_fops;
1953	vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
1954	mutex_init(&vout->lock);
1955
1956	vfd->minor = -1;
1957	return 0;
1958
1959}
1960
1961/* Setup video buffers */
1962static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
1963		int vid_num)
1964{
1965	u32 numbuffers;
1966	int ret = 0, i;
1967	struct omapvideo_info *ovid;
1968	struct omap_vout_device *vout;
1969	struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1970	struct omap2video_device *vid_dev =
1971		container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
1972
1973	vout = vid_dev->vouts[vid_num];
1974	ovid = &vout->vid_info;
1975
1976	numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers;
1977	vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize;
1978	dev_info(&pdev->dev, "Buffer Size = %d\n", vout->buffer_size);
1979
1980	for (i = 0; i < numbuffers; i++) {
1981		vout->buf_virt_addr[i] =
1982			omap_vout_alloc_buffer(vout->buffer_size,
1983					(u32 *) &vout->buf_phy_addr[i]);
1984		if (!vout->buf_virt_addr[i]) {
1985			numbuffers = i;
1986			ret = -ENOMEM;
1987			goto free_buffers;
1988		}
1989	}
1990
1991	vout->cropped_offset = 0;
1992
1993	if (ovid->rotation_type == VOUT_ROT_VRFB) {
1994		int static_vrfb_allocation = (vid_num == 0) ?
1995			vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
1996		ret = omap_vout_setup_vrfb_bufs(pdev, vid_num,
1997				static_vrfb_allocation);
1998	}
1999
2000	return ret;
2001
2002free_buffers:
2003	for (i = 0; i < numbuffers; i++) {
2004		omap_vout_free_buffer(vout->buf_virt_addr[i],
2005						vout->buffer_size);
2006		vout->buf_virt_addr[i] = 0;
2007		vout->buf_phy_addr[i] = 0;
2008	}
2009	return ret;
2010
2011}
2012
2013/* Create video out devices */
2014static int __init omap_vout_create_video_devices(struct platform_device *pdev)
2015{
2016	int ret = 0, k;
2017	struct omap_vout_device *vout;
2018	struct video_device *vfd = NULL;
2019	struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2020	struct omap2video_device *vid_dev = container_of(v4l2_dev,
2021			struct omap2video_device, v4l2_dev);
2022
2023	for (k = 0; k < pdev->num_resources; k++) {
2024
2025		vout = kzalloc(sizeof(struct omap_vout_device), GFP_KERNEL);
2026		if (!vout) {
2027			dev_err(&pdev->dev, ": could not allocate memory\n");
2028			return -ENOMEM;
2029		}
2030
2031		vout->vid = k;
2032		vid_dev->vouts[k] = vout;
2033		vout->vid_dev = vid_dev;
2034		/* Select video2 if only 1 overlay is controlled by V4L2 */
2035		if (pdev->num_resources == 1)
2036			vout->vid_info.overlays[0] = vid_dev->overlays[k + 2];
2037		else
2038			/* Else select video1 and video2 one by one. */
2039			vout->vid_info.overlays[0] = vid_dev->overlays[k + 1];
2040		vout->vid_info.num_overlays = 1;
2041		vout->vid_info.id = k + 1;
2042
2043		/* Set VRFB as rotation_type for omap2 and omap3 */
2044		if (cpu_is_omap24xx() || cpu_is_omap34xx())
2045			vout->vid_info.rotation_type = VOUT_ROT_VRFB;
2046
2047		/* Setup the default configuration for the video devices
2048		 */
2049		if (omap_vout_setup_video_data(vout) != 0) {
2050			ret = -ENOMEM;
2051			goto error;
2052		}
2053
2054		/* Allocate default number of buffers for the video streaming
2055		 * and reserve the VRFB space for rotation
2056		 */
2057		if (omap_vout_setup_video_bufs(pdev, k) != 0) {
2058			ret = -ENOMEM;
2059			goto error1;
2060		}
2061
2062		/* Register the Video device with V4L2
2063		 */
2064		vfd = vout->vfd;
2065		if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) {
2066			dev_err(&pdev->dev, ": Could not register "
2067					"Video for Linux device\n");
2068			vfd->minor = -1;
2069			ret = -ENODEV;
2070			goto error2;
2071		}
2072		video_set_drvdata(vfd, vout);
2073
2074		/* Configure the overlay structure */
2075		ret = omapvid_init(vid_dev->vouts[k], 0);
2076		if (!ret)
2077			goto success;
2078
2079error2:
2080		if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
2081			omap_vout_release_vrfb(vout);
2082		omap_vout_free_buffers(vout);
2083error1:
2084		video_device_release(vfd);
2085error:
2086		kfree(vout);
2087		return ret;
2088
2089success:
2090		dev_info(&pdev->dev, ": registered and initialized"
2091				" video device %d\n", vfd->minor);
2092		if (k == (pdev->num_resources - 1))
2093			return 0;
2094	}
2095
2096	return -ENODEV;
2097}
2098/* Driver functions */
2099static void omap_vout_cleanup_device(struct omap_vout_device *vout)
2100{
2101	struct video_device *vfd;
2102	struct omapvideo_info *ovid;
2103
2104	if (!vout)
2105		return;
2106
2107	vfd = vout->vfd;
2108	ovid = &vout->vid_info;
2109	if (vfd) {
2110		if (!video_is_registered(vfd)) {
2111			/*
2112			 * The device was never registered, so release the
2113			 * video_device struct directly.
2114			 */
2115			video_device_release(vfd);
2116		} else {
2117			/*
2118			 * The unregister function will release the video_device
2119			 * struct as well as unregistering it.
2120			 */
2121			video_unregister_device(vfd);
2122		}
2123	}
2124	if (ovid->rotation_type == VOUT_ROT_VRFB) {
2125		omap_vout_release_vrfb(vout);
2126		/* Free the VRFB buffer if allocated
2127		 * init time
2128		 */
2129		if (vout->vrfb_static_allocation)
2130			omap_vout_free_vrfb_buffers(vout);
2131	}
2132	omap_vout_free_buffers(vout);
2133
2134	kfree(vout);
2135}
2136
2137static int omap_vout_remove(struct platform_device *pdev)
2138{
2139	int k;
2140	struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2141	struct omap2video_device *vid_dev = container_of(v4l2_dev, struct
2142			omap2video_device, v4l2_dev);
2143
2144	v4l2_device_unregister(v4l2_dev);
2145	for (k = 0; k < pdev->num_resources; k++)
2146		omap_vout_cleanup_device(vid_dev->vouts[k]);
2147
2148	for (k = 0; k < vid_dev->num_displays; k++) {
2149		if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED)
2150			vid_dev->displays[k]->driver->disable(vid_dev->displays[k]);
2151
2152		omap_dss_put_device(vid_dev->displays[k]);
2153	}
2154	kfree(vid_dev);
2155	return 0;
2156}
2157
2158static int __init omap_vout_probe(struct platform_device *pdev)
2159{
2160	int ret = 0, i;
2161	struct omap_overlay *ovl;
2162	struct omap_dss_device *dssdev = NULL;
2163	struct omap_dss_device *def_display;
2164	struct omap2video_device *vid_dev = NULL;
2165
2166	if (pdev->num_resources == 0) {
2167		dev_err(&pdev->dev, "probed for an unknown device\n");
2168		return -ENODEV;
2169	}
2170
2171	vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL);
2172	if (vid_dev == NULL)
2173		return -ENOMEM;
2174
2175	vid_dev->num_displays = 0;
2176	for_each_dss_dev(dssdev) {
2177		omap_dss_get_device(dssdev);
2178
2179		if (!dssdev->driver) {
2180			dev_warn(&pdev->dev, "no driver for display: %s\n",
2181					dssdev->name);
2182			omap_dss_put_device(dssdev);
2183			continue;
2184		}
2185
2186		vid_dev->displays[vid_dev->num_displays++] = dssdev;
2187	}
2188
2189	if (vid_dev->num_displays == 0) {
2190		dev_err(&pdev->dev, "no displays\n");
2191		ret = -EINVAL;
2192		goto probe_err0;
2193	}
2194
2195	vid_dev->num_overlays = omap_dss_get_num_overlays();
2196	for (i = 0; i < vid_dev->num_overlays; i++)
2197		vid_dev->overlays[i] = omap_dss_get_overlay(i);
2198
2199	vid_dev->num_managers = omap_dss_get_num_overlay_managers();
2200	for (i = 0; i < vid_dev->num_managers; i++)
2201		vid_dev->managers[i] = omap_dss_get_overlay_manager(i);
2202
2203	/* Get the Video1 overlay and video2 overlay.
2204	 * Setup the Display attached to that overlays
2205	 */
2206	for (i = 1; i < vid_dev->num_overlays; i++) {
2207		ovl = omap_dss_get_overlay(i);
2208		if (ovl->manager && ovl->manager->device) {
2209			def_display = ovl->manager->device;
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		if (ovl->manager && ovl->manager->device)
2257			def_display = ovl->manager->device;
2258
2259		if (def_display && def_display->driver)
2260			def_display->driver->disable(def_display);
2261	}
2262probe_err0:
2263	kfree(vid_dev);
2264	return ret;
2265}
2266
2267static struct platform_driver omap_vout_driver = {
2268	.driver = {
2269		.name = VOUT_NAME,
2270	},
2271	.remove = omap_vout_remove,
2272};
2273
2274static int __init omap_vout_init(void)
2275{
2276	if (platform_driver_probe(&omap_vout_driver, omap_vout_probe) != 0) {
2277		printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
2278		return -EINVAL;
2279	}
2280	return 0;
2281}
2282
2283static void omap_vout_cleanup(void)
2284{
2285	platform_driver_unregister(&omap_vout_driver);
2286}
2287
2288late_initcall(omap_vout_init);
2289module_exit(omap_vout_cleanup);