Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
[cascardo/linux.git] / drivers / media / platform / davinci / vpif_capture.c
index 1e4ec69..b054b7e 100644 (file)
@@ -39,32 +39,10 @@ MODULE_VERSION(VPIF_CAPTURE_VERSION);
                v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
 
 static int debug = 1;
-static u32 ch0_numbuffers = 3;
-static u32 ch1_numbuffers = 3;
-static u32 ch0_bufsize = 1920 * 1080 * 2;
-static u32 ch1_bufsize = 720 * 576 * 2;
 
 module_param(debug, int, 0644);
-module_param(ch0_numbuffers, uint, S_IRUGO);
-module_param(ch1_numbuffers, uint, S_IRUGO);
-module_param(ch0_bufsize, uint, S_IRUGO);
-module_param(ch1_bufsize, uint, S_IRUGO);
 
 MODULE_PARM_DESC(debug, "Debug level 0-1");
-MODULE_PARM_DESC(ch2_numbuffers, "Channel0 buffer count (default:3)");
-MODULE_PARM_DESC(ch3_numbuffers, "Channel1 buffer count (default:3)");
-MODULE_PARM_DESC(ch2_bufsize, "Channel0 buffer size (default:1920 x 1080 x 2)");
-MODULE_PARM_DESC(ch3_bufsize, "Channel1 buffer size (default:720 x 576 x 2)");
-
-static struct vpif_config_params config_params = {
-       .min_numbuffers = 3,
-       .numbuffers[0] = 3,
-       .numbuffers[1] = 3,
-       .min_bufsize[0] = 720 * 480 * 2,
-       .min_bufsize[1] = 720 * 480 * 2,
-       .channel_bufsize[0] = 1920 * 1080 * 2,
-       .channel_bufsize[1] = 720 * 576 * 2,
-};
 
 #define VPIF_DRIVER_NAME       "vpif_capture"
 
@@ -521,10 +499,28 @@ static int vpif_update_std_info(struct channel_obj *ch)
        common->width = std_info->width;
        common->fmt.fmt.pix.height = std_info->height;
        common->height = std_info->height;
+       common->fmt.fmt.pix.sizeimage = common->height * common->width * 2;
        common->fmt.fmt.pix.bytesperline = std_info->width;
        vpifparams->video_params.hpitch = std_info->width;
        vpifparams->video_params.storage_mode = std_info->frm_fmt;
 
+       if (vid_ch->stdid)
+               common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+       else
+               common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+
+       if (ch->vpifparams.std_info.frm_fmt)
+               common->fmt.fmt.pix.field = V4L2_FIELD_NONE;
+       else
+               common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+       if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
+               common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
+       else
+               common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
+
+       common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
        return 0;
 }
 
@@ -600,27 +596,6 @@ static void vpif_calculate_offsets(struct channel_obj *ch)
        ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
 }
 
-/**
- * vpif_config_format: configure default frame format in the device
- * ch : ptr to channel object
- */
-static void vpif_config_format(struct channel_obj *ch)
-{
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
-       vpif_dbg(2, debug, "vpif_config_format\n");
-
-       common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
-       common->fmt.fmt.pix.sizeimage
-           = config_params.channel_bufsize[ch->channel_id];
-
-       if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
-               common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
-       else
-               common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
-       common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-}
-
 /**
  * vpif_get_default_field() - Get default field type based on interface
  * @vpif_params - ptr to vpif params
@@ -632,112 +607,6 @@ static inline enum v4l2_field vpif_get_default_field(
                                                V4L2_FIELD_INTERLACED;
 }
 
-/**
- * vpif_check_format()  - check given pixel format for compatibility
- * @ch - channel  ptr
- * @pixfmt - Given pixel format
- * @update - update the values as per hardware requirement
- *
- * Check the application pixel format for S_FMT and update the input
- * values as per hardware limits for TRY_FMT. The default pixel and
- * field format is selected based on interface type.
- */
-static int vpif_check_format(struct channel_obj *ch,
-                            struct v4l2_pix_format *pixfmt,
-                            int update)
-{
-       struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
-       struct vpif_params *vpif_params = &ch->vpifparams;
-       enum v4l2_field field = pixfmt->field;
-       u32 sizeimage, hpitch, vpitch;
-       int ret = -EINVAL;
-
-       vpif_dbg(2, debug, "vpif_check_format\n");
-       /**
-        * first check for the pixel format. If if_type is Raw bayer,
-        * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only
-        * V4L2_PIX_FMT_YUV422P is supported
-        */
-       if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
-               if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) {
-                       if (!update) {
-                               vpif_dbg(2, debug, "invalid pix format\n");
-                               goto exit;
-                       }
-                       pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
-               }
-       } else {
-               if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) {
-                       if (!update) {
-                               vpif_dbg(2, debug, "invalid pixel format\n");
-                               goto exit;
-                       }
-                       pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
-               }
-       }
-
-       if (!(VPIF_VALID_FIELD(field))) {
-               if (!update) {
-                       vpif_dbg(2, debug, "invalid field format\n");
-                       goto exit;
-               }
-               /**
-                * By default use FIELD_NONE for RAW Bayer capture
-                * and FIELD_INTERLACED for other interfaces
-                */
-               field = vpif_get_default_field(&vpif_params->iface);
-       } else if (field == V4L2_FIELD_ANY)
-               /* unsupported field. Use default */
-               field = vpif_get_default_field(&vpif_params->iface);
-
-       /* validate the hpitch */
-       hpitch = pixfmt->bytesperline;
-       if (hpitch < vpif_params->std_info.width) {
-               if (!update) {
-                       vpif_dbg(2, debug, "invalid hpitch\n");
-                       goto exit;
-               }
-               hpitch = vpif_params->std_info.width;
-       }
-
-       sizeimage = pixfmt->sizeimage;
-
-       vpitch = sizeimage / (hpitch * 2);
-
-       /* validate the vpitch */
-       if (vpitch < vpif_params->std_info.height) {
-               if (!update) {
-                       vpif_dbg(2, debug, "Invalid vpitch\n");
-                       goto exit;
-               }
-               vpitch = vpif_params->std_info.height;
-       }
-
-       /* Check for 8 byte alignment */
-       if (!ALIGN(hpitch, 8)) {
-               if (!update) {
-                       vpif_dbg(2, debug, "invalid pitch alignment\n");
-                       goto exit;
-               }
-               /* adjust to next 8 byte boundary */
-               hpitch = (((hpitch + 7) / 8) * 8);
-       }
-       /* if update is set, modify the bytesperline and sizeimage */
-       if (update) {
-               pixfmt->bytesperline = hpitch;
-               pixfmt->sizeimage = hpitch * vpitch * 2;
-       }
-       /**
-        * Image width and height is always based on current standard width and
-        * height
-        */
-       pixfmt->width = common->fmt.fmt.pix.width;
-       pixfmt->height = common->fmt.fmt.pix.height;
-       return 0;
-exit:
-       return ret;
-}
-
 /**
  * vpif_config_addr() - function to configure buffer address in vpif
  * @ch - channel ptr
@@ -948,9 +817,6 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
                return -EINVAL;
        }
 
-       /* Configure the default format information */
-       vpif_config_format(ch);
-
        /* set standard in the sub device */
        ret = v4l2_subdev_call(ch->sd, video, s_std, std_id);
        if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
@@ -977,10 +843,8 @@ static int vpif_enum_input(struct file *file, void *priv,
 
        chan_cfg = &config->chan_config[ch->channel_id];
 
-       if (input->index >= chan_cfg->input_count) {
-               vpif_dbg(1, debug, "Invalid input index\n");
+       if (input->index >= chan_cfg->input_count)
                return -EINVAL;
-       }
 
        memcpy(input, &chan_cfg->inputs[input->index].input,
                sizeof(*input));
@@ -1069,8 +933,34 @@ static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
        struct video_device *vdev = video_devdata(file);
        struct channel_obj *ch = video_get_drvdata(vdev);
        struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+       struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
+       struct vpif_params *vpif_params = &ch->vpifparams;
 
-       return vpif_check_format(ch, pixfmt, 1);
+       /*
+        * to supress v4l-compliance warnings silently correct
+        * the pixelformat
+        */
+       if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
+               if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8)
+                       pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
+       } else {
+               if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
+                       pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
+       }
+
+       common->fmt.fmt.pix.pixelformat = pixfmt->pixelformat;
+
+       vpif_update_std_info(ch);
+
+       pixfmt->field = common->fmt.fmt.pix.field;
+       pixfmt->colorspace = common->fmt.fmt.pix.colorspace;
+       pixfmt->bytesperline = common->fmt.fmt.pix.width;
+       pixfmt->width = common->fmt.fmt.pix.width;
+       pixfmt->height = common->fmt.fmt.pix.height;
+       pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;
+       pixfmt->priv = 0;
+
+       return 0;
 }
 
 
@@ -1108,20 +998,17 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
        struct video_device *vdev = video_devdata(file);
        struct channel_obj *ch = video_get_drvdata(vdev);
        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct v4l2_pix_format *pixfmt;
-       int ret = 0;
+       int ret;
 
        vpif_dbg(2, debug, "%s\n", __func__);
 
        if (vb2_is_busy(&common->buffer_queue))
                return -EBUSY;
 
-       pixfmt = &fmt->fmt.pix;
-       /* Check for valid field format */
-       ret = vpif_check_format(ch, pixfmt, 0);
-
+       ret = vpif_try_fmt_vid_cap(file, priv, fmt);
        if (ret)
                return ret;
+
        /* store the format in the channel object */
        common->fmt = *fmt;
        return 0;
@@ -1411,36 +1298,9 @@ static struct v4l2_file_operations vpif_fops = {
  */
 static int initialize_vpif(void)
 {
-       int err = 0, i, j;
+       int err, i, j;
        int free_channel_objects_index;
 
-       /* Default number of buffers should be 3 */
-       if ((ch0_numbuffers > 0) &&
-           (ch0_numbuffers < config_params.min_numbuffers))
-               ch0_numbuffers = config_params.min_numbuffers;
-       if ((ch1_numbuffers > 0) &&
-           (ch1_numbuffers < config_params.min_numbuffers))
-               ch1_numbuffers = config_params.min_numbuffers;
-
-       /* Set buffer size to min buffers size if it is invalid */
-       if (ch0_bufsize < config_params.min_bufsize[VPIF_CHANNEL0_VIDEO])
-               ch0_bufsize =
-                   config_params.min_bufsize[VPIF_CHANNEL0_VIDEO];
-       if (ch1_bufsize < config_params.min_bufsize[VPIF_CHANNEL1_VIDEO])
-               ch1_bufsize =
-                   config_params.min_bufsize[VPIF_CHANNEL1_VIDEO];
-
-       config_params.numbuffers[VPIF_CHANNEL0_VIDEO] = ch0_numbuffers;
-       config_params.numbuffers[VPIF_CHANNEL1_VIDEO] = ch1_numbuffers;
-       if (ch0_numbuffers) {
-               config_params.channel_bufsize[VPIF_CHANNEL0_VIDEO]
-                   = ch0_bufsize;
-       }
-       if (ch1_numbuffers) {
-               config_params.channel_bufsize[VPIF_CHANNEL1_VIDEO]
-                   = ch1_bufsize;
-       }
-
        /* Allocate memory for six channel objects */
        for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
                vpif_obj.dev[i] =
@@ -1496,6 +1356,11 @@ static int vpif_probe_complete(void)
                if (err)
                        goto probe_out;
 
+               /* set initial format */
+               ch->video.stdid = V4L2_STD_525_60;
+               memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
+               vpif_update_std_info(ch);
+
                /* Initialize vb2 queue */
                q = &common->buffer_queue;
                q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -1533,7 +1398,6 @@ static int vpif_probe_complete(void)
                vdev->vfl_dir = VFL_DIR_RX;
                vdev->queue = q;
                vdev->lock = &common->lock;
-               set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
                video_set_drvdata(ch->video_dev, ch);
                err = video_register_device(vdev,
                                            VFL_TYPE_GRABBER, (j ? 1 : 0));
@@ -1714,7 +1578,7 @@ static int vpif_remove(struct platform_device *device)
        for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
                /* Get the pointer to the channel object */
                ch = vpif_obj.dev[i];
-               common = &ch->common[i];
+               common = &ch->common[VPIF_VIDEO_INDEX];
                vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
                /* Unregister video device */
                video_unregister_device(ch->video_dev);