Commit 434aa74b authored by Rajmohan Mani's avatar Rajmohan Mani Committed by Rafael J. Wysocki

media: i2c: imx319: 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.
Signed-off-by: default avatarRajmohan Mani <rajmohan.mani@intel.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: default avatarTomasz Figa <tfiga@chromium.org>
Reviewed-by: default avatarBingbu Cao <bingbu.cao@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent b82a7df4
...@@ -140,6 +140,8 @@ struct imx319 { ...@@ -140,6 +140,8 @@ struct imx319 {
/* Streaming on/off */ /* Streaming on/off */
bool streaming; bool streaming;
/* True if the device has been identified */
bool identified;
}; };
static const struct imx319_reg imx319_global_regs[] = { static const struct imx319_reg imx319_global_regs[] = {
...@@ -2084,6 +2086,31 @@ imx319_set_pad_format(struct v4l2_subdev *sd, ...@@ -2084,6 +2086,31 @@ imx319_set_pad_format(struct v4l2_subdev *sd,
return 0; return 0;
} }
/* Verify chip ID */
static int imx319_identify_module(struct imx319 *imx319)
{
struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
int ret;
u32 val;
if (imx319->identified)
return 0;
ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val);
if (ret)
return ret;
if (val != IMX319_CHIP_ID) {
dev_err(&client->dev, "chip id mismatch: %x!=%x",
IMX319_CHIP_ID, val);
return -EIO;
}
imx319->identified = true;
return 0;
}
/* Start streaming */ /* Start streaming */
static int imx319_start_streaming(struct imx319 *imx319) static int imx319_start_streaming(struct imx319 *imx319)
{ {
...@@ -2091,6 +2118,10 @@ static int imx319_start_streaming(struct imx319 *imx319) ...@@ -2091,6 +2118,10 @@ static int imx319_start_streaming(struct imx319 *imx319)
const struct imx319_reg_list *reg_list; const struct imx319_reg_list *reg_list;
int ret; int ret;
ret = imx319_identify_module(imx319);
if (ret)
return ret;
/* Global Setting */ /* Global Setting */
reg_list = &imx319_global_setting; reg_list = &imx319_global_setting;
ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs); ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
...@@ -2206,26 +2237,6 @@ static int __maybe_unused imx319_resume(struct device *dev) ...@@ -2206,26 +2237,6 @@ static int __maybe_unused imx319_resume(struct device *dev)
return ret; return ret;
} }
/* Verify chip ID */
static int imx319_identify_module(struct imx319 *imx319)
{
struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
int ret;
u32 val;
ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val);
if (ret)
return ret;
if (val != IMX319_CHIP_ID) {
dev_err(&client->dev, "chip id mismatch: %x!=%x",
IMX319_CHIP_ID, val);
return -EIO;
}
return 0;
}
static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = { static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = {
.subscribe_event = v4l2_ctrl_subdev_subscribe_event, .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
.unsubscribe_event = v4l2_event_subdev_unsubscribe, .unsubscribe_event = v4l2_event_subdev_unsubscribe,
...@@ -2420,6 +2431,7 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev) ...@@ -2420,6 +2431,7 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
static int imx319_probe(struct i2c_client *client) static int imx319_probe(struct i2c_client *client)
{ {
struct imx319 *imx319; struct imx319 *imx319;
bool full_power;
int ret; int ret;
u32 i; u32 i;
...@@ -2432,11 +2444,14 @@ static int imx319_probe(struct i2c_client *client) ...@@ -2432,11 +2444,14 @@ static int imx319_probe(struct i2c_client *client)
/* Initialize subdev */ /* Initialize subdev */
v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops); v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);
/* Check module identity */ full_power = acpi_dev_state_d0(&client->dev);
ret = imx319_identify_module(imx319); if (full_power) {
if (ret) { /* Check module identity */
dev_err(&client->dev, "failed to find sensor: %d", ret); ret = imx319_identify_module(imx319);
goto error_probe; if (ret) {
dev_err(&client->dev, "failed to find sensor: %d", ret);
goto error_probe;
}
} }
imx319->hwcfg = imx319_get_hwcfg(&client->dev); imx319->hwcfg = imx319_get_hwcfg(&client->dev);
...@@ -2488,11 +2503,9 @@ static int imx319_probe(struct i2c_client *client) ...@@ -2488,11 +2503,9 @@ static int imx319_probe(struct i2c_client *client)
if (ret < 0) if (ret < 0)
goto error_media_entity; goto error_media_entity;
/* /* Set the device's state to active if it's in D0 state. */
* Device is already turned on by i2c-core with ACPI domain PM. if (full_power)
* Enable runtime PM and turn off the device. pm_runtime_set_active(&client->dev);
*/
pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev); pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev); pm_runtime_idle(&client->dev);
...@@ -2545,6 +2558,7 @@ static struct i2c_driver imx319_i2c_driver = { ...@@ -2545,6 +2558,7 @@ static struct i2c_driver imx319_i2c_driver = {
}, },
.probe_new = imx319_probe, .probe_new = imx319_probe,
.remove = imx319_remove, .remove = imx319_remove,
.flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
}; };
module_i2c_driver(imx319_i2c_driver); module_i2c_driver(imx319_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