From patchwork Wed Dec 15 11:08:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Cao, Bingbu" X-Patchwork-Id: 12678071 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 785CAC433F5 for ; Wed, 15 Dec 2021 11:12:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236953AbhLOLMO (ORCPT ); Wed, 15 Dec 2021 06:12:14 -0500 Received: from mga14.intel.com ([192.55.52.115]:63314 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234229AbhLOLMN (ORCPT ); Wed, 15 Dec 2021 06:12:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1639566733; x=1671102733; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=p19gpVdGsv/fT3Wrp1AQfJVSEjVYbZ/RYJNivq+7aKY=; b=PHbCKPITI9r/b5rnw3ykaz2R4aUYaqEKOQzEJzLTg+fkN6hSz6mbiW/I 2Uvx3jDVh/8nzv1Ml14t1T0e06vTklIKJj7/r+ug/EkYt4dPE6WZTPsTp DKgnoyTXZjMzD0k4kTSArcMiKZWzgb8zeBvqFiBEZ+8yfLIp9rREfuwhw bwyktTZcvTOBdS1Qg1Z0rADlpeEHQEsJus+SarpiZ9x22jV7mzzfOY/ny HddF9qPyvsH5ltzqiuavdVrKupUa2AuLKFtRj6i/BHPTqnz6ARcVpbQH7 7zsSvwsNtKKjyWpHvJAbytA6hyyhFX80FgKiMtETipMBwUDdTZ5rIB243 Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10198"; a="239424547" X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="239424547" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Dec 2021 03:12:13 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="661891533" Received: from ipu5-build.bj.intel.com ([10.238.232.188]) by fmsmga001.fm.intel.com with ESMTP; 15 Dec 2021 03:12:10 -0800 From: Bingbu Cao To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, rafael@kernel.org Cc: shawnx.tu@intel.com, chiranjeevi.rapolu@intel.com, tfiga@chromium.org, senozhatsky@chromium.org, linux-kernel@vger.kernel.org, bingbu.cao@linux.intel.com Subject: [PATCH v2 1/6] media: ov8856: support device probe in non-zero ACPI D state Date: Wed, 15 Dec 2021 19:08:58 +0800 Message-Id: <1639566543-8561-2-git-send-email-bingbu.cao@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> References: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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 --- drivers/media/i2c/ov8856.c | 162 +++++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 73 deletions(-) diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c index c6c6050cda1a..8785764b7a74 100644 --- a/drivers/media/i2c/ov8856.c +++ b/drivers/media/i2c/ov8856.c @@ -1445,6 +1445,9 @@ struct ov8856 { const struct ov8856_lane_cfg *priv_lane; u8 modes_size; + + /* True if the device has been identified */ + bool identified; }; struct ov8856_lane_cfg { @@ -1685,6 +1688,71 @@ static int ov8856_write_reg_list(struct ov8856 *ov8856, return 0; } +static int ov8856_identify_module(struct ov8856 *ov8856) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd); + int ret; + u32 val; + + if (ov8856->identified) + return 0; + + ret = ov8856_read_reg(ov8856, OV8856_REG_CHIP_ID, + OV8856_REG_VALUE_24BIT, &val); + if (ret) + return ret; + + if (val != OV8856_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%x", + OV8856_CHIP_ID, val); + return -ENXIO; + } + + ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT, + OV8856_REG_VALUE_08BIT, OV8856_MODE_STREAMING); + if (ret) + return ret; + + ret = ov8856_write_reg(ov8856, OV8856_OTP_MODE_CTRL, + OV8856_REG_VALUE_08BIT, OV8856_OTP_MODE_AUTO); + if (ret) { + dev_err(&client->dev, "failed to set otp mode"); + return ret; + } + + ret = ov8856_write_reg(ov8856, OV8856_OTP_LOAD_CTRL, + OV8856_REG_VALUE_08BIT, + OV8856_OTP_LOAD_CTRL_ENABLE); + if (ret) { + dev_err(&client->dev, "failed to enable load control"); + return ret; + } + + ret = ov8856_read_reg(ov8856, OV8856_MODULE_REVISION, + OV8856_REG_VALUE_08BIT, &val); + if (ret) { + dev_err(&client->dev, "failed to read module revision"); + return ret; + } + + dev_info(&client->dev, "OV8856 revision %x (%s) at address 0x%02x\n", + val, + val == OV8856_2A_MODULE ? "2A" : + val == OV8856_1B_MODULE ? "1B" : "unknown revision", + client->addr); + + ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT, + OV8856_REG_VALUE_08BIT, OV8856_MODE_STANDBY); + if (ret) { + dev_err(&client->dev, "failed to exit streaming mode"); + return ret; + } + + ov8856->identified = true; + + return 0; +} + static int ov8856_update_digital_gain(struct ov8856 *ov8856, u32 d_gain) { int ret; @@ -1969,6 +2037,10 @@ static int ov8856_start_streaming(struct ov8856 *ov8856) const struct ov8856_reg_list *reg_list; int link_freq_index, ret; + ret = ov8856_identify_module(ov8856); + if (ret) + return ret; + link_freq_index = ov8856->cur_mode->link_freq_index; reg_list = &ov8856->priv_lane->link_freq_configs[link_freq_index].reg_list; @@ -2276,65 +2348,6 @@ static const struct v4l2_subdev_internal_ops ov8856_internal_ops = { .open = ov8856_open, }; -static int ov8856_identify_module(struct ov8856 *ov8856) -{ - struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd); - int ret; - u32 val; - - ret = ov8856_read_reg(ov8856, OV8856_REG_CHIP_ID, - OV8856_REG_VALUE_24BIT, &val); - if (ret) - return ret; - - if (val != OV8856_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%x", - OV8856_CHIP_ID, val); - return -ENXIO; - } - - ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT, - OV8856_REG_VALUE_08BIT, OV8856_MODE_STREAMING); - if (ret) - return ret; - - ret = ov8856_write_reg(ov8856, OV8856_OTP_MODE_CTRL, - OV8856_REG_VALUE_08BIT, OV8856_OTP_MODE_AUTO); - if (ret) { - dev_err(&client->dev, "failed to set otp mode"); - return ret; - } - - ret = ov8856_write_reg(ov8856, OV8856_OTP_LOAD_CTRL, - OV8856_REG_VALUE_08BIT, - OV8856_OTP_LOAD_CTRL_ENABLE); - if (ret) { - dev_err(&client->dev, "failed to enable load control"); - return ret; - } - - ret = ov8856_read_reg(ov8856, OV8856_MODULE_REVISION, - OV8856_REG_VALUE_08BIT, &val); - if (ret) { - dev_err(&client->dev, "failed to read module revision"); - return ret; - } - - dev_info(&client->dev, "OV8856 revision %x (%s) at address 0x%02x\n", - val, - val == OV8856_2A_MODULE ? "2A" : - val == OV8856_1B_MODULE ? "1B" : "unknown revision", - client->addr); - - ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT, - OV8856_REG_VALUE_08BIT, OV8856_MODE_STANDBY); - if (ret) { - dev_err(&client->dev, "failed to exit streaming mode"); - return ret; - } - - return 0; -} static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev) { @@ -2458,6 +2471,7 @@ static int ov8856_probe(struct i2c_client *client) { struct ov8856 *ov8856; int ret; + bool full_power; ov8856 = devm_kzalloc(&client->dev, sizeof(*ov8856), GFP_KERNEL); if (!ov8856) @@ -2472,16 +2486,19 @@ static int ov8856_probe(struct i2c_client *client) v4l2_i2c_subdev_init(&ov8856->sd, client, &ov8856_subdev_ops); - ret = __ov8856_power_on(ov8856); - if (ret) { - dev_err(&client->dev, "failed to power on\n"); - return ret; - } + full_power = acpi_dev_state_d0(&client->dev); + if (full_power) { + ret = __ov8856_power_on(ov8856); + if (ret) { + dev_err(&client->dev, "failed to power on\n"); + return ret; + } - ret = ov8856_identify_module(ov8856); - if (ret) { - dev_err(&client->dev, "failed to find sensor: %d", ret); - goto probe_power_off; + ret = ov8856_identify_module(ov8856); + if (ret) { + dev_err(&client->dev, "failed to find sensor: %d", ret); + goto probe_power_off; + } } mutex_init(&ov8856->mutex); @@ -2511,11 +2528,9 @@ static int ov8856_probe(struct i2c_client *client) goto probe_error_media_entity_cleanup; } - /* - * 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); @@ -2562,6 +2577,7 @@ static struct i2c_driver ov8856_i2c_driver = { }, .probe_new = ov8856_probe, .remove = ov8856_remove, + .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; module_i2c_driver(ov8856_i2c_driver); From patchwork Wed Dec 15 11:08:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Cao, Bingbu" X-Patchwork-Id: 12678073 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 451AEC433F5 for ; Wed, 15 Dec 2021 11:12:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241981AbhLOLMT (ORCPT ); Wed, 15 Dec 2021 06:12:19 -0500 Received: from mga14.intel.com ([192.55.52.115]:63314 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241963AbhLOLMQ (ORCPT ); Wed, 15 Dec 2021 06:12:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1639566736; x=1671102736; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=LEvdEP6VbQLXdwbGej7ww+xvYhpru80UVqBFLpRnufA=; b=LvNxDSCgnksn1h43HWzmrUov43nCFEZLhgrhhDVUJOmZl0v5q2UwkAhS IlnI6w0+PUFtkgvhI3QGvynDk5tihV1Z/Y/Y1RPvtFxSO8HquD/DvHiev 7a4GD+E0Yqi4cyR4qV7IEfOBcIVvVkiUJrPE+gIn9QAdIFiTdslC4dKA7 rs9fI3RdjabBx9P8iAROmheGu2PJvm2bBYMJzPfHex4dZz9cdX2oXKRAE EMzh7cgx3D/SnMm9uJUjW7I+YbszRvH2ko49OzCK3zOhX4ualJx/5p8AS ZnWG7KsJQs6Y2tzX/7B4gxkcgDVAPD8XaqaxdBtvC88IdkN/8ur7k03ML A==; X-IronPort-AV: E=McAfee;i="6200,9189,10198"; a="239424550" X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="239424550" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Dec 2021 03:12:16 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="661891544" Received: from ipu5-build.bj.intel.com ([10.238.232.188]) by fmsmga001.fm.intel.com with ESMTP; 15 Dec 2021 03:12:13 -0800 From: Bingbu Cao To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, rafael@kernel.org Cc: shawnx.tu@intel.com, chiranjeevi.rapolu@intel.com, tfiga@chromium.org, senozhatsky@chromium.org, linux-kernel@vger.kernel.org, bingbu.cao@linux.intel.com Subject: [PATCH v2 2/6] media: ov5670: Support device probe in non-zero ACPI D state Date: Wed, 15 Dec 2021 19:08:59 +0800 Message-Id: <1639566543-8561-3-git-send-email-bingbu.cao@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> References: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus 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 Signed-off-by: Sakari Ailus --- drivers/media/i2c/ov5670.c | 78 +++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 251f459ab484..5adf73cb88d4 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -1833,6 +1833,8 @@ struct ov5670 { /* Streaming on/off */ bool streaming; + /* True if the device has been identified */ + bool identified; }; #define to_ov5670(_sd) container_of(_sd, struct ov5670, sd) @@ -2273,6 +2275,32 @@ static int ov5670_get_skip_frames(struct v4l2_subdev *sd, u32 *frames) return 0; } +/* Verify chip ID */ +static int ov5670_identify_module(struct ov5670 *ov5670) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); + int ret; + u32 val; + + if (ov5670->identified) + return 0; + + ret = ov5670_read_reg(ov5670, OV5670_REG_CHIP_ID, + OV5670_REG_VALUE_24BIT, &val); + if (ret) + return ret; + + if (val != OV5670_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%x\n", + OV5670_CHIP_ID, val); + return -ENXIO; + } + + ov5670->identified = true; + + return 0; +} + /* Prepare streaming by writing default values and customized values */ static int ov5670_start_streaming(struct ov5670 *ov5670) { @@ -2281,6 +2309,10 @@ static int ov5670_start_streaming(struct ov5670 *ov5670) int link_freq_index; int ret; + ret = ov5670_identify_module(ov5670); + if (ret) + return ret; + /* Get out of from software reset */ ret = ov5670_write_reg(ov5670, OV5670_REG_SOFTWARE_RST, OV5670_REG_VALUE_08BIT, OV5670_SOFTWARE_RST); @@ -2400,27 +2432,6 @@ static int __maybe_unused ov5670_resume(struct device *dev) return 0; } -/* Verify chip ID */ -static int ov5670_identify_module(struct ov5670 *ov5670) -{ - struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); - int ret; - u32 val; - - ret = ov5670_read_reg(ov5670, OV5670_REG_CHIP_ID, - OV5670_REG_VALUE_24BIT, &val); - if (ret) - return ret; - - if (val != OV5670_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%x\n", - OV5670_CHIP_ID, val); - return -ENXIO; - } - - return 0; -} - static const struct v4l2_subdev_core_ops ov5670_core_ops = { .log_status = v4l2_ctrl_subdev_log_status, .subscribe_event = v4l2_ctrl_subdev_subscribe_event, @@ -2462,6 +2473,7 @@ static int ov5670_probe(struct i2c_client *client) struct ov5670 *ov5670; const char *err_msg; u32 input_clk = 0; + bool full_power; int ret; device_property_read_u32(&client->dev, "clock-frequency", &input_clk); @@ -2478,11 +2490,14 @@ static int ov5670_probe(struct i2c_client *client) /* Initialize subdev */ v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops); - /* Check module identity */ - ret = ov5670_identify_module(ov5670); - if (ret) { - err_msg = "ov5670_identify_module() error"; - goto error_print; + full_power = acpi_dev_state_d0(&client->dev); + if (full_power) { + /* Check module identity */ + ret = ov5670_identify_module(ov5670); + if (ret) { + err_msg = "ov5670_identify_module() error"; + goto error_print; + } } mutex_init(&ov5670->mutex); @@ -2519,11 +2534,9 @@ static int ov5670_probe(struct i2c_client *client) ov5670->streaming = false; - /* - * 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); @@ -2565,7 +2578,7 @@ static const struct dev_pm_ops ov5670_pm_ops = { #ifdef CONFIG_ACPI static const struct acpi_device_id ov5670_acpi_ids[] = { - {"INT3479"}, + { "INT3479" }, { /* sentinel */ } }; @@ -2580,6 +2593,7 @@ static struct i2c_driver ov5670_i2c_driver = { }, .probe_new = ov5670_probe, .remove = ov5670_remove, + .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; module_i2c_driver(ov5670_i2c_driver); From patchwork Wed Dec 15 11:09:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Cao, Bingbu" X-Patchwork-Id: 12678075 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F09DEC433EF for ; Wed, 15 Dec 2021 11:12:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241994AbhLOLMV (ORCPT ); Wed, 15 Dec 2021 06:12:21 -0500 Received: from mga14.intel.com ([192.55.52.115]:63314 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237049AbhLOLMT (ORCPT ); Wed, 15 Dec 2021 06:12:19 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1639566739; x=1671102739; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=b3BZukaP2MFDjvcBAuPIdYvzAH8qFopuf9TzlXx7JzY=; b=ZJH9qCIpc/4puXgnRSrU1hnkyh1nyTeyixKPxfNzLWUo2MQ/voq70ZBx YzyOk9fyt8+QQEJPfYW7veLwXKdjfL0Z55B6DuRkfZz6PSwfzOC8IiGq7 x94yzPEjAIQYX2l21yvUtE1vy+LF+VOlS59IYDXZfE9jOzLZP3lqcbVer iyYYy2RlWh8Oa6+nFB4g3kyuZNMRAQD2DaL8P+fYiEtnJTCQrsZCtFnkf yJ5Z3qmrhNmdGmUTDt9AxawOb+ccLkX8UueyCCiQw8uYW34kW//CyVmCB E3hDErkKYaTXF02zlWfdbkCUW3Lyh2tCM+qvuX5FxjdusRqkRwVFoQJA1 Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10198"; a="239424563" X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="239424563" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Dec 2021 03:12:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="661891567" Received: from ipu5-build.bj.intel.com ([10.238.232.188]) by fmsmga001.fm.intel.com with ESMTP; 15 Dec 2021 03:12:16 -0800 From: Bingbu Cao To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, rafael@kernel.org Cc: shawnx.tu@intel.com, chiranjeevi.rapolu@intel.com, tfiga@chromium.org, senozhatsky@chromium.org, linux-kernel@vger.kernel.org, bingbu.cao@linux.intel.com Subject: [PATCH v2 3/6] media: ov2740: support device probe in non-zero ACPI D state Date: Wed, 15 Dec 2021 19:09:00 +0800 Message-Id: <1639566543-8561-4-git-send-email-bingbu.cao@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> References: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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 --- drivers/media/i2c/ov2740.c | 69 ++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index 934c9d65cb09..bab720c7c1de 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -345,6 +345,9 @@ struct ov2740 { /* NVM data inforamtion */ struct nvm_data *nvm; + + /* True if the device has been identified */ + bool identified; }; static inline struct ov2740 *to_ov2740(struct v4l2_subdev *subdev) @@ -440,6 +443,30 @@ static int ov2740_write_reg_list(struct ov2740 *ov2740, return 0; } +static int ov2740_identify_module(struct ov2740 *ov2740) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd); + int ret; + u32 val; + + if (ov2740->identified) + return 0; + + ret = ov2740_read_reg(ov2740, OV2740_REG_CHIP_ID, 3, &val); + if (ret) + return ret; + + if (val != OV2740_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%x", + OV2740_CHIP_ID, val); + return -ENXIO; + } + + ov2740->identified = true; + + return 0; +} + static int ov2740_update_digital_gain(struct ov2740 *ov2740, u32 d_gain) { int ret = 0; @@ -724,6 +751,10 @@ static int ov2740_start_streaming(struct ov2740 *ov2740) int link_freq_index; int ret = 0; + ret = ov2740_identify_module(ov2740); + if (ret) + return ret; + ov2740_load_otp_data(nvm); link_freq_index = ov2740->cur_mode->link_freq_index; @@ -956,25 +987,6 @@ static const struct v4l2_subdev_internal_ops ov2740_internal_ops = { .open = ov2740_open, }; -static int ov2740_identify_module(struct ov2740 *ov2740) -{ - struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd); - int ret; - u32 val; - - ret = ov2740_read_reg(ov2740, OV2740_REG_CHIP_ID, 3, &val); - if (ret) - return ret; - - if (val != OV2740_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%x", - OV2740_CHIP_ID, val); - return -ENXIO; - } - - return 0; -} - static int ov2740_check_hwcfg(struct device *dev) { struct fwnode_handle *ep; @@ -1137,6 +1149,7 @@ static int ov2740_probe(struct i2c_client *client) { struct ov2740 *ov2740; int ret = 0; + bool full_power; ret = ov2740_check_hwcfg(&client->dev); if (ret) { @@ -1149,6 +1162,15 @@ static int ov2740_probe(struct i2c_client *client) if (!ov2740) return -ENOMEM; + full_power = acpi_dev_state_d0(&client->dev); + if (full_power) { + ret = ov2740_identify_module(ov2740); + if (ret) { + dev_err(&client->dev, "failed to find sensor: %d", ret); + return ret; + } + } + v4l2_i2c_subdev_init(&ov2740->sd, client, &ov2740_subdev_ops); ret = ov2740_identify_module(ov2740); if (ret) { @@ -1186,11 +1208,9 @@ static int ov2740_probe(struct i2c_client *client) if (ret) dev_warn(&client->dev, "register nvmem failed, ret %d\n", ret); - /* - * 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); @@ -1225,6 +1245,7 @@ static struct i2c_driver ov2740_i2c_driver = { }, .probe_new = ov2740_probe, .remove = ov2740_remove, + .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; module_i2c_driver(ov2740_i2c_driver); From patchwork Wed Dec 15 11:09:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Cao, Bingbu" X-Patchwork-Id: 12678077 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 09EF1C433F5 for ; Wed, 15 Dec 2021 11:12:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242008AbhLOLMY (ORCPT ); Wed, 15 Dec 2021 06:12:24 -0500 Received: from mga14.intel.com ([192.55.52.115]:63314 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234438AbhLOLMV (ORCPT ); Wed, 15 Dec 2021 06:12:21 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1639566741; x=1671102741; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=Z1lFsYlZv4n937462Dsck0ZQm1xRcuffqO61eFtiITU=; b=gykct4P3cyg1Z5Q3FntHv+OiEZ4pl308lczYY51nonGoyF1wbjTJBMGG HgmvgPwOS/8qOWexGnT2DfrOdDJ+zNAAGIKQ7APu9AAlT95I2piSG4pBG 1D7Vfol5B+L3aZwkb5WuqJ/U1L/GawMOKisqfg+uxu9LPRVuwRxcE3zA3 9fQI48Eyese64jeZ92214l0gRre32WG8TzdXLl0q+E9Z33mXNobKHoHO1 LK+ybHyECpWDmDuxzvI1R13qpYX+qAt1d0a06+8lB3Bn44ZT+r9+cozN/ wzY78xsh7ySU5g8lGVX8Gm3kb+JFZwxZ3XtGrJ9I3xh7PYhoYR7PFND7p w==; X-IronPort-AV: E=McAfee;i="6200,9189,10198"; a="239424570" X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="239424570" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Dec 2021 03:12:21 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="661891577" Received: from ipu5-build.bj.intel.com ([10.238.232.188]) by fmsmga001.fm.intel.com with ESMTP; 15 Dec 2021 03:12:19 -0800 From: Bingbu Cao To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, rafael@kernel.org Cc: shawnx.tu@intel.com, chiranjeevi.rapolu@intel.com, tfiga@chromium.org, senozhatsky@chromium.org, linux-kernel@vger.kernel.org, bingbu.cao@linux.intel.com Subject: [PATCH v2 4/6] media: imx208: Support device probe in non-zero ACPI D state Date: Wed, 15 Dec 2021 19:09:01 +0800 Message-Id: <1639566543-8561-5-git-send-email-bingbu.cao@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> References: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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 --- drivers/media/i2c/imx208.c | 82 ++++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/drivers/media/i2c/imx208.c b/drivers/media/i2c/imx208.c index 6f3d9c1b5879..b9516b2f1c15 100644 --- a/drivers/media/i2c/imx208.c +++ b/drivers/media/i2c/imx208.c @@ -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,11 +996,14 @@ static int imx208_probe(struct i2c_client *client) /* Initialize subdev */ v4l2_i2c_subdev_init(&imx208->sd, client, &imx208_subdev_ops); - /* Check module identity */ - ret = imx208_identify_module(imx208); - 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 = 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 */ @@ -1017,7 +1038,9 @@ static int imx208_probe(struct i2c_client *client) goto error_async_subdev; } - 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); @@ -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); From patchwork Wed Dec 15 11:09:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Cao, Bingbu" X-Patchwork-Id: 12678079 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8B21C4332F for ; Wed, 15 Dec 2021 11:12:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242023AbhLOLM1 (ORCPT ); Wed, 15 Dec 2021 06:12:27 -0500 Received: from mga14.intel.com ([192.55.52.115]:63314 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242000AbhLOLMY (ORCPT ); Wed, 15 Dec 2021 06:12:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1639566744; x=1671102744; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=pqyUJZNA695XA2/jLm5NMQB5lQ3C4KIqTxok8z0ABUA=; b=WNjNeGcnAKoJrS3CyOu6nlh1JwJVjm6ITnuPtaed0rkPDrRaPeB8ZG1t /kN7iMs7L3Ise2pvV+ROY6hl8usAaHMcrp230K1tOTEi8T1cEUoeTceFp fajyZtHfvTfrWpN+2LrQxU3HKIL6tJYTvsEGH0IhMjIFo19NpKwwroj4t EBnZHqWPishiEqV/RruAdFEsleepIjpC8gQuIcMr7xV3jOUlpym+PFbuw OxCzTvYlRZrMNgJIExHPBqjMsYKzfq8XkVcNXEm9PfYTcXq0L+XmrZZdR +ICM3RM4etXZvuZCFGLl+UAN5/1aaq9KGPNG0pKkOI0ffEN0DZ4E6ljLn A==; X-IronPort-AV: E=McAfee;i="6200,9189,10198"; a="239424577" X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="239424577" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Dec 2021 03:12:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="661891586" Received: from ipu5-build.bj.intel.com ([10.238.232.188]) by fmsmga001.fm.intel.com with ESMTP; 15 Dec 2021 03:12:21 -0800 From: Bingbu Cao To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, rafael@kernel.org Cc: shawnx.tu@intel.com, chiranjeevi.rapolu@intel.com, tfiga@chromium.org, senozhatsky@chromium.org, linux-kernel@vger.kernel.org, bingbu.cao@linux.intel.com Subject: [PATCH v2 5/6] media: ov5675: Support device probe in non-zero ACPI D state Date: Wed, 15 Dec 2021 19:09:02 +0800 Message-Id: <1639566543-8561-6-git-send-email-bingbu.cao@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> References: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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 --- drivers/media/i2c/ov5675.c | 71 ++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c index da5850b7ad07..00925850fa7c 100644 --- a/drivers/media/i2c/ov5675.c +++ b/drivers/media/i2c/ov5675.c @@ -493,6 +493,9 @@ struct ov5675 { /* Streaming on/off */ bool streaming; + + /* True if the device has been identified */ + bool identified; }; static u64 to_pixel_rate(u32 f_index) @@ -808,12 +811,41 @@ static void ov5675_update_pad_format(const struct ov5675_mode *mode, fmt->field = V4L2_FIELD_NONE; } +static int ov5675_identify_module(struct ov5675 *ov5675) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd); + int ret; + u32 val; + + if (ov5675->identified) + return 0; + + ret = ov5675_read_reg(ov5675, OV5675_REG_CHIP_ID, + OV5675_REG_VALUE_24BIT, &val); + if (ret) + return ret; + + if (val != OV5675_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%x", + OV5675_CHIP_ID, val); + return -ENXIO; + } + + ov5675->identified = true; + + return 0; +} + static int ov5675_start_streaming(struct ov5675 *ov5675) { struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd); const struct ov5675_reg_list *reg_list; int link_freq_index, ret; + ret = ov5675_identify_module(ov5675); + if (ret) + return ret; + link_freq_index = ov5675->cur_mode->link_freq_index; reg_list = &link_freq_configs[link_freq_index].reg_list; ret = ov5675_write_reg_list(ov5675, reg_list); @@ -1048,26 +1080,6 @@ static const struct v4l2_subdev_internal_ops ov5675_internal_ops = { .open = ov5675_open, }; -static int ov5675_identify_module(struct ov5675 *ov5675) -{ - struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd); - int ret; - u32 val; - - ret = ov5675_read_reg(ov5675, OV5675_REG_CHIP_ID, - OV5675_REG_VALUE_24BIT, &val); - if (ret) - return ret; - - if (val != OV5675_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%x", - OV5675_CHIP_ID, val); - return -ENXIO; - } - - return 0; -} - static int ov5675_check_hwcfg(struct device *dev) { struct fwnode_handle *ep; @@ -1154,6 +1166,7 @@ static int ov5675_remove(struct i2c_client *client) static int ov5675_probe(struct i2c_client *client) { struct ov5675 *ov5675; + bool full_power; int ret; ret = ov5675_check_hwcfg(&client->dev); @@ -1168,10 +1181,14 @@ static int ov5675_probe(struct i2c_client *client) return -ENOMEM; v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops); - ret = ov5675_identify_module(ov5675); - if (ret) { - dev_err(&client->dev, "failed to find sensor: %d", ret); - return ret; + + full_power = acpi_dev_state_d0(&client->dev); + if (full_power) { + ret = ov5675_identify_module(ov5675); + if (ret) { + dev_err(&client->dev, "failed to find sensor: %d", ret); + return ret; + } } mutex_init(&ov5675->mutex); @@ -1204,7 +1221,10 @@ static int ov5675_probe(struct i2c_client *client) * 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); @@ -1241,6 +1261,7 @@ static struct i2c_driver ov5675_i2c_driver = { }, .probe_new = ov5675_probe, .remove = ov5675_remove, + .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; module_i2c_driver(ov5675_i2c_driver); From patchwork Wed Dec 15 11:09:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Cao, Bingbu" X-Patchwork-Id: 12678081 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8D67AC433F5 for ; Wed, 15 Dec 2021 11:12:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242040AbhLOLMb (ORCPT ); Wed, 15 Dec 2021 06:12:31 -0500 Received: from mga14.intel.com ([192.55.52.115]:63314 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241982AbhLOLM1 (ORCPT ); Wed, 15 Dec 2021 06:12:27 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1639566747; x=1671102747; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=9l7vz7S6sHBPOubcfHs4L+ETl/DmVqg9c1nE2ISAZVA=; b=PzvIZCLSuLC+hzy+cjEf1d0JtmXwtiiRBzn6zhNa6Jbx4wqefZye3ZbR Uj23gq1iZymMZUJetHEAFjPKVOWehGOYv+KA7wYHVMzlDtfz9RR5b8KNB S7qdNFFIjQJIfNU6uGQOZS0m7kRirsro/WzG0NvOWheGUNwJpsiTReAV7 XsZmFqvArsJNc4q3MNa2Bi73i5u9nZdH5wtcLTyAEorgOCkUTjxR9x9Dd lPKQQlSx+OYZqBmbMTd/O00vpwztDFkajnKV0MrJnuUbaxxRA3hrQf+9/ brXjzZqJmM7xM6bPXLV66je7gwZ4wTPynCwMvb4/e5ARBLeYDeu23Fqmm g==; X-IronPort-AV: E=McAfee;i="6200,9189,10198"; a="239424584" X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="239424584" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Dec 2021 03:12:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="661891592" Received: from ipu5-build.bj.intel.com ([10.238.232.188]) by fmsmga001.fm.intel.com with ESMTP; 15 Dec 2021 03:12:24 -0800 From: Bingbu Cao To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, rafael@kernel.org Cc: shawnx.tu@intel.com, chiranjeevi.rapolu@intel.com, tfiga@chromium.org, senozhatsky@chromium.org, linux-kernel@vger.kernel.org, bingbu.cao@linux.intel.com Subject: [PATCH v2 6/6] media: hi556: Support device probe in non-zero ACPI D state Date: Wed, 15 Dec 2021 19:09:03 +0800 Message-Id: <1639566543-8561-7-git-send-email-bingbu.cao@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> References: <1639566543-8561-1-git-send-email-bingbu.cao@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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 Signed-off-by: Kao, Arec --- drivers/media/i2c/hi556.c | 70 ++++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c index 8db1cbedc1fd..055d1aa8410e 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c @@ -495,6 +495,9 @@ struct hi556 { /* Streaming on/off */ bool streaming; + + /* True if the device has been identified */ + bool identified; }; static u64 to_pixel_rate(u32 f_index) @@ -757,12 +760,41 @@ static void hi556_assign_pad_format(const struct hi556_mode *mode, fmt->field = V4L2_FIELD_NONE; } +static int hi556_identify_module(struct hi556 *hi556) +{ + struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd); + int ret; + u32 val; + + if (hi556->identified) + return 0; + + ret = hi556_read_reg(hi556, HI556_REG_CHIP_ID, + HI556_REG_VALUE_16BIT, &val); + if (ret) + return ret; + + if (val != HI556_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%x", + HI556_CHIP_ID, val); + return -ENXIO; + } + + hi556->identified = true; + + return 0; +} + static int hi556_start_streaming(struct hi556 *hi556) { struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd); const struct hi556_reg_list *reg_list; int link_freq_index, ret; + ret = hi556_identify_module(hi556); + if (ret) + return ret; + link_freq_index = hi556->cur_mode->link_freq_index; reg_list = &link_freq_configs[link_freq_index].reg_list; ret = hi556_write_reg_list(hi556, reg_list); @@ -1001,26 +1033,6 @@ static const struct v4l2_subdev_internal_ops hi556_internal_ops = { .open = hi556_open, }; -static int hi556_identify_module(struct hi556 *hi556) -{ - struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd); - int ret; - u32 val; - - ret = hi556_read_reg(hi556, HI556_REG_CHIP_ID, - HI556_REG_VALUE_16BIT, &val); - if (ret) - return ret; - - if (val != HI556_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%x", - HI556_CHIP_ID, val); - return -ENXIO; - } - - return 0; -} - static int hi556_check_hwcfg(struct device *dev) { struct fwnode_handle *ep; @@ -1106,6 +1118,7 @@ static int hi556_remove(struct i2c_client *client) static int hi556_probe(struct i2c_client *client) { struct hi556 *hi556; + bool full_power; int ret; ret = hi556_check_hwcfg(&client->dev); @@ -1120,10 +1133,14 @@ static int hi556_probe(struct i2c_client *client) return -ENOMEM; v4l2_i2c_subdev_init(&hi556->sd, client, &hi556_subdev_ops); - ret = hi556_identify_module(hi556); - if (ret) { - dev_err(&client->dev, "failed to find sensor: %d", ret); - return ret; + + full_power = acpi_dev_state_d0(&client->dev); + if (full_power) { + ret = hi556_identify_module(hi556); + if (ret) { + dev_err(&client->dev, "failed to find sensor: %d", ret); + return ret; + } } mutex_init(&hi556->mutex); @@ -1152,7 +1169,9 @@ static int hi556_probe(struct i2c_client *client) goto probe_error_media_entity_cleanup; } - 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); @@ -1189,6 +1208,7 @@ static struct i2c_driver hi556_i2c_driver = { }, .probe_new = hi556_probe, .remove = hi556_remove, + .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; module_i2c_driver(hi556_i2c_driver);