X-Git-Url: http://git.cascardo.info/?a=blobdiff_plain;f=drivers%2Fmedia%2Fplatform%2Fdavinci%2Fvpif_capture.c;h=b054b7eec53dc5a98dd43ba02dd8e343bbc19005;hb=e669830526a0abaf301bf408df69cde33901ac63;hp=1e4ec697fb1054c69becb4f4483f228508c2efe7;hpb=8331c49c48af37f435aa9d9daa3b2ce38db64856;p=cascardo%2Flinux.git diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 1e4ec697fb10..b054b7eec53d 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -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);