From patchwork Wed Feb 18 00:03:54 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 7691 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 n1I03fL5005691 for ; Wed, 18 Feb 2009 00:03:53 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751504AbZBRADw (ORCPT ); Tue, 17 Feb 2009 19:03:52 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751898AbZBRADw (ORCPT ); Tue, 17 Feb 2009 19:03:52 -0500 Received: from mail.gmx.net ([213.165.64.20]:52274 "HELO mail.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1751504AbZBRADv (ORCPT ); Tue, 17 Feb 2009 19:03:51 -0500 Received: (qmail invoked by alias); 18 Feb 2009 00:03:49 -0000 Received: from p57BD3A9A.dip0.t-ipconnect.de (EHLO axis700.grange) [87.189.58.154] by mail.gmx.net (mp023) with SMTP; 18 Feb 2009 01:03:49 +0100 X-Authenticated: #20450766 X-Provags-ID: V01U2FsdGVkX18vWuNLSCsvgq7WxRXZe/c5MxHPCWSAXF7N2GSdZU MXvUEKuRDB+Xzz Received: from lyakh (helo=localhost) by axis700.grange with local-esmtp (Exim 4.63) (envelope-from ) id 1LZZus-0003Wt-5I; Wed, 18 Feb 2009 01:03:54 +0100 Date: Wed, 18 Feb 2009 01:03:54 +0100 (CET) From: Guennadi Liakhovetski To: Valentin Longchamp cc: Agustin , Linux Arm Kernel , Linux Media Mailing List , Sascha Hauer Subject: [PATCH/FYI 3/4] soc-camera: board bindings for camera host driver for i.MX3x SoCs In-Reply-To: Message-ID: References: <50561.11594.qm@web32108.mail.mud.yahoo.com> <499B2A60.9080009@epfl.ch> User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 X-Y-GMX-Trusted: 0 X-FuHaFi: 0.4 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Guennadi Liakhovetski The driver has been tested on a pcm037 test-board from Phycore. The driver uses a coherent memory buffer, because although i.MX31 supports video to scatter-gather lists, it can only pack an integer number of rows in an sg-buffer, which makes it useless with fixed size sg-elements, and videobuf-dma-sg.c uses fixed page-sized buffers. Signed-off-by: Guennadi Liakhovetski --- This one will have to be updated for new-style pin-configuration macros, etc. Just for the ease of testing here. arch/arm/mach-mx3/devices.c | 56 +++++++++++++++++++++++++++ arch/arm/mach-mx3/pcm037.c | 46 ++++++++++++++++++++++ arch/arm/plat-mxc/include/mach/mx3_camera.h | 2 + 3 files changed, 104 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index 1138a61..e03b127 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -28,6 +28,7 @@ #include #include #include +#include static struct resource uart0[] = { { @@ -229,6 +230,61 @@ int __init mx3_register_fb(const char *name, const struct fb_videomode *modes, return platform_device_register(&mx3_fb); } +struct mx3_camera_pdata camera_pdata = { + .dma_dev = &mx3_ipu.dev, +}; + +static struct resource camera_resources[] = { + { + .start = IPU_CTRL_BASE_ADDR + 0x60, + .end = IPU_CTRL_BASE_ADDR + 0x87, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mx3_camera = { + .name = "mx3-camera", + .id = 0, + .num_resources = ARRAY_SIZE(camera_resources), + .resource = camera_resources, + .dev = { + .platform_data = &camera_pdata, + .coherent_dma_mask = DMA_32BIT_MASK, + }, +}; + +int __init mx3_register_camera(size_t buf_size, unsigned long flags, + unsigned long mclk_freq_10khz) +{ + dma_addr_t dma_handle; + void *buf; + + if (!ipu_registered) { + int ret = platform_device_register(&mx3_ipu); + if (ret < 0) + return ret; + ipu_registered = true; + } + + buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, + GFP_KERNEL); + if (!buf) { + pr_err("%s: cannot allocate camera buffer-memory\n", __func__); + return -ENOMEM; + } + + memset(buf, 0, buf_size); + + dma_declare_coherent_memory(&mx3_camera.dev, + dma_handle, dma_handle, buf_size, + DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); + + camera_pdata.flags = flags; + camera_pdata.mclk_10khz = mclk_freq_10khz; + + return platform_device_register(&mx3_camera); +} + /* Resource definition for the I2C1 */ static struct resource mxci2c1_resources[] = { [0] = { diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c index 12e4d68..4678407 100644 --- a/arch/arm/mach-mx3/pcm037.c +++ b/arch/arm/mach-mx3/pcm037.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "devices.h" @@ -132,6 +133,12 @@ static struct i2c_board_info __initdata pcm037_i2c_devices[] = { }, }; +/* + * Try to reserve buffer space enough for 8 buffers 320x240@1 for + * streaming plus 2 buffers 2048x1536@1 for still image < 10MB + */ +#define PCM037_CAMERA_MEM_SIZE (4 * 1024 * 1024) + static struct platform_device *devices[] __initdata = { &pcm037_flash, &pcm037_eth, @@ -163,6 +170,8 @@ static const struct fb_videomode fb_modedb[] = { */ static void __init mxc_board_init(void) { + int ret; + platform_add_devices(devices, ARRAY_SIZE(devices)); mxc_iomux_mode(MX31_PIN_CTS1__CTS1); @@ -218,6 +227,43 @@ static void __init mxc_board_init(void) mxc_iomux_mode(IOMUX_MODE(MX31_PIN_D3_CLS, IOMUX_CONFIG_FUNC)); mx3_register_fb(fb_modedb[0].name, fb_modedb, ARRAY_SIZE(fb_modedb)); + + /* CSI */ + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D6, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D7, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D8, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D9, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D10, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D11, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D12, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D13, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D14, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D15, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_HSYNC, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_MCLK, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_PIXCLK, IOMUX_CONFIG_FUNC)); + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_VSYNC, IOMUX_CONFIG_FUNC)); + + /* ATA power off, disable ATA Buffer, enable CSI buffer */ + ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D4), "CSI D4"); + if (!ret) { + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_GPIO)); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D4), 0); + } else + printk(KERN_WARNING "Could not get GPIO %u\n", + IOMUX_TO_GPIO(MX31_PIN_CSI_D4)); + + ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), "CSI D5"); + if (!ret) { + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO)); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1); + } else + printk(KERN_WARNING "Could not get GPIO %u\n", + IOMUX_TO_GPIO(MX31_PIN_CSI_D5)); + + mx3_register_camera(PCM037_CAMERA_MEM_SIZE, + MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10, + 2000); } /* diff --git a/arch/arm/plat-mxc/include/mach/mx3_camera.h b/arch/arm/plat-mxc/include/mach/mx3_camera.h index 36d7ff2..eddbdc0 100644 --- a/arch/arm/plat-mxc/include/mach/mx3_camera.h +++ b/arch/arm/plat-mxc/include/mach/mx3_camera.h @@ -49,4 +49,6 @@ struct mx3_camera_pdata { struct device *dma_dev; }; +extern int mx3_register_camera(size_t, unsigned long, unsigned long); + #endif