AnsweredAssumed Answered

Custom imx6Solo board + ov5640 mipi issues

Question asked by kalkanalack on Mar 24, 2013
Latest reply on Aug 7, 2013 by ZeeFrench

Hello,

we have been struggling with a custom board using i.MX 6Solo and ov5640 mipi camera.

 

So far the board works except for the camera interface.

 

The ov5640 is plugged via MIPI using the following configuration:

 

- i2c2 interface for SDA / CLK:

 

static iomux_v3_cfg_t mx6dl_customboard_i2c2_pads[] = {

  MX6DL_PAD_KEY_COL3__I2C2_SCL, /* I2C2 SCL */

  MX6DL_PAD_KEY_ROW3__I2C2_SDA, /* I2C2 SDA */

};

 

The ov5640 is plugged using the following pins:

 

Camera RST --> SD1_CLK

Camera PWN --> SD1_CMD

PIXCLK --> CSI0_PIXCLK

 

CSI_D1P

CSI_D1M

CSI_CLK0P

CSI_CLK0M

CSI_D0P

CSI_D0M

 

 

static iomux_v3_cfg_t mx6dl_customboard_mipi_sensor_pads[] = {

    MX6DL_PAD_GPIO_0__CCM_CLKO,

    MX6DL_PAD_SD1_CMD__GPIO_1_18,  /* camera PWDN */

    MX6DL_PAD_SD1_CLK__GPIO_1_20,  /* camera RESET */

};

 

At board's file configuration we declare the i2c / camera interface as:

 

 

#define MIPICSI_PWN IMX_GPIO_NR(1, 18)

#define MIPICSI_RST IMX_GPIO_NR(1, 20)

 

[...]

 

static struct fsl_mxc_camera_platform_data ov5640_mipi_data = {

    .mclk = 22000000,

    .csi = 0,

    .io_init = mx6q_mipi_sensor_io_init,

    .pwdn = mx6q_mipi_powerdown,

};

 

[...]

 

static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {

  {

        I2C_BOARD_INFO("ov5640_mipi", 0x3c),

        .platform_data = (void *)&ov5640_mipi_data,

  },

};

 

[...]

 

struct pwm_device *mipi_pwm;

 

static void mx6q_mipi_powerdown(int powerdown)

{

    if (!IS_ERR(mipi_pwm)) {

        if (powerdown) {

            pwm_disable(mipi_pwm);

        } else {

            unsigned period = 1000/24;

            pwm_config(mipi_pwm, period >> 1, period);

            pwm_enable(mipi_pwm);

        }

    }

 

    pr_info("%s: powerdown=%d, power_gp=0x%x\n", __func__, powerdown, MIPICSI_PWN);

    gpio_set_value(MIPICSI_PWN, powerdown ? 1 : 0);

    if (!powerdown)

        msleep(2);

}

 

 

static void camera_reset(int power_gp, int reset_gp, int reset_gp2)

{

    pr_info("%s: power_gp=0x%x, reset_gp=0x%x reset_gp2=0x%x\n",

            __func__, power_gp, reset_gp, reset_gp2);

    /* Camera power down */

    gpio_request(power_gp, "cam-pwdn");

    gpio_request(reset_gp, "cam-reset");

    if (reset_gp2 >= 0)

        gpio_request(reset_gp2, "cam-reset2");

    gpio_direction_output(power_gp, 1);

    /* Camera reset */

    gpio_direction_output(reset_gp, 0);

    if (reset_gp2 >= 0)

        gpio_direction_output(reset_gp2, 0);

    msleep(1);

    gpio_set_value(power_gp, 0);

    msleep(1);

    gpio_set_value(reset_gp, 1);

    if (reset_gp2 >= 0)

        gpio_set_value(reset_gp2, 1);

}

 

 

static void mx6q_mipi_sensor_io_init(void)

{

    mxc_iomux_v3_setup_multiple_pads(mx6dl_customboard_mipi_sensor_pads,

                                     ARRAY_SIZE(mx6dl_customboard_mipi_sensor_pads));

 

    mipi_pwm = pwm_request(3, "mipi_clock");

    if (IS_ERR(mipi_pwm)) {

        pr_err("unable to request PWM for mipi_clock\n");

    } else {

        unsigned period = 1000/22;

        pr_info("got pwm for mipi_clock\n");

        pwm_config(mipi_pwm, period >> 1, period);

        pwm_enable(mipi_pwm);

    }

 

    camera_reset(MIPICSI_PWN,MIPICSI_RST, NULL);

    mxc_iomux_set_gpr_register(13, 0, 3, 1);

}

 

[...]

 

However, we constantly get the following error:

 

i2c-core: driver [ov5640] registered

ov5640_mipi 2-003c: probe

got pwm for mipi_clock

pwm_config: pwm freq = 2250000, clk_select=2 clock_rate=4500000

camera_reset: power_gp=0x12, reset_gp=0x14 reset_gp2=0x0

pwm_config: pwm freq = 2250000, clk_select=2 clock_rate=4500000

mx6q_mipi_powerdown: powerdown=0, power_gp=0x12

i2c i2c-2: master_xfer[0] W, addr=0x3c, len=2

i2c i2c-2: <i2c_imx_xfer>

i2c i2c-2: <i2c_imx_start>

i2c i2c-2: <i2c_imx_bus_busy>

i2c i2c-2: <i2c_imx_bus_busy> I2C bus is busy

i2c i2c-2: <i2c_imx_stop>

i2c i2c-2: <i2c_imx_bus_busy>

i2c i2c-2: <i2c_imx_xfer> exit with: error: -110

ov5640_read_reg:write reg error:reg=300a

ov5640_probe:cannot find camera

 

Note we are tried to use boundarydevice's patch for pwm[1], but

apparently it is not a clock issue either. The kernel's version used is imx_3.0.35_3.0.0

 

Can anyone point out if the pins are the correct ones?

 

Thanks.

 

 

1 - https://github.com/boundarydevices/linux-imx6/commit/82c720893fc5459ee948fdbfd33ba9be2fc4894e

 

Outcomes