diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-09 18:04:09 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-09 18:04:09 -0400 |
| commit | 79a6fb1acec93ef829a59d88429aafddf42793d3 (patch) | |
| tree | fe5c1c543c4f77d69da42cc7f94e99d1e3771d58 | |
| parent | 58c59bc997d86593f0bea41845885917cf304d22 (diff) | |
| parent | f813b5775b471b656382ae8f087bb34dc894261f (diff) | |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media fixes from Mauro Carvalho Chehab:
"Some driver fixes (em28xx, coda, usbtv, s5p, hdpvr and ml86v7667) and
a fix for media DocBook"
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
[media] em28xx: fix assignment of the eeprom data
[media] hdpvr: fix iteration over uninitialized lists in hdpvr_probe()
[media] usbtv: fix dependency
[media] usbtv: Throw corrupted frames away
[media] usbtv: Fix deinterlacing
[media] v4l2: added missing mutex.h include to v4l2-ctrls.h
[media] DocBook: upgrade media_api DocBook version to 4.2
[media] ml86v7667: fix compile warning: 'ret' set but not used
[media] s5p-g2d: Fix registration failure
[media] media: coda: Fix DT driver data pointer for i.MX27
[media] s5p-mfc: Fix input/output format reporting
| -rw-r--r-- | Documentation/DocBook/media_api.tmpl | 4 | ||||
| -rw-r--r-- | drivers/media/i2c/ml86v7667.c | 4 | ||||
| -rw-r--r-- | drivers/media/platform/coda.c | 2 | ||||
| -rw-r--r-- | drivers/media/platform/s5p-g2d/g2d.c | 1 | ||||
| -rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 79 | ||||
| -rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 46 | ||||
| -rw-r--r-- | drivers/media/usb/em28xx/em28xx-i2c.c | 2 | ||||
| -rw-r--r-- | drivers/media/usb/hdpvr/hdpvr-core.c | 11 | ||||
| -rw-r--r-- | drivers/media/usb/usbtv/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/media/usb/usbtv/usbtv.c | 51 | ||||
| -rw-r--r-- | include/media/v4l2-ctrls.h | 1 |
11 files changed, 101 insertions, 102 deletions
diff --git a/Documentation/DocBook/media_api.tmpl b/Documentation/DocBook/media_api.tmpl index 6a8b7158697f..9c92bb879b6d 100644 --- a/Documentation/DocBook/media_api.tmpl +++ b/Documentation/DocBook/media_api.tmpl | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | <?xml version="1.0"?> | 1 | <?xml version="1.0"?> |
| 2 | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | 2 | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" |
| 3 | "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ | 3 | "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [ |
| 4 | <!ENTITY % media-entities SYSTEM "./media-entities.tmpl"> %media-entities; | 4 | <!ENTITY % media-entities SYSTEM "./media-entities.tmpl"> %media-entities; |
| 5 | <!ENTITY media-indices SYSTEM "./media-indices.tmpl"> | 5 | <!ENTITY media-indices SYSTEM "./media-indices.tmpl"> |
| 6 | 6 | ||
diff --git a/drivers/media/i2c/ml86v7667.c b/drivers/media/i2c/ml86v7667.c index efdc873e58d1..a9857022f71d 100644 --- a/drivers/media/i2c/ml86v7667.c +++ b/drivers/media/i2c/ml86v7667.c | |||
| @@ -117,7 +117,7 @@ static int ml86v7667_s_ctrl(struct v4l2_ctrl *ctrl) | |||
| 117 | { | 117 | { |
| 118 | struct v4l2_subdev *sd = to_sd(ctrl); | 118 | struct v4l2_subdev *sd = to_sd(ctrl); |
| 119 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 119 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 120 | int ret; | 120 | int ret = -EINVAL; |
| 121 | 121 | ||
| 122 | switch (ctrl->id) { | 122 | switch (ctrl->id) { |
| 123 | case V4L2_CID_BRIGHTNESS: | 123 | case V4L2_CID_BRIGHTNESS: |
| @@ -157,7 +157,7 @@ static int ml86v7667_s_ctrl(struct v4l2_ctrl *ctrl) | |||
| 157 | break; | 157 | break; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | return 0; | 160 | return ret; |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | static int ml86v7667_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) | 163 | static int ml86v7667_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) |
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index df4ada880e42..bd9405df1bd6 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c | |||
| @@ -1987,7 +1987,7 @@ MODULE_DEVICE_TABLE(platform, coda_platform_ids); | |||
| 1987 | 1987 | ||
| 1988 | #ifdef CONFIG_OF | 1988 | #ifdef CONFIG_OF |
| 1989 | static const struct of_device_id coda_dt_ids[] = { | 1989 | static const struct of_device_id coda_dt_ids[] = { |
| 1990 | { .compatible = "fsl,imx27-vpu", .data = &coda_platform_ids[CODA_IMX27] }, | 1990 | { .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] }, |
| 1991 | { .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] }, | 1991 | { .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] }, |
| 1992 | { /* sentinel */ } | 1992 | { /* sentinel */ } |
| 1993 | }; | 1993 | }; |
diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index 553d87e5ceab..fd6289d60cde 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c | |||
| @@ -784,6 +784,7 @@ static int g2d_probe(struct platform_device *pdev) | |||
| 784 | } | 784 | } |
| 785 | *vfd = g2d_videodev; | 785 | *vfd = g2d_videodev; |
| 786 | vfd->lock = &dev->mutex; | 786 | vfd->lock = &dev->mutex; |
| 787 | vfd->v4l2_dev = &dev->v4l2_dev; | ||
| 787 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | 788 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); |
| 788 | if (ret) { | 789 | if (ret) { |
| 789 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); | 790 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index 5296385153d5..4f6dd42c9adb 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | |||
| @@ -344,7 +344,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 344 | pix_mp->num_planes = 2; | 344 | pix_mp->num_planes = 2; |
| 345 | /* Set pixelformat to the format in which MFC | 345 | /* Set pixelformat to the format in which MFC |
| 346 | outputs the decoded frame */ | 346 | outputs the decoded frame */ |
| 347 | pix_mp->pixelformat = V4L2_PIX_FMT_NV12MT; | 347 | pix_mp->pixelformat = ctx->dst_fmt->fourcc; |
| 348 | pix_mp->plane_fmt[0].bytesperline = ctx->buf_width; | 348 | pix_mp->plane_fmt[0].bytesperline = ctx->buf_width; |
| 349 | pix_mp->plane_fmt[0].sizeimage = ctx->luma_size; | 349 | pix_mp->plane_fmt[0].sizeimage = ctx->luma_size; |
| 350 | pix_mp->plane_fmt[1].bytesperline = ctx->buf_width; | 350 | pix_mp->plane_fmt[1].bytesperline = ctx->buf_width; |
| @@ -382,10 +382,16 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 382 | mfc_err("Unsupported format for source.\n"); | 382 | mfc_err("Unsupported format for source.\n"); |
| 383 | return -EINVAL; | 383 | return -EINVAL; |
| 384 | } | 384 | } |
| 385 | if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) { | 385 | if (fmt->codec_mode == S5P_FIMV_CODEC_NONE) { |
| 386 | mfc_err("Not supported format.\n"); | 386 | mfc_err("Unknown codec\n"); |
| 387 | return -EINVAL; | 387 | return -EINVAL; |
| 388 | } | 388 | } |
| 389 | if (!IS_MFCV6(dev)) { | ||
| 390 | if (fmt->fourcc == V4L2_PIX_FMT_VP8) { | ||
| 391 | mfc_err("Not supported format.\n"); | ||
| 392 | return -EINVAL; | ||
| 393 | } | ||
| 394 | } | ||
| 389 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 395 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
| 390 | fmt = find_format(f, MFC_FMT_RAW); | 396 | fmt = find_format(f, MFC_FMT_RAW); |
| 391 | if (!fmt) { | 397 | if (!fmt) { |
| @@ -411,7 +417,6 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 411 | struct s5p_mfc_dev *dev = video_drvdata(file); | 417 | struct s5p_mfc_dev *dev = video_drvdata(file); |
| 412 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); | 418 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); |
| 413 | int ret = 0; | 419 | int ret = 0; |
| 414 | struct s5p_mfc_fmt *fmt; | ||
| 415 | struct v4l2_pix_format_mplane *pix_mp; | 420 | struct v4l2_pix_format_mplane *pix_mp; |
| 416 | 421 | ||
| 417 | mfc_debug_enter(); | 422 | mfc_debug_enter(); |
| @@ -425,54 +430,32 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 425 | goto out; | 430 | goto out; |
| 426 | } | 431 | } |
| 427 | if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 432 | if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
| 428 | fmt = find_format(f, MFC_FMT_RAW); | 433 | /* dst_fmt is validated by call to vidioc_try_fmt */ |
| 429 | if (!fmt) { | 434 | ctx->dst_fmt = find_format(f, MFC_FMT_RAW); |
| 430 | mfc_err("Unsupported format for source.\n"); | 435 | ret = 0; |
| 431 | return -EINVAL; | ||
| 432 | } | ||
| 433 | if (!IS_MFCV6(dev) && (fmt->fourcc != V4L2_PIX_FMT_NV12MT)) { | ||
| 434 | mfc_err("Not supported format.\n"); | ||
| 435 | return -EINVAL; | ||
| 436 | } else if (IS_MFCV6(dev) && | ||
| 437 | (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) { | ||
| 438 | mfc_err("Not supported format.\n"); | ||
| 439 | return -EINVAL; | ||
| 440 | } | ||
| 441 | ctx->dst_fmt = fmt; | ||
| 442 | mfc_debug_leave(); | ||
| 443 | return ret; | ||
| 444 | } else if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | ||
| 445 | mfc_err("Wrong type error for S_FMT : %d", f->type); | ||
| 446 | return -EINVAL; | ||
| 447 | } | ||
| 448 | fmt = find_format(f, MFC_FMT_DEC); | ||
| 449 | if (!fmt || fmt->codec_mode == S5P_MFC_CODEC_NONE) { | ||
| 450 | mfc_err("Unknown codec\n"); | ||
| 451 | ret = -EINVAL; | ||
| 452 | goto out; | 436 | goto out; |
| 453 | } | 437 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
| 454 | if (fmt->type != MFC_FMT_DEC) { | 438 | /* src_fmt is validated by call to vidioc_try_fmt */ |
| 455 | mfc_err("Wrong format selected, you should choose " | 439 | ctx->src_fmt = find_format(f, MFC_FMT_DEC); |
| 456 | "format for decoding\n"); | 440 | ctx->codec_mode = ctx->src_fmt->codec_mode; |
| 441 | mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode); | ||
| 442 | pix_mp->height = 0; | ||
| 443 | pix_mp->width = 0; | ||
| 444 | if (pix_mp->plane_fmt[0].sizeimage) | ||
| 445 | ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage; | ||
| 446 | else | ||
| 447 | pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size = | ||
| 448 | DEF_CPB_SIZE; | ||
| 449 | pix_mp->plane_fmt[0].bytesperline = 0; | ||
| 450 | ctx->state = MFCINST_INIT; | ||
| 451 | ret = 0; | ||
| 452 | goto out; | ||
| 453 | } else { | ||
| 454 | mfc_err("Wrong type error for S_FMT : %d", f->type); | ||
| 457 | ret = -EINVAL; | 455 | ret = -EINVAL; |
| 458 | goto out; | 456 | goto out; |
| 459 | } | 457 | } |
| 460 | if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) { | 458 | |
| 461 | mfc_err("Not supported format.\n"); | ||
| 462 | return -EINVAL; | ||
| 463 | } | ||
| 464 | ctx->src_fmt = fmt; | ||
| 465 | ctx->codec_mode = fmt->codec_mode; | ||
| 466 | mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode); | ||
| 467 | pix_mp->height = 0; | ||
| 468 | pix_mp->width = 0; | ||
| 469 | if (pix_mp->plane_fmt[0].sizeimage) | ||
| 470 | ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage; | ||
| 471 | else | ||
| 472 | pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size = | ||
| 473 | DEF_CPB_SIZE; | ||
| 474 | pix_mp->plane_fmt[0].bytesperline = 0; | ||
| 475 | ctx->state = MFCINST_INIT; | ||
| 476 | out: | 459 | out: |
| 477 | mfc_debug_leave(); | 460 | mfc_debug_leave(); |
| 478 | return ret; | 461 | return ret; |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 2549967b2f85..59e56f4c8ce3 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | |||
| @@ -906,6 +906,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 906 | 906 | ||
| 907 | static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | 907 | static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) |
| 908 | { | 908 | { |
| 909 | struct s5p_mfc_dev *dev = video_drvdata(file); | ||
| 909 | struct s5p_mfc_fmt *fmt; | 910 | struct s5p_mfc_fmt *fmt; |
| 910 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; | 911 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; |
| 911 | 912 | ||
| @@ -930,6 +931,18 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 930 | return -EINVAL; | 931 | return -EINVAL; |
| 931 | } | 932 | } |
| 932 | 933 | ||
| 934 | if (!IS_MFCV6(dev)) { | ||
| 935 | if (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) { | ||
| 936 | mfc_err("Not supported format.\n"); | ||
| 937 | return -EINVAL; | ||
| 938 | } | ||
| 939 | } else if (IS_MFCV6(dev)) { | ||
| 940 | if (fmt->fourcc == V4L2_PIX_FMT_NV12MT) { | ||
| 941 | mfc_err("Not supported format.\n"); | ||
| 942 | return -EINVAL; | ||
| 943 | } | ||
| 944 | } | ||
| 945 | |||
| 933 | if (fmt->num_planes != pix_fmt_mp->num_planes) { | 946 | if (fmt->num_planes != pix_fmt_mp->num_planes) { |
| 934 | mfc_err("failed to try output format\n"); | 947 | mfc_err("failed to try output format\n"); |
| 935 | return -EINVAL; | 948 | return -EINVAL; |
| @@ -947,7 +960,6 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 947 | { | 960 | { |
| 948 | struct s5p_mfc_dev *dev = video_drvdata(file); | 961 | struct s5p_mfc_dev *dev = video_drvdata(file); |
| 949 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); | 962 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); |
| 950 | struct s5p_mfc_fmt *fmt; | ||
| 951 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; | 963 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; |
| 952 | int ret = 0; | 964 | int ret = 0; |
| 953 | 965 | ||
| @@ -960,13 +972,9 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 960 | goto out; | 972 | goto out; |
| 961 | } | 973 | } |
| 962 | if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 974 | if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
| 963 | fmt = find_format(f, MFC_FMT_ENC); | 975 | /* dst_fmt is validated by call to vidioc_try_fmt */ |
| 964 | if (!fmt) { | 976 | ctx->dst_fmt = find_format(f, MFC_FMT_ENC); |
| 965 | mfc_err("failed to set capture format\n"); | ||
| 966 | return -EINVAL; | ||
| 967 | } | ||
| 968 | ctx->state = MFCINST_INIT; | 977 | ctx->state = MFCINST_INIT; |
| 969 | ctx->dst_fmt = fmt; | ||
| 970 | ctx->codec_mode = ctx->dst_fmt->codec_mode; | 978 | ctx->codec_mode = ctx->dst_fmt->codec_mode; |
| 971 | ctx->enc_dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage; | 979 | ctx->enc_dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage; |
| 972 | pix_fmt_mp->plane_fmt[0].bytesperline = 0; | 980 | pix_fmt_mp->plane_fmt[0].bytesperline = 0; |
| @@ -987,28 +995,8 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 987 | } | 995 | } |
| 988 | mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); | 996 | mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); |
| 989 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 997 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
| 990 | fmt = find_format(f, MFC_FMT_RAW); | 998 | /* src_fmt is validated by call to vidioc_try_fmt */ |
| 991 | if (!fmt) { | 999 | ctx->src_fmt = find_format(f, MFC_FMT_RAW); |
| 992 | mfc_err("failed to set output format\n"); | ||
| 993 | return -EINVAL; | ||
| 994 | } | ||
| 995 | |||
| 996 | if (!IS_MFCV6(dev) && | ||
| 997 | (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)) { | ||
| 998 | mfc_err("Not supported format.\n"); | ||
| 999 | return -EINVAL; | ||
| 1000 | } else if (IS_MFCV6(dev) && | ||
| 1001 | (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) { | ||
| 1002 | mfc_err("Not supported format.\n"); | ||
| 1003 | return -EINVAL; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | if (fmt->num_planes != pix_fmt_mp->num_planes) { | ||
| 1007 | mfc_err("failed to set output format\n"); | ||
| 1008 | ret = -EINVAL; | ||
| 1009 | goto out; | ||
| 1010 | } | ||
| 1011 | ctx->src_fmt = fmt; | ||
| 1012 | ctx->img_width = pix_fmt_mp->width; | 1000 | ctx->img_width = pix_fmt_mp->width; |
| 1013 | ctx->img_height = pix_fmt_mp->height; | 1001 | ctx->img_height = pix_fmt_mp->height; |
| 1014 | mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode); | 1002 | mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode); |
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 4851cc2e4a4d..c4ff9739a7ae 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c | |||
| @@ -726,7 +726,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, | |||
| 726 | 726 | ||
| 727 | *eedata = data; | 727 | *eedata = data; |
| 728 | *eedata_len = len; | 728 | *eedata_len = len; |
| 729 | dev_config = (void *)eedata; | 729 | dev_config = (void *)*eedata; |
| 730 | 730 | ||
| 731 | switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) { | 731 | switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) { |
| 732 | case 0: | 732 | case 0: |
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index cb694055ba7d..6e5070774dc2 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c | |||
| @@ -303,6 +303,11 @@ static int hdpvr_probe(struct usb_interface *interface, | |||
| 303 | 303 | ||
| 304 | dev->workqueue = 0; | 304 | dev->workqueue = 0; |
| 305 | 305 | ||
| 306 | /* init video transfer queues first of all */ | ||
| 307 | /* to prevent oops in hdpvr_delete() on error paths */ | ||
| 308 | INIT_LIST_HEAD(&dev->free_buff_list); | ||
| 309 | INIT_LIST_HEAD(&dev->rec_buff_list); | ||
| 310 | |||
| 306 | /* register v4l2_device early so it can be used for printks */ | 311 | /* register v4l2_device early so it can be used for printks */ |
| 307 | if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) { | 312 | if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) { |
| 308 | dev_err(&interface->dev, "v4l2_device_register failed\n"); | 313 | dev_err(&interface->dev, "v4l2_device_register failed\n"); |
| @@ -325,10 +330,6 @@ static int hdpvr_probe(struct usb_interface *interface, | |||
| 325 | if (!dev->workqueue) | 330 | if (!dev->workqueue) |
| 326 | goto error; | 331 | goto error; |
| 327 | 332 | ||
| 328 | /* init video transfer queues */ | ||
| 329 | INIT_LIST_HEAD(&dev->free_buff_list); | ||
| 330 | INIT_LIST_HEAD(&dev->rec_buff_list); | ||
| 331 | |||
| 332 | dev->options = hdpvr_default_options; | 333 | dev->options = hdpvr_default_options; |
| 333 | 334 | ||
| 334 | if (default_video_input < HDPVR_VIDEO_INPUTS) | 335 | if (default_video_input < HDPVR_VIDEO_INPUTS) |
| @@ -405,7 +406,7 @@ static int hdpvr_probe(struct usb_interface *interface, | |||
| 405 | video_nr[atomic_inc_return(&dev_nr)]); | 406 | video_nr[atomic_inc_return(&dev_nr)]); |
| 406 | if (retval < 0) { | 407 | if (retval < 0) { |
| 407 | v4l2_err(&dev->v4l2_dev, "registering videodev failed\n"); | 408 | v4l2_err(&dev->v4l2_dev, "registering videodev failed\n"); |
| 408 | goto error; | 409 | goto reg_fail; |
| 409 | } | 410 | } |
| 410 | 411 | ||
| 411 | /* let the user know what node this device is now attached to */ | 412 | /* let the user know what node this device is now attached to */ |
diff --git a/drivers/media/usb/usbtv/Kconfig b/drivers/media/usb/usbtv/Kconfig index 8864436464bf..7c5b86006ee6 100644 --- a/drivers/media/usb/usbtv/Kconfig +++ b/drivers/media/usb/usbtv/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config VIDEO_USBTV | 1 | config VIDEO_USBTV |
| 2 | tristate "USBTV007 video capture support" | 2 | tristate "USBTV007 video capture support" |
| 3 | depends on VIDEO_DEV | 3 | depends on VIDEO_V4L2 |
| 4 | select VIDEOBUF2_VMALLOC | 4 | select VIDEOBUF2_VMALLOC |
| 5 | 5 | ||
| 6 | ---help--- | 6 | ---help--- |
diff --git a/drivers/media/usb/usbtv/usbtv.c b/drivers/media/usb/usbtv/usbtv.c index bf43f874685e..91650173941a 100644 --- a/drivers/media/usb/usbtv/usbtv.c +++ b/drivers/media/usb/usbtv/usbtv.c | |||
| @@ -57,7 +57,7 @@ | |||
| 57 | #define USBTV_CHUNK_SIZE 256 | 57 | #define USBTV_CHUNK_SIZE 256 |
| 58 | #define USBTV_CHUNK 240 | 58 | #define USBTV_CHUNK 240 |
| 59 | #define USBTV_CHUNKS (USBTV_WIDTH * USBTV_HEIGHT \ | 59 | #define USBTV_CHUNKS (USBTV_WIDTH * USBTV_HEIGHT \ |
| 60 | / 2 / USBTV_CHUNK) | 60 | / 4 / USBTV_CHUNK) |
| 61 | 61 | ||
| 62 | /* Chunk header. */ | 62 | /* Chunk header. */ |
| 63 | #define USBTV_MAGIC_OK(chunk) ((be32_to_cpu(chunk[0]) & 0xff000000) \ | 63 | #define USBTV_MAGIC_OK(chunk) ((be32_to_cpu(chunk[0]) & 0xff000000) \ |
| @@ -89,6 +89,7 @@ struct usbtv { | |||
| 89 | /* Number of currently processed frame, useful find | 89 | /* Number of currently processed frame, useful find |
| 90 | * out when a new one begins. */ | 90 | * out when a new one begins. */ |
| 91 | u32 frame_id; | 91 | u32 frame_id; |
| 92 | int chunks_done; | ||
| 92 | 93 | ||
| 93 | int iso_size; | 94 | int iso_size; |
| 94 | unsigned int sequence; | 95 | unsigned int sequence; |
| @@ -202,6 +203,26 @@ static int usbtv_setup_capture(struct usbtv *usbtv) | |||
| 202 | return 0; | 203 | return 0; |
| 203 | } | 204 | } |
| 204 | 205 | ||
| 206 | /* Copy data from chunk into a frame buffer, deinterlacing the data | ||
| 207 | * into every second line. Unfortunately, they don't align nicely into | ||
| 208 | * 720 pixel lines, as the chunk is 240 words long, which is 480 pixels. | ||
| 209 | * Therefore, we break down the chunk into two halves before copyting, | ||
| 210 | * so that we can interleave a line if needed. */ | ||
| 211 | static void usbtv_chunk_to_vbuf(u32 *frame, u32 *src, int chunk_no, int odd) | ||
| 212 | { | ||
| 213 | int half; | ||
| 214 | |||
| 215 | for (half = 0; half < 2; half++) { | ||
| 216 | int part_no = chunk_no * 2 + half; | ||
| 217 | int line = part_no / 3; | ||
| 218 | int part_index = (line * 2 + !odd) * 3 + (part_no % 3); | ||
| 219 | |||
| 220 | u32 *dst = &frame[part_index * USBTV_CHUNK/2]; | ||
| 221 | memcpy(dst, src, USBTV_CHUNK/2 * sizeof(*src)); | ||
| 222 | src += USBTV_CHUNK/2; | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 205 | /* Called for each 256-byte image chunk. | 226 | /* Called for each 256-byte image chunk. |
| 206 | * First word identifies the chunk, followed by 240 words of image | 227 | * First word identifies the chunk, followed by 240 words of image |
| 207 | * data and padding. */ | 228 | * data and padding. */ |
| @@ -218,17 +239,17 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk) | |||
| 218 | frame_id = USBTV_FRAME_ID(chunk); | 239 | frame_id = USBTV_FRAME_ID(chunk); |
| 219 | odd = USBTV_ODD(chunk); | 240 | odd = USBTV_ODD(chunk); |
| 220 | chunk_no = USBTV_CHUNK_NO(chunk); | 241 | chunk_no = USBTV_CHUNK_NO(chunk); |
| 221 | |||
| 222 | /* Deinterlace. TODO: Use interlaced frame format. */ | ||
| 223 | chunk_no = (chunk_no - chunk_no % 3) * 2 + chunk_no % 3; | ||
| 224 | chunk_no += !odd * 3; | ||
| 225 | |||
| 226 | if (chunk_no >= USBTV_CHUNKS) | 242 | if (chunk_no >= USBTV_CHUNKS) |
| 227 | return; | 243 | return; |
| 228 | 244 | ||
| 229 | /* Beginning of a frame. */ | 245 | /* Beginning of a frame. */ |
| 230 | if (chunk_no == 0) | 246 | if (chunk_no == 0) { |
| 231 | usbtv->frame_id = frame_id; | 247 | usbtv->frame_id = frame_id; |
| 248 | usbtv->chunks_done = 0; | ||
| 249 | } | ||
| 250 | |||
| 251 | if (usbtv->frame_id != frame_id) | ||
| 252 | return; | ||
| 232 | 253 | ||
| 233 | spin_lock_irqsave(&usbtv->buflock, flags); | 254 | spin_lock_irqsave(&usbtv->buflock, flags); |
| 234 | if (list_empty(&usbtv->bufs)) { | 255 | if (list_empty(&usbtv->bufs)) { |
| @@ -241,19 +262,23 @@ static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk) | |||
| 241 | buf = list_first_entry(&usbtv->bufs, struct usbtv_buf, list); | 262 | buf = list_first_entry(&usbtv->bufs, struct usbtv_buf, list); |
| 242 | frame = vb2_plane_vaddr(&buf->vb, 0); | 263 | frame = vb2_plane_vaddr(&buf->vb, 0); |
| 243 | 264 | ||
| 244 | /* Copy the chunk. */ | 265 | /* Copy the chunk data. */ |
| 245 | memcpy(&frame[chunk_no * USBTV_CHUNK], &chunk[1], | 266 | usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd); |
| 246 | USBTV_CHUNK * sizeof(chunk[1])); | 267 | usbtv->chunks_done++; |
| 247 | 268 | ||
| 248 | /* Last chunk in a frame, signalling an end */ | 269 | /* Last chunk in a frame, signalling an end */ |
| 249 | if (usbtv->frame_id && chunk_no == USBTV_CHUNKS-1) { | 270 | if (odd && chunk_no == USBTV_CHUNKS-1) { |
| 250 | int size = vb2_plane_size(&buf->vb, 0); | 271 | int size = vb2_plane_size(&buf->vb, 0); |
| 272 | enum vb2_buffer_state state = usbtv->chunks_done == | ||
| 273 | USBTV_CHUNKS ? | ||
| 274 | VB2_BUF_STATE_DONE : | ||
| 275 | VB2_BUF_STATE_ERROR; | ||
| 251 | 276 | ||
| 252 | buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED; | 277 | buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED; |
| 253 | buf->vb.v4l2_buf.sequence = usbtv->sequence++; | 278 | buf->vb.v4l2_buf.sequence = usbtv->sequence++; |
| 254 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); | 279 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); |
| 255 | vb2_set_plane_payload(&buf->vb, 0, size); | 280 | vb2_set_plane_payload(&buf->vb, 0, size); |
| 256 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); | 281 | vb2_buffer_done(&buf->vb, state); |
| 257 | list_del(&buf->list); | 282 | list_del(&buf->list); |
| 258 | } | 283 | } |
| 259 | 284 | ||
| @@ -518,7 +543,7 @@ static int usbtv_queue_setup(struct vb2_queue *vq, | |||
| 518 | if (*nbuffers < 2) | 543 | if (*nbuffers < 2) |
| 519 | *nbuffers = 2; | 544 | *nbuffers = 2; |
| 520 | *nplanes = 1; | 545 | *nplanes = 1; |
| 521 | sizes[0] = USBTV_CHUNK * USBTV_CHUNKS * sizeof(u32); | 546 | sizes[0] = USBTV_WIDTH * USBTV_HEIGHT / 2 * sizeof(u32); |
| 522 | 547 | ||
| 523 | return 0; | 548 | return 0; |
| 524 | } | 549 | } |
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 7343a27fe819..47ada23345a1 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #define _V4L2_CTRLS_H | 22 | #define _V4L2_CTRLS_H |
| 23 | 23 | ||
| 24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
| 25 | #include <linux/mutex.h> | ||
| 25 | #include <linux/videodev2.h> | 26 | #include <linux/videodev2.h> |
| 26 | 27 | ||
| 27 | /* forward references */ | 28 | /* forward references */ |
