From patchwork Mon Dec 14 15:23:34 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 67301 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nBEFMi53014742 for ; Mon, 14 Dec 2009 15:22:44 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757512AbZLNPWn (ORCPT ); Mon, 14 Dec 2009 10:22:43 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1757506AbZLNPWn (ORCPT ); Mon, 14 Dec 2009 10:22:43 -0500 Received: from ppsw-5.csi.cam.ac.uk ([131.111.8.135]:52627 "EHLO ppsw-5.csi.cam.ac.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753233AbZLNPWm (ORCPT ); Mon, 14 Dec 2009 10:22:42 -0500 X-Cam-AntiVirus: no malware found X-Cam-SpamDetails: not scanned X-Cam-ScannerInfo: http://www.cam.ac.uk/cs/email/scanner/ Received: from arcturus.eng.cam.ac.uk ([129.169.154.73]:48025) by ppsw-5.csi.cam.ac.uk (smtp.hermes.cam.ac.uk [131.111.8.155]:25) with esmtpsa (PLAIN:jic23) (TLSv1:DHE-RSA-AES256-SHA:256) id 1NKCky-0003Cy-H7 (Exim 4.70) (return-path ); Mon, 14 Dec 2009 15:22:40 +0000 Message-ID: <4B265876.3020901@cam.ac.uk> Date: Mon, 14 Dec 2009 15:23:34 +0000 From: Jonathan Cameron User-Agent: Thunderbird 2.0.0.23 (X11/20091029) MIME-Version: 1.0 To: Guennadi Liakhovetski CC: Mauro Carvalho Chehab , Linux Media Mailing List Subject: Re: [PULL] soc-camera and mediabus References: <4B264FE8.1080709@infradead.org> In-Reply-To: X-Enigmail-Version: 0.95.7 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index 0e2184e..e57c3b5 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -18,6 +18,7 @@ #include #include #include +#include MODULE_AUTHOR("Jonathan Corbet "); @@ -545,7 +546,7 @@ static struct ov7670_format_struct { .bpp = 1 }, }; -#define N_OV7670_FMTS ARRAY_SIZE(ov7670_formats) + /* @@ -668,52 +669,37 @@ static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop, return ret; } +static enum v4l2_mbus_pixelcode ov7670_codes[] = { + V4L2_MBUS_FMT_YUYV8_2X8, + V4L2_MBUS_FMT_RGB565_2X8_LE, +}; -static int ov7670_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) +static int ov7670_enum_fmt(struct v4l2_subdev *sd, int index, enum v4l2_mbus_pixelcode *code) { - struct ov7670_format_struct *ofmt; - - if (fmt->index >= N_OV7670_FMTS) + if (index >= ARRAY_SIZE(ov7670_codes)) return -EINVAL; - ofmt = ov7670_formats + fmt->index; - fmt->flags = 0; - strcpy(fmt->description, ofmt->desc); - fmt->pixelformat = ofmt->pixelformat; + *code = ov7670_codes[index]; return 0; } static int ov7670_try_fmt_internal(struct v4l2_subdev *sd, - struct v4l2_format *fmt, - struct ov7670_format_struct **ret_fmt, - struct ov7670_win_size **ret_wsize) + struct v4l2_mbus_framefmt *mf, + struct ov7670_format_struct **ret_fmt, + struct ov7670_win_size **ret_wsize) { int index; struct ov7670_win_size *wsize; - struct v4l2_pix_format *pix = &fmt->fmt.pix; - for (index = 0; index < N_OV7670_FMTS; index++) - if (ov7670_formats[index].pixelformat == pix->pixelformat) - break; - if (index >= N_OV7670_FMTS) { - /* default to first format */ - index = 0; - pix->pixelformat = ov7670_formats[0].pixelformat; - } - if (ret_fmt != NULL) - *ret_fmt = ov7670_formats + index; - /* - * Fields: the OV devices claim to be progressive. - */ - pix->field = V4L2_FIELD_NONE; + mf->field = V4L2_FIELD_NONE; /* * Round requested image size down to the nearest * we support, but not below the smallest. */ for (wsize = ov7670_win_sizes; wsize < ov7670_win_sizes + N_WIN_SIZES; wsize++) - if (pix->width >= wsize->width && pix->height >= wsize->height) + if ( mf->width >= wsize->width && mf->height >= wsize->height) break; if (wsize >= ov7670_win_sizes + N_WIN_SIZES) wsize--; /* Take the smallest one */ @@ -722,22 +708,34 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev *sd, /* * Note the size we'll actually handle. */ - pix->width = wsize->width; - pix->height = wsize->height; - pix->bytesperline = pix->width*ov7670_formats[index].bpp; - pix->sizeimage = pix->height*pix->bytesperline; + mf->width = wsize->width; + mf->height = wsize->height; + switch (mf->code) { + case V4L2_MBUS_FMT_RGB565_2X8_LE: + mf->colorspace = V4L2_COLORSPACE_SRGB; + if (ret_fmt != NULL) + *ret_fmt = ov7670_formats + 2; + break; + default: + mf->code = V4L2_MBUS_FMT_YUYV8_2X8; + case V4L2_MBUS_FMT_YUYV8_2X8: + mf->colorspace = V4L2_COLORSPACE_JPEG; + if (ret_fmt != NULL) + *ret_fmt = ov7670_formats; + break; + } return 0; } -static int ov7670_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +static int ov7670_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - return ov7670_try_fmt_internal(sd, fmt, NULL, NULL); + return ov7670_try_fmt_internal(sd, mf, NULL, NULL); } /* * Set a format. */ -static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { int ret; struct ov7670_format_struct *ovfmt; @@ -745,7 +743,11 @@ static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) struct ov7670_info *info = to_state(sd); unsigned char com7, clkrc = 0; - ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize); + ret = ov7670_init(sd, 0); + if (ret) + return ret; + + ret = ov7670_try_fmt_internal(sd, mf, &ovfmt, &wsize); if (ret) return ret; /* @@ -753,7 +755,7 @@ static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) * CLKRC. If we're *not*, however, then rewriting clkrc hoses * the colors. */ - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) { + if (mf->code == V4L2_MBUS_FMT_RGB565_2X8_LE) { ret = ov7670_read(sd, REG_CLKRC, &clkrc); if (ret) return ret; @@ -778,7 +780,7 @@ static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) ret = ov7670_write_array(sd, wsize->regs); info->fmt = ovfmt; - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 && ret == 0) + if (mf->code == V4L2_MBUS_FMT_RGB565_2X8_LE && ret == 0) ret = ov7670_write(sd, REG_CLKRC, clkrc); return ret; } @@ -1226,11 +1228,11 @@ static const struct v4l2_subdev_core_ops ov7670_core_ops = { }; static const struct v4l2_subdev_video_ops ov7670_video_ops = { - .enum_fmt = ov7670_enum_fmt, - .try_fmt = ov7670_try_fmt, - .s_fmt = ov7670_s_fmt, .s_parm = ov7670_s_parm, .g_parm = ov7670_g_parm, + .s_mbus_fmt = ov7670_s_fmt, + .try_mbus_fmt = ov7670_try_fmt, + .enum_mbus_fmt = ov7670_enum_fmt, }; static const struct v4l2_subdev_ops ov7670_ops = { @@ -1239,6 +1241,28 @@ static const struct v4l2_subdev_ops ov7670_ops = { }; /* ----------------------------------------------------------------------- */ +static unsigned long ov7670_soc_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + + unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | + SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | + SOCAM_DATAWIDTH_8 | SOCAM_DATA_ACTIVE_HIGH; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +/* This device only supports one bus option */ +static int ov7670_soc_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + return 0; +} + +static struct soc_camera_ops ov7670_soc_ops = { + .set_bus_param = ov7670_soc_set_bus_param, + .query_bus_param = ov7670_soc_query_bus_param, +}; static int ov7670_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -1246,6 +1270,12 @@ static int ov7670_probe(struct i2c_client *client, struct v4l2_subdev *sd; struct ov7670_info *info; int ret; + struct soc_camera_device *icd = client->dev.platform_data; + if (!icd) { + dev_err(&client->dev, "OV7670: missing soc-camera data!\n"); + return -EINVAL; + } + icd->ops = &ov7670_soc_ops; info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL); if (info == NULL)