Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+79 −16
Original line number Original line Diff line number Diff line
@@ -1547,17 +1547,25 @@ 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) {
		dev_err(&client->dev, "%s: failed to enable regulators\n",
			__func__);
		goto xclk_off;
		goto xclk_off;
	}


	ov5640_reset(sensor);
	ov5640_reset(sensor);
	ov5640_power(sensor, true);
	ov5640_power(sensor, true);
@@ -1566,6 +1574,32 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
	if (ret)
	if (ret)
		goto power_off;
		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)
{
	int ret = 0;

	if (on) {
		ret = ov5640_set_power_on(sensor);
		if (ret)
			return ret;

		ret = ov5640_restore_mode(sensor);
		ret = ov5640_restore_mode(sensor);
		if (ret)
		if (ret)
			goto power_off;
			goto power_off;
@@ -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;