Commit 56ca3be8 authored by Bingbu Cao's avatar Bingbu Cao Committed by Mauro Carvalho Chehab

media: imx208: Support device probe in non-zero ACPI D state

Tell ACPI device PM code that the driver supports the device being in
non-zero ACPI D state when the driver's probe function is entered.

Also do identification on the first access of the device, whether in probe
or when starting streaming.
Signed-off-by: default avatarBingbu Cao <bingbu.cao@intel.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent ada2c4f5
......@@ -296,6 +296,9 @@ struct imx208 {
/* OTP data */
bool otp_read;
char otp_data[IMX208_OTP_SIZE];
/* True if the device has been identified */
bool identified;
};
static inline struct imx208 *to_imx208(struct v4l2_subdev *_sd)
......@@ -619,6 +622,34 @@ static int imx208_set_pad_format(struct v4l2_subdev *sd,
return 0;
}
static int imx208_identify_module(struct imx208 *imx208)
{
struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
int ret;
u32 val;
if (imx208->identified)
return 0;
ret = imx208_read_reg(imx208, IMX208_REG_CHIP_ID,
2, &val);
if (ret) {
dev_err(&client->dev, "failed to read chip id %x\n",
IMX208_CHIP_ID);
return ret;
}
if (val != IMX208_CHIP_ID) {
dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
IMX208_CHIP_ID, val);
return -EIO;
}
imx208->identified = true;
return 0;
}
/* Start streaming */
static int imx208_start_streaming(struct imx208 *imx208)
{
......@@ -626,6 +657,10 @@ static int imx208_start_streaming(struct imx208 *imx208)
const struct imx208_reg_list *reg_list;
int ret, link_freq_index;
ret = imx208_identify_module(imx208);
if (ret)
return ret;
/* Setup PLL */
link_freq_index = imx208->cur_mode->link_freq_index;
reg_list = &link_freq_configs[link_freq_index].reg_list;
......@@ -752,29 +787,6 @@ static int __maybe_unused imx208_resume(struct device *dev)
}
/* Verify chip ID */
static int imx208_identify_module(struct imx208 *imx208)
{
struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
int ret;
u32 val;
ret = imx208_read_reg(imx208, IMX208_REG_CHIP_ID,
2, &val);
if (ret) {
dev_err(&client->dev, "failed to read chip id %x\n",
IMX208_CHIP_ID);
return ret;
}
if (val != IMX208_CHIP_ID) {
dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
IMX208_CHIP_ID, val);
return -EIO;
}
return 0;
}
static const struct v4l2_subdev_video_ops imx208_video_ops = {
.s_stream = imx208_set_stream,
};
......@@ -813,6 +825,10 @@ static int imx208_read_otp(struct imx208 *imx208)
goto out_unlock;
}
ret = imx208_identify_module(imx208);
if (ret)
goto out_pm_put;
/* Write register address */
msgs[0].addr = client->addr;
msgs[0].flags = 0;
......@@ -831,6 +847,7 @@ static int imx208_read_otp(struct imx208 *imx208)
ret = 0;
}
out_pm_put:
pm_runtime_put(&client->dev);
out_unlock:
......@@ -961,6 +978,7 @@ static int imx208_probe(struct i2c_client *client)
{
struct imx208 *imx208;
int ret;
bool full_power;
u32 val = 0;
device_property_read_u32(&client->dev, "clock-frequency", &val);
......@@ -978,12 +996,15 @@ static int imx208_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx208->sd, client, &imx208_subdev_ops);
full_power = acpi_dev_state_d0(&client->dev);
if (full_power) {
/* Check module identity */
ret = imx208_identify_module(imx208);
if (ret) {
dev_err(&client->dev, "failed to find sensor: %d", ret);
goto error_probe;
}
}
/* Set default mode to max resolution */
imx208->cur_mode = &supported_modes[0];
......@@ -1017,6 +1038,8 @@ static int imx208_probe(struct i2c_client *client)
goto error_async_subdev;
}
/* Set the device's state to active if it's in D0 state. */
if (full_power)
pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
......@@ -1077,6 +1100,7 @@ static struct i2c_driver imx208_i2c_driver = {
},
.probe_new = imx208_probe,
.remove = imx208_remove,
.flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
};
module_i2c_driver(imx208_i2c_driver);
......
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