summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx6/board-wand.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-mx6/board-wand.c')
-rw-r--r--arch/arm/mach-mx6/board-wand.c153
1 files changed, 150 insertions, 3 deletions
diff --git a/arch/arm/mach-mx6/board-wand.c b/arch/arm/mach-mx6/board-wand.c
index e7ce54cf1128..2fa4f21fac25 100644
--- a/arch/arm/mach-mx6/board-wand.c
+++ b/arch/arm/mach-mx6/board-wand.c
@@ -31,7 +31,6 @@
#include <mach/ahci_sata.h>
#include <mach/common.h>
-//#include <mach/devices-common.h>
#include <mach/gpio.h>
#include <mach/iomux-mx6dl.h>
#include <mach/iomux-mx6q.h>
@@ -65,6 +64,10 @@
#define WAND_WL_HOST_WAKE IMX_GPIO_NR(1, 29)
#define WAND_WL_WAKE IMX_GPIO_NR(1, 30)
+#define WAND_MIPICSI_PWN IMX_GPIO_NR(1, 6)
+#define WAND_MIPICSI_RESET IMX_GPIO_NR(4, 14)
+
+
/* Syntactic sugar for pad configuration */
#define IMX6_SETUP_PAD(p) \
if (cpu_is_mx6q()) \
@@ -438,10 +441,10 @@ static __init void wand_init_usb(void) {
static struct imx_ipuv3_platform_data wand_ipu_data[] = {
{
.rev = 4,
- .csi_clk[0] = "ccm_clk0",
+ .csi_clk[0] = "clko2_clk",
}, {
.rev = 4,
- .csi_clk[0] = "ccm_clk0",
+ .csi_clk[0] = "clko2_clk",
},
};
@@ -510,6 +513,132 @@ static void wand_init_hdmi(void) {
mxc_iomux_set_gpr_register(0, 0, 1, 1);
}
+/****************************************************************************
+ *
+ * MIPI CSI
+ *
+ ****************************************************************************/
+static void wand_mipi_sensor_io_init(void) {
+
+ struct clk *mipi_csi_mclk;
+
+ IMX6_SETUP_PAD( GPIO_3__CCM_CLKO2 ); /* Camera clock */
+ IMX6_SETUP_PAD( KEY_COL4__GPIO_4_14 ); /* Camera reset */
+ IMX6_SETUP_PAD( GPIO_6__GPIO_1_6 ); /* Camera power down */
+
+ pr_debug("%s\n", __func__);
+
+ gpio_request(WAND_MIPICSI_RESET, "cam-reset");
+ gpio_direction_output(WAND_MIPICSI_RESET, 1);
+
+ gpio_request(WAND_MIPICSI_PWN, "cam-pwdn");
+ gpio_direction_output(WAND_MIPICSI_PWN, 1);
+
+ int rate;
+
+ /* Master clock for the sensor */
+ mipi_csi_mclk = clk_get(NULL, "clko2_clk");
+ if (IS_ERR(mipi_csi_mclk)) {
+ pr_err("can't get CLKO2 clock.\n");
+ return PTR_ERR(mipi_csi_mclk);
+ }
+
+ rate = clk_round_rate(mipi_csi_mclk, 24000000);
+ clk_set_rate(mipi_csi_mclk, rate);
+ clk_enable(mipi_csi_mclk);
+
+ msleep(5);
+ /* Power up */
+ gpio_set_value(WAND_MIPICSI_PWN, 0);
+ msleep(5);
+ /* Reset on */
+ gpio_set_value(WAND_MIPICSI_RESET, 0);
+ msleep(1);
+ /* Reset off */
+ gpio_set_value(WAND_MIPICSI_RESET, 1);
+ msleep(5);
+ /* power down */
+ gpio_set_value(WAND_MIPICSI_PWN, 1);
+
+ /* For MX6Q:
+ * GPR1 bit19 and bit20 meaning:
+ * Bit19: 0 - Enable mipi to IPU1 CSI0
+ * virtual channel is fixed to 0
+ * 1 - Enable parallel interface to IPU1 CSI0
+ * Bit20: 0 - Enable mipi to IPU2 CSI1
+ * virtual channel is fixed to 3
+ * 1 - Enable parallel interface to IPU2 CSI1
+ * IPU1 CSI1 directly connect to mipi csi2,
+ * virtual channel is fixed to 1
+ * IPU2 CSI0 directly connect to mipi csi2,
+ * virtual channel is fixed to 2
+ *
+ * For MX6DL:
+ * GPR13 bit 0-2 IPU_CSI0_MUX
+ * 000 MIPI_CSI0
+ * 100 IPU CSI0
+ */
+
+ if (cpu_is_mx6q())
+ mxc_iomux_set_gpr_register(1, 19, 1, 1);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_set_gpr_register(13, 0, 3, 0);
+}
+
+static void wand_mipi_powerdown(int powerdown)
+{
+ pr_debug("%s: powerdown=%d\n", __func__,powerdown);
+
+ if (powerdown)
+ gpio_set_value(WAND_MIPICSI_PWN, 1); /* Power off */
+ else
+ gpio_set_value(WAND_MIPICSI_PWN, 0); /* Power on */
+
+ msleep(2);
+}
+
+/* Platform data for CSI sensor driver, passed to driver
+ through i2c platform data */
+static struct fsl_mxc_camera_platform_data wand_mipi_csi2_data = {
+ .mclk = 24000000,
+ .mclk_source = 0,
+ .csi = 0,
+ .io_init = wand_mipi_sensor_io_init,
+ .pwdn = wand_mipi_powerdown,
+};
+
+/* TODO - reorg code so that adding i2c board info is done all in one
+ step at init. This makes adding I2C devices easier */
+static struct i2c_board_info wand_mipi_csi_i2c_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ov5640_mipi", 0x3C),
+ .platform_data = (void*)&wand_mipi_csi2_data,
+ },
+};
+
+/* Platform data for MIPI CSI init */
+static struct mipi_csi2_platform_data wand_mipi_csi2_platform_data = {
+ .ipu_id = 0,
+ .csi_id = 0,
+ .v_channel = 0,
+ .lanes = 2,
+ .dphy_clk = "mipi_pllref_clk",
+ .pixel_clk = "emi_clk",
+};
+
+/* Wandboard MIPI CSI init function */
+static void __init wand_init_mipi_csi(void){
+
+ pr_debug("%s\n", __func__);
+
+ /* Add CSI2 */
+ imx6q_add_mipi_csi2(&wand_mipi_csi2_platform_data);
+
+ /* Register MIPI CSI I2C board info. This sits on I2C2, which
+ is i2c device index 1 */
+ i2c_register_board_info(1, wand_mipi_csi_i2c_board_info,
+ ARRAY_SIZE(wand_mipi_csi_i2c_board_info));
+}
/****************************************************************************
*
@@ -1024,7 +1153,19 @@ static void __init wand_reserve(void) {
*
*****************************************************************************/
+static struct fsl_mxc_capture_platform_data capture_data[] = {
+#if defined(CONFIG_MXC_CAMERA_OV5640_MIPI) || defined(CONFIG_MXC_CAMERA_OV5640_MIPI_MODULE)
+ {
+ .ipu = 0,
+ .csi = 0,
+ .mclk_source = 0,
+ .is_mipi = 1,
+ },
+#endif
+};
+
static void __init wand_board_init(void) {
+ int i;
wand_init_dma();
wand_init_uart();
wand_init_sd();
@@ -1034,6 +1175,12 @@ static void __init wand_board_init(void) {
wand_init_usb();
wand_init_ipu();
wand_init_hdmi();
+ for (i = 0; i < ARRAY_SIZE(capture_data); i++) {
+ if (!cpu_is_mx6q())
+ capture_data[i].ipu = 0;
+ imx6q_add_v4l2_capture(i, &capture_data[i]);
+ }
+ wand_init_mipi_csi();
wand_init_lcd();
wand_init_wifi();
wand_init_bluetooth();