Commit 0f7acb52 authored by Hugues Fruchet's avatar Hugues Fruchet Committed by Mauro Carvalho Chehab

media: ov5640: check chip id

Verify that chip identifier is correct when probing.
Signed-off-by: default avatarHugues Fruchet <hugues.fruchet@st.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 1fddc5da
...@@ -1547,24 +1547,58 @@ static void ov5640_reset(struct ov5640_dev *sensor) ...@@ -1547,24 +1547,58 @@ static void ov5640_reset(struct ov5640_dev *sensor)
usleep_range(5000, 10000); usleep_range(5000, 10000);
} }
static int ov5640_set_power(struct ov5640_dev *sensor, bool on) static int ov5640_set_power_on(struct ov5640_dev *sensor)
{ {
int ret = 0; struct i2c_client *client = sensor->i2c_client;
int ret;
if (on) { ret = clk_prepare_enable(sensor->xclk);
clk_prepare_enable(sensor->xclk); if (ret) {
dev_err(&client->dev, "%s: failed to enable clock\n",
__func__);
return ret;
}
ret = regulator_bulk_enable(OV5640_NUM_SUPPLIES, ret = regulator_bulk_enable(OV5640_NUM_SUPPLIES,
sensor->supplies); sensor->supplies);
if (ret) if (ret) {
goto xclk_off; dev_err(&client->dev, "%s: failed to enable regulators\n",
__func__);
goto xclk_off;
}
ov5640_reset(sensor);
ov5640_power(sensor, true);
ret = ov5640_init_slave_id(sensor);
if (ret)
goto power_off;
return 0;
power_off:
ov5640_power(sensor, false);
regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
xclk_off:
clk_disable_unprepare(sensor->xclk);
return ret;
}
static void ov5640_set_power_off(struct ov5640_dev *sensor)
{
ov5640_power(sensor, false);
regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
clk_disable_unprepare(sensor->xclk);
}
ov5640_reset(sensor); static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
ov5640_power(sensor, true); {
int ret = 0;
ret = ov5640_init_slave_id(sensor); if (on) {
ret = ov5640_set_power_on(sensor);
if (ret) if (ret)
goto power_off; return ret;
ret = ov5640_restore_mode(sensor); ret = ov5640_restore_mode(sensor);
if (ret) if (ret)
...@@ -1586,10 +1620,7 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on) ...@@ -1586,10 +1620,7 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
} }
power_off: power_off:
ov5640_power(sensor, false); ov5640_set_power_off(sensor);
regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
xclk_off:
clk_disable_unprepare(sensor->xclk);
return ret; return ret;
} }
...@@ -2202,6 +2233,34 @@ static int ov5640_get_regulators(struct ov5640_dev *sensor) ...@@ -2202,6 +2233,34 @@ static int ov5640_get_regulators(struct ov5640_dev *sensor)
sensor->supplies); sensor->supplies);
} }
static int ov5640_check_chip_id(struct ov5640_dev *sensor)
{
struct i2c_client *client = sensor->i2c_client;
int ret = 0;
u16 chip_id;
ret = ov5640_set_power_on(sensor);
if (ret)
return ret;
ret = ov5640_read_reg16(sensor, OV5640_REG_CHIP_ID, &chip_id);
if (ret) {
dev_err(&client->dev, "%s: failed to read chip identifier\n",
__func__);
goto power_off;
}
if (chip_id != 0x5640) {
dev_err(&client->dev, "%s: wrong chip identifier, expected 0x5640, got 0x%x\n",
__func__, chip_id);
ret = -ENXIO;
}
power_off:
ov5640_set_power_off(sensor);
return ret;
}
static int ov5640_probe(struct i2c_client *client, static int ov5640_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -2284,6 +2343,10 @@ static int ov5640_probe(struct i2c_client *client, ...@@ -2284,6 +2343,10 @@ static int ov5640_probe(struct i2c_client *client,
mutex_init(&sensor->lock); mutex_init(&sensor->lock);
ret = ov5640_check_chip_id(sensor);
if (ret)
goto entity_cleanup;
ret = ov5640_init_controls(sensor); ret = ov5640_init_controls(sensor);
if (ret) if (ret)
goto entity_cleanup; goto entity_cleanup;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment