@@ -296,6 +296,9 @@ struct imx208 {
296296 /* OTP data */
297297 bool otp_read ;
298298 char otp_data [IMX208_OTP_SIZE ];
299+
300+ /* True if the device has been identified */
301+ bool identified ;
299302};
300303
301304static inline struct imx208 * to_imx208 (struct v4l2_subdev * _sd )
@@ -619,13 +622,45 @@ static int imx208_set_pad_format(struct v4l2_subdev *sd,
619622 return 0 ;
620623}
621624
625+ static int imx208_identify_module (struct imx208 * imx208 )
626+ {
627+ struct i2c_client * client = v4l2_get_subdevdata (& imx208 -> sd );
628+ int ret ;
629+ u32 val ;
630+
631+ if (imx208 -> identified )
632+ return 0 ;
633+
634+ ret = imx208_read_reg (imx208 , IMX208_REG_CHIP_ID ,
635+ 2 , & val );
636+ if (ret ) {
637+ dev_err (& client -> dev , "failed to read chip id %x\n" ,
638+ IMX208_CHIP_ID );
639+ return ret ;
640+ }
641+
642+ if (val != IMX208_CHIP_ID ) {
643+ dev_err (& client -> dev , "chip id mismatch: %x!=%x\n" ,
644+ IMX208_CHIP_ID , val );
645+ return - EIO ;
646+ }
647+
648+ imx208 -> identified = true;
649+
650+ return 0 ;
651+ }
652+
622653/* Start streaming */
623654static int imx208_start_streaming (struct imx208 * imx208 )
624655{
625656 struct i2c_client * client = v4l2_get_subdevdata (& imx208 -> sd );
626657 const struct imx208_reg_list * reg_list ;
627658 int ret , link_freq_index ;
628659
660+ ret = imx208_identify_module (imx208 );
661+ if (ret )
662+ return ret ;
663+
629664 /* Setup PLL */
630665 link_freq_index = imx208 -> cur_mode -> link_freq_index ;
631666 reg_list = & link_freq_configs [link_freq_index ].reg_list ;
@@ -752,29 +787,6 @@ static int __maybe_unused imx208_resume(struct device *dev)
752787}
753788
754789/* Verify chip ID */
755- static int imx208_identify_module (struct imx208 * imx208 )
756- {
757- struct i2c_client * client = v4l2_get_subdevdata (& imx208 -> sd );
758- int ret ;
759- u32 val ;
760-
761- ret = imx208_read_reg (imx208 , IMX208_REG_CHIP_ID ,
762- 2 , & val );
763- if (ret ) {
764- dev_err (& client -> dev , "failed to read chip id %x\n" ,
765- IMX208_CHIP_ID );
766- return ret ;
767- }
768-
769- if (val != IMX208_CHIP_ID ) {
770- dev_err (& client -> dev , "chip id mismatch: %x!=%x\n" ,
771- IMX208_CHIP_ID , val );
772- return - EIO ;
773- }
774-
775- return 0 ;
776- }
777-
778790static const struct v4l2_subdev_video_ops imx208_video_ops = {
779791 .s_stream = imx208_set_stream ,
780792};
@@ -813,6 +825,10 @@ static int imx208_read_otp(struct imx208 *imx208)
813825 goto out_unlock ;
814826 }
815827
828+ ret = imx208_identify_module (imx208 );
829+ if (ret )
830+ goto out_pm_put ;
831+
816832 /* Write register address */
817833 msgs [0 ].addr = client -> addr ;
818834 msgs [0 ].flags = 0 ;
@@ -831,6 +847,7 @@ static int imx208_read_otp(struct imx208 *imx208)
831847 ret = 0 ;
832848 }
833849
850+ out_pm_put :
834851 pm_runtime_put (& client -> dev );
835852
836853out_unlock :
@@ -961,6 +978,7 @@ static int imx208_probe(struct i2c_client *client)
961978{
962979 struct imx208 * imx208 ;
963980 int ret ;
981+ bool full_power ;
964982 u32 val = 0 ;
965983
966984 device_property_read_u32 (& client -> dev , "clock-frequency" , & val );
@@ -978,11 +996,14 @@ static int imx208_probe(struct i2c_client *client)
978996 /* Initialize subdev */
979997 v4l2_i2c_subdev_init (& imx208 -> sd , client , & imx208_subdev_ops );
980998
981- /* Check module identity */
982- ret = imx208_identify_module (imx208 );
983- if (ret ) {
984- dev_err (& client -> dev , "failed to find sensor: %d" , ret );
985- goto error_probe ;
999+ full_power = acpi_dev_state_d0 (& client -> dev );
1000+ if (full_power ) {
1001+ /* Check module identity */
1002+ ret = imx208_identify_module (imx208 );
1003+ if (ret ) {
1004+ dev_err (& client -> dev , "failed to find sensor: %d" , ret );
1005+ goto error_probe ;
1006+ }
9861007 }
9871008
9881009 /* Set default mode to max resolution */
@@ -1017,7 +1038,9 @@ static int imx208_probe(struct i2c_client *client)
10171038 goto error_async_subdev ;
10181039 }
10191040
1020- pm_runtime_set_active (& client -> dev );
1041+ /* Set the device's state to active if it's in D0 state. */
1042+ if (full_power )
1043+ pm_runtime_set_active (& client -> dev );
10211044 pm_runtime_enable (& client -> dev );
10221045 pm_runtime_idle (& client -> dev );
10231046
@@ -1077,6 +1100,7 @@ static struct i2c_driver imx208_i2c_driver = {
10771100 },
10781101 .probe_new = imx208_probe ,
10791102 .remove = imx208_remove ,
1103+ .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE ,
10801104};
10811105
10821106module_i2c_driver (imx208_i2c_driver );
0 commit comments