mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
media: ov5640: check chip id
Verify that chip identifier is correct when probing. Signed-off-by: Hugues Fruchet <hugues.fruchet@st.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
parent
1fddc5da9e
commit
0f7acb5291
1 changed files with 79 additions and 16 deletions
|
@ -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_on(struct ov5640_dev *sensor)
|
||||||
|
{
|
||||||
|
struct i2c_client *client = sensor->i2c_client;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = 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,
|
||||||
|
sensor->supplies);
|
||||||
|
if (ret) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
|
static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (on) {
|
if (on) {
|
||||||
clk_prepare_enable(sensor->xclk);
|
ret = ov5640_set_power_on(sensor);
|
||||||
|
|
||||||
ret = regulator_bulk_enable(OV5640_NUM_SUPPLIES,
|
|
||||||
sensor->supplies);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto xclk_off;
|
return ret;
|
||||||
|
|
||||||
ov5640_reset(sensor);
|
|
||||||
ov5640_power(sensor, true);
|
|
||||||
|
|
||||||
ret = ov5640_init_slave_id(sensor);
|
|
||||||
if (ret)
|
|
||||||
goto power_off;
|
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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,
|
||||||
|
|
||||||
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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue