Skip to content

Commit d1d2ed5

Browse files
bingbucaomchehab
authored andcommitted
media: hi556: 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: Bingbu Cao <[email protected]> Signed-off-by: Kao, Arec <[email protected]> Signed-off-by: Sakari Ailus <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 5525fd8 commit d1d2ed5

File tree

1 file changed

+45
-25
lines changed

1 file changed

+45
-25
lines changed

drivers/media/i2c/hi556.c

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,9 @@ struct hi556 {
495495

496496
/* Streaming on/off */
497497
bool streaming;
498+
499+
/* True if the device has been identified */
500+
bool identified;
498501
};
499502

500503
static u64 to_pixel_rate(u32 f_index)
@@ -757,12 +760,41 @@ static void hi556_assign_pad_format(const struct hi556_mode *mode,
757760
fmt->field = V4L2_FIELD_NONE;
758761
}
759762

763+
static int hi556_identify_module(struct hi556 *hi556)
764+
{
765+
struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
766+
int ret;
767+
u32 val;
768+
769+
if (hi556->identified)
770+
return 0;
771+
772+
ret = hi556_read_reg(hi556, HI556_REG_CHIP_ID,
773+
HI556_REG_VALUE_16BIT, &val);
774+
if (ret)
775+
return ret;
776+
777+
if (val != HI556_CHIP_ID) {
778+
dev_err(&client->dev, "chip id mismatch: %x!=%x",
779+
HI556_CHIP_ID, val);
780+
return -ENXIO;
781+
}
782+
783+
hi556->identified = true;
784+
785+
return 0;
786+
}
787+
760788
static int hi556_start_streaming(struct hi556 *hi556)
761789
{
762790
struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
763791
const struct hi556_reg_list *reg_list;
764792
int link_freq_index, ret;
765793

794+
ret = hi556_identify_module(hi556);
795+
if (ret)
796+
return ret;
797+
766798
link_freq_index = hi556->cur_mode->link_freq_index;
767799
reg_list = &link_freq_configs[link_freq_index].reg_list;
768800
ret = hi556_write_reg_list(hi556, reg_list);
@@ -1001,26 +1033,6 @@ static const struct v4l2_subdev_internal_ops hi556_internal_ops = {
10011033
.open = hi556_open,
10021034
};
10031035

1004-
static int hi556_identify_module(struct hi556 *hi556)
1005-
{
1006-
struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
1007-
int ret;
1008-
u32 val;
1009-
1010-
ret = hi556_read_reg(hi556, HI556_REG_CHIP_ID,
1011-
HI556_REG_VALUE_16BIT, &val);
1012-
if (ret)
1013-
return ret;
1014-
1015-
if (val != HI556_CHIP_ID) {
1016-
dev_err(&client->dev, "chip id mismatch: %x!=%x",
1017-
HI556_CHIP_ID, val);
1018-
return -ENXIO;
1019-
}
1020-
1021-
return 0;
1022-
}
1023-
10241036
static int hi556_check_hwcfg(struct device *dev)
10251037
{
10261038
struct fwnode_handle *ep;
@@ -1106,6 +1118,7 @@ static int hi556_remove(struct i2c_client *client)
11061118
static int hi556_probe(struct i2c_client *client)
11071119
{
11081120
struct hi556 *hi556;
1121+
bool full_power;
11091122
int ret;
11101123

11111124
ret = hi556_check_hwcfg(&client->dev);
@@ -1120,10 +1133,14 @@ static int hi556_probe(struct i2c_client *client)
11201133
return -ENOMEM;
11211134

11221135
v4l2_i2c_subdev_init(&hi556->sd, client, &hi556_subdev_ops);
1123-
ret = hi556_identify_module(hi556);
1124-
if (ret) {
1125-
dev_err(&client->dev, "failed to find sensor: %d", ret);
1126-
return ret;
1136+
1137+
full_power = acpi_dev_state_d0(&client->dev);
1138+
if (full_power) {
1139+
ret = hi556_identify_module(hi556);
1140+
if (ret) {
1141+
dev_err(&client->dev, "failed to find sensor: %d", ret);
1142+
return ret;
1143+
}
11271144
}
11281145

11291146
mutex_init(&hi556->mutex);
@@ -1152,7 +1169,9 @@ static int hi556_probe(struct i2c_client *client)
11521169
goto probe_error_media_entity_cleanup;
11531170
}
11541171

1155-
pm_runtime_set_active(&client->dev);
1172+
/* Set the device's state to active if it's in D0 state. */
1173+
if (full_power)
1174+
pm_runtime_set_active(&client->dev);
11561175
pm_runtime_enable(&client->dev);
11571176
pm_runtime_idle(&client->dev);
11581177

@@ -1189,6 +1208,7 @@ static struct i2c_driver hi556_i2c_driver = {
11891208
},
11901209
.probe_new = hi556_probe,
11911210
.remove = hi556_remove,
1211+
.flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
11921212
};
11931213

11941214
module_i2c_driver(hi556_i2c_driver);

0 commit comments

Comments
 (0)