diff options
Diffstat (limited to 'drivers/media/video/ivtv/ivtvfb.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtvfb.c | 92 |
1 files changed, 25 insertions, 67 deletions
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index 9684048fe56c..52ffd154a3d8 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c | |||
@@ -55,7 +55,6 @@ | |||
55 | static int ivtvfb_card_id = -1; | 55 | static int ivtvfb_card_id = -1; |
56 | static int ivtvfb_debug = 0; | 56 | static int ivtvfb_debug = 0; |
57 | static int osd_laced; | 57 | static int osd_laced; |
58 | static int osd_compat; | ||
59 | static int osd_depth; | 58 | static int osd_depth; |
60 | static int osd_upper; | 59 | static int osd_upper; |
61 | static int osd_left; | 60 | static int osd_left; |
@@ -65,7 +64,6 @@ static int osd_xres; | |||
65 | module_param(ivtvfb_card_id, int, 0444); | 64 | module_param(ivtvfb_card_id, int, 0444); |
66 | module_param_named(debug,ivtvfb_debug, int, 0644); | 65 | module_param_named(debug,ivtvfb_debug, int, 0644); |
67 | module_param(osd_laced, bool, 0444); | 66 | module_param(osd_laced, bool, 0444); |
68 | module_param(osd_compat, bool, 0444); | ||
69 | module_param(osd_depth, int, 0444); | 67 | module_param(osd_depth, int, 0444); |
70 | module_param(osd_upper, int, 0444); | 68 | module_param(osd_upper, int, 0444); |
71 | module_param(osd_left, int, 0444); | 69 | module_param(osd_left, int, 0444); |
@@ -80,12 +78,6 @@ MODULE_PARM_DESC(debug, | |||
80 | "Debug level (bitmask). Default: errors only\n" | 78 | "Debug level (bitmask). Default: errors only\n" |
81 | "\t\t\t(debug = 3 gives full debugging)"); | 79 | "\t\t\t(debug = 3 gives full debugging)"); |
82 | 80 | ||
83 | MODULE_PARM_DESC(osd_compat, | ||
84 | "Compatibility mode - Display size is locked (use for old X drivers)\n" | ||
85 | "\t\t\t0=off\n" | ||
86 | "\t\t\t1=on\n" | ||
87 | "\t\t\tdefault off"); | ||
88 | |||
89 | /* Why upper, left, xres, yres, depth, laced ? To match terminology used | 81 | /* Why upper, left, xres, yres, depth, laced ? To match terminology used |
90 | by fbset. | 82 | by fbset. |
91 | Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */ | 83 | Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */ |
@@ -166,9 +158,6 @@ struct osd_info { | |||
166 | unsigned long fb_end_aligned_physaddr; | 158 | unsigned long fb_end_aligned_physaddr; |
167 | #endif | 159 | #endif |
168 | 160 | ||
169 | /* Current osd mode */ | ||
170 | int osd_mode; | ||
171 | |||
172 | /* Store the buffer offset */ | 161 | /* Store the buffer offset */ |
173 | int set_osd_coords_x; | 162 | int set_osd_coords_x; |
174 | int set_osd_coords_y; | 163 | int set_osd_coords_y; |
@@ -470,13 +459,11 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) | |||
470 | IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); | 459 | IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); |
471 | } | 460 | } |
472 | 461 | ||
473 | /* Change osd mode if needed. | 462 | /* Set video mode. Although rare, the display can become scrambled even |
474 | Although rare, things can go wrong. The extra mode | 463 | if we don't change mode. Always 'bounce' to osd_mode via mode 0 */ |
475 | change seems to help... */ | 464 | if (osd_mode != -1) { |
476 | if (osd_mode != -1 && osd_mode != oi->osd_mode) { | ||
477 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); | 465 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); |
478 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode); | 466 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode); |
479 | oi->osd_mode = osd_mode; | ||
480 | } | 467 | } |
481 | 468 | ||
482 | oi->bits_per_pixel = var->bits_per_pixel; | 469 | oi->bits_per_pixel = var->bits_per_pixel; |
@@ -579,14 +566,6 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv) | |||
579 | osd_height_limit = 480; | 566 | osd_height_limit = 480; |
580 | } | 567 | } |
581 | 568 | ||
582 | /* Check the bits per pixel */ | ||
583 | if (osd_compat) { | ||
584 | if (var->bits_per_pixel != 32) { | ||
585 | IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | } | ||
589 | |||
590 | if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) { | 569 | if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) { |
591 | var->transp.offset = 24; | 570 | var->transp.offset = 24; |
592 | var->transp.length = 8; | 571 | var->transp.length = 8; |
@@ -638,32 +617,20 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv) | |||
638 | } | 617 | } |
639 | 618 | ||
640 | /* Check the resolution */ | 619 | /* Check the resolution */ |
641 | if (osd_compat) { | 620 | if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) { |
642 | if (var->xres != oi->ivtvfb_defined.xres || | 621 | IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n", |
643 | var->yres != oi->ivtvfb_defined.yres || | 622 | var->xres, var->yres); |
644 | var->xres_virtual != oi->ivtvfb_defined.xres_virtual || | 623 | return -EINVAL; |
645 | var->yres_virtual != oi->ivtvfb_defined.yres_virtual) { | ||
646 | IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d (virtual %dx%d)\n", | ||
647 | var->xres, var->yres, var->xres_virtual, var->yres_virtual); | ||
648 | return -EINVAL; | ||
649 | } | ||
650 | } | 624 | } |
651 | else { | ||
652 | if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) { | ||
653 | IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n", | ||
654 | var->xres, var->yres); | ||
655 | return -EINVAL; | ||
656 | } | ||
657 | 625 | ||
658 | /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */ | 626 | /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */ |
659 | if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) || | 627 | if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) || |
660 | var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size || | 628 | var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size || |
661 | var->xres_virtual < var->xres || | 629 | var->xres_virtual < var->xres || |
662 | var->yres_virtual < var->yres) { | 630 | var->yres_virtual < var->yres) { |
663 | IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n", | 631 | IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n", |
664 | var->xres_virtual, var->yres_virtual); | 632 | var->xres_virtual, var->yres_virtual); |
665 | return -EINVAL; | 633 | return -EINVAL; |
666 | } | ||
667 | } | 634 | } |
668 | 635 | ||
669 | /* Some extra checks if in 8 bit mode */ | 636 | /* Some extra checks if in 8 bit mode */ |
@@ -877,17 +844,15 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) | |||
877 | 844 | ||
878 | /* Color mode */ | 845 | /* Color mode */ |
879 | 846 | ||
880 | if (osd_compat) osd_depth = 32; | 847 | if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) |
881 | if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) osd_depth = 8; | 848 | osd_depth = 8; |
882 | oi->bits_per_pixel = osd_depth; | 849 | oi->bits_per_pixel = osd_depth; |
883 | oi->bytes_per_pixel = oi->bits_per_pixel / 8; | 850 | oi->bytes_per_pixel = oi->bits_per_pixel / 8; |
884 | 851 | ||
885 | /* Invalidate current osd mode to force a mode switch later */ | ||
886 | oi->osd_mode = -1; | ||
887 | |||
888 | /* Horizontal size & position */ | 852 | /* Horizontal size & position */ |
889 | 853 | ||
890 | if (osd_xres > 720) osd_xres = 720; | 854 | if (osd_xres > 720) |
855 | osd_xres = 720; | ||
891 | 856 | ||
892 | /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */ | 857 | /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */ |
893 | if (osd_depth == 8) | 858 | if (osd_depth == 8) |
@@ -895,10 +860,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) | |||
895 | else if (osd_depth == 16) | 860 | else if (osd_depth == 16) |
896 | osd_xres &= ~1; | 861 | osd_xres &= ~1; |
897 | 862 | ||
898 | if (osd_xres) | 863 | start_window.width = osd_xres ? osd_xres : 640; |
899 | start_window.width = osd_xres; | ||
900 | else | ||
901 | start_window.width = osd_compat ? 720: 640; | ||
902 | 864 | ||
903 | /* Check horizontal start (osd_left). */ | 865 | /* Check horizontal start (osd_left). */ |
904 | if (osd_left && osd_left + start_window.width > 721) { | 866 | if (osd_left && osd_left + start_window.width > 721) { |
@@ -921,10 +883,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) | |||
921 | if (osd_yres > max_height) | 883 | if (osd_yres > max_height) |
922 | osd_yres = max_height; | 884 | osd_yres = max_height; |
923 | 885 | ||
924 | if (osd_yres) | 886 | start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400; |
925 | start_window.height = osd_yres; | ||
926 | else | ||
927 | start_window.height = osd_compat ? max_height : (itv->is_50hz ? 480 : 400); | ||
928 | 887 | ||
929 | /* Check vertical start (osd_upper). */ | 888 | /* Check vertical start (osd_upper). */ |
930 | if (osd_upper + start_window.height > max_height + 1) { | 889 | if (osd_upper + start_window.height > max_height + 1) { |
@@ -1127,10 +1086,6 @@ static int ivtvfb_init_card(struct ivtv *itv) | |||
1127 | /* Enable the osd */ | 1086 | /* Enable the osd */ |
1128 | ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info); | 1087 | ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info); |
1129 | 1088 | ||
1130 | /* Note if we're running in compatibility mode */ | ||
1131 | if (osd_compat) | ||
1132 | IVTVFB_INFO("Running in compatibility mode. Display resize & mode change disabled\n"); | ||
1133 | |||
1134 | /* Allocate DMA */ | 1089 | /* Allocate DMA */ |
1135 | ivtv_udma_alloc(itv); | 1090 | ivtv_udma_alloc(itv); |
1136 | return 0; | 1091 | return 0; |
@@ -1177,9 +1132,12 @@ static void ivtvfb_cleanup(void) | |||
1177 | for (i = 0; i < ivtv_cards_active; i++) { | 1132 | for (i = 0; i < ivtv_cards_active; i++) { |
1178 | itv = ivtv_cards[i]; | 1133 | itv = ivtv_cards[i]; |
1179 | if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) { | 1134 | if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) { |
1135 | if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { | ||
1136 | IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", i); | ||
1137 | return; | ||
1138 | } | ||
1180 | IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i); | 1139 | IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i); |
1181 | ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); | 1140 | ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); |
1182 | unregister_framebuffer(&itv->osd_info->ivtvfb_info); | ||
1183 | ivtvfb_release_buffers(itv); | 1141 | ivtvfb_release_buffers(itv); |
1184 | itv->osd_video_pbase = 0; | 1142 | itv->osd_video_pbase = 0; |
1185 | } | 1143 | } |