]> err.no Git - linux-2.6/blobdiff - drivers/media/video/ivtv/ivtv-fb.c
V4L/DVB (6090): ivtv-fb: correct transparency bit reporting
[linux-2.6] / drivers / media / video / ivtv / ivtv-fb.c
index 56ce5c08bbb336c065afbda338b590caae1d424a..7618cd47a35de05e85e15806572f05ea8a6f8f79 100644 (file)
 #endif
 
 #include "ivtv-driver.h"
-#include "ivtv-queue.h"
 #include "ivtv-udma.h"
-#include "ivtv-irq.h"
-#include "ivtv-fileops.h"
 #include "ivtv-mailbox.h"
-#include "ivtv-cards.h"
 #include <media/ivtv-fb.h>
 
 /* card parameters */
@@ -164,11 +160,6 @@ MODULE_LICENSE("GPL");
 #define IVTV_OSD_BPP_32     0x04
 
 struct osd_info {
-       /* Timing info for modes */
-       u32 pixclock;
-       u32 hlimit;
-       u32 vlimit;
-
        /* Physical base address */
        unsigned long video_pbase;
        /* Relative base address (relative to start of decoder memory) */
@@ -439,7 +430,7 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
                }
 
                default:
-                       IVTV_FB_ERR("Unknown IOCTL %d\n", cmd);
+                       IVTV_FB_DEBUG_INFO("Unknown ioctl %08x\n", cmd);
                        return -EINVAL;
        }
        return 0;
@@ -579,10 +570,25 @@ static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
 static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
 {
        struct osd_info *oi = itv->osd_info;
-       int osd_height_limit = itv->is_50hz ? 576 : 480;
+       int osd_height_limit;
+       u32 pixclock, hlimit, vlimit;
 
        IVTV_FB_DEBUG_INFO("ivtvfb_check_var\n");
 
+       /* Set base references for mode calcs. */
+       if (itv->is_50hz) {
+               pixclock = 84316;
+               hlimit = 776;
+               vlimit = 591;
+               osd_height_limit = 576;
+       }
+       else {
+               pixclock = 83926;
+               hlimit = 776;
+               vlimit = 495;
+               osd_height_limit = 480;
+       }
+
        /* Check the bits per pixel */
        if (osd_compat) {
                if (var->bits_per_pixel != 32) {
@@ -602,9 +608,6 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
                var->blue.length = 8;
        }
        else if (var->bits_per_pixel == 16) {
-               var->transp.offset = 0;
-               var->transp.length = 0;
-
                /* To find out the true mode, check green length */
                switch (var->green.length) {
                        case 4:
@@ -614,6 +617,8 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
                                var->green.length = 4;
                                var->blue.offset = 0;
                                var->blue.length = 4;
+                               var->transp.offset = 12;
+                               var->transp.length = 1;
                                break;
                        case 5:
                                var->red.offset = 10;
@@ -622,6 +627,8 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
                                var->green.length = 5;
                                var->blue.offset = 0;
                                var->blue.length = 5;
+                               var->transp.offset = 15;
+                               var->transp.length = 1;
                                break;
                        default:
                                var->red.offset = 11;
@@ -630,6 +637,8 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
                                var->green.length = 6;
                                var->blue.offset = 0;
                                var->blue.length = 5;
+                               var->transp.offset = 0;
+                               var->transp.length = 0;
                                break;
                }
        }
@@ -723,8 +732,8 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
        }
 
        /* Maintain overall 'size' for a constant refresh rate */
-       var->right_margin = oi->hlimit - var->left_margin - var->xres;
-       var->lower_margin = oi->vlimit - var->upper_margin - var->yres;
+       var->right_margin = hlimit - var->left_margin - var->xres;
+       var->lower_margin = vlimit - var->upper_margin - var->yres;
 
        /* Fixed sync times */
        var->hsync_len = 24;
@@ -733,9 +742,10 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
        /* Non-interlaced / interlaced mode is used to switch the OSD filter
           on or off. Adjust the clock timings to maintain a constant
           vertical refresh rate. */
-       var->pixclock = oi->pixclock;
        if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
-               var->pixclock /= 2;
+               var->pixclock = pixclock / 2;
+       else
+               var->pixclock = pixclock;
 
        IVTV_FB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
                      var->xres, var->yres,
@@ -875,18 +885,6 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
        struct v4l2_rect start_window;
        int max_height;
 
-       /* Set base references for mode calcs. */
-       if (itv->is_50hz) {
-               oi->pixclock = 84316;
-               oi->hlimit = 776;
-               oi->vlimit = 591;
-       }
-       else {
-               oi->pixclock = 83926;
-               oi->hlimit = 776;
-               oi->vlimit = 495;
-       }
-
        /* Color mode */
 
        if (osd_compat) osd_depth = 32;
@@ -1013,6 +1011,11 @@ static int ivtvfb_init_io(struct ivtv *itv)
 {
        struct osd_info *oi = itv->osd_info;
 
+       if (ivtv_init_on_first_open(itv)) {
+               IVTV_FB_ERR("Failed to initialize ivtv\n");
+               return -ENXIO;
+       }
+
        ivtv_fb_get_framebuffer(itv, &oi->video_rbase, &oi->video_buffer_size);
 
        /* The osd buffer size depends on the number of video buffers allocated