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