aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-fb.c
diff options
context:
space:
mode:
authorIan Armstrong <ian@iarmst.co.uk>2007-07-21 15:43:36 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:03:08 -0400
commitaaf9fa21b684509973dd593e30423fc0a6a5e7a3 (patch)
tree404e36cfcdd643dcfa261327da336c57db0b9c05 /drivers/media/video/ivtv/ivtv-fb.c
parent84149a0f70a73385ee7fbb77024544cbed4fe16d (diff)
V4L/DVB (5908): ivtv-fb: cleanups, prevent fw calls in some cases
Signed-off-by: Ian Armstrong <ian@iarmst.co.uk> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-fb.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-fb.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fb.c b/drivers/media/video/ivtv/ivtv-fb.c
index 6f5da57299a1..56ce5c08bbb3 100644
--- a/drivers/media/video/ivtv/ivtv-fb.c
+++ b/drivers/media/video/ivtv/ivtv-fb.c
@@ -185,6 +185,9 @@ struct osd_info {
185 unsigned long fb_end_aligned_physaddr; 185 unsigned long fb_end_aligned_physaddr;
186#endif 186#endif
187 187
188 /* Current osd mode */
189 int osd_mode;
190
188 /* Store the buffer offset */ 191 /* Store the buffer offset */
189 int set_osd_coords_x; 192 int set_osd_coords_x;
190 int set_osd_coords_y; 193 int set_osd_coords_y;
@@ -350,6 +353,7 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
350 unsigned long dest_offset, int count) 353 unsigned long dest_offset, int count)
351{ 354{
352 DEFINE_WAIT(wait); 355 DEFINE_WAIT(wait);
356 struct osd_info *oi = itv->osd_info;
353 357
354 /* Nothing to do */ 358 /* Nothing to do */
355 if (count == 0) { 359 if (count == 0) {
@@ -358,9 +362,9 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
358 } 362 }
359 363
360 /* Check Total FB Size */ 364 /* Check Total FB Size */
361 if ((dest_offset + count) > itv->osd_info->video_buffer_size) { 365 if ((dest_offset + count) > oi->video_buffer_size) {
362 IVTV_FB_WARN("ivtv_fb_prep_frame: Overflowing the framebuffer %ld, only %d available\n", 366 IVTV_FB_WARN("ivtv_fb_prep_frame: Overflowing the framebuffer %ld, only %d available\n",
363 dest_offset + count, itv->osd_info->video_buffer_size); 367 dest_offset + count, oi->video_buffer_size);
364 return -E2BIG; 368 return -E2BIG;
365 } 369 }
366 370
@@ -387,7 +391,7 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
387 } 391 }
388 392
389 /* OSD Address to send DMA to */ 393 /* OSD Address to send DMA to */
390 dest_offset += IVTV_DEC_MEM_START + itv->osd_info->video_rbase; 394 dest_offset += IVTV_DEC_MEM_START + oi->video_rbase;
391 395
392 /* Fill Buffers */ 396 /* Fill Buffers */
393 return ivtv_fb_prep_dec_dma_to_device(itv, dest_offset, source, count); 397 return ivtv_fb_prep_dec_dma_to_device(itv, dest_offset, source, count);
@@ -445,8 +449,10 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
445 449
446static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) 450static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
447{ 451{
452 struct osd_info *oi = itv->osd_info;
448 struct ivtv_osd_coords ivtv_osd; 453 struct ivtv_osd_coords ivtv_osd;
449 struct v4l2_rect ivtv_window; 454 struct v4l2_rect ivtv_window;
455 int osd_mode = -1;
450 456
451 IVTV_FB_DEBUG_INFO("ivtvfb_set_var\n"); 457 IVTV_FB_DEBUG_INFO("ivtvfb_set_var\n");
452 458
@@ -456,32 +462,24 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
456 else /* RGB */ 462 else /* RGB */
457 write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00); 463 write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00);
458 464
459 /* Set the color mode 465 /* Set the color mode */
460 Although rare, occasionally things go wrong. The extra mode
461 change seems to help... */
462
463 switch (var->bits_per_pixel) { 466 switch (var->bits_per_pixel) {
464 case 8: 467 case 8:
465 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); 468 osd_mode = IVTV_OSD_BPP_8;
466 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_8);
467 break; 469 break;
468 case 32: 470 case 32:
469 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); 471 osd_mode = IVTV_OSD_BPP_32;
470 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_32);
471 break; 472 break;
472 case 16: 473 case 16:
473 switch (var->green.length) { 474 switch (var->green.length) {
474 case 4: 475 case 4:
475 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); 476 osd_mode = IVTV_OSD_BPP_16_444;
476 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_16_444);
477 break; 477 break;
478 case 5: 478 case 5:
479 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); 479 osd_mode = IVTV_OSD_BPP_16_555;
480 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_16_555);
481 break; 480 break;
482 case 6: 481 case 6:
483 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); 482 osd_mode = IVTV_OSD_BPP_16_565;
484 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_16_565);
485 break; 483 break;
486 default: 484 default:
487 IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); 485 IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
@@ -491,8 +489,17 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
491 IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); 489 IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
492 } 490 }
493 491
494 itv->osd_info->bits_per_pixel = var->bits_per_pixel; 492 /* Change osd mode if needed.
495 itv->osd_info->bytes_per_pixel = var->bits_per_pixel / 8; 493 Although rare, things can go wrong. The extra mode
494 change seems to help... */
495 if (osd_mode != -1 && osd_mode != oi->osd_mode) {
496 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
497 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
498 oi->osd_mode = osd_mode;
499 }
500
501 oi->bits_per_pixel = var->bits_per_pixel;
502 oi->bytes_per_pixel = var->bits_per_pixel / 8;
496 503
497 /* Set the flicker filter */ 504 /* Set the flicker filter */
498 switch (var->vmode & FB_VMODE_MASK) { 505 switch (var->vmode & FB_VMODE_MASK) {
@@ -887,6 +894,9 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
887 oi->bits_per_pixel = osd_depth; 894 oi->bits_per_pixel = osd_depth;
888 oi->bytes_per_pixel = oi->bits_per_pixel / 8; 895 oi->bytes_per_pixel = oi->bits_per_pixel / 8;
889 896
897 /* Invalidate current osd mode to force a mode switch later */
898 oi->osd_mode = -1;
899
890 /* Horizontal size & position */ 900 /* Horizontal size & position */
891 901
892 if (osd_xres > 720) osd_xres = 720; 902 if (osd_xres > 720) osd_xres = 720;