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