Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart
[pandora-kernel.git] / drivers / media / video / cx2341x.c
index 7cd1c4c..2f5ca71 100644 (file)
@@ -43,6 +43,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
 const u32 cx2341x_mpeg_ctrls[] = {
        V4L2_CID_MPEG_CLASS,
        V4L2_CID_MPEG_STREAM_TYPE,
+       V4L2_CID_MPEG_STREAM_VBI_FMT,
        V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
        V4L2_CID_MPEG_AUDIO_ENCODING,
        V4L2_CID_MPEG_AUDIO_L2_BITRATE,
@@ -135,6 +136,9 @@ static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
        case V4L2_CID_MPEG_STREAM_TYPE:
                ctrl->value = params->stream_type;
                break;
+       case V4L2_CID_MPEG_STREAM_VBI_FMT:
+               ctrl->value = params->stream_vbi_fmt;
+               break;
        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
                ctrl->value = params->video_spatial_filter_mode;
                break;
@@ -257,6 +261,9 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
                        params->video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
                }
                break;
+       case V4L2_CID_MPEG_STREAM_VBI_FMT:
+               params->stream_vbi_fmt = ctrl->value;
+               break;
        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
                params->video_spatial_filter_mode = ctrl->value;
                break;
@@ -418,6 +425,14 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, struct v4l2_queryctrl
                        qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
                return err;
 
+       case V4L2_CID_MPEG_STREAM_VBI_FMT:
+               if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
+                       return v4l2_ctrl_query_fill_std(qctrl);
+               return cx2341x_ctrl_query_fill(qctrl,
+                               V4L2_MPEG_STREAM_VBI_FMT_NONE,
+                               V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
+                               V4L2_MPEG_STREAM_VBI_FMT_NONE);
+
        /* CX23415/6 specific */
        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
                return cx2341x_ctrl_query_fill(qctrl,
@@ -586,7 +601,7 @@ static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
 }
 
 int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params,
-                 struct v4l2_ext_controls *ctrls, int cmd)
+                 struct v4l2_ext_controls *ctrls, unsigned int cmd)
 {
        int err = 0;
        int i;
@@ -639,12 +654,15 @@ void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
 {
        static struct cx2341x_mpeg_params default_params = {
        /* misc */
+       .capabilities = 0,
+       .port = CX2341X_PORT_MEMORY,
        .width = 720,
        .height = 480,
        .is_50hz = 0,
 
        /* stream */
        .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
+       .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
 
        /* audio */
        .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
@@ -673,7 +691,7 @@ void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
        .video_luma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
        .video_chroma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
        .video_temporal_filter_mode = V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
-       .video_temporal_filter = 0,
+       .video_temporal_filter = 8,
        .video_median_filter_type = V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
        .video_luma_median_filter_top = 255,
        .video_luma_median_filter_bottom = 0,
@@ -713,8 +731,9 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
        };
 
        int err = 0;
+       u16 temporal = new->video_temporal_filter;
 
-       cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 1, 0);     /* 0 = Memory */
+       cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
 
        if (old == NULL || old->is_50hz != new->is_50hz) {
                err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1, new->is_50hz);
@@ -734,6 +753,18 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
                if (err) return err;
        }
 
+       if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
+               /* Adjust temporal filter if necessary. The problem with the temporal
+                  filter is that it works well with full resolution capturing, but
+                  not when the capture window is scaled (the filter introduces
+                  a ghosting effect). So if the capture window is scaled, then
+                  force the filter to 0.
+
+                  For full resolution the filter really improves the video
+                  quality, especially if the original video quality is suboptimal. */
+               temporal = 0;
+       }
+
        if (old == NULL || old->stream_type != new->stream_type) {
                err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[new->stream_type]);
                if (err) return err;
@@ -797,9 +828,9 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
        }
        if (old == NULL ||
                old->video_spatial_filter != new->video_spatial_filter ||
-               old->video_temporal_filter != new->video_temporal_filter) {
+               old->video_temporal_filter != temporal) {
                err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2,
-                       new->video_spatial_filter, new->video_temporal_filter);
+                       new->video_spatial_filter, temporal);
                if (err) return err;
        }
        if (old == NULL || old->video_temporal_decimation != new->video_temporal_decimation) {
@@ -829,22 +860,26 @@ invalid:
        return "<invalid>";
 }
 
-void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id)
+void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
 {
        int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
+       int temporal = p->video_temporal_filter;
 
        /* Stream */
-       printk(KERN_INFO "cx2341x-%d: Stream: %s\n",
-               card_id,
+       printk(KERN_INFO "%s: Stream: %s\n",
+               prefix,
                cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
+       printk(KERN_INFO "%s: VBI Format: %s\n",
+               prefix,
+               cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
 
        /* Video */
-       printk(KERN_INFO "cx2341x-%d: Video:  %dx%d, %d fps\n",
-               card_id,
+       printk(KERN_INFO "%s: Video:  %dx%d, %d fps\n",
+               prefix,
                p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
                p->is_50hz ? 25 : 30);
-       printk(KERN_INFO "cx2341x-%d: Video:  %s, %s, %s, %d",
-               card_id,
+       printk(KERN_INFO "%s: Video:  %s, %s, %s, %d",
+               prefix,
                cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
                cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
                cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
@@ -853,19 +888,19 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id)
                printk(", Peak %d", p->video_bitrate_peak);
        }
        printk("\n");
-       printk(KERN_INFO "cx2341x-%d: Video:  GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n",
-               card_id,
+       printk(KERN_INFO "%s: Video:  GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n",
+               prefix,
                p->video_gop_size, p->video_b_frames,
                p->video_gop_closure ? "" : "No ",
                p->video_pulldown ? "" : "No ");
        if (p->video_temporal_decimation) {
-               printk(KERN_INFO "cx2341x-%d: Video: Temporal Decimation %d\n",
-                       card_id, p->video_temporal_decimation);
+               printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
+                       prefix, p->video_temporal_decimation);
        }
 
        /* Audio */
-       printk(KERN_INFO "cx2341x-%d: Audio:  %s, %s, %s, %s",
-               card_id,
+       printk(KERN_INFO "%s: Audio:  %s, %s, %s, %s",
+               prefix,
                cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
                cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
                cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
@@ -879,18 +914,21 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id)
                cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
 
        /* Encoding filters */
-       printk(KERN_INFO "cx2341x-%d: Spatial Filter:  %s, Luma %s, Chroma %s, %d\n",
-               card_id,
+       printk(KERN_INFO "%s: Spatial Filter:  %s, Luma %s, Chroma %s, %d\n",
+               prefix,
                cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
                cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
                cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
                p->video_spatial_filter);
-       printk(KERN_INFO "cx2341x-%d: Temporal Filter: %s, %d\n",
-               card_id,
+       if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480)) {
+               temporal = 0;
+       }
+       printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
+               prefix,
                cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
-               p->video_temporal_filter);
-       printk(KERN_INFO "cx2341x-%d: Median Filter:   %s, Luma [%d, %d], Chroma [%d, %d]\n",
-               card_id,
+               temporal);
+       printk(KERN_INFO "%s: Median Filter:   %s, Luma [%d, %d], Chroma [%d, %d]\n",
+               prefix,
                cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
                p->video_luma_median_filter_bottom,
                p->video_luma_median_filter_top,