From patchwork Fri Nov 20 13:32:03 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 61642 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nAKDWCG5000900 for ; Fri, 20 Nov 2009 13:32:12 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753352AbZKTNbt (ORCPT ); Fri, 20 Nov 2009 08:31:49 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753351AbZKTNbt (ORCPT ); Fri, 20 Nov 2009 08:31:49 -0500 Received: from mail.gmx.net ([213.165.64.20]:46853 "HELO mail.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1753347AbZKTNbs (ORCPT ); Fri, 20 Nov 2009 08:31:48 -0500 Received: (qmail invoked by alias); 20 Nov 2009 13:31:52 -0000 Received: from p57BD1E72.dip0.t-ipconnect.de (EHLO axis700.grange) [87.189.30.114] by mail.gmx.net (mp057) with SMTP; 20 Nov 2009 14:31:52 +0100 X-Authenticated: #20450766 X-Provags-ID: V01U2FsdGVkX18kwR8Ixxwk4cjylTF6x/ZHNejqgWLC29MiAugHM3 gMMQbcYQktSjYs Received: from lyakh (helo=localhost) by axis700.grange with local-esmtp (Exim 4.63) (envelope-from ) id 1NBTal-0001mD-7T for linux-media@vger.kernel.org; Fri, 20 Nov 2009 14:32:03 +0100 Date: Fri, 20 Nov 2009 14:32:03 +0100 (CET) From: Guennadi Liakhovetski To: Linux Media Mailing List Subject: [PATCH/RFC] sh_mobile_ceu_camera: fix pass-through geometry parameters and try_fmt reporting Message-ID: MIME-Version: 1.0 X-Y-GMX-Trusted: 0 X-FuHaFi: 0.43 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/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 0114a2b..e7d6191 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -586,20 +586,30 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd, in_width *= 2; left_offset *= 2; } - width = cdwdr_width = out_width; + width = out_width; + cdwdr_width = out_width; } else { - unsigned int w_factor = (7 + - icd->current_fmt->host_fmt->bits_per_sample) >> 3; + int bytes_per_line = v4l2_imgbus_bytes_per_line(out_width, + icd->current_fmt->host_fmt); + unsigned int w_factor; - width = out_width * w_factor / 2; + width = out_width; - if (!pcdev->is_16bit) - w_factor *= 2; + switch (icd->current_fmt->host_fmt->packing) { + case V4L2_IMGBUS_PACKING_2X8_PADHI: + w_factor = 2; + break; + default: + w_factor = 1; + } - in_width = rect->width * w_factor / 2; - left_offset = left_offset * w_factor / 2; + in_width = rect->width * w_factor; + left_offset = left_offset * w_factor; - cdwdr_width = width * 2; + if (bytes_per_line < 0) + cdwdr_width = out_width; + else + cdwdr_width = bytes_per_line; } height = out_height; @@ -1547,16 +1557,23 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, if (pix->height > ceu_rect.height) pix->height = ceu_rect.height; - /* Let's rock: scale pix->{width x height} down to width x height */ - scale_h = calc_scale(ceu_rect.width, &pix->width); - scale_v = calc_scale(ceu_rect.height, &pix->height); + if (image_mode) { + /* Scale pix->{width x height} down to width x height */ + scale_h = calc_scale(ceu_rect.width, &pix->width); + scale_v = calc_scale(ceu_rect.height, &pix->height); + + pcdev->cflcr = scale_h | (scale_v << 16); + } else { + pix->width = ceu_rect.width; + pix->height = ceu_rect.height; + scale_h = scale_v = 0; + pcdev->cflcr = 0; + } dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n", ceu_rect.width, scale_h, pix->width, ceu_rect.height, scale_v, pix->height); - pcdev->cflcr = scale_h | (scale_v << 16); - cam->code = xlate->code; cam->ceu_rect = ceu_rect; icd->current_fmt = xlate; @@ -1618,21 +1635,25 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, /* FIXME: check against rect_max after converting soc-camera */ /* We can scale precisely, need a bigger image from camera */ if (pix->width < width || pix->height < height) { - int tmp_w = pix->width, tmp_h = pix->height; - pix->width = 2560; - pix->height = 1920; + /* + * We presume, the sensor behaves sanely, i.e., if + * requested a bigger rectangle, it will not return a + * smaller one. + */ + imgf.width = 2560; + imgf.height = 1920; ret = v4l2_subdev_call(sd, video, try_imgbus_fmt, &imgf); if (ret < 0) { /* Shouldn't actually happen... */ dev_err(icd->dev.parent, - "FIXME: try_fmt() returned %d\n", ret); - pix->width = tmp_w; - pix->height = tmp_h; + "FIXME: client try_fmt() = %d\n", ret); + return ret; } } - if (pix->width > width) + /* We will scale exactly */ + if (imgf.width > width) pix->width = width; - if (pix->height > height) + if (imgf.height > height) pix->height = height; }