summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/pci/cx23885/cx23885-video.c39
-rw-r--r--drivers/media/pci/cx23885/cx23885.h5
2 files changed, 38 insertions, 6 deletions
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 63f302e06379..ad4d7e683ba7 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -114,11 +114,19 @@ void cx23885_video_wakeup(struct cx23885_dev *dev,
int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
{
+ struct v4l2_subdev_format format = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .format.code = MEDIA_BUS_FMT_FIXED,
+ };
+
dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
__func__,
(unsigned int)norm,
v4l2_norm_to_name(norm));
+ if (dev->tvnorm == norm)
+ return 0;
+
if (dev->tvnorm != norm) {
if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
vb2_is_busy(&dev->vb2_mpegq))
@@ -126,9 +134,17 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
}
dev->tvnorm = norm;
+ dev->width = 720;
+ dev->height = norm_maxh(norm);
+ dev->field = V4L2_FIELD_INTERLACED;
call_all(dev, video, s_std, norm);
+ format.format.width = dev->width;
+ format.format.height = dev->height;
+ format.format.field = dev->field;
+ call_all(dev, pad, set_fmt, NULL, &format);
+
return 0;
}
@@ -545,7 +561,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
return -EINVAL;
field = f->fmt.pix.field;
- maxw = norm_maxw(dev->tvnorm);
+ maxw = 720;
maxh = norm_maxh(dev->tvnorm);
if (V4L2_FIELD_ANY == field) {
@@ -648,6 +664,26 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
+static int vidioc_cropcap(struct file *file, void *priv,
+ struct v4l2_cropcap *cc)
+{
+ struct cx23885_dev *dev = video_drvdata(file);
+ bool is_50hz = dev->tvnorm & V4L2_STD_625_50;
+
+ if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ cc->bounds.left = 0;
+ cc->bounds.top = 0;
+ cc->bounds.width = 720;
+ cc->bounds.height = norm_maxh(dev->tvnorm);
+ cc->defrect = cc->bounds;
+ cc->pixelaspect.numerator = is_50hz ? 54 : 11;
+ cc->pixelaspect.denominator = is_50hz ? 59 : 10;
+
+ return 0;
+}
+
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
{
struct cx23885_dev *dev = video_drvdata(file);
@@ -1082,6 +1118,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_dqbuf = vb2_ioctl_dqbuf,
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
+ .vidioc_cropcap = vidioc_cropcap,
.vidioc_s_std = vidioc_s_std,
.vidioc_g_std = vidioc_g_std,
.vidioc_enum_input = vidioc_enum_input,
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index f9eb57b186fa..9a8938b1085a 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -627,11 +627,6 @@ extern int cx23885_risc_databuffer(struct pci_dev *pci,
/* ----------------------------------------------------------- */
/* tv norms */
-static inline unsigned int norm_maxw(v4l2_std_id norm)
-{
- return (norm & V4L2_STD_525_60) ? 720 : 768;
-}
-
static inline unsigned int norm_maxh(v4l2_std_id norm)
{
return (norm & V4L2_STD_525_60) ? 480 : 576;