diff options
author | Liu Ying <Ying.liu@freescale.com> | 2012-07-24 17:58:03 +0800 |
---|---|---|
committer | Liu Ying <Ying.liu@freescale.com> | 2012-07-25 16:02:12 +0800 |
commit | 6474118ccd32ba14700c35bd0fc147cd4d2a0240 (patch) | |
tree | b39cbf6afe88f6944fec5560c019cf2ce75a796c | |
parent | cf3095062b75f6e518c6ef8a25b47a5b2ced7668 (diff) |
ENGR00182061-1 OV5642 camera:Check dev id before register
This patch checks camera device id via i2c bus before register
v4l2 internal device.
Signed-off-by: Liu Ying <Ying.Liu@freescale.com>
-rw-r--r-- | drivers/media/video/mxc/capture/ov5642.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/media/video/mxc/capture/ov5642.c b/drivers/media/video/mxc/capture/ov5642.c index 31dc279b4a62..f3a82dbcadec 100644 --- a/drivers/media/video/mxc/capture/ov5642.c +++ b/drivers/media/video/mxc/capture/ov5642.c @@ -43,6 +43,9 @@ #define OV5642_XCLK_MIN 6000000 #define OV5642_XCLK_MAX 24000000 +#define OV5642_CHIP_ID_HIGH_BYTE 0x300A +#define OV5642_CHIP_ID_LOW_BYTE 0x300B + enum ov5642_mode { ov5642_mode_MIN = 0, ov5642_mode_VGA_640_480 = 0, @@ -3911,6 +3914,7 @@ static int ov5642_probe(struct i2c_client *client, { int retval; struct fsl_mxc_camera_platform_data *plat_data = client->dev.platform_data; + u8 chip_id_high, chip_id_low; /* Set initial values for the sensor struct. */ memset(&ov5642_data, 0, sizeof(ov5642_data)); @@ -3937,7 +3941,8 @@ static int ov5642_probe(struct i2c_client *client, regulator_set_voltage(io_regulator, OV5642_VOLTAGE_DIGITAL_IO, OV5642_VOLTAGE_DIGITAL_IO); - if (regulator_enable(io_regulator) != 0) { + retval = regulator_enable(io_regulator); + if (retval) { pr_err("%s:io set voltage error\n", __func__); goto err1; } else { @@ -3955,7 +3960,8 @@ static int ov5642_probe(struct i2c_client *client, regulator_set_voltage(core_regulator, OV5642_VOLTAGE_DIGITAL_CORE, OV5642_VOLTAGE_DIGITAL_CORE); - if (regulator_enable(core_regulator) != 0) { + retval = regulator_enable(core_regulator); + if (retval) { pr_err("%s:core set voltage error\n", __func__); goto err2; } else { @@ -3973,7 +3979,8 @@ static int ov5642_probe(struct i2c_client *client, regulator_set_voltage(analog_regulator, OV5642_VOLTAGE_ANALOG, OV5642_VOLTAGE_ANALOG); - if (regulator_enable(analog_regulator) != 0) { + retval = regulator_enable(analog_regulator); + if (retval) { pr_err("%s:analog set voltage error\n", __func__); goto err3; @@ -3988,6 +3995,22 @@ static int ov5642_probe(struct i2c_client *client, if (plat_data->io_init) plat_data->io_init(); + if (plat_data->pwdn) + plat_data->pwdn(0); + + retval = ov5642_read_reg(OV5642_CHIP_ID_HIGH_BYTE, &chip_id_high); + if (retval < 0 || chip_id_high != 0x56) { + pr_err("%s:cannot find camera\n", __func__); + retval = -ENODEV; + goto err4; + } + retval = ov5642_read_reg(OV5642_CHIP_ID_LOW_BYTE, &chip_id_low); + if (retval < 0 || chip_id_low != 0x42) { + pr_err("%s:cannot find camera\n", __func__); + retval = -ENODEV; + goto err4; + } + camera_plat = plat_data; ov5642_int_device.priv = &ov5642_data; @@ -3995,6 +4018,11 @@ static int ov5642_probe(struct i2c_client *client, return retval; +err4: + if (analog_regulator) { + regulator_disable(analog_regulator); + regulator_put(analog_regulator); + } err3: if (core_regulator) { regulator_disable(core_regulator); @@ -4006,7 +4034,7 @@ err2: regulator_put(io_regulator); } err1: - return -1; + return retval; } /*! |