diff options
Diffstat (limited to 'drivers/media/i2c/ov7670.c')
-rw-r--r-- | drivers/media/i2c/ov7670.c | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index b9847527e..2d1e25f10 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -639,7 +639,7 @@ static struct ov7670_format_struct { } ov7670_formats[] = { { .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, - .colorspace = V4L2_COLORSPACE_JPEG, + .colorspace = V4L2_COLORSPACE_SRGB, .regs = ov7670_fmt_yuv422, .cmatrix = { 128, -128, 0, -34, -94, 128 }, }, @@ -899,13 +899,14 @@ static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop, } -static int ov7670_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, - u32 *code) +static int ov7670_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= N_OV7670_FMTS) + if (code->pad || code->index >= N_OV7670_FMTS) return -EINVAL; - *code = ov7670_formats[index].mbus_code; + code->code = ov7670_formats[code->index].mbus_code; return 0; } @@ -970,17 +971,12 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev *sd, return 0; } -static int ov7670_try_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) -{ - return ov7670_try_fmt_internal(sd, fmt, NULL, NULL); -} - /* * Set a format. */ -static int ov7670_s_mbus_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int ov7670_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { struct ov7670_format_struct *ovfmt; struct ov7670_win_size *wsize; @@ -988,7 +984,18 @@ static int ov7670_s_mbus_fmt(struct v4l2_subdev *sd, unsigned char com7; int ret; - ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize); + if (format->pad) + return -EINVAL; + + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + ret = ov7670_try_fmt_internal(sd, &format->format, NULL, NULL); + if (ret) + return ret; + cfg->try_fmt = format->format; + return 0; + } + + ret = ov7670_try_fmt_internal(sd, &format->format, &ovfmt, &wsize); if (ret) return ret; @@ -1073,10 +1080,33 @@ static int ov7670_enum_frame_interval(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_interval_enum *fie) { + struct ov7670_info *info = to_state(sd); + unsigned int n_win_sizes = info->devtype->n_win_sizes; + int i; + if (fie->pad) return -EINVAL; if (fie->index >= ARRAY_SIZE(ov7670_frame_rates)) return -EINVAL; + + /* + * Check if the width/height is valid. + * + * If a minimum width/height was requested, filter out the capture + * windows that fall outside that. + */ + for (i = 0; i < n_win_sizes; i++) { + struct ov7670_win_size *win = &info->devtype->win_sizes[i]; + + if (info->min_width && win->width < info->min_width) + continue; + if (info->min_height && win->height < info->min_height) + continue; + if (fie->width == win->width && fie->height == win->height) + break; + } + if (i == n_win_sizes) + return -EINVAL; fie->interval.numerator = 1; fie->interval.denominator = ov7670_frame_rates[fie->index]; return 0; @@ -1362,7 +1392,7 @@ static int ov7670_s_exp(struct v4l2_subdev *sd, int value) unsigned char com1, com8, aech, aechh; ret = ov7670_read(sd, REG_COM1, &com1) + - ov7670_read(sd, REG_COM8, &com8); + ov7670_read(sd, REG_COM8, &com8) + ov7670_read(sd, REG_AECHH, &aechh); if (ret) return ret; @@ -1485,9 +1515,6 @@ static const struct v4l2_subdev_core_ops ov7670_core_ops = { }; static const struct v4l2_subdev_video_ops ov7670_video_ops = { - .enum_mbus_fmt = ov7670_enum_mbus_fmt, - .try_mbus_fmt = ov7670_try_mbus_fmt, - .s_mbus_fmt = ov7670_s_mbus_fmt, .s_parm = ov7670_s_parm, .g_parm = ov7670_g_parm, }; @@ -1495,6 +1522,8 @@ static const struct v4l2_subdev_video_ops ov7670_video_ops = { static const struct v4l2_subdev_pad_ops ov7670_pad_ops = { .enum_frame_interval = ov7670_enum_frame_interval, .enum_frame_size = ov7670_enum_frame_size, + .enum_mbus_code = ov7670_enum_mbus_code, + .set_fmt = ov7670_set_fmt, }; static const struct v4l2_subdev_ops ov7670_ops = { |