summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <lg@denx.de>2009-05-19 13:38:44 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2009-06-23 13:16:29 +0200
commit8c07e0e3ef39fd447a32ab5e8c0fbcac5aa554ea (patch)
tree7f1a9c0ff174aad94fb18596b02828ce62ab150f
parent6d17b25fec3a13282437f2083d3bb9e837500643 (diff)
downloadlinux-2.6-8c07e0e3ef39fd447a32ab5e8c0fbcac5aa554ea.tar.gz
linux-2.6-8c07e0e3ef39fd447a32ab5e8c0fbcac5aa554ea.tar.xz
mx31:Add MT9T031 CMOS camera sensor to PCM037 board
Add support for the MT9T031 CMOS camera sensor from Aptina to the PCM037 board. Also add two I2C iomux pin definitions, needed for pcm037 Changes since v1: removed #ifdef CONFIG_I2C_IMX* checks, added a call to dma_free_coherent() on the error path. Signed-off-by: Guennadi Liakhovetski <lg@denx.de> Signed-off-by: Luotao Fu <l.fu@pengutronix.de>
-rw-r--r--arch/arm/mach-mx3/pcm037.c111
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx3.h2
2 files changed, 100 insertions, 13 deletions
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c
index 3dee3c45a84..2b67c10b8d1 100644
--- a/arch/arm/mach-mx3/pcm037.c
+++ b/arch/arm/mach-mx3/pcm037.c
@@ -18,7 +18,7 @@
#include <linux/types.h>
#include <linux/init.h>
-
+#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/plat-ram.h>
@@ -34,22 +34,24 @@
#include <linux/fsl_devices.h>
#include <linux/can/platform/sja1000.h>
-#include <mach/hardware.h>
+#include <media/soc_camera.h>
+
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/mach/map.h>
+#include <mach/board-pcm037.h>
#include <mach/common.h>
#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
-#include <mach/ipu.h>
-#include <mach/board-pcm037.h>
-#include <mach/mx3fb.h>
+#include <mach/hardware.h>
+#include <mach/mx3_camera.h>
#include <mach/mxc_nand.h>
#include <mach/mmc.h>
-#ifdef CONFIG_I2C_IMX
+#include <mach/ipu.h>
+#include <mach/mx3fb.h>
+#include <mach/irqs.h>
#include <mach/i2c.h>
-#endif
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include <mach/spi.h>
@@ -60,6 +62,8 @@ static unsigned int pcm037_pins[] = {
/* I2C */
MX31_PIN_CSPI2_MOSI__SCL,
MX31_PIN_CSPI2_MISO__SDA,
+ MX31_PIN_CSPI2_SS2__I2C3_SDA,
+ MX31_PIN_CSPI2_SCLK__I2C3_SCL,
/* SDHC1 */
MX31_PIN_SD1_DATA3__SD1_DATA3,
MX31_PIN_SD1_DATA2__SD1_DATA2,
@@ -151,6 +155,22 @@ static int usbotg_pins[] = {
MX31_PIN_USBOTG_DIR__USBOTG_DIR,
MX31_PIN_USBOTG_NXT__USBOTG_NXT,
MX31_PIN_USBOTG_STP__USBOTG_STP,
+ /* CSI */
+ IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO),
+ MX31_PIN_CSI_D6__CSI_D6,
+ MX31_PIN_CSI_D7__CSI_D7,
+ MX31_PIN_CSI_D8__CSI_D8,
+ MX31_PIN_CSI_D9__CSI_D9,
+ MX31_PIN_CSI_D10__CSI_D10,
+ MX31_PIN_CSI_D11__CSI_D11,
+ MX31_PIN_CSI_D12__CSI_D12,
+ MX31_PIN_CSI_D13__CSI_D13,
+ MX31_PIN_CSI_D14__CSI_D14,
+ MX31_PIN_CSI_D15__CSI_D15,
+ MX31_PIN_CSI_HSYNC__CSI_HSYNC,
+ MX31_PIN_CSI_MCLK__CSI_MCLK,
+ MX31_PIN_CSI_PIXCLK__CSI_PIXCLK,
+ MX31_PIN_CSI_VSYNC__CSI_VSYNC,
};
/* USB OTG HS port */
@@ -256,7 +276,6 @@ static struct mxc_nand_platform_data pcm037_nand_board_info = {
.hw_ecc = 1,
};
-#ifdef CONFIG_I2C_IMX
static struct imxi2c_platform_data pcm037_i2c_1_data = {
.bitrate = 100000,
};
@@ -268,7 +287,7 @@ static struct at24_platform_data board_eeprom = {
};
static struct i2c_board_info pcm037_i2c_devices[] = {
- {
+ {
I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
.platform_data = &board_eeprom,
}, {
@@ -276,7 +295,29 @@ static struct i2c_board_info pcm037_i2c_devices[] = {
.type = "pcf8563",
}
};
-#endif
+
+static struct imxi2c_platform_data pcm037_i2c_2_data = {
+ .bitrate = 20000,
+};
+
+static int pcm037_camera_power(struct device *dev, int on)
+{
+ /* disable or enable the camera on X7 or X8 PCM970 connector */
+ gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), !on);
+ return 0;
+}
+
+static struct soc_camera_link iclink = {
+ .bus_id = 0, /* Must match with the camera ID */
+ .power = pcm037_camera_power,
+};
+
+static struct i2c_board_info pcm037_i2c_2_devices[] = {
+ {
+ I2C_BOARD_INFO("mt9t031", 0x5d),
+ .platform_data = &iclink,
+ },
+};
/* Not connected by default */
#ifdef PCM970_SDHC_RW_SWITCH
@@ -359,6 +400,42 @@ static struct imxmmc_platform_data sdhc_pdata = {
.exit = pcm970_sdhc1_exit,
};
+struct mx3_camera_pdata camera_pdata = {
+ .dma_dev = &mx3_ipu.dev,
+ .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
+ .mclk_10khz = 2000,
+};
+
+static int __init pcm037_camera_alloc_dma(const size_t buf_size)
+{
+ dma_addr_t dma_handle;
+ void *buf;
+ int dma;
+
+ if (buf_size < 2 * 1024 * 1024)
+ return -EINVAL;
+
+ 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 = dma_declare_coherent_memory(&mx3_camera.dev,
+ dma_handle, dma_handle, buf_size,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+
+ if (dma & DMA_MEMORY_MAP)
+ return 0;
+
+ dma_free_coherent(NULL, buf_size, buf, dma_handle);
+
+ /* The way we call dma_declare_coherent_memory only a malloc can fail */
+ return -ENOMEM;
+}
+
static struct platform_device *devices[] __initdata = {
&pcm037_flash,
&pcm037_sram_device,
@@ -608,13 +685,14 @@ static void __init mxc_board_init(void)
platform_device_register(&pcm037_eth);
}
-
-#ifdef CONFIG_I2C_IMX
i2c_register_board_info(1, pcm037_i2c_devices,
ARRAY_SIZE(pcm037_i2c_devices));
+ i2c_register_board_info(2, pcm037_i2c_2_devices,
+ ARRAY_SIZE(pcm037_i2c_2_devices));
mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data);
-#endif
+ mxc_register_device(&mxc_i2c_device2, &pcm037_i2c_2_data);
+
mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
mxc_register_device(&mx3_ipu, &mx3_ipu_data);
@@ -632,6 +710,13 @@ static void __init mxc_board_init(void)
#endif
platform_device_register(&pcm970_sja1000);
+
+ /* CSI */
+ /* Camera power: default - off */
+ gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1);
+
+ if (!pcm037_camera_alloc_dma(4 * 1024 * 1024))
+ mxc_register_device(&mx3_camera, &camera_pdata);
}
static void __init pcm037_timer_init(void)
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
index 27f8d1b2bc6..2eb182f7387 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -602,6 +602,8 @@ enum iomux_pins {
#define MX31_PIN_I2C_DAT__SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC)
#define MX31_PIN_DCD_DTE1__I2C2_SDA IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT2)
#define MX31_PIN_RI_DTE1__I2C2_SCL IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_CSPI2_SS2__I2C3_SDA IOMUX_MODE(MX31_PIN_CSPI2_SS2, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI2_SCLK__I2C3_SCL IOMUX_MODE(MX31_PIN_CSPI2_SCLK, IOMUX_CONFIG_ALT1)
#define MX31_PIN_CSI_D4__CSI_D4 IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_FUNC)
#define MX31_PIN_CSI_D5__CSI_D5 IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_FUNC)
#define MX31_PIN_CSI_D6__CSI_D6 IOMUX_MODE(MX31_PIN_CSI_D6, IOMUX_CONFIG_FUNC)