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
Hello,
Just spent 3 hours on a SabreSD I knew was working, both cameras (ov5642 and mipi) not recognised with same error after loading camera module :
root@freescale ~$ modprobe ov5640_camera_mipi
ov5640_read_reg:write reg error:reg=300a
camera ov5640_mipi is not found
To discover I plugged the cameras the wrong way (sensors should be on the edge of screen, at least it is not destructive), no i2c signal means no communication to initialize cameras !
After that, modprobe mxc_v4l2_capture and you should have your /dev/video0 and / or 1 appearing.
My 2 cents, Philippe.
Hello,
I wonder if you have figured out the issue. I am trying to connect a ov5640 MIPI camera to iMX6 solo (wandboard). I face the same issue, not able to detect the camera.
Any suggestion to debug will b helful.
Thanks!
I think first step is make sure you're getting the right clock to camera. Do you have an scope?
Next step would take some i2c debug tool (just like i2c-tools) and found your camera in some i2c bus.