Skip to content

Commit

Permalink
media: i2c: imx319: Support device probe in non-zero ACPI D state
Browse files Browse the repository at this point in the history
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: Rajmohan Mani <rajmohan.mani@intel.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Bingbu Cao <bingbu.cao@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Rajmohan Mani authored and Rafael J. Wysocki committed Nov 3, 2021
1 parent b82a7df commit 434aa74
Showing 1 changed file with 44 additions and 30 deletions.
74 changes: 44 additions & 30 deletions drivers/media/i2c/imx319.c
Original file line number Diff line number Diff line change
@@ -140,6 +140,8 @@ struct imx319 {

/* Streaming on/off */
bool streaming;
/* True if the device has been identified */
bool identified;
};

static const struct imx319_reg imx319_global_regs[] = {
@@ -2084,13 +2086,42 @@ imx319_set_pad_format(struct v4l2_subdev *sd,
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 */
static int imx319_start_streaming(struct imx319 *imx319)
{
struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
const struct imx319_reg_list *reg_list;
int ret;

ret = imx319_identify_module(imx319);
if (ret)
return ret;

/* Global Setting */
reg_list = &imx319_global_setting;
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)
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 = {
.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
@@ -2420,6 +2431,7 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
static int imx319_probe(struct i2c_client *client)
{
struct imx319 *imx319;
bool full_power;
int ret;
u32 i;

@@ -2432,11 +2444,14 @@ static int imx319_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);

/* Check module identity */
ret = imx319_identify_module(imx319);
if (ret) {
dev_err(&client->dev, "failed to find sensor: %d", ret);
goto error_probe;
full_power = acpi_dev_state_d0(&client->dev);
if (full_power) {
/* Check module identity */
ret = imx319_identify_module(imx319);
if (ret) {
dev_err(&client->dev, "failed to find sensor: %d", ret);
goto error_probe;
}
}

imx319->hwcfg = imx319_get_hwcfg(&client->dev);
@@ -2488,11 +2503,9 @@ static int imx319_probe(struct i2c_client *client)
if (ret < 0)
goto error_media_entity;

/*
* Device is already turned on by i2c-core with ACPI domain PM.
* Enable runtime PM and turn off the device.
*/
pm_runtime_set_active(&client->dev);
/* 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);

@@ -2545,6 +2558,7 @@ static struct i2c_driver imx319_i2c_driver = {
},
.probe_new = imx319_probe,
.remove = imx319_remove,
.flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
};
module_i2c_driver(imx319_i2c_driver);

0 comments on commit 434aa74

Please sign in to comment.