From patchwork Tue Nov 24 09:31:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331718 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4775EC63798 for ; Tue, 24 Nov 2020 09:38:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ED2CC2073C for ; Tue, 24 Nov 2020 09:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731475AbgKXJia (ORCPT ); Tue, 24 Nov 2020 04:38:30 -0500 Received: from retiisi.eu ([95.216.213.190]:44958 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731197AbgKXJi3 (ORCPT ); Tue, 24 Nov 2020 04:38:29 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id E80E0634C87; Tue, 24 Nov 2020 11:37:50 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 01/30] ccs: Add MIPI CCS compatible strings Date: Tue, 24 Nov 2020 11:31:57 +0200 Message-Id: <20201124093226.23737-2-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add "mipi-ccs-1.0" and "mipi-ccs-1.1" compatible strings to the CCS driver. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 69e7990c65f3..64bad5b678a3 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -3236,6 +3236,9 @@ static int ccs_remove(struct i2c_client *client) } static const struct of_device_id ccs_of_table[] = { + { .compatible = "mipi-ccs-1.1" }, + { .compatible = "mipi-ccs-1.0" }, + { .compatible = "mipi-ccs" }, { .compatible = "nokia,smia" }, { }, }; From patchwork Tue Nov 24 09:31:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332642 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1DF7C56202 for ; Tue, 24 Nov 2020 09:38:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 92E582073C for ; Tue, 24 Nov 2020 09:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731180AbgKXJi2 (ORCPT ); Tue, 24 Nov 2020 04:38:28 -0500 Received: from retiisi.eu ([95.216.213.190]:44936 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731143AbgKXJi1 (ORCPT ); Tue, 24 Nov 2020 04:38:27 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 0B45F634C89; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 02/30] ccs: Add device compatible identifiers for telling SMIA and CCS apart Date: Tue, 24 Nov 2020 11:31:58 +0200 Message-Id: <20201124093226.23737-3-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add device data specific to DT compatible ID to tell SMIA and CCS devices apart already in power-up. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 64bad5b678a3..1d365da570a6 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -58,6 +58,12 @@ static const struct ccs_module_ident ccs_module_idents[] = { CCS_IDENT_LQ(0x10, 0x4241, -1, "imx125es", &smiapp_imx125es_quirk), }; +#define CCS_DEVICE_FLAG_IS_SMIA BIT(0) + +struct ccs_device { + unsigned char flags; +}; + /* * * Dynamic Capability Identification @@ -3235,11 +3241,17 @@ static int ccs_remove(struct i2c_client *client) return 0; } +static const struct ccs_device smia_device = { + .flags = CCS_DEVICE_FLAG_IS_SMIA, +}; + +static const struct ccs_device ccs_device = {}; + static const struct of_device_id ccs_of_table[] = { - { .compatible = "mipi-ccs-1.1" }, - { .compatible = "mipi-ccs-1.0" }, - { .compatible = "mipi-ccs" }, - { .compatible = "nokia,smia" }, + { .compatible = "mipi-ccs-1.1", .data = &ccs_device }, + { .compatible = "mipi-ccs-1.0", .data = &ccs_device }, + { .compatible = "mipi-ccs", .data = &ccs_device }, + { .compatible = "nokia,smia", .data = &smia_device }, { }, }; MODULE_DEVICE_TABLE(of, ccs_of_table); From patchwork Tue Nov 24 09:31:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331717 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8CBCFC6379D for ; Tue, 24 Nov 2020 09:38:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5A1C72073C for ; Tue, 24 Nov 2020 09:38:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731478AbgKXJia (ORCPT ); Tue, 24 Nov 2020 04:38:30 -0500 Received: from retiisi.eu ([95.216.213.190]:44960 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731296AbgKXJi3 (ORCPT ); Tue, 24 Nov 2020 04:38:29 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 1DDFC634C8B; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 03/30] ccs: Add CCS ACPI device ID Date: Tue, 24 Nov 2020 11:31:59 +0200 Message-Id: <20201124093226.23737-4-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The CCS compliant sensors use device ID "MIPI0200". Use this id for ACPI device matching. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 1d365da570a6..bb712d71b8c8 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -3247,6 +3247,12 @@ static const struct ccs_device smia_device = { static const struct ccs_device ccs_device = {}; +static const struct acpi_device_id ccs_acpi_table[] = { + { .id = "MIPI0200", .driver_data = (unsigned long)&ccs_device }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, ccs_acpi_table); + static const struct of_device_id ccs_of_table[] = { { .compatible = "mipi-ccs-1.1", .data = &ccs_device }, { .compatible = "mipi-ccs-1.0", .data = &ccs_device }, @@ -3269,6 +3275,7 @@ static const struct dev_pm_ops ccs_pm_ops = { static struct i2c_driver ccs_i2c_driver = { .driver = { + .acpi_match_table = ccs_acpi_table, .of_match_table = ccs_of_table, .name = CCS_NAME, .pm = &ccs_pm_ops, From patchwork Tue Nov 24 09:32:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332641 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16A6BC56201 for ; Tue, 24 Nov 2020 09:38:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BD5F32076B for ; Tue, 24 Nov 2020 09:38:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731474AbgKXJi3 (ORCPT ); Tue, 24 Nov 2020 04:38:29 -0500 Received: from retiisi.eu ([95.216.213.190]:44952 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731160AbgKXJi2 (ORCPT ); Tue, 24 Nov 2020 04:38:28 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 2D4A8634C8C; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 04/30] =?utf-8?q?ccs=3A_Remove_the_I=C2=B2C_ID_table?= Date: Tue, 24 Nov 2020 11:32:00 +0200 Message-Id: <20201124093226.23737-5-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The I²C ID table is no longer needed; remove it. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index bb712d71b8c8..bb3759e2534c 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -3262,12 +3262,6 @@ static const struct of_device_id ccs_of_table[] = { }; MODULE_DEVICE_TABLE(of, ccs_of_table); -static const struct i2c_device_id ccs_id_table[] = { - { SMIAPP_NAME, 0 }, - { }, -}; -MODULE_DEVICE_TABLE(i2c, ccs_id_table); - static const struct dev_pm_ops ccs_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(ccs_suspend, ccs_resume) SET_RUNTIME_PM_OPS(ccs_power_off, ccs_power_on, NULL) @@ -3282,7 +3276,6 @@ static struct i2c_driver ccs_i2c_driver = { }, .probe_new = ccs_probe, .remove = ccs_remove, - .id_table = ccs_id_table, }; static int ccs_module_init(void) From patchwork Tue Nov 24 09:32:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332627 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 52BFEC64E8A for ; Tue, 24 Nov 2020 09:38:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0DFE12073C for ; Tue, 24 Nov 2020 09:38:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731545AbgKXJiv (ORCPT ); Tue, 24 Nov 2020 04:38:51 -0500 Received: from retiisi.eu ([95.216.213.190]:45010 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731481AbgKXJic (ORCPT ); Tue, 24 Nov 2020 04:38:32 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 4091F634C8E; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 05/30] ccs: Remove remaining support for platform data Date: Tue, 24 Nov 2020 11:32:01 +0200 Message-Id: <20201124093226.23737-6-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org No need to support platform data; remove support for conveying hardware configuration that way. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index bb3759e2534c..af79d80ebb59 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -2860,9 +2860,6 @@ static struct ccs_hwconfig *ccs_get_hwconfig(struct device *dev) int i; int rval; - if (!fwnode) - return dev->platform_data; - ep = fwnode_graph_get_next_endpoint(fwnode, NULL); if (!ep) return NULL; From patchwork Tue Nov 24 09:32:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332640 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E127DC64E7B for ; Tue, 24 Nov 2020 09:38:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8640E2076B for ; Tue, 24 Nov 2020 09:38:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731486AbgKXJib (ORCPT ); Tue, 24 Nov 2020 04:38:31 -0500 Received: from retiisi.eu ([95.216.213.190]:44964 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731143AbgKXJia (ORCPT ); Tue, 24 Nov 2020 04:38:30 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 51F3F634C90; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 06/30] ccs: Make hwcfg part of the device specific struct Date: Tue, 24 Nov 2020 11:32:02 +0200 Message-Id: <20201124093226.23737-7-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org There's no need to allocate the hardware configuration struct separately. Put it in struct ccs_sensor. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 94 ++++++++++++++++--------------- drivers/media/i2c/ccs/ccs-quirk.c | 4 +- drivers/media/i2c/ccs/ccs.h | 2 +- 3 files changed, 51 insertions(+), 49 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index af79d80ebb59..dcc71c8fe075 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -809,7 +809,7 @@ static int ccs_init_late_controls(struct ccs_sensor *sensor) sensor->link_freq = v4l2_ctrl_new_int_menu( &sensor->src->ctrl_handler, &ccs_ctrl_ops, V4L2_CID_LINK_FREQ, __fls(*valid_link_freqs), - __ffs(*valid_link_freqs), sensor->hwcfg->op_sys_clock); + __ffs(*valid_link_freqs), sensor->hwcfg.op_sys_clock); return sensor->src->ctrl_handler.error; } @@ -922,8 +922,8 @@ static int ccs_get_mbus_formats(struct ccs_sensor *sensor) pll->bits_per_pixel = f->compressed; - for (j = 0; sensor->hwcfg->op_sys_clock[j]; j++) { - pll->link_freq = sensor->hwcfg->op_sys_clock[j]; + for (j = 0; sensor->hwcfg.op_sys_clock[j]; j++) { + pll->link_freq = sensor->hwcfg.op_sys_clock[j]; rval = ccs_pll_try(sensor, pll); dev_dbg(&client->dev, "link freq %u Hz, bpp %u %s\n", @@ -1123,21 +1123,21 @@ static int ccs_change_cci_addr(struct ccs_sensor *sensor) int rval; u32 val; - client->addr = sensor->hwcfg->i2c_addr_dfl; + client->addr = sensor->hwcfg.i2c_addr_dfl; rval = ccs_write(sensor, CCI_ADDRESS_CTRL, - sensor->hwcfg->i2c_addr_alt << 1); + sensor->hwcfg.i2c_addr_alt << 1); if (rval) return rval; - client->addr = sensor->hwcfg->i2c_addr_alt; + client->addr = sensor->hwcfg.i2c_addr_alt; /* verify addr change went ok */ rval = ccs_read(sensor, CCI_ADDRESS_CTRL, &val); if (rval) return rval; - if (val != sensor->hwcfg->i2c_addr_alt << 1) + if (val != sensor->hwcfg.i2c_addr_alt << 1) return -ENODEV; return 0; @@ -1151,13 +1151,13 @@ static int ccs_change_cci_addr(struct ccs_sensor *sensor) static int ccs_setup_flash_strobe(struct ccs_sensor *sensor) { struct ccs_flash_strobe_parms *strobe_setup; - unsigned int ext_freq = sensor->hwcfg->ext_clk; + unsigned int ext_freq = sensor->hwcfg.ext_clk; u32 tmp; u32 strobe_adjustment; u32 strobe_width_high_rs; int rval; - strobe_setup = sensor->hwcfg->strobe_setup; + strobe_setup = sensor->hwcfg.strobe_setup; /* * How to calculate registers related to strobe length. Please @@ -1265,7 +1265,7 @@ static int ccs_setup_flash_strobe(struct ccs_sensor *sensor) rval = ccs_write(sensor, FLASH_TRIGGER_RS, strobe_setup->trigger); out: - sensor->hwcfg->strobe_setup->trigger = 0; + sensor->hwcfg.strobe_setup->trigger = 0; return rval; } @@ -1304,7 +1304,7 @@ static int ccs_power_on(struct device *dev) gpiod_set_value(sensor->reset, 0); gpiod_set_value(sensor->xshutdown, 1); - sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk); + sleep = SMIAPP_RESET_DELAY(sensor->hwcfg.ext_clk); usleep_range(sleep, sleep); /* @@ -1318,7 +1318,7 @@ static int ccs_power_on(struct device *dev) * is found. */ - if (sensor->hwcfg->i2c_addr_alt) { + if (sensor->hwcfg.i2c_addr_alt) { rval = ccs_change_cci_addr(sensor); if (rval) { dev_err(dev, "cci address change error\n"); @@ -1332,7 +1332,7 @@ static int ccs_power_on(struct device *dev) goto out_cci_addr_fail; } - if (sensor->hwcfg->i2c_addr_alt) { + if (sensor->hwcfg.i2c_addr_alt) { rval = ccs_change_cci_addr(sensor); if (rval) { dev_err(dev, "cci address change error\n"); @@ -1348,13 +1348,13 @@ static int ccs_power_on(struct device *dev) } rval = ccs_write(sensor, EXTCLK_FREQUENCY_MHZ, - sensor->hwcfg->ext_clk / (1000000 / (1 << 8))); + sensor->hwcfg.ext_clk / (1000000 / (1 << 8))); if (rval) { dev_err(dev, "extclk frequency set failed\n"); goto out_cci_addr_fail; } - rval = ccs_write(sensor, CSI_LANE_MODE, sensor->hwcfg->lanes - 1); + rval = ccs_write(sensor, CSI_LANE_MODE, sensor->hwcfg.lanes - 1); if (rval) { dev_err(dev, "csi lane mode set failed\n"); goto out_cci_addr_fail; @@ -1368,7 +1368,7 @@ static int ccs_power_on(struct device *dev) } rval = ccs_write(sensor, CSI_SIGNALING_MODE, - sensor->hwcfg->csi_signalling_mode); + sensor->hwcfg.csi_signalling_mode); if (rval) { dev_err(dev, "csi signalling mode set failed\n"); goto out_cci_addr_fail; @@ -1412,7 +1412,7 @@ static int ccs_power_off(struct device *dev) * really see a power off and next time the cci address change * will fail. So do a soft reset explicitly here. */ - if (sensor->hwcfg->i2c_addr_alt) + if (sensor->hwcfg.i2c_addr_alt) ccs_write(sensor, SOFTWARE_RESET, CCS_SOFTWARE_RESET_ON); gpiod_set_value(sensor->reset, 1); @@ -1551,8 +1551,8 @@ static int ccs_start_streaming(struct ccs_sensor *sensor) if (CCS_LIM(sensor, FLASH_MODE_CAPABILITY) & (CCS_FLASH_MODE_CAPABILITY_SINGLE_STROBE | SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE) && - sensor->hwcfg->strobe_setup != NULL && - sensor->hwcfg->strobe_setup->trigger != 0) { + sensor->hwcfg.strobe_setup != NULL && + sensor->hwcfg.strobe_setup->trigger != 0) { rval = ccs_setup_flash_strobe(sensor); if (rval) goto out; @@ -2850,9 +2850,9 @@ static int __maybe_unused ccs_resume(struct device *dev) return rval; } -static struct ccs_hwconfig *ccs_get_hwconfig(struct device *dev) +static int ccs_get_hwconfig(struct ccs_sensor *sensor, struct device *dev) { - struct ccs_hwconfig *hwcfg; + struct ccs_hwconfig *hwcfg = &sensor->hwcfg; struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; struct fwnode_handle *ep; struct fwnode_handle *fwnode = dev_fwnode(dev); @@ -2862,7 +2862,7 @@ static struct ccs_hwconfig *ccs_get_hwconfig(struct device *dev) ep = fwnode_graph_get_next_endpoint(fwnode, NULL); if (!ep) - return NULL; + return -ENODEV; bus_cfg.bus_type = V4L2_MBUS_CSI2_DPHY; rval = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); @@ -2874,10 +2874,6 @@ static struct ccs_hwconfig *ccs_get_hwconfig(struct device *dev) if (rval) goto out_err; - hwcfg = devm_kzalloc(dev, sizeof(*hwcfg), GFP_KERNEL); - if (!hwcfg) - goto out_err; - switch (bus_cfg.bus_type) { case V4L2_MBUS_CSI2_DPHY: hwcfg->csi_signalling_mode = CCS_CSI_SIGNALING_MODE_CSI_2_DPHY; @@ -2891,6 +2887,7 @@ static struct ccs_hwconfig *ccs_get_hwconfig(struct device *dev) break; default: dev_err(dev, "unsupported bus %u\n", bus_cfg.bus_type); + rval = -EINVAL; goto out_err; } @@ -2907,6 +2904,7 @@ static struct ccs_hwconfig *ccs_get_hwconfig(struct device *dev) break; default: dev_err(dev, "invalid rotation %u\n", rotation); + rval = -EINVAL; goto out_err; } } @@ -2921,14 +2919,17 @@ static struct ccs_hwconfig *ccs_get_hwconfig(struct device *dev) if (!bus_cfg.nr_of_link_frequencies) { dev_warn(dev, "no link frequencies defined\n"); + rval = -EINVAL; goto out_err; } hwcfg->op_sys_clock = devm_kcalloc( dev, bus_cfg.nr_of_link_frequencies + 1 /* guardian */, sizeof(*hwcfg->op_sys_clock), GFP_KERNEL); - if (!hwcfg->op_sys_clock) + if (!hwcfg->op_sys_clock) { + rval = -ENOMEM; goto out_err; + } for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { hwcfg->op_sys_clock[i] = bus_cfg.link_frequencies[i]; @@ -2937,29 +2938,30 @@ static struct ccs_hwconfig *ccs_get_hwconfig(struct device *dev) v4l2_fwnode_endpoint_free(&bus_cfg); fwnode_handle_put(ep); - return hwcfg; + + return 0; out_err: v4l2_fwnode_endpoint_free(&bus_cfg); fwnode_handle_put(ep); - return NULL; + + return rval; } static int ccs_probe(struct i2c_client *client) { struct ccs_sensor *sensor; - struct ccs_hwconfig *hwcfg = ccs_get_hwconfig(&client->dev); unsigned int i; int rval; - if (hwcfg == NULL) - return -ENODEV; - sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL); if (sensor == NULL) return -ENOMEM; - sensor->hwcfg = hwcfg; + rval = ccs_get_hwconfig(sensor, &client->dev); + if (rval) + return rval; + sensor->src = &sensor->ssds[sensor->ssds_used]; v4l2_i2c_subdev_init(&sensor->src->sd, client, &ccs_ops); @@ -2982,33 +2984,33 @@ static int ccs_probe(struct i2c_client *client) } if (sensor->ext_clk) { - if (sensor->hwcfg->ext_clk) { + if (sensor->hwcfg.ext_clk) { unsigned long rate; rval = clk_set_rate(sensor->ext_clk, - sensor->hwcfg->ext_clk); + sensor->hwcfg.ext_clk); if (rval < 0) { dev_err(&client->dev, "unable to set clock freq to %u\n", - sensor->hwcfg->ext_clk); + sensor->hwcfg.ext_clk); return rval; } rate = clk_get_rate(sensor->ext_clk); - if (rate != sensor->hwcfg->ext_clk) { + if (rate != sensor->hwcfg.ext_clk) { dev_err(&client->dev, "can't set clock freq, asked for %u but got %lu\n", - sensor->hwcfg->ext_clk, rate); + sensor->hwcfg.ext_clk, rate); return rval; } } else { - sensor->hwcfg->ext_clk = clk_get_rate(sensor->ext_clk); + sensor->hwcfg.ext_clk = clk_get_rate(sensor->ext_clk); dev_dbg(&client->dev, "obtained clock freq %u\n", - sensor->hwcfg->ext_clk); + sensor->hwcfg.ext_clk); } - } else if (sensor->hwcfg->ext_clk) { + } else if (sensor->hwcfg.ext_clk) { dev_dbg(&client->dev, "assuming clock freq %u\n", - sensor->hwcfg->ext_clk); + sensor->hwcfg.ext_clk); } else { dev_err(&client->dev, "unable to obtain clock freq\n"); return -EINVAL; @@ -3061,7 +3063,7 @@ static int ccs_probe(struct i2c_client *client) * * Rotation also changes the bayer pattern. */ - if (sensor->hwcfg->module_board_orient == + if (sensor->hwcfg.module_board_orient == CCS_MODULE_BOARD_ORIENT_180) sensor->hvflip_inv_mask = CCS_IMAGE_ORIENTATION_HORIZONTAL_MIRROR | @@ -3133,8 +3135,8 @@ static int ccs_probe(struct i2c_client *client) /* prepare PLL configuration input values */ sensor->pll.bus_type = SMIAPP_PLL_BUS_TYPE_CSI2; - sensor->pll.csi2.lanes = sensor->hwcfg->lanes; - sensor->pll.ext_clk_freq_hz = sensor->hwcfg->ext_clk; + sensor->pll.csi2.lanes = sensor->hwcfg.lanes; + sensor->pll.ext_clk_freq_hz = sensor->hwcfg.ext_clk; sensor->pll.scale_n = CCS_LIM(sensor, SCALER_N_MIN); ccs_create_subdev(sensor, sensor->scaler, " scaler", 2, diff --git a/drivers/media/i2c/ccs/ccs-quirk.c b/drivers/media/i2c/ccs/ccs-quirk.c index 5a24da1d7aa9..facec28f8447 100644 --- a/drivers/media/i2c/ccs/ccs-quirk.c +++ b/drivers/media/i2c/ccs/ccs-quirk.c @@ -152,13 +152,13 @@ static int jt8ev1_post_poweron(struct ccs_sensor *sensor) if (rval < 0) return rval; - switch (sensor->hwcfg->ext_clk) { + switch (sensor->hwcfg.ext_clk) { case 9600000: return ccs_write_addr_8s(sensor, regs_96, ARRAY_SIZE(regs_96)); default: dev_warn(&client->dev, "no MSRs for %d Hz ext_clk\n", - sensor->hwcfg->ext_clk); + sensor->hwcfg.ext_clk); return 0; } } diff --git a/drivers/media/i2c/ccs/ccs.h b/drivers/media/i2c/ccs/ccs.h index bfe39e02f5e9..2d1e8339f663 100644 --- a/drivers/media/i2c/ccs/ccs.h +++ b/drivers/media/i2c/ccs/ccs.h @@ -215,7 +215,7 @@ struct ccs_sensor { struct ccs_subdev *binner; struct ccs_subdev *scaler; struct ccs_subdev *pixel_array; - struct ccs_hwconfig *hwcfg; + struct ccs_hwconfig hwcfg; struct regulator *vana; struct clk *ext_clk; struct gpio_desc *xshutdown; From patchwork Tue Nov 24 09:32:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332628 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9EB89C8300C for ; Tue, 24 Nov 2020 09:38:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 659812073C for ; Tue, 24 Nov 2020 09:38:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731537AbgKXJiu (ORCPT ); Tue, 24 Nov 2020 04:38:50 -0500 Received: from retiisi.eu ([95.216.213.190]:45012 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731483AbgKXJic (ORCPT ); Tue, 24 Nov 2020 04:38:32 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 6D6C4634C91; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 07/30] ccs: Fix obtaining bus information from firmware Date: Tue, 24 Nov 2020 11:32:03 +0200 Message-Id: <20201124093226.23737-8-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Let v4l2_fwnode_endpoint_alloc_parse to figure out the type of the data bus. As the old bindings did not require the "bus-type" property, we need to rely on guessing between CSI-2 D-PHY and CCP2. Setting the type to CSI-2 D-PHY will parse just that and succeed even if no data-lanes are set. Also add a comment on the matter to the driver to avoid breaking this in the future. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index dcc71c8fe075..6fb546ca08f3 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -2853,7 +2853,7 @@ static int __maybe_unused ccs_resume(struct device *dev) static int ccs_get_hwconfig(struct ccs_sensor *sensor, struct device *dev) { struct ccs_hwconfig *hwcfg = &sensor->hwcfg; - struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; + struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = V4L2_MBUS_UNKNOWN }; struct fwnode_handle *ep; struct fwnode_handle *fwnode = dev_fwnode(dev); u32 rotation; @@ -2864,13 +2864,11 @@ static int ccs_get_hwconfig(struct ccs_sensor *sensor, struct device *dev) if (!ep) return -ENODEV; - bus_cfg.bus_type = V4L2_MBUS_CSI2_DPHY; + /* + * Note that we do need to rely on detecting the bus type between CSI-2 + * D-PHY and CCP2 as the old bindings did not require it. + */ rval = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); - if (rval == -ENXIO) { - bus_cfg = (struct v4l2_fwnode_endpoint) - { .bus_type = V4L2_MBUS_CCP2 }; - rval = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); - } if (rval) goto out_err; @@ -2879,6 +2877,7 @@ static int ccs_get_hwconfig(struct ccs_sensor *sensor, struct device *dev) hwcfg->csi_signalling_mode = CCS_CSI_SIGNALING_MODE_CSI_2_DPHY; hwcfg->lanes = bus_cfg.bus.mipi_csi2.num_data_lanes; break; + case V4L2_MBUS_CSI1: case V4L2_MBUS_CCP2: hwcfg->csi_signalling_mode = (bus_cfg.bus.mipi_csi1.strobe) ? SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE : From patchwork Tue Nov 24 09:32:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331708 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75851C64E7D for ; Tue, 24 Nov 2020 09:38:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 275472073C for ; Tue, 24 Nov 2020 09:38:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731497AbgKXJie (ORCPT ); Tue, 24 Nov 2020 04:38:34 -0500 Received: from retiisi.eu ([95.216.213.190]:44968 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731473AbgKXJic (ORCPT ); Tue, 24 Nov 2020 04:38:32 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 83B9B634C92; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 08/30] ccs: Add CCS static data parser library Date: Tue, 24 Nov 2020 11:32:04 +0200 Message-Id: <20201124093226.23737-9-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add a parser library for parsing the CCS static data format. The library may be also compiled in user space as the format has uses also in the user space. Therefore it is dual licensed under the 3-clause BSD license as well. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/Makefile | 2 +- drivers/media/i2c/ccs/ccs-data-defs.h | 219 ++++++ drivers/media/i2c/ccs/ccs-data.c | 944 ++++++++++++++++++++++++++ drivers/media/i2c/ccs/ccs-data.h | 120 ++++ 4 files changed, 1284 insertions(+), 1 deletion(-) create mode 100644 drivers/media/i2c/ccs/ccs-data-defs.h create mode 100644 drivers/media/i2c/ccs/ccs-data.c create mode 100644 drivers/media/i2c/ccs/ccs-data.h diff --git a/drivers/media/i2c/ccs/Makefile b/drivers/media/i2c/ccs/Makefile index 08dd4e948fb0..44601ba8cd53 100644 --- a/drivers/media/i2c/ccs/Makefile +++ b/drivers/media/i2c/ccs/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only ccs-objs += ccs-core.o ccs-reg-access.o \ - ccs-quirk.o ccs-limits.o + ccs-quirk.o ccs-limits.o ccs-data.o obj-$(CONFIG_VIDEO_CCS) += ccs.o ccflags-y += -I $(srctree)/drivers/media/i2c diff --git a/drivers/media/i2c/ccs/ccs-data-defs.h b/drivers/media/i2c/ccs/ccs-data-defs.h new file mode 100644 index 000000000000..db556f3e78d8 --- /dev/null +++ b/drivers/media/i2c/ccs/ccs-data-defs.h @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * CCS static data binary format definitions + * + * Copyright 2019--2020 Intel Corporation + */ + +#ifndef __CCS_DATA_DEFS_H__ +#define __CCS_DATA_DEFS_H__ + +#include "ccs-data.h" + +#define CCS_STATIC_DATA_VERSION 0 + +enum __ccs_data_length_specifier_id { + CCS_DATA_LENGTH_SPECIFIER_1 = 0, + CCS_DATA_LENGTH_SPECIFIER_2 = 1, + CCS_DATA_LENGTH_SPECIFIER_3 = 2 +}; +#define CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT 6 + +struct __ccs_data_length_specifier { + uint8_t length; +} __attribute__((packed)); + +struct __ccs_data_length_specifier2 { + uint8_t length[2]; +} __attribute__((packed)); + +struct __ccs_data_length_specifier3 { + uint8_t length[3]; +} __attribute__((packed)); + +struct __ccs_data_block { + uint8_t id; + struct __ccs_data_length_specifier length; +} __attribute__((packed)); + +#define CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT 5 + +struct __ccs_data_block3 { + uint8_t id; + struct __ccs_data_length_specifier2 length; +} __attribute__((packed)); + +struct __ccs_data_block4 { + uint8_t id; + struct __ccs_data_length_specifier3 length; +} __attribute__((packed)); + +enum __ccs_data_block_id { + CCS_DATA_BLOCK_ID_DUMMY = 1, + CCS_DATA_BLOCK_ID_DATA_VERSION = 2, + CCS_DATA_BLOCK_ID_SENSOR_READ_ONLY_REGS = 3, + CCS_DATA_BLOCK_ID_MODULE_READ_ONLY_REGS = 4, + CCS_DATA_BLOCK_ID_SENSOR_MANUFACTURER_REGS = 5, + CCS_DATA_BLOCK_ID_MODULE_MANUFACTURER_REGS = 6, + CCS_DATA_BLOCK_ID_SENSOR_RULE_BASED_BLOCK = 32, + CCS_DATA_BLOCK_ID_MODULE_RULE_BASED_BLOCK = 33, + CCS_DATA_BLOCK_ID_SENSOR_PDAF_PIXEL_LOCATION = 36, + CCS_DATA_BLOCK_ID_MODULE_PDAF_PIXEL_LOCATION = 37, + CCS_DATA_BLOCK_ID_LICENSE = 40, + CCS_DATA_BLOCK_ID_END = 127, +}; + +struct __ccs_data_block_version { + uint8_t static_data_version_major[2]; + uint8_t static_data_version_minor[2]; + uint8_t year[2]; + uint8_t month; + uint8_t day; +} __attribute__((packed)); + +struct __ccs_data_block_regs { + uint8_t reg_len; +} __attribute__((packed)); + +#define CCS_DATA_BLOCK_REGS_ADDR_MASK 0x07 +#define CCS_DATA_BLOCK_REGS_LEN_SHIFT 3 +#define CCS_DATA_BLOCK_REGS_LEN_MASK 0x38 +#define CCS_DATA_BLOCK_REGS_SEL_SHIFT 6 +enum ccs_data_block_regs_sel { + CCS_DATA_BLOCK_REGS_SEL_REGS = 0, + CCS_DATA_BLOCK_REGS_SEL_REGS2 = 1, + CCS_DATA_BLOCK_REGS_SEL_REGS3 = 2, +}; + +struct __ccs_data_block_regs2 { + uint8_t reg_len; + uint8_t addr; +} __attribute__((packed)); + +#define CCS_DATA_BLOCK_REGS_2_ADDR_MASK 0x01 +#define CCS_DATA_BLOCK_REGS_2_LEN_SHIFT 1 +#define CCS_DATA_BLOCK_REGS_2_LEN_MASK 0x3e + +struct __ccs_data_block_regs3 { + uint8_t reg_len; + uint8_t addr[2]; +} __attribute__((packed)); + +#define CCS_DATA_BLOCK_REGS_3_LEN_MASK 0x3f + +enum __ccs_data_ffd_pixelcode { + CCS_DATA_BLOCK_FFD_PIXELCODE_EMBEDDED = 1, + CCS_DATA_BLOCK_FFD_PIXELCODE_DUMMY = 2, + CCS_DATA_BLOCK_FFD_PIXELCODE_BLACK = 3, + CCS_DATA_BLOCK_FFD_PIXELCODE_DARK = 4, + CCS_DATA_BLOCK_FFD_PIXELCODE_VISIBLE = 5, + CCS_DATA_BLOCK_FFD_PIXELCODE_MS_0 = 8, + CCS_DATA_BLOCK_FFD_PIXELCODE_MS_1 = 9, + CCS_DATA_BLOCK_FFD_PIXELCODE_MS_2 = 10, + CCS_DATA_BLOCK_FFD_PIXELCODE_MS_3 = 11, + CCS_DATA_BLOCK_FFD_PIXELCODE_MS_4 = 12, + CCS_DATA_BLOCK_FFD_PIXELCODE_MS_5 = 13, + CCS_DATA_BLOCK_FFD_PIXELCODE_MS_6 = 14, + CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_OB = 16, + CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_OB = 17, + CCS_DATA_BLOCK_FFD_PIXELCODE_LEFT_OB = 18, + CCS_DATA_BLOCK_FFD_PIXELCODE_RIGHT_OB = 19, + CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_LEFT_OB = 20, + CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_RIGHT_OB = 21, + CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_LEFT_OB = 22, + CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_RIGHT_OB = 23, + CCS_DATA_BLOCK_FFD_PIXELCODE_TOTAL = 24, + CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_PDAF = 32, + CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_PDAF = 33, + CCS_DATA_BLOCK_FFD_PIXELCODE_LEFT_PDAF = 34, + CCS_DATA_BLOCK_FFD_PIXELCODE_RIGHT_PDAF = 35, + CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_LEFT_PDAF = 36, + CCS_DATA_BLOCK_FFD_PIXELCODE_TOP_RIGHT_PDAF = 37, + CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_LEFT_PDAF = 38, + CCS_DATA_BLOCK_FFD_PIXELCODE_BOTTOM_RIGHT_PDAF = 39, + CCS_DATA_BLOCK_FFD_PIXELCODE_SEPARATED_PDAF = 40, + CCS_DATA_BLOCK_FFD_PIXELCODE_ORIGINAL_ORDER_PDAF = 41, + CCS_DATA_BLOCK_FFD_PIXELCODE_VENDOR_PDAF = 41, +}; + +struct __ccs_data_block_ffd_entry { + uint8_t pixelcode; + uint8_t reserved; + uint8_t value[2]; +} __attribute__((packed)); + +struct __ccs_data_block_ffd { + uint8_t num_column_descs; + uint8_t num_row_descs; +} __attribute__((packed)); + +enum __ccs_data_block_rule_id { + CCS_DATA_BLOCK_RULE_ID_IF = 1, + CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS = 2, + CCS_DATA_BLOCK_RULE_ID_FFD = 3, + CCS_DATA_BLOCK_RULE_ID_MSR = 4, + CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT = 5, +}; + +struct __ccs_data_block_rule_if { + uint8_t addr[2]; + uint8_t value; + uint8_t mask; +} __attribute__((packed)); + +enum __ccs_data_block_pdaf_readout_order{ + CCS_DATA_BLOCK_PDAF_READOUT_ORDER_ORIGINAL = 1, + CCS_DATA_BLOCK_PDAF_READOUT_ORDER_SEPARATE_WITHIN_LINE = 2, + CCS_DATA_BLOCK_PDAF_READOUT_ORDER_SEPARATE_TYPES_SEPARATE_LINES = 3, +}; + +struct __ccs_data_block_pdaf_readout { + uint8_t pdaf_readout_info_reserved; + uint8_t pdaf_readout_info_order; +} __attribute__((packed)); + +struct __ccs_data_block_pdaf_pix_loc_block_desc { + uint8_t block_type_id; + uint8_t repeat_x[2]; +} __attribute__((packed)); + +struct __ccs_data_block_pdaf_pix_loc_block_desc_group { + uint8_t num_block_descs[2]; + uint8_t repeat_y; +} __attribute__((packed)); + +enum __ccs_data_block_pdaf_pix_loc_pixel_type { + CCS_DATA_PDAF_PIXEL_TYPE_LEFT_SEPARATED = 0, + CCS_DATA_PDAF_PIXEL_TYPE_RIGHT_SEPARATED = 1, + CCS_DATA_PDAF_PIXEL_TYPE_TOP_SEPARATED = 2, + CCS_DATA_PDAF_PIXEL_TYPE_BOTTOM_SEPARATED = 3, + CCS_DATA_PDAF_PIXEL_TYPE_LEFT_SIDE_BY_SIDE = 4, + CCS_DATA_PDAF_PIXEL_TYPE_RIGHT_SIDE_BY_SIDE = 5, + CCS_DATA_PDAF_PIXEL_TYPE_TOP_SIDE_BY_SIDE = 6, + CCS_DATA_PDAF_PIXEL_TYPE_BOTTOM_SIDE_BY_SIDE = 7, + CCS_DATA_PDAF_PIXEL_TYPE_TOP_LEFT = 8, + CCS_DATA_PDAF_PIXEL_TYPE_TOP_RIGHT = 9, + CCS_DATA_PDAF_PIXEL_TYPE_BOTTOM_LEFT = 10, + CCS_DATA_PDAF_PIXEL_TYPE_BOTTOM_RIGHT = 11, +}; + +struct __ccs_data_block_pdaf_pix_loc_pixel_desc { + uint8_t pixel_type; + uint8_t small_offset_x; + uint8_t small_offset_y; +} __attribute__((packed)); + +struct __ccs_data_block_pdaf_pix_loc { + uint8_t main_offset_x[2]; + uint8_t main_offset_y[2]; + uint8_t global_pdaf_type; + uint8_t block_width; + uint8_t block_height; + uint8_t num_block_desc_groups[2]; +} __attribute__((packed)); + +struct __ccs_data_block_end { + uint8_t crc[4]; +} __attribute__((packed)); + +#endif /* __CCS_DATA_DEFS_H__ */ diff --git a/drivers/media/i2c/ccs/ccs-data.c b/drivers/media/i2c/ccs/ccs-data.c new file mode 100644 index 000000000000..de6473600a3d --- /dev/null +++ b/drivers/media/i2c/ccs/ccs-data.c @@ -0,0 +1,944 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * CCS static data binary parser library + * + * Copyright 2019--2020 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include + +#include "ccs-data-defs.h" + +struct bin_container { + void *base; + void *now; + void *end; + size_t size; +}; + +static void *bin_alloc(struct bin_container *bin, size_t len) +{ + void *ptr; + + len = ALIGN(len, 8); + + if (bin->end - bin->now < len) + return NULL; + + ptr = bin->now; + bin->now += len; + + return ptr; +} + +static void bin_reserve(struct bin_container *bin, size_t len) +{ + bin->size += ALIGN(len, 8); +} + +static int bin_backing_alloc(struct bin_container *bin) +{ + bin->base = bin->now = kvzalloc(bin->size, GFP_KERNEL); + if (!bin->base) + return -ENOMEM; + + bin->end = bin->base + bin->size; + + return 0; +} + +#define is_contained(var, endp) \ + (sizeof(*var) <= (endp) - (void *)(var)) +#define has_headroom(ptr, headroom, endp) \ + ((headroom) <= (endp) - (void *)(ptr)) +#define is_contained_with_headroom(var, headroom, endp) \ + (sizeof(*var) + (headroom) <= (endp) - (void *)(var)) + +static int +ccs_data_parse_length_specifier(const struct __ccs_data_length_specifier *__len, + size_t *__hlen, size_t *__plen, + const void *endp) +{ + size_t hlen, plen; + + if (!is_contained(__len, endp)) + return -ENODATA; + + switch (__len->length >> CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) { + case CCS_DATA_LENGTH_SPECIFIER_1: + hlen = sizeof(*__len); + plen = __len->length & + ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1); + break; + case CCS_DATA_LENGTH_SPECIFIER_2: { + struct __ccs_data_length_specifier2 *__len2 = (void *)__len; + + if (!is_contained(__len2, endp)) + return -ENODATA; + + hlen = sizeof(*__len2); + plen = ((size_t) + (__len2->length[0] & + ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1)) + << 8) + __len2->length[1]; + break; + } + case CCS_DATA_LENGTH_SPECIFIER_3: { + struct __ccs_data_length_specifier3 *__len3 = (void *)__len; + + if (!is_contained(__len3, endp)) + return -ENODATA; + + hlen = sizeof(*__len3); + plen = ((size_t) + (__len3->length[0] & + ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1)) + << 16) + (__len3->length[0] << 8) + __len3->length[1]; + break; + } + default: + return -EINVAL; + } + + if (!has_headroom(__len, hlen + plen, endp)) + return -ENODATA; + + *__hlen = hlen; + *__plen = plen; + + return 0; +} + +static uint8_t +ccs_data_parse_format_version(const struct __ccs_data_block *block) +{ + return block->id >> CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT; +} + +static uint8_t ccs_data_parse_block_id(const struct __ccs_data_block *block, + bool is_first) +{ + if (!is_first) + return block->id; + + return block->id & ((1 << CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT) - 1); +} + +static int ccs_data_parse_version(struct bin_container *bin, + struct ccs_data_container *ccsdata, + const void *payload, const void *endp) +{ + const struct __ccs_data_block_version *v = payload; + struct ccs_data_block_version *vv; + + if (v + 1 != endp) + return -ENODATA; + + if (!bin->base) { + bin_reserve(bin, sizeof(*ccsdata->version)); + return 0; + } + + ccsdata->version = bin_alloc(bin, sizeof(*ccsdata->version)); + if (!ccsdata->version) + return -ENOMEM; + + vv = ccsdata->version; + vv->version_major = ((uint16_t)v->static_data_version_minor[0] << 8) + + v->static_data_version_major[1]; + vv->version_minor = ((uint16_t)v->static_data_version_minor[0] << 8) + + v->static_data_version_major[1]; + vv->date_year = ((uint16_t)v->year[0] << 8) + v->year[1]; + vv->date_month = v->month; + vv->date_day = v->day; + + return 0; +} + +static void print_ccs_data_version(struct device *dev, + struct ccs_data_block_version *v) +{ + dev_dbg(dev, + "static data version %4.4x.%4.4x, date %4.4u-%2.2u-%2.2u\n", + v->version_major, v->version_minor, + v->date_year, v->date_month, v->date_day); +} + +static int ccs_data_block_parse_header(const struct __ccs_data_block *block, + bool is_first, unsigned int *__block_id, + const void **payload, + const struct __ccs_data_block **next_block, + const void *endp, struct device *dev, + bool verbose) +{ + size_t plen, hlen; + uint8_t block_id; + int rval; + + if (!is_contained(block, endp)) + return -ENODATA; + + rval = ccs_data_parse_length_specifier(&block->length, &hlen, &plen, + endp); + if (rval < 0) + return rval; + + block_id = ccs_data_parse_block_id(block, is_first); + + if (verbose) + dev_dbg(dev, + "Block ID 0x%2.2x, header length %zu, payload length %zu\n", + block_id, hlen, plen); + + if (!has_headroom(&block->length, hlen + plen, endp)) + return -ENODATA; + + if (__block_id) + *__block_id = block_id; + + if (payload) + *payload = (void *)&block->length + hlen; + + if (next_block) + *next_block = (void *)&block->length + hlen + plen; + + return 0; +} + +static int ccs_data_parse_regs(struct bin_container *bin, + struct ccs_reg **__regs, + size_t *__num_regs, const void *payload, + const void *endp, struct device *dev) +{ + struct ccs_reg *regs_base, *regs; + size_t num_regs = 0; + uint16_t addr = 0; + + if (bin->base && __regs) { + regs = regs_base = bin_alloc(bin, sizeof(*regs) * *__num_regs); + if (!regs) + return -ENOMEM; + } + + while (payload < endp && num_regs < INT_MAX) { + const struct __ccs_data_block_regs *r = payload; + size_t len; + const void *data; + + if (!is_contained(r, endp)) + return -ENODATA; + + switch (r->reg_len >> CCS_DATA_BLOCK_REGS_SEL_SHIFT) { + case CCS_DATA_BLOCK_REGS_SEL_REGS: + addr += r->reg_len & CCS_DATA_BLOCK_REGS_ADDR_MASK; + len = ((r->reg_len & CCS_DATA_BLOCK_REGS_LEN_MASK) + >> CCS_DATA_BLOCK_REGS_LEN_SHIFT) + 1; + + if (!is_contained_with_headroom(r, len, endp)) + return -ENODATA; + + data = r + 1; + break; + case CCS_DATA_BLOCK_REGS_SEL_REGS2: { + const struct __ccs_data_block_regs2 *r2 = payload; + + if (!is_contained(r2, endp)) + return -ENODATA; + + addr += ((uint16_t)(r2->reg_len & + CCS_DATA_BLOCK_REGS_2_ADDR_MASK) << 8) + + r2->addr; + len = ((r2->reg_len & CCS_DATA_BLOCK_REGS_2_LEN_MASK) + >> CCS_DATA_BLOCK_REGS_2_LEN_SHIFT) + 1; + + if (!is_contained_with_headroom(r2, len, endp)) + return -ENODATA; + + data = r2 + 1; + break; + } + case CCS_DATA_BLOCK_REGS_SEL_REGS3: { + const struct __ccs_data_block_regs3 *r3 = payload; + + if (!is_contained(r3, endp)) + return -ENODATA; + + addr = ((uint16_t)r3->addr[0] << 8) + r3->addr[1]; + len = (r3->reg_len & CCS_DATA_BLOCK_REGS_3_LEN_MASK) + 1; + + if (!is_contained_with_headroom(r3, len, endp)) + return -ENODATA; + + data = r3 + 1; + break; + } + default: + return -EINVAL; + } + + num_regs++; + + if (!bin->base) { + bin_reserve(bin, len); + } else if (__regs) { + regs->addr = addr; + regs->len = len; + regs->value = bin_alloc(bin, len); + if (!regs->value) + return -ENOMEM; + + memcpy(regs->value, data, len); + regs++; + } + + addr += len; + payload = data + len; + } + + if (!bin->base) + bin_reserve(bin, sizeof(*regs) * num_regs); + + if (__num_regs) + *__num_regs = num_regs; + + if (bin->base && __regs) + *__regs = regs_base; + + return 0; +} + +static int ccs_data_parse_reg_rules(struct bin_container *bin, + struct ccs_reg **__regs, + size_t *__num_regs, + const void *payload, + const void *endp, struct device *dev) +{ + int rval; + + if (!bin->base) + return ccs_data_parse_regs(bin, NULL, NULL, payload, endp, dev); + + rval = ccs_data_parse_regs(bin, NULL, __num_regs, payload, endp, dev); + if (rval) + return rval; + + return ccs_data_parse_regs(bin, __regs, __num_regs, payload, endp, + dev); +} + +static void assign_ffd_entry(struct ccs_frame_format_desc *desc, + const struct __ccs_data_block_ffd_entry *ent) +{ + desc->pixelcode = ent->pixelcode; + desc->value = ((uint16_t)ent->value[0] << 8) + ent->value[1]; +} + +static int ccs_data_parse_ffd(struct bin_container *bin, + struct ccs_frame_format_descs **ffd, + const void *payload, + const void *endp, struct device *dev) +{ + const struct __ccs_data_block_ffd *__ffd = payload; + const struct __ccs_data_block_ffd_entry *__entry; + unsigned int i; + + if (!is_contained(__ffd, endp)) + return -ENODATA; + + if ((void *)__ffd + sizeof(*__ffd) + + ((uint32_t)__ffd->num_column_descs + + (uint32_t)__ffd->num_row_descs) * + sizeof(struct __ccs_data_block_ffd_entry) != endp) + return -ENODATA; + + if (!bin->base) { + bin_reserve(bin, sizeof(**ffd)); + bin_reserve(bin, __ffd->num_column_descs * + sizeof(struct ccs_frame_format_desc)); + bin_reserve(bin, __ffd->num_row_descs * + sizeof(struct ccs_frame_format_desc)); + + return 0; + } + + *ffd = bin_alloc(bin, sizeof(**ffd)); + if (!*ffd) + return -ENOMEM; + + (*ffd)->num_column_descs = __ffd->num_column_descs; + (*ffd)->num_row_descs = __ffd->num_row_descs; + __entry = (void *)(__ffd + 1); + + (*ffd)->column_descs = bin_alloc(bin, __ffd->num_column_descs * + sizeof(*(*ffd)->column_descs)); + if (!(*ffd)->column_descs) + return -ENOMEM; + + for (i = 0; i < __ffd->num_column_descs; i++, __entry++) + assign_ffd_entry(&(*ffd)->column_descs[i], __entry); + + (*ffd)->row_descs = bin_alloc(bin, __ffd->num_row_descs * + sizeof(*(*ffd)->row_descs)); + if (!(*ffd)->row_descs) + return -ENOMEM; + + for (i = 0; i < __ffd->num_row_descs; i++, __entry++) + assign_ffd_entry(&(*ffd)->row_descs[i], __entry); + + if (__entry != endp) + return -EPROTO; + + return 0; +} + +static int ccs_data_parse_pdaf_readout(struct bin_container *bin, + struct ccs_pdaf_readout **pdaf_readout, + const void *payload, + const void *endp, struct device *dev) +{ + const struct __ccs_data_block_pdaf_readout *__pdaf = payload; + + if (!is_contained(__pdaf, endp)) + return -ENODATA; + + if (!bin->base) { + bin_reserve(bin, sizeof(**pdaf_readout)); + } else { + *pdaf_readout = bin_alloc(bin, sizeof(**pdaf_readout)); + if (!*pdaf_readout) + return -ENOMEM; + + (*pdaf_readout)->pdaf_readout_info_order = + __pdaf->pdaf_readout_info_order; + } + + return ccs_data_parse_ffd(bin, !bin->base ? NULL : &(*pdaf_readout)->ffd, + __pdaf + 1, endp, dev); +} + +static int ccs_data_parse_rules(struct bin_container *bin, + struct ccs_rule **__rules, + size_t *__num_rules, const void *payload, + const void *endp, struct device *dev) +{ + struct ccs_rule *rules_base, *rules = NULL, *next_rule; + size_t num_rules = 0; + const void *__next_rule = payload; + int rval; + + if (bin->base) { + rules_base = next_rule = + bin_alloc(bin, sizeof(*rules) * *__num_rules); + if (!rules_base) + return -ENOMEM; + } + + while (__next_rule < endp) { + size_t rule_hlen, rule_plen, rule_plen2; + const uint8_t *__rule_type; + const void *rule_payload; + + /* Size of a single rule */ + rval = ccs_data_parse_length_specifier(__next_rule, &rule_hlen, + &rule_plen, endp); + + if (rval < 0) + return rval; + + __rule_type = __next_rule + rule_hlen; + + if (!is_contained(__rule_type, endp)) + return -ENODATA; + + rule_payload = __rule_type + 1; + rule_plen2 = rule_plen - sizeof(*__rule_type); + + switch (*__rule_type) { + case CCS_DATA_BLOCK_RULE_ID_IF: { + const struct __ccs_data_block_rule_if *__if_rules = + rule_payload; + const size_t __num_if_rules = + rule_plen2 / sizeof(*__if_rules); + struct ccs_if_rule *if_rule; + + if (!has_headroom(__if_rules, + sizeof(*__if_rules) * __num_if_rules, + rule_payload + rule_plen2)) + return -ENODATA; + + /* Also check there is no extra data */ + if (__if_rules + __num_if_rules != + rule_payload + rule_plen2) + return -EINVAL; + + if (!bin->base) { + bin_reserve(bin, + sizeof(*if_rule) * + __num_if_rules); + num_rules++; + } else { + unsigned int i; + + rules = next_rule; + next_rule++; + + if_rule = bin_alloc(bin, + sizeof(*if_rule) * + __num_if_rules); + if (!if_rule) + return -ENOMEM; + + for (i = 0; i < __num_if_rules; i++) { + if_rule[i].addr = + ((uint16_t)__if_rules[i].addr[0] + << 8) + + __if_rules[i].addr[1]; + if_rule[i].value = __if_rules[i].value; + if_rule[i].mask = __if_rules[i].mask; + } + + rules->if_rules = if_rule; + rules->num_if_rules = __num_if_rules; + } + break; + } + case CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS: + rval = ccs_data_parse_reg_rules(bin, &rules->read_only_regs, + &rules->num_read_only_regs, + rule_payload, + rule_payload + rule_plen2, + dev); + if (rval) + return rval; + break; + case CCS_DATA_BLOCK_RULE_ID_FFD: + rval = ccs_data_parse_ffd(bin, &rules->frame_format, + rule_payload, + rule_payload + rule_plen2, + dev); + if (rval) + return rval; + break; + case CCS_DATA_BLOCK_RULE_ID_MSR: + rval = ccs_data_parse_reg_rules(bin, + &rules->manufacturer_regs, + &rules->num_manufacturer_regs, + rule_payload, + rule_payload + rule_plen2, + dev); + if (rval) + return rval; + break; + case CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT: + rval = ccs_data_parse_pdaf_readout(bin, + &rules->pdaf_readout, + rule_payload, + rule_payload + rule_plen2, + dev); + if (rval) + return rval; + break; + default: + dev_dbg(dev, + "Don't know how to handle rule type %u!\n", + *__rule_type); + return -EINVAL; + } + __next_rule = __next_rule + rule_hlen + rule_plen; + } + + if (!bin->base) { + bin_reserve(bin, sizeof(*rules) * num_rules); + *__num_rules = num_rules; + } else { + *__rules = rules_base; + } + + return 0; +} + +static int ccs_data_parse_pdaf(struct bin_container *bin, struct ccs_pdaf_pix_loc **pdaf, + const void *payload, const void *endp, + struct device *dev) +{ + const struct __ccs_data_block_pdaf_pix_loc *__pdaf = payload; + const struct __ccs_data_block_pdaf_pix_loc_block_desc_group *__bdesc_group; + const struct __ccs_data_block_pdaf_pix_loc_pixel_desc *__pixel_desc; + unsigned int i; + uint16_t num_block_desc_groups; + uint8_t max_block_type_id = 0; + const uint8_t *__num_pixel_descs; + + if (!is_contained(__pdaf, endp)) + return -ENODATA; + + if (bin->base) { + *pdaf = bin_alloc(bin, sizeof(**pdaf)); + if (!*pdaf) + return -ENOMEM; + } else { + bin_reserve(bin, sizeof(**pdaf)); + } + + num_block_desc_groups = + ((uint16_t)__pdaf->num_block_desc_groups[0] << 8) + + __pdaf->num_block_desc_groups[1]; + + if (bin->base) { + (*pdaf)->main_offset_x = + ((uint16_t)__pdaf->main_offset_x[0] << 8) + + __pdaf->main_offset_x[1]; + (*pdaf)->main_offset_y = + ((uint16_t)__pdaf->main_offset_y[0] << 8) + + __pdaf->main_offset_y[1]; + (*pdaf)->global_pdaf_type = __pdaf->global_pdaf_type; + (*pdaf)->block_width = __pdaf->block_width; + (*pdaf)->block_height = __pdaf->block_height; + (*pdaf)->num_block_desc_groups = num_block_desc_groups; + } + + __bdesc_group = (const void *)(__pdaf + 1); + + if (bin->base) { + (*pdaf)->block_desc_groups = + bin_alloc(bin, + sizeof(struct ccs_pdaf_pix_loc_block_desc_group) * + num_block_desc_groups); + if (!(*pdaf)->block_desc_groups) + return -ENOMEM; + } else { + bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_block_desc_group) * + num_block_desc_groups); + } + + for (i = 0; i < num_block_desc_groups; i++) { + const struct __ccs_data_block_pdaf_pix_loc_block_desc *__bdesc; + uint16_t num_block_descs; + unsigned int j; + + if (!is_contained(__bdesc_group, endp)) + return -ENODATA; + + num_block_descs = + ((uint16_t)__bdesc_group->num_block_descs[0] << 8) + + __bdesc_group->num_block_descs[1]; + + if (bin->base) { + (*pdaf)->block_desc_groups[i].repeat_y = + __bdesc_group->repeat_y; + (*pdaf)->block_desc_groups[i].num_block_descs = + num_block_descs; + } + + __bdesc = (const void *)(__bdesc_group + 1); + + if (bin->base) { + (*pdaf)->block_desc_groups[i].block_descs = + bin_alloc(bin, + sizeof(struct ccs_pdaf_pix_loc_block_desc) * + num_block_descs); + if (!(*pdaf)->block_desc_groups[i].block_descs) + return -ENOMEM; + } else { + bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_block_desc) * + num_block_descs); + } + + for (j = 0; j < num_block_descs; j++, __bdesc++) { + struct ccs_pdaf_pix_loc_block_desc *bdesc; + + if (!is_contained(__bdesc, endp)) + return -ENODATA; + + if (max_block_type_id <= __bdesc->block_type_id) + max_block_type_id = __bdesc->block_type_id + 1; + + if (!bin->base) + continue; + + bdesc = &(*pdaf)->block_desc_groups[i].block_descs[j]; + + bdesc->repeat_x = ((uint16_t)__bdesc->repeat_x[0] << 8) + + __bdesc->repeat_x[1]; + + if (__bdesc->block_type_id >= num_block_descs) + return -EINVAL; + + bdesc->block_type_id = __bdesc->block_type_id; + } + + __bdesc_group = (const void *)__bdesc; + } + + __num_pixel_descs = (const void *)__bdesc_group; + + if (bin->base) { + (*pdaf)->pixel_desc_groups = + bin_alloc(bin, + sizeof(struct ccs_pdaf_pix_loc_pixel_desc_group) * + max_block_type_id); + if (!(*pdaf)->pixel_desc_groups) + return -ENOMEM; + (*pdaf)->num_pixel_desc_grups = max_block_type_id; + } else { + bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_pixel_desc_group) * + max_block_type_id); + } + + for (i = 0; i < max_block_type_id; i++) { + struct ccs_pdaf_pix_loc_pixel_desc_group *pdgroup; + unsigned int j; + + if (!is_contained(__num_pixel_descs, endp)) + return -ENODATA; + + if (bin->base) { + pdgroup = &(*pdaf)->pixel_desc_groups[i]; + pdgroup->descs = + bin_alloc(bin, + sizeof(struct ccs_pdaf_pix_loc_pixel_desc) * + *__num_pixel_descs); + if (!pdgroup->descs) + return -ENOMEM; + pdgroup->num_descs = *__num_pixel_descs; + } else { + bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_pixel_desc) * + *__num_pixel_descs); + } + + __pixel_desc = (const void *)(__num_pixel_descs + 1); + + for (j = 0; j < *__num_pixel_descs; j++, __pixel_desc++) { + struct ccs_pdaf_pix_loc_pixel_desc *pdesc; + + if (!is_contained(__pixel_desc, endp)) + return -ENODATA; + + if (!bin->base) + continue; + + pdesc = &pdgroup->descs[j]; + pdesc->pixel_type = __pixel_desc->pixel_type; + pdesc->small_offset_x = __pixel_desc->small_offset_x; + pdesc->small_offset_y = __pixel_desc->small_offset_y; + } + + __num_pixel_descs = (const void *)(__pixel_desc + 1); + } + + return 0; +} + +static int ccs_data_parse_license(struct bin_container *bin, + char **__license, + size_t *__license_length, + const void *payload, const void *endp) +{ + size_t size = endp - payload; + char *license; + + if (!bin->base) { + bin_reserve(bin, size); + return 0; + } + + license = bin_alloc(bin, size); + if (!license) + return -ENOMEM; + + memcpy(license, payload, size); + + *__license = license; + *__license_length = size; + + return 0; +} + +static int ccs_data_parse_end(bool *end, const void *payload, const void *endp, + struct device *dev) +{ + const struct __ccs_data_block_end *__end = payload; + + if (__end + 1 != endp) { + dev_dbg(dev, "Invalid end block length %u\n", + (unsigned int)(endp - payload)); + return -ENODATA; + } + + *end = true; + + return 0; +} + +static int __ccs_data_parse(struct bin_container *bin, + struct ccs_data_container *ccsdata, + const void *data, size_t len, struct device *dev, + bool verbose) +{ + const struct __ccs_data_block *block = data; + const struct __ccs_data_block *endp = data + len; + unsigned int version; + bool is_first = true; + int rval; + + version = ccs_data_parse_format_version(block); + if (version != CCS_STATIC_DATA_VERSION) { + dev_dbg(dev, "Don't know how to handle version %u\n", version); + return -EINVAL; + } + + if (verbose) + dev_dbg(dev, "Parsing CCS static data version %u\n", version); + + if (!bin->base) + *ccsdata = (struct ccs_data_container){ 0 }; + + while (block < endp) { + const struct __ccs_data_block *next_block; + unsigned int block_id; + const void *payload; + + rval = ccs_data_block_parse_header(block, is_first, &block_id, + &payload, &next_block, endp, + dev, + bin->base ? false : verbose); + + if (rval < 0) + return rval; + + switch (block_id) { + case CCS_DATA_BLOCK_ID_DUMMY: + break; + case CCS_DATA_BLOCK_ID_DATA_VERSION: + rval = ccs_data_parse_version(bin, ccsdata, payload, + next_block); + if (rval < 0) + return rval; + break; + case CCS_DATA_BLOCK_ID_SENSOR_READ_ONLY_REGS: + rval = ccs_data_parse_regs( + bin, &ccsdata->sensor_read_only_regs, + &ccsdata->num_sensor_read_only_regs, payload, + next_block, dev); + if (rval < 0) + return rval; + break; + case CCS_DATA_BLOCK_ID_SENSOR_MANUFACTURER_REGS: + rval = ccs_data_parse_regs( + bin, &ccsdata->sensor_manufacturer_regs, + &ccsdata->num_sensor_manufacturer_regs, payload, + next_block, dev); + if (rval < 0) + return rval; + break; + case CCS_DATA_BLOCK_ID_MODULE_READ_ONLY_REGS: + rval = ccs_data_parse_regs( + bin, &ccsdata->module_read_only_regs, + &ccsdata->num_module_read_only_regs, payload, + next_block, dev); + if (rval < 0) + return rval; + break; + case CCS_DATA_BLOCK_ID_MODULE_MANUFACTURER_REGS: + rval = ccs_data_parse_regs( + bin, &ccsdata->module_manufacturer_regs, + &ccsdata->num_module_manufacturer_regs, payload, + next_block, dev); + if (rval < 0) + return rval; + break; + case CCS_DATA_BLOCK_ID_SENSOR_PDAF_PIXEL_LOCATION: + rval = ccs_data_parse_pdaf(bin, &ccsdata->sensor_pdaf, + payload, next_block, dev); + if (rval < 0) + return rval; + break; + case CCS_DATA_BLOCK_ID_MODULE_PDAF_PIXEL_LOCATION: + rval = ccs_data_parse_pdaf(bin, &ccsdata->module_pdaf, + payload, next_block, dev); + if (rval < 0) + return rval; + break; + case CCS_DATA_BLOCK_ID_SENSOR_RULE_BASED_BLOCK: + rval = ccs_data_parse_rules( + bin, &ccsdata->sensor_rules, + &ccsdata->num_sensor_rules, payload, next_block, + dev); + if (rval < 0) + return rval; + break; + case CCS_DATA_BLOCK_ID_MODULE_RULE_BASED_BLOCK: + rval = ccs_data_parse_rules( + bin, &ccsdata->module_rules, + &ccsdata->num_module_rules, payload, next_block, + dev); + if (rval < 0) + return rval; + break; + case CCS_DATA_BLOCK_ID_LICENSE: + rval = ccs_data_parse_license(bin, &ccsdata->license, + &ccsdata->license_length, + payload, next_block); + if (rval < 0) + return rval; + break; + case CCS_DATA_BLOCK_ID_END: + rval = ccs_data_parse_end(&ccsdata->end, payload, + next_block, dev); + if (rval < 0) + return rval; + break; + default: + dev_dbg(dev, "WARNING: not handling block ID 0x%2.2x\n", + block_id); + } + + block = next_block; + is_first = false; + } + + return 0; +} + +int ccs_data_parse(struct ccs_data_container *ccsdata, const void *data, + size_t len, struct device *dev, bool verbose) +{ + struct bin_container bin = { 0 }; + int rval; + + rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, verbose); + if (rval) + return rval; + + rval = bin_backing_alloc(&bin); + if (rval) + return rval; + + rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, false); + if (rval) + goto out_free; + + if (verbose && ccsdata->version) + print_ccs_data_version(dev, ccsdata->version); + + if (bin.now != bin.end) { + rval = -EPROTO; + dev_dbg(dev, "parsing mismatch; base %p; now %p; end %p\n", + bin.base, bin.now, bin.end); + goto out_free; + } + + ccsdata->backing = bin.base; + + return 0; + +out_free: + kvfree(bin.base); + + return rval; +} diff --git a/drivers/media/i2c/ccs/ccs-data.h b/drivers/media/i2c/ccs/ccs-data.h new file mode 100644 index 000000000000..323201a15bf7 --- /dev/null +++ b/drivers/media/i2c/ccs/ccs-data.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * CCS static data in-memory data structure definitions + * + * Copyright 2019--2020 Intel Corporation + */ + +#ifndef __CCS_DATA_H__ +#define __CCS_DATA_H__ + +#include + +struct ccs_data_block_version { + uint16_t version_major; + uint16_t version_minor; + uint16_t date_year; + uint8_t date_month; + uint8_t date_day; +}; + +struct ccs_reg { + uint16_t addr; + uint16_t len; + uint8_t *value; +}; + +struct ccs_if_rule { + uint16_t addr; + uint8_t value; + uint8_t mask; +}; + +struct ccs_frame_format_desc { + uint8_t pixelcode; + uint16_t value; +}; + +struct ccs_frame_format_descs { + uint8_t num_column_descs; + uint8_t num_row_descs; + struct ccs_frame_format_desc *column_descs; + struct ccs_frame_format_desc *row_descs; +}; + +struct ccs_pdaf_readout { + uint8_t pdaf_readout_info_order; + struct ccs_frame_format_descs *ffd; +}; + +struct ccs_rule { + size_t num_if_rules; + struct ccs_if_rule *if_rules; + size_t num_read_only_regs; + struct ccs_reg *read_only_regs; + size_t num_manufacturer_regs; + struct ccs_reg *manufacturer_regs; + struct ccs_frame_format_descs *frame_format; + struct ccs_pdaf_readout *pdaf_readout; +}; + +struct ccs_pdaf_pix_loc_block_desc { + uint8_t block_type_id; + uint16_t repeat_x; +}; + +struct ccs_pdaf_pix_loc_block_desc_group { + uint8_t repeat_y; + uint16_t num_block_descs; + struct ccs_pdaf_pix_loc_block_desc *block_descs; +}; + +struct ccs_pdaf_pix_loc_pixel_desc { + uint8_t pixel_type; + uint8_t small_offset_x; + uint8_t small_offset_y; +}; + +struct ccs_pdaf_pix_loc_pixel_desc_group { + uint8_t num_descs; + struct ccs_pdaf_pix_loc_pixel_desc *descs; +}; + +struct ccs_pdaf_pix_loc { + uint16_t main_offset_x; + uint16_t main_offset_y; + uint8_t global_pdaf_type; + uint8_t block_width; + uint8_t block_height; + uint16_t num_block_desc_groups; + struct ccs_pdaf_pix_loc_block_desc_group *block_desc_groups; + uint8_t num_pixel_desc_grups; + struct ccs_pdaf_pix_loc_pixel_desc_group *pixel_desc_groups; +}; + +struct ccs_data_container { + struct ccs_data_block_version *version; + size_t num_sensor_read_only_regs; + struct ccs_reg *sensor_read_only_regs; + size_t num_sensor_manufacturer_regs; + struct ccs_reg *sensor_manufacturer_regs; + size_t num_sensor_rules; + struct ccs_rule *sensor_rules; + size_t num_module_read_only_regs; + struct ccs_reg *module_read_only_regs; + size_t num_module_manufacturer_regs; + struct ccs_reg *module_manufacturer_regs; + size_t num_module_rules; + struct ccs_rule *module_rules; + struct ccs_pdaf_pix_loc *sensor_pdaf; + struct ccs_pdaf_pix_loc *module_pdaf; + size_t license_length; + char *license; + bool end; + void *backing; +}; + +int ccs_data_parse(struct ccs_data_container *ccsdata, const void *data, + size_t len, struct device *dev, bool verbose); + +#endif /* __CCS_DATA_H__ */ From patchwork Tue Nov 24 09:32:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331709 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03BB4C64E7A for ; Tue, 24 Nov 2020 09:38:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AAE1E2076B for ; Tue, 24 Nov 2020 09:38:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731199AbgKXJiu (ORCPT ); Tue, 24 Nov 2020 04:38:50 -0500 Received: from retiisi.eu ([95.216.213.190]:45026 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731143AbgKXJid (ORCPT ); Tue, 24 Nov 2020 04:38:33 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id A4A0D634C93; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 09/30] ccs: Combine revision number major and minor into one Date: Tue, 24 Nov 2020 11:32:05 +0200 Message-Id: <20201124093226.23737-10-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The module revision number major and minor are both 8 bits while the sensor revision number is 16 bits. Combine the module revision into one number. This also adds printing the lowest 8 bits of the module version through the sysfs attribute. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 25 ++++++++++++++----------- drivers/media/i2c/ccs/ccs-quirk.c | 2 +- drivers/media/i2c/ccs/ccs.h | 3 +-- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 6fb546ca08f3..17287a8f539c 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -2427,11 +2427,11 @@ ccs_sysfs_ident_read(struct device *dev, struct device_attribute *attr, if (minfo->mipi_manufacturer_id) return snprintf(buf, PAGE_SIZE, "%4.4x%4.4x%2.2x\n", minfo->mipi_manufacturer_id, minfo->model_id, - minfo->revision_number_major) + 1; + minfo->revision_number) + 1; else return snprintf(buf, PAGE_SIZE, "%2.2x%4.4x%2.2x\n", minfo->smia_manufacturer_id, minfo->model_id, - minfo->revision_number_major) + 1; + minfo->revision_number) + 1; } static DEVICE_ATTR(ident, S_IRUGO, ccs_sysfs_ident_read, NULL); @@ -2445,6 +2445,7 @@ static int ccs_identify_module(struct ccs_sensor *sensor) struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); struct ccs_module_info *minfo = &sensor->minfo; unsigned int i; + u32 rev; int rval = 0; /* Module info */ @@ -2460,11 +2461,13 @@ static int ccs_identify_module(struct ccs_sensor *sensor) if (!rval) rval = ccs_read_addr_8only(sensor, CCS_R_MODULE_REVISION_NUMBER_MAJOR, - &minfo->revision_number_major); - if (!rval) + &rev); + if (!rval) { rval = ccs_read_addr_8only(sensor, CCS_R_MODULE_REVISION_NUMBER_MINOR, - &minfo->revision_number_minor); + &minfo->revision_number); + minfo->revision_number |= rev << 8; + } if (!rval) rval = ccs_read_addr_8only(sensor, CCS_R_MODULE_DATE_YEAR, &minfo->module_year); @@ -2519,9 +2522,9 @@ static int ccs_identify_module(struct ccs_sensor *sensor) minfo->smia_manufacturer_id, minfo->model_id); dev_dbg(&client->dev, - "module revision 0x%2.2x-0x%2.2x date %2.2d-%2.2d-%2.2d\n", - minfo->revision_number_major, minfo->revision_number_minor, - minfo->module_year, minfo->module_month, minfo->module_day); + "module revision 0x%4.4x date %2.2d-%2.2d-%2.2d\n", + minfo->revision_number, minfo->module_year, minfo->module_month, + minfo->module_day); if (minfo->sensor_mipi_manufacturer_id) dev_dbg(&client->dev, "MIPI CCS sensor 0x%4.4x-0x%4.4x\n", @@ -2559,7 +2562,7 @@ static int ccs_identify_module(struct ccs_sensor *sensor) minfo->smia_manufacturer_id = minfo->sensor_smia_manufacturer_id; minfo->model_id = minfo->sensor_model_id; - minfo->revision_number_major = minfo->sensor_revision_number; + minfo->revision_number = minfo->sensor_revision_number; } for (i = 0; i < ARRAY_SIZE(ccs_module_idents); i++) { @@ -2576,11 +2579,11 @@ static int ccs_identify_module(struct ccs_sensor *sensor) if (ccs_module_idents[i].flags & CCS_MODULE_IDENT_FLAG_REV_LE) { if (ccs_module_idents[i].revision_number_major - < minfo->revision_number_major) + < (minfo->revision_number >> 8)) continue; } else { if (ccs_module_idents[i].revision_number_major - != minfo->revision_number_major) + != (minfo->revision_number >> 8)) continue; } diff --git a/drivers/media/i2c/ccs/ccs-quirk.c b/drivers/media/i2c/ccs/ccs-quirk.c index facec28f8447..07c5733b4244 100644 --- a/drivers/media/i2c/ccs/ccs-quirk.c +++ b/drivers/media/i2c/ccs/ccs-quirk.c @@ -35,7 +35,7 @@ static int ccs_write_addr_8s(struct ccs_sensor *sensor, static int jt8ew9_limits(struct ccs_sensor *sensor) { - if (sensor->minfo.revision_number_major < 0x03) + if (sensor->minfo.revision_number < 0x0300) sensor->frame_skip = 1; /* Below 24 gain doesn't have effect at all, */ diff --git a/drivers/media/i2c/ccs/ccs.h b/drivers/media/i2c/ccs/ccs.h index 2d1e8339f663..ad2ff5a74424 100644 --- a/drivers/media/i2c/ccs/ccs.h +++ b/drivers/media/i2c/ccs/ccs.h @@ -107,8 +107,7 @@ struct ccs_module_info { u32 smia_manufacturer_id; u32 mipi_manufacturer_id; u32 model_id; - u32 revision_number_major; - u32 revision_number_minor; + u32 revision_number; u32 module_year; u32 module_month; From patchwork Tue Nov 24 09:32:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332632 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90D49C71156 for ; Tue, 24 Nov 2020 09:38:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 626FD2073C for ; Tue, 24 Nov 2020 09:38:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731512AbgKXJih (ORCPT ); Tue, 24 Nov 2020 04:38:37 -0500 Received: from retiisi.eu ([95.216.213.190]:45028 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731487AbgKXJif (ORCPT ); Tue, 24 Nov 2020 04:38:35 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id ABF41634C94; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 10/30] ccs: Read CCS static data from firmware binaries Date: Tue, 24 Nov 2020 11:32:06 +0200 Message-Id: <20201124093226.23737-11-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Read the CCS static data for sensors and modules. The files are expected to be found in "ccs" directory. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 47 +++++++++++++++++++++++++++++++- drivers/media/i2c/ccs/ccs.h | 2 ++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 17287a8f539c..be27b002a772 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -2953,6 +2954,8 @@ static int ccs_get_hwconfig(struct ccs_sensor *sensor, struct device *dev) static int ccs_probe(struct i2c_client *client) { struct ccs_sensor *sensor; + const struct firmware *fw; + char filename[40]; unsigned int i; int rval; @@ -3042,9 +3045,43 @@ static int ccs_probe(struct i2c_client *client) goto out_power_off; } + rval = snprintf(filename, sizeof(filename), + "ccs/ccs-sensor-%4.4x-%4.4x-%4.4x.fw", + sensor->minfo.sensor_mipi_manufacturer_id, + sensor->minfo.sensor_model_id, + sensor->minfo.sensor_revision_number); + if (rval >= sizeof(filename)) { + rval = -ENOMEM; + goto out_power_off; + } + + rval = request_firmware(&fw, filename, &client->dev); + if (!rval) { + ccs_data_parse(&sensor->sdata, fw->data, fw->size, &client->dev, + true); + release_firmware(fw); + } + + rval = snprintf(filename, sizeof(filename), + "ccs/ccs-module-%4.4x-%4.4x-%4.4x.fw", + sensor->minfo.mipi_manufacturer_id, + sensor->minfo.model_id, + sensor->minfo.revision_number); + if (rval >= sizeof(filename)) { + rval = -ENOMEM; + goto out_release_sdata; + } + + rval = request_firmware(&fw, filename, &client->dev); + if (!rval) { + ccs_data_parse(&sensor->mdata, fw->data, fw->size, &client->dev, + true); + release_firmware(fw); + } + rval = ccs_read_all_limits(sensor); if (rval) - goto out_power_off; + goto out_release_mdata; rval = ccs_read_frame_fmt(sensor); if (rval) { @@ -3208,6 +3245,12 @@ static int ccs_probe(struct i2c_client *client) out_cleanup: ccs_cleanup(sensor); +out_release_mdata: + kvfree(sensor->mdata.backing); + +out_release_sdata: + kvfree(sensor->sdata.backing); + out_free_ccs_limits: kfree(sensor->ccs_limits); @@ -3238,6 +3281,8 @@ static int ccs_remove(struct i2c_client *client) ccs_cleanup(sensor); mutex_destroy(&sensor->mutex); kfree(sensor->ccs_limits); + kvfree(sensor->sdata.backing); + kvfree(sensor->mdata.backing); return 0; } diff --git a/drivers/media/i2c/ccs/ccs.h b/drivers/media/i2c/ccs/ccs.h index ad2ff5a74424..cbcd93b519da 100644 --- a/drivers/media/i2c/ccs/ccs.h +++ b/drivers/media/i2c/ccs/ccs.h @@ -16,6 +16,7 @@ #include #include +#include "ccs-data.h" #include "ccs-quirk.h" #include "ccs-regs.h" #include "ccs-reg-access.h" @@ -227,6 +228,7 @@ struct ccs_sensor { const struct ccs_csi_data_format *internal_csi_format; u32 default_mbus_frame_fmts; int default_pixel_order; + struct ccs_data_container sdata, mdata; u8 binning_horizontal; u8 binning_vertical; From patchwork Tue Nov 24 09:32:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332634 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D49B3C2D0E4 for ; Tue, 24 Nov 2020 09:38:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9935B2073C for ; Tue, 24 Nov 2020 09:38:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731504AbgKXJif (ORCPT ); Tue, 24 Nov 2020 04:38:35 -0500 Received: from retiisi.eu ([95.216.213.190]:45030 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731488AbgKXJie (ORCPT ); Tue, 24 Nov 2020 04:38:34 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id C0434634C95; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 11/30] ccs: Stop reading arrays after the first zero Date: Tue, 24 Nov 2020 11:32:07 +0200 Message-Id: <20201124093226.23737-12-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The register arrays have a certain size but not all the entries will be relevant. In practice reading can be stopped after encountering a zero value in the array. Do that to avoid extra reads. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index be27b002a772..dec248fe7cc1 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -199,6 +199,9 @@ static int ccs_read_all_limits(struct ccs_sensor *sensor) goto out_err; } + if (!val && j) + break; + ccs_assign_limit(ptr, width, val); dev_dbg(&client->dev, "0x%8.8x \"%s\" = %u, 0x%x\n", From patchwork Tue Nov 24 09:32:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331706 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05D1CC71155 for ; Tue, 24 Nov 2020 09:38:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C934520897 for ; Tue, 24 Nov 2020 09:38:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731506AbgKXJig (ORCPT ); Tue, 24 Nov 2020 04:38:36 -0500 Received: from retiisi.eu ([95.216.213.190]:45032 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731489AbgKXJie (ORCPT ); Tue, 24 Nov 2020 04:38:34 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id D550D634C96; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 12/30] ccs: The functions to get compose or crop rectangle never return NULL Date: Tue, 24 Nov 2020 11:32:08 +0200 Message-Id: <20201124093226.23737-13-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The NULL check is not needed as the functions do not return NULL. Remove the check (and BUG). Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index dec248fe7cc1..25b4c84524ff 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -1766,16 +1766,12 @@ static void ccs_get_crop_compose(struct v4l2_subdev *subdev, *comps = &ssd->compose; } else { if (crops) { - for (i = 0; i < subdev->entity.num_pads; i++) { + for (i = 0; i < subdev->entity.num_pads; i++) crops[i] = v4l2_subdev_get_try_crop(subdev, cfg, i); - BUG_ON(!crops[i]); - } } - if (comps) { + if (comps) *comps = v4l2_subdev_get_try_compose(subdev, cfg, CCS_PAD_SINK); - BUG_ON(!*comps); - } } } From patchwork Tue Nov 24 09:32:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331716 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 31737C64E8A for ; Tue, 24 Nov 2020 09:38:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EE12A20897 for ; Tue, 24 Nov 2020 09:38:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731494AbgKXJie (ORCPT ); Tue, 24 Nov 2020 04:38:34 -0500 Received: from retiisi.eu ([95.216.213.190]:45006 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731479AbgKXJib (ORCPT ); Tue, 24 Nov 2020 04:38:31 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id EAEF0634C97; Tue, 24 Nov 2020 11:37:51 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 13/30] ccs: Replace somewhat harsh internal checks based on BUG with WARN_ON Date: Tue, 24 Nov 2020 11:32:09 +0200 Message-Id: <20201124093226.23737-14-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org If an internal driver error was encountered, BUG was issued. Instead, do less harsh WARN_ON_ONCE and try to manage with the consequences. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 25b4c84524ff..70b4d2180971 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -546,6 +546,10 @@ static void ccs_update_mbus_formats(struct ccs_sensor *sensor) to_csi_format_idx(sensor->internal_csi_format) & ~3; unsigned int pixel_order = ccs_pixel_order(sensor); + if (WARN_ON_ONCE(max(internal_csi_format_idx, csi_format_idx) + + pixel_order >= ARRAY_SIZE(ccs_csi_data_formats))) + return; + sensor->mbus_frame_fmts = sensor->default_mbus_frame_fmts << pixel_order; sensor->csi_format = @@ -554,9 +558,6 @@ static void ccs_update_mbus_formats(struct ccs_sensor *sensor) &ccs_csi_data_formats[internal_csi_format_idx + pixel_order]; - BUG_ON(max(internal_csi_format_idx, csi_format_idx) + pixel_order - >= ARRAY_SIZE(ccs_csi_data_formats)); - dev_dbg(&client->dev, "new pixel order %s\n", pixel_order_str[pixel_order]); } @@ -1806,7 +1807,7 @@ static void ccs_propagate(struct v4l2_subdev *subdev, *crops[CCS_PAD_SRC] = *comp; break; default: - BUG(); + WARN_ON_ONCE(1); } } From patchwork Tue Nov 24 09:32:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331715 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18B9DC64E7C for ; Tue, 24 Nov 2020 09:38:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C06D32073C for ; Tue, 24 Nov 2020 09:38:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731493AbgKXJid (ORCPT ); Tue, 24 Nov 2020 04:38:33 -0500 Received: from retiisi.eu ([95.216.213.190]:45008 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731296AbgKXJib (ORCPT ); Tue, 24 Nov 2020 04:38:31 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 0D717634C98; Tue, 24 Nov 2020 11:37:52 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 14/30] ccs: Refactor register reading a little Date: Tue, 24 Nov 2020 11:32:10 +0200 Message-Id: <20201124093226.23737-15-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Rework quirk and 8-bit only access functions with a single function that takes arguments. This is later extensible to support yet more flags. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-reg-access.c | 37 ++++++++++++-------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-reg-access.c b/drivers/media/i2c/ccs/ccs-reg-access.c index a8e9a235bfb3..abec746f3c93 100644 --- a/drivers/media/i2c/ccs/ccs-reg-access.c +++ b/drivers/media/i2c/ccs/ccs-reg-access.c @@ -168,39 +168,36 @@ static int __ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val, return 0; } -int ccs_read_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 *val) -{ - return __ccs_read_addr( - sensor, reg, val, - ccs_needs_quirk(sensor, CCS_QUIRK_FLAG_8BIT_READ_ONLY)); -} - -static int ccs_read_addr_quirk(struct ccs_sensor *sensor, u32 reg, u32 *val, - bool force8) +static int ccs_read_addr_raw(struct ccs_sensor *sensor, u32 reg, u32 *val, + bool force8, bool quirk) { int rval; - *val = 0; - rval = ccs_call_quirk(sensor, reg_access, false, ®, val); - if (rval == -ENOIOCTLCMD) - return 0; - if (rval < 0) - return rval; + if (quirk) { + *val = 0; + rval = ccs_call_quirk(sensor, reg_access, false, ®, val); + if (rval == -ENOIOCTLCMD) + return 0; + if (rval < 0) + return rval; - if (force8) - return __ccs_read_addr(sensor, reg, val, true); + if (force8) + return __ccs_read_addr(sensor, reg, val, true); + } - return ccs_read_addr_no_quirk(sensor, reg, val); + return __ccs_read_addr(sensor, reg, val, + ccs_needs_quirk(sensor, + CCS_QUIRK_FLAG_8BIT_READ_ONLY)); } int ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val) { - return ccs_read_addr_quirk(sensor, reg, val, false); + return ccs_read_addr_raw(sensor, reg, val, false, true); } int ccs_read_addr_8only(struct ccs_sensor *sensor, u32 reg, u32 *val) { - return ccs_read_addr_quirk(sensor, reg, val, true); + return ccs_read_addr_raw(sensor, reg, val, true, true); } int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val) From patchwork Tue Nov 24 09:32:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332637 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B74F6C64E90 for ; Tue, 24 Nov 2020 09:38:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 64C312076B for ; Tue, 24 Nov 2020 09:38:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731500AbgKXJif (ORCPT ); Tue, 24 Nov 2020 04:38:35 -0500 Received: from retiisi.eu ([95.216.213.190]:44964 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731485AbgKXJid (ORCPT ); Tue, 24 Nov 2020 04:38:33 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 25CDB634C99; Tue, 24 Nov 2020 11:37:52 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 15/30] ccs: Make real to integer number conversion optional Date: Tue, 24 Nov 2020 11:32:11 +0200 Message-Id: <20201124093226.23737-16-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The limit values will be raw soon, and the conversion takes place later on. Prepare for that. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-reg-access.c | 35 +++++++++++++++++++------- drivers/media/i2c/ccs/ccs-reg-access.h | 2 ++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-reg-access.c b/drivers/media/i2c/ccs/ccs-reg-access.c index abec746f3c93..fe6112cba6be 100644 --- a/drivers/media/i2c/ccs/ccs-reg-access.c +++ b/drivers/media/i2c/ccs/ccs-reg-access.c @@ -143,14 +143,23 @@ unsigned int ccs_reg_width(u32 reg) return sizeof(uint8_t); } +u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); + + if (reg & CCS_FL_FLOAT_IREAL) + val = float_to_u32_mul_1000000(client, val); + + return val; +} + /* * Read a 8/16/32-bit i2c register. The value is returned in 'val'. * Returns zero if successful, or non-zero otherwise. */ static int __ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val, - bool only8) + bool only8, bool conv) { - struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); unsigned int len = ccs_reg_width(reg); int rval; @@ -162,14 +171,16 @@ static int __ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val, if (rval < 0) return rval; - if (reg & CCS_FL_FLOAT_IREAL) - *val = float_to_u32_mul_1000000(client, *val); + if (!conv) + return 0; + + *val = ccs_reg_conv(sensor, reg, *val); return 0; } static int ccs_read_addr_raw(struct ccs_sensor *sensor, u32 reg, u32 *val, - bool force8, bool quirk) + bool force8, bool quirk, bool conv) { int rval; @@ -182,22 +193,28 @@ static int ccs_read_addr_raw(struct ccs_sensor *sensor, u32 reg, u32 *val, return rval; if (force8) - return __ccs_read_addr(sensor, reg, val, true); + return __ccs_read_addr(sensor, reg, val, true, conv); } return __ccs_read_addr(sensor, reg, val, ccs_needs_quirk(sensor, - CCS_QUIRK_FLAG_8BIT_READ_ONLY)); + CCS_QUIRK_FLAG_8BIT_READ_ONLY), + conv); } int ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val) { - return ccs_read_addr_raw(sensor, reg, val, false, true); + return ccs_read_addr_raw(sensor, reg, val, false, true, true); } int ccs_read_addr_8only(struct ccs_sensor *sensor, u32 reg, u32 *val) { - return ccs_read_addr_raw(sensor, reg, val, true, true); + return ccs_read_addr_raw(sensor, reg, val, true, true, true); +} + +int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val) +{ + return ccs_read_addr_raw(sensor, reg, val, false, true, false); } int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val) diff --git a/drivers/media/i2c/ccs/ccs-reg-access.h b/drivers/media/i2c/ccs/ccs-reg-access.h index 9fdf5659ed09..5f6ff9c57698 100644 --- a/drivers/media/i2c/ccs/ccs-reg-access.h +++ b/drivers/media/i2c/ccs/ccs-reg-access.h @@ -24,10 +24,12 @@ struct ccs_sensor; int ccs_read_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 *val); int ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val); int ccs_read_addr_8only(struct ccs_sensor *sensor, u32 reg, u32 *val); +int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val); int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val); int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val); unsigned int ccs_reg_width(u32 reg); +u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val); #define ccs_read(sensor, reg_name, val) \ ccs_read_addr(sensor, CCS_R_##reg_name, val) From patchwork Tue Nov 24 09:32:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332630 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 505B0C56202 for ; Tue, 24 Nov 2020 09:38:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 017022073C for ; Tue, 24 Nov 2020 09:38:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731509AbgKXJig (ORCPT ); Tue, 24 Nov 2020 04:38:36 -0500 Received: from retiisi.eu ([95.216.213.190]:45006 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731490AbgKXJie (ORCPT ); Tue, 24 Nov 2020 04:38:34 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 3EB1B634CA1; Tue, 24 Nov 2020 11:37:52 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 16/30] ccs: Move limit value real to integer conversion from read to access time Date: Tue, 24 Nov 2020 11:32:12 +0200 Message-Id: <20201124093226.23737-17-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Instead of converting the limit values at register read time, do that at access time instead. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 70b4d2180971..57efc34fc67d 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -130,6 +130,7 @@ static u32 ccs_get_limit(struct ccs_sensor *sensor, unsigned int limit, unsigned int offset) { void *ptr; + u32 val; int ret; ret = ccs_limit_ptr(sensor, limit, offset, &ptr); @@ -138,16 +139,20 @@ static u32 ccs_get_limit(struct ccs_sensor *sensor, switch (ccs_reg_width(ccs_limits[ccs_limit_offsets[limit].info].reg)) { case sizeof(u8): - return *(u8 *)ptr; + val = *(u8 *)ptr; + break; case sizeof(u16): - return *(u16 *)ptr; + val = *(u16 *)ptr; + break; case sizeof(u32): - return *(u32 *)ptr; + val = *(u32 *)ptr; + break; + default: + WARN_ON(1); + return 0; } - WARN_ON(1); - - return 0; + return ccs_reg_conv(sensor, ccs_limits[limit].reg, val); } #define CCS_LIM(sensor, limit) \ @@ -188,7 +193,7 @@ static int ccs_read_all_limits(struct ccs_sensor *sensor) j++, reg += width, ptr += width) { u32 val; - ret = ccs_read_addr(sensor, reg, &val); + ret = ccs_read_addr_noconv(sensor, reg, &val); if (ret) goto out_err; From patchwork Tue Nov 24 09:32:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331714 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C834C8300B for ; Tue, 24 Nov 2020 09:38:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 304F02076B for ; Tue, 24 Nov 2020 09:38:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731510AbgKXJih (ORCPT ); Tue, 24 Nov 2020 04:38:37 -0500 Received: from retiisi.eu ([95.216.213.190]:45008 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731491AbgKXJif (ORCPT ); Tue, 24 Nov 2020 04:38:35 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 583DF634CA3; Tue, 24 Nov 2020 11:37:52 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 17/30] ccs: Read ireal numbers correctly Date: Tue, 24 Nov 2020 11:32:13 +0200 Message-Id: <20201124093226.23737-18-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Some limit values are available in q16.q16 format, referred to as 32-bit unsigned ireal in CCS. Read these correctly. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 10 ++-------- drivers/media/i2c/ccs/ccs-reg-access.c | 23 +++++++++++++++++++++-- drivers/media/i2c/ccs/ccs.h | 9 +++++++++ 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 57efc34fc67d..074b246538d2 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -126,8 +126,8 @@ void ccs_replace_limit(struct ccs_sensor *sensor, ccs_assign_limit(ptr, ccs_reg_width(linfo->reg), val); } -static u32 ccs_get_limit(struct ccs_sensor *sensor, - unsigned int limit, unsigned int offset) +u32 ccs_get_limit(struct ccs_sensor *sensor, unsigned int limit, + unsigned int offset) { void *ptr; u32 val; @@ -155,12 +155,6 @@ static u32 ccs_get_limit(struct ccs_sensor *sensor, return ccs_reg_conv(sensor, ccs_limits[limit].reg, val); } -#define CCS_LIM(sensor, limit) \ - ccs_get_limit(sensor, CCS_L_##limit, 0) - -#define CCS_LIM_AT(sensor, limit, offset) \ - ccs_get_limit(sensor, CCS_L_##limit, CCS_L_##limit##_OFFSET(offset)) - static int ccs_read_all_limits(struct ccs_sensor *sensor) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); diff --git a/drivers/media/i2c/ccs/ccs-reg-access.c b/drivers/media/i2c/ccs/ccs-reg-access.c index fe6112cba6be..91ccbca11577 100644 --- a/drivers/media/i2c/ccs/ccs-reg-access.c +++ b/drivers/media/i2c/ccs/ccs-reg-access.c @@ -15,6 +15,7 @@ #include #include "ccs.h" +#include "ccs-limits.h" static uint32_t float_to_u32_mul_1000000(struct i2c_client *client, uint32_t phloat) @@ -143,12 +144,30 @@ unsigned int ccs_reg_width(u32 reg) return sizeof(uint8_t); } +static u32 ireal32_to_u32_mul_1000000(struct i2c_client *client, u32 val) +{ + if (val >> 10 > U32_MAX / 15625) { + dev_warn(&client->dev, "value %u overflows!\n", val); + return U32_MAX; + } + + return ((val >> 10) * 15625) + + (val & GENMASK(9, 0)) * 15625 / 1024; +} + u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); - if (reg & CCS_FL_FLOAT_IREAL) - val = float_to_u32_mul_1000000(client, val); + if (reg & CCS_FL_FLOAT_IREAL) { + if (CCS_LIM(sensor, CLOCK_CAPA_TYPE_CAPABILITY) & + CCS_CLOCK_CAPA_TYPE_CAPABILITY_IREAL) + val = ireal32_to_u32_mul_1000000(client, val); + else + val = float_to_u32_mul_1000000(client, val); + } else if (reg & CCS_FL_IREAL) { + val = ireal32_to_u32_mul_1000000(client, val); + } return val; } diff --git a/drivers/media/i2c/ccs/ccs.h b/drivers/media/i2c/ccs/ccs.h index cbcd93b519da..f60d1801c469 100644 --- a/drivers/media/i2c/ccs/ccs.h +++ b/drivers/media/i2c/ccs/ccs.h @@ -17,6 +17,7 @@ #include #include "ccs-data.h" +#include "ccs-limits.h" #include "ccs-quirk.h" #include "ccs-regs.h" #include "ccs-reg-access.h" @@ -50,6 +51,12 @@ #define CCS_DFL_I2C_ADDR (0x20 >> 1) /* Default I2C Address */ #define CCS_ALT_I2C_ADDR (0x6e >> 1) /* Alternate I2C Address */ +#define CCS_LIM(sensor, limit) \ + ccs_get_limit(sensor, CCS_L_##limit, 0) + +#define CCS_LIM_AT(sensor, limit, offset) \ + ccs_get_limit(sensor, CCS_L_##limit, CCS_L_##limit##_OFFSET(offset)) + /* * Sometimes due to board layout considerations the camera module can be * mounted rotated. The typical rotation used is 180 degrees which can be @@ -277,5 +284,7 @@ struct ccs_sensor { void ccs_replace_limit(struct ccs_sensor *sensor, unsigned int limit, unsigned int offset, u32 val); +u32 ccs_get_limit(struct ccs_sensor *sensor, unsigned int limit, + unsigned int offset); #endif /* __CCS_H__ */ From patchwork Tue Nov 24 09:32:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332629 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0A84C64E7C for ; Tue, 24 Nov 2020 09:38:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 74DD62073C for ; Tue, 24 Nov 2020 09:38:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731536AbgKXJis (ORCPT ); Tue, 24 Nov 2020 04:38:48 -0500 Received: from retiisi.eu ([95.216.213.190]:44968 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731495AbgKXJif (ORCPT ); Tue, 24 Nov 2020 04:38:35 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 6E903634CA4; Tue, 24 Nov 2020 11:37:52 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 18/30] smiapp-pll: Rename as ccs-pll Date: Tue, 24 Nov 2020 11:32:14 +0200 Message-Id: <20201124093226.23737-19-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org MIPI CCS replaces SMIA and SMIA++ as the current standard. CCS brings new features while existing functionality will be supported. Rename the smiapp-pll as ccs-pll accordingly. Also add Intel copyright to the files. Signed-off-by: Sakari Ailus --- MAINTAINERS | 4 +- drivers/media/i2c/Kconfig | 2 +- drivers/media/i2c/Makefile | 2 +- drivers/media/i2c/{smiapp-pll.c => ccs-pll.c} | 60 +++++++++---------- drivers/media/i2c/{smiapp-pll.h => ccs-pll.h} | 40 ++++++------- drivers/media/i2c/ccs/Kconfig | 2 +- drivers/media/i2c/ccs/ccs-core.c | 18 +++--- drivers/media/i2c/ccs/ccs-quirk.c | 2 +- drivers/media/i2c/ccs/ccs.h | 4 +- 9 files changed, 66 insertions(+), 68 deletions(-) rename drivers/media/i2c/{smiapp-pll.c => ccs-pll.c} (90%) rename drivers/media/i2c/{smiapp-pll.h => ccs-pll.h} (68%) diff --git a/MAINTAINERS b/MAINTAINERS index d6892e1abdc5..252c9e86fccc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11668,8 +11668,8 @@ L: linux-media@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml F: drivers/media/i2c/ccs/ -F: drivers/media/i2c/smiapp-pll.c -F: drivers/media/i2c/smiapp-pll.h +F: drivers/media/i2c/ccs-pll.c +F: drivers/media/i2c/ccs-pll.h F: include/uapi/linux/smiapp.h MIPS diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 41a8b6189259..4b6fcf13d527 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -722,7 +722,7 @@ menu "Camera sensor devices" config VIDEO_APTINA_PLL tristate -config VIDEO_SMIAPP_PLL +config VIDEO_CCS_PLL tristate config VIDEO_HI556 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index cb0be09e38bd..c716bac3ed4b 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -104,7 +104,7 @@ obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/ obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o obj-$(CONFIG_VIDEO_LM3560) += lm3560.o obj-$(CONFIG_VIDEO_LM3646) += lm3646.o -obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o +obj-$(CONFIG_VIDEO_CCS_PLL) += ccs-pll.o obj-$(CONFIG_VIDEO_AK881X) += ak881x.o obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o obj-$(CONFIG_VIDEO_I2C) += video-i2c.o diff --git a/drivers/media/i2c/smiapp-pll.c b/drivers/media/i2c/ccs-pll.c similarity index 90% rename from drivers/media/i2c/smiapp-pll.c rename to drivers/media/i2c/ccs-pll.c index 690abe8cbdb2..d2f0f7375f5c 100644 --- a/drivers/media/i2c/smiapp-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -1,9 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * drivers/media/i2c/smiapp-pll.c + * drivers/media/i2c/ccs-pll.c * - * Generic driver for SMIA/SMIA++ compliant camera modules + * Generic MIPI CCS/SMIA/SMIA++ PLL calculator * + * Copyright (C) 2020 Intel Corporation * Copyright (C) 2011--2012 Nokia Corporation * Contact: Sakari Ailus */ @@ -13,7 +14,7 @@ #include #include -#include "smiapp-pll.h" +#include "ccs-pll.h" /* Return an even number or one. */ static inline uint32_t clk_div_even(uint32_t a) @@ -50,11 +51,11 @@ static int bounds_check(struct device *dev, uint32_t val, return -EINVAL; } -static void print_pll(struct device *dev, struct smiapp_pll *pll) +static void print_pll(struct device *dev, struct ccs_pll *pll) { dev_dbg(dev, "pre_pll_clk_div\t%u\n", pll->pre_pll_clk_div); dev_dbg(dev, "pll_multiplier \t%u\n", pll->pll_multiplier); - if (!(pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS)) { + if (!(pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS)) { dev_dbg(dev, "op_sys_clk_div \t%u\n", pll->op.sys_clk_div); dev_dbg(dev, "op_pix_clk_div \t%u\n", pll->op.pix_clk_div); } @@ -64,7 +65,7 @@ static void print_pll(struct device *dev, struct smiapp_pll *pll) dev_dbg(dev, "ext_clk_freq_hz \t%u\n", pll->ext_clk_freq_hz); dev_dbg(dev, "pll_ip_clk_freq_hz \t%u\n", pll->pll_ip_clk_freq_hz); dev_dbg(dev, "pll_op_clk_freq_hz \t%u\n", pll->pll_op_clk_freq_hz); - if (!(pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS)) { + if (!(pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS)) { dev_dbg(dev, "op_sys_clk_freq_hz \t%u\n", pll->op.sys_clk_freq_hz); dev_dbg(dev, "op_pix_clk_freq_hz \t%u\n", @@ -75,10 +76,9 @@ static void print_pll(struct device *dev, struct smiapp_pll *pll) } static int check_all_bounds(struct device *dev, - const struct smiapp_pll_limits *limits, - const struct smiapp_pll_branch_limits *op_limits, - struct smiapp_pll *pll, - struct smiapp_pll_branch *op_pll) + const struct ccs_pll_limits *limits, + const struct ccs_pll_branch_limits *op_limits, + struct ccs_pll *pll, struct ccs_pll_branch *op_pll) { int rval; @@ -118,7 +118,7 @@ static int check_all_bounds(struct device *dev, * If there are no OP clocks, the VT clocks are contained in * the OP clock struct. */ - if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) + if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS) return rval; if (!rval) @@ -148,11 +148,11 @@ static int check_all_bounds(struct device *dev, * * @return Zero on success, error code on error. */ -static int __smiapp_pll_calculate( - struct device *dev, const struct smiapp_pll_limits *limits, - const struct smiapp_pll_branch_limits *op_limits, - struct smiapp_pll *pll, struct smiapp_pll_branch *op_pll, uint32_t mul, - uint32_t div, uint32_t lane_op_clock_ratio) +static int +__ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *limits, + const struct ccs_pll_branch_limits *op_limits, + struct ccs_pll *pll, struct ccs_pll_branch *op_pll, + uint32_t mul, uint32_t div, uint32_t lane_op_clock_ratio) { uint32_t sys_div; uint32_t best_pix_div = INT_MAX >> 1; @@ -252,7 +252,7 @@ static int __smiapp_pll_calculate( op_pll->pix_clk_freq_hz = op_pll->sys_clk_freq_hz / op_pll->pix_clk_div; - if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) { + if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS) { /* No OP clocks --- VT clocks are used instead. */ goto out_skip_vt_calc; } @@ -383,12 +383,11 @@ static int __smiapp_pll_calculate( return check_all_bounds(dev, limits, op_limits, pll, op_pll); } -int smiapp_pll_calculate(struct device *dev, - const struct smiapp_pll_limits *limits, - struct smiapp_pll *pll) +int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *limits, + struct ccs_pll *pll) { - const struct smiapp_pll_branch_limits *op_limits = &limits->op; - struct smiapp_pll_branch *op_pll = &pll->op; + const struct ccs_pll_branch_limits *op_limits = &limits->op; + struct ccs_pll_branch *op_pll = &pll->op; uint16_t min_pre_pll_clk_div; uint16_t max_pre_pll_clk_div; uint32_t lane_op_clock_ratio; @@ -396,7 +395,7 @@ int smiapp_pll_calculate(struct device *dev, unsigned int i; int rval = -EINVAL; - if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) { + if (pll->flags & CCS_PLL_FLAG_NO_OP_CLOCKS) { /* * If there's no OP PLL at all, use the VT values * instead. The OP values are ignored for the rest of @@ -406,7 +405,7 @@ int smiapp_pll_calculate(struct device *dev, op_pll = &pll->vt; } - if (pll->flags & SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE) + if (pll->flags & CCS_PLL_FLAG_OP_PIX_CLOCK_PER_LANE) lane_op_clock_ratio = pll->csi2.lanes; else lane_op_clock_ratio = 1; @@ -416,12 +415,12 @@ int smiapp_pll_calculate(struct device *dev, pll->binning_vertical); switch (pll->bus_type) { - case SMIAPP_PLL_BUS_TYPE_CSI2: + case CCS_PLL_BUS_TYPE_CSI2: /* CSI transfers 2 bits per clock per lane; thus times 2 */ pll->pll_op_clk_freq_hz = pll->link_freq * 2 * (pll->csi2.lanes / lane_op_clock_ratio); break; - case SMIAPP_PLL_BUS_TYPE_PARALLEL: + case CCS_PLL_BUS_TYPE_PARALLEL: pll->pll_op_clk_freq_hz = pll->link_freq * pll->bits_per_pixel / DIV_ROUND_UP(pll->bits_per_pixel, pll->parallel.bus_width); @@ -461,9 +460,8 @@ int smiapp_pll_calculate(struct device *dev, for (pll->pre_pll_clk_div = min_pre_pll_clk_div; pll->pre_pll_clk_div <= max_pre_pll_clk_div; pll->pre_pll_clk_div += 2 - (pll->pre_pll_clk_div & 1)) { - rval = __smiapp_pll_calculate(dev, limits, op_limits, pll, - op_pll, mul, div, - lane_op_clock_ratio); + rval = __ccs_pll_calculate(dev, limits, op_limits, pll, op_pll, + mul, div, lane_op_clock_ratio); if (rval) continue; @@ -475,8 +473,8 @@ int smiapp_pll_calculate(struct device *dev, return rval; } -EXPORT_SYMBOL_GPL(smiapp_pll_calculate); +EXPORT_SYMBOL_GPL(ccs_pll_calculate); MODULE_AUTHOR("Sakari Ailus "); -MODULE_DESCRIPTION("Generic SMIA/SMIA++ PLL calculator"); +MODULE_DESCRIPTION("Generic MIPI CCS/SMIA/SMIA++ PLL calculator"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/smiapp-pll.h b/drivers/media/i2c/ccs-pll.h similarity index 68% rename from drivers/media/i2c/smiapp-pll.h rename to drivers/media/i2c/ccs-pll.h index bd6902f54539..88d641ee3fa1 100644 --- a/drivers/media/i2c/smiapp-pll.h +++ b/drivers/media/i2c/ccs-pll.h @@ -1,32 +1,33 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * drivers/media/i2c/smiapp-pll.h + * drivers/media/i2c/ccs-pll.h * - * Generic driver for SMIA/SMIA++ compliant camera modules + * Generic MIPI CCS/SMIA/SMIA++ PLL calculator * + * Copyright (C) 2020 Intel Corporation * Copyright (C) 2012 Nokia Corporation * Contact: Sakari Ailus */ -#ifndef SMIAPP_PLL_H -#define SMIAPP_PLL_H +#ifndef CCS_PLL_H +#define CCS_PLL_H /* CSI-2 or CCP-2 */ -#define SMIAPP_PLL_BUS_TYPE_CSI2 0x00 -#define SMIAPP_PLL_BUS_TYPE_PARALLEL 0x01 +#define CCS_PLL_BUS_TYPE_CSI2 0x00 +#define CCS_PLL_BUS_TYPE_PARALLEL 0x01 /* op pix clock is for all lanes in total normally */ -#define SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE (1 << 0) -#define SMIAPP_PLL_FLAG_NO_OP_CLOCKS (1 << 1) +#define CCS_PLL_FLAG_OP_PIX_CLOCK_PER_LANE (1 << 0) +#define CCS_PLL_FLAG_NO_OP_CLOCKS (1 << 1) -struct smiapp_pll_branch { +struct ccs_pll_branch { uint16_t sys_clk_div; uint16_t pix_clk_div; uint32_t sys_clk_freq_hz; uint32_t pix_clk_freq_hz; }; -struct smiapp_pll { +struct ccs_pll { /* input values */ uint8_t bus_type; union { @@ -51,14 +52,14 @@ struct smiapp_pll { uint16_t pll_multiplier; uint32_t pll_ip_clk_freq_hz; uint32_t pll_op_clk_freq_hz; - struct smiapp_pll_branch vt; - struct smiapp_pll_branch op; + struct ccs_pll_branch vt; + struct ccs_pll_branch op; uint32_t pixel_rate_csi; uint32_t pixel_rate_pixel_array; }; -struct smiapp_pll_branch_limits { +struct ccs_pll_branch_limits { uint16_t min_sys_clk_div; uint16_t max_sys_clk_div; uint32_t min_sys_clk_freq_hz; @@ -69,7 +70,7 @@ struct smiapp_pll_branch_limits { uint32_t max_pix_clk_freq_hz; }; -struct smiapp_pll_limits { +struct ccs_pll_limits { /* Strict PLL limits */ uint32_t min_ext_clk_freq_hz; uint32_t max_ext_clk_freq_hz; @@ -82,8 +83,8 @@ struct smiapp_pll_limits { uint32_t min_pll_op_freq_hz; uint32_t max_pll_op_freq_hz; - struct smiapp_pll_branch_limits vt; - struct smiapp_pll_branch_limits op; + struct ccs_pll_branch_limits vt; + struct ccs_pll_branch_limits op; /* Other relevant limits */ uint32_t min_line_length_pck_bin; @@ -92,8 +93,7 @@ struct smiapp_pll_limits { struct device; -int smiapp_pll_calculate(struct device *dev, - const struct smiapp_pll_limits *limits, - struct smiapp_pll *pll); +int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *limits, + struct ccs_pll *pll); -#endif /* SMIAPP_PLL_H */ +#endif /* CCS_PLL_H */ diff --git a/drivers/media/i2c/ccs/Kconfig b/drivers/media/i2c/ccs/Kconfig index b4f8b10da420..59f35b33ddc1 100644 --- a/drivers/media/i2c/ccs/Kconfig +++ b/drivers/media/i2c/ccs/Kconfig @@ -4,7 +4,7 @@ config VIDEO_CCS depends on I2C && VIDEO_V4L2 && HAVE_CLK select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API - select VIDEO_SMIAPP_PLL + select VIDEO_CCS_PLL select V4L2_FWNODE help This is a generic driver for MIPI CCS, SMIA++ and SMIA compliant diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 074b246538d2..6c8528e6ac96 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -363,7 +363,7 @@ static int ccs_read_frame_fmt(struct ccs_sensor *sensor) static int ccs_pll_configure(struct ccs_sensor *sensor) { - struct smiapp_pll *pll = &sensor->pll; + struct ccs_pll *pll = &sensor->pll; int rval; rval = ccs_write(sensor, VT_PIX_CLK_DIV, pll->vt.pix_clk_div); @@ -386,7 +386,7 @@ static int ccs_pll_configure(struct ccs_sensor *sensor) rval = ccs_write(sensor, REQUESTED_LINK_RATE, DIV_ROUND_UP(pll->op.sys_clk_freq_hz, 1000000 / 256 / 256)); - if (rval < 0 || sensor->pll.flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) + if (rval < 0 || sensor->pll.flags & CCS_PLL_FLAG_NO_OP_CLOCKS) return rval; rval = ccs_write(sensor, OP_PIX_CLK_DIV, pll->op.pix_clk_div); @@ -396,10 +396,10 @@ static int ccs_pll_configure(struct ccs_sensor *sensor) return ccs_write(sensor, OP_SYS_CLK_DIV, pll->op.sys_clk_div); } -static int ccs_pll_try(struct ccs_sensor *sensor, struct smiapp_pll *pll) +static int ccs_pll_try(struct ccs_sensor *sensor, struct ccs_pll *pll) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); - struct smiapp_pll_limits lim = { + struct ccs_pll_limits lim = { .min_pre_pll_clk_div = CCS_LIM(sensor, MIN_PRE_PLL_CLK_DIV), .max_pre_pll_clk_div = CCS_LIM(sensor, MAX_PRE_PLL_CLK_DIV), .min_pll_ip_freq_hz = CCS_LIM(sensor, MIN_PLL_IP_CLK_FREQ_MHZ), @@ -431,12 +431,12 @@ static int ccs_pll_try(struct ccs_sensor *sensor, struct smiapp_pll *pll) .min_line_length_pck = CCS_LIM(sensor, MIN_LINE_LENGTH_PCK), }; - return smiapp_pll_calculate(&client->dev, &lim, pll); + return ccs_pll_calculate(&client->dev, &lim, pll); } static int ccs_pll_update(struct ccs_sensor *sensor) { - struct smiapp_pll *pll = &sensor->pll; + struct ccs_pll *pll = &sensor->pll; int rval; pll->binning_horizontal = sensor->binning_horizontal; @@ -829,7 +829,7 @@ static void ccs_free_controls(struct ccs_sensor *sensor) static int ccs_get_mbus_formats(struct ccs_sensor *sensor) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); - struct smiapp_pll *pll = &sensor->pll; + struct ccs_pll *pll = &sensor->pll; u8 compressed_max_bpp = 0; unsigned int type, n; unsigned int i, pixel_order; @@ -3155,7 +3155,7 @@ static int ccs_probe(struct i2c_client *client) !CCS_LIM(sensor, MIN_OP_PIX_CLK_DIV) || !CCS_LIM(sensor, MAX_OP_PIX_CLK_DIV)) { /* No OP clock branch */ - sensor->pll.flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS; + sensor->pll.flags |= CCS_PLL_FLAG_NO_OP_CLOCKS; } else if (CCS_LIM(sensor, SCALING_CAPABILITY) != CCS_SCALING_CAPABILITY_NONE || CCS_LIM(sensor, DIGITAL_CROP_CAPABILITY) @@ -3172,7 +3172,7 @@ static int ccs_probe(struct i2c_client *client) sensor->scale_m = CCS_LIM(sensor, SCALER_N_MIN); /* prepare PLL configuration input values */ - sensor->pll.bus_type = SMIAPP_PLL_BUS_TYPE_CSI2; + sensor->pll.bus_type = CCS_PLL_BUS_TYPE_CSI2; sensor->pll.csi2.lanes = sensor->hwcfg.lanes; sensor->pll.ext_clk_freq_hz = sensor->hwcfg.ext_clk; sensor->pll.scale_n = CCS_LIM(sensor, SCALER_N_MIN); diff --git a/drivers/media/i2c/ccs/ccs-quirk.c b/drivers/media/i2c/ccs/ccs-quirk.c index 07c5733b4244..8b4fa60044b2 100644 --- a/drivers/media/i2c/ccs/ccs-quirk.c +++ b/drivers/media/i2c/ccs/ccs-quirk.c @@ -190,7 +190,7 @@ static int jt8ev1_post_streamoff(struct ccs_sensor *sensor) static int jt8ev1_init(struct ccs_sensor *sensor) { - sensor->pll.flags |= SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE; + sensor->pll.flags |= CCS_PLL_FLAG_OP_PIX_CLOCK_PER_LANE; return 0; } diff --git a/drivers/media/i2c/ccs/ccs.h b/drivers/media/i2c/ccs/ccs.h index f60d1801c469..c8a9f4ee093e 100644 --- a/drivers/media/i2c/ccs/ccs.h +++ b/drivers/media/i2c/ccs/ccs.h @@ -21,7 +21,7 @@ #include "ccs-quirk.h" #include "ccs-regs.h" #include "ccs-reg-access.h" -#include "../smiapp-pll.h" +#include "../ccs-pll.h" #include "smiapp-reg-defs.h" /* @@ -256,7 +256,7 @@ struct ccs_sensor { struct ccs_module_info minfo; - struct smiapp_pll pll; + struct ccs_pll pll; /* Is a default format supported for a given BPP? */ unsigned long *valid_link_freqs; From patchwork Tue Nov 24 09:32:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332638 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BBC69C8300C for ; Tue, 24 Nov 2020 09:38:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8CCCF20897 for ; Tue, 24 Nov 2020 09:38:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731514AbgKXJii (ORCPT ); Tue, 24 Nov 2020 04:38:38 -0500 Received: from retiisi.eu ([95.216.213.190]:45010 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731496AbgKXJif (ORCPT ); Tue, 24 Nov 2020 04:38:35 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 8A1CE634CA5; Tue, 24 Nov 2020 11:37:52 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 19/30] ccs-pll: Fix MODULE_LICENSE Date: Tue, 24 Nov 2020 11:32:15 +0200 Message-Id: <20201124093226.23737-20-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Change MODULE_LICENSE to "GPL v2" as indicated by the SPDX tag. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index d2f0f7375f5c..58f5fe7062ae 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -477,4 +477,4 @@ EXPORT_SYMBOL_GPL(ccs_pll_calculate); MODULE_AUTHOR("Sakari Ailus "); MODULE_DESCRIPTION("Generic MIPI CCS/SMIA/SMIA++ PLL calculator"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); From patchwork Tue Nov 24 09:32:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331704 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D0BBC64E7B for ; Tue, 24 Nov 2020 09:38:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 182462076B for ; Tue, 24 Nov 2020 09:38:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731534AbgKXJir (ORCPT ); Tue, 24 Nov 2020 04:38:47 -0500 Received: from retiisi.eu ([95.216.213.190]:45012 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731498AbgKXJig (ORCPT ); Tue, 24 Nov 2020 04:38:36 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 9FFD1634CA9; Tue, 24 Nov 2020 11:37:52 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 20/30] ccs: Change my e-mail address Date: Tue, 24 Nov 2020 11:32:16 +0200 Message-Id: <20201124093226.23737-21-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Use my @linux.intel.com e-mail address in the CCS driver. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs-pll.c | 4 ++-- drivers/media/i2c/ccs-pll.h | 2 +- drivers/media/i2c/ccs/ccs-core.c | 6 +++--- drivers/media/i2c/ccs/ccs-quirk.c | 2 +- drivers/media/i2c/ccs/ccs-quirk.h | 2 +- drivers/media/i2c/ccs/ccs-reg-access.c | 2 +- drivers/media/i2c/ccs/ccs-reg-access.h | 2 +- drivers/media/i2c/ccs/ccs.h | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index 58f5fe7062ae..0d57bac1599a 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -6,7 +6,7 @@ * * Copyright (C) 2020 Intel Corporation * Copyright (C) 2011--2012 Nokia Corporation - * Contact: Sakari Ailus + * Contact: Sakari Ailus */ #include @@ -475,6 +475,6 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *limits, } EXPORT_SYMBOL_GPL(ccs_pll_calculate); -MODULE_AUTHOR("Sakari Ailus "); +MODULE_AUTHOR("Sakari Ailus "); MODULE_DESCRIPTION("Generic MIPI CCS/SMIA/SMIA++ PLL calculator"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/i2c/ccs-pll.h b/drivers/media/i2c/ccs-pll.h index 88d641ee3fa1..07f7f9e8a1cc 100644 --- a/drivers/media/i2c/ccs-pll.h +++ b/drivers/media/i2c/ccs-pll.h @@ -6,7 +6,7 @@ * * Copyright (C) 2020 Intel Corporation * Copyright (C) 2012 Nokia Corporation - * Contact: Sakari Ailus + * Contact: Sakari Ailus */ #ifndef CCS_PLL_H diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 6c8528e6ac96..c53911b1c78b 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -6,7 +6,7 @@ * * Copyright (C) 2020 Intel Corporation * Copyright (C) 2010--2012 Nokia Corporation - * Contact: Sakari Ailus + * Contact: Sakari Ailus * * Based on smiapp driver by Vimarsh Zutshi * Based on jt8ev1.c by Vimarsh Zutshi @@ -1168,7 +1168,7 @@ static int ccs_setup_flash_strobe(struct ccs_sensor *sensor) * do not change, or if you do at least know what you're * doing. :-) * - * Sakari Ailus 2010-10-25 + * Sakari Ailus 2010-10-25 * * flash_strobe_length [us] / 10^6 = (tFlash_strobe_width_ctrl * / EXTCLK freq [Hz]) * flash_strobe_adjustment @@ -3357,7 +3357,7 @@ static void ccs_module_cleanup(void) module_init(ccs_module_init); module_exit(ccs_module_cleanup); -MODULE_AUTHOR("Sakari Ailus "); +MODULE_AUTHOR("Sakari Ailus "); MODULE_DESCRIPTION("Generic MIPI CCS/SMIA/SMIA++ camera sensor driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("smiapp"); diff --git a/drivers/media/i2c/ccs/ccs-quirk.c b/drivers/media/i2c/ccs/ccs-quirk.c index 8b4fa60044b2..4fe8c6f70579 100644 --- a/drivers/media/i2c/ccs/ccs-quirk.c +++ b/drivers/media/i2c/ccs/ccs-quirk.c @@ -6,7 +6,7 @@ * * Copyright (C) 2020 Intel Corporation * Copyright (C) 2011--2012 Nokia Corporation - * Contact: Sakari Ailus + * Contact: Sakari Ailus */ #include diff --git a/drivers/media/i2c/ccs/ccs-quirk.h b/drivers/media/i2c/ccs/ccs-quirk.h index 3e7779e2fc4b..6b4ec4beaba0 100644 --- a/drivers/media/i2c/ccs/ccs-quirk.h +++ b/drivers/media/i2c/ccs/ccs-quirk.h @@ -6,7 +6,7 @@ * * Copyright (C) 2020 Intel Corporation * Copyright (C) 2011--2012 Nokia Corporation - * Contact: Sakari Ailus + * Contact: Sakari Ailus */ #ifndef __CCS_QUIRK__ diff --git a/drivers/media/i2c/ccs/ccs-reg-access.c b/drivers/media/i2c/ccs/ccs-reg-access.c index 91ccbca11577..aad2727570ec 100644 --- a/drivers/media/i2c/ccs/ccs-reg-access.c +++ b/drivers/media/i2c/ccs/ccs-reg-access.c @@ -6,7 +6,7 @@ * * Copyright (C) 2020 Intel Corporation * Copyright (C) 2011--2012 Nokia Corporation - * Contact: Sakari Ailus + * Contact: Sakari Ailus */ #include diff --git a/drivers/media/i2c/ccs/ccs-reg-access.h b/drivers/media/i2c/ccs/ccs-reg-access.h index 5f6ff9c57698..cfad2e520fe2 100644 --- a/drivers/media/i2c/ccs/ccs-reg-access.h +++ b/drivers/media/i2c/ccs/ccs-reg-access.h @@ -6,7 +6,7 @@ * * Copyright (C) 2020 Intel Corporation * Copyright (C) 2011--2012 Nokia Corporation - * Contact: Sakari Ailus + * Contact: Sakari Ailus */ #ifndef SMIAPP_REGS_H diff --git a/drivers/media/i2c/ccs/ccs.h b/drivers/media/i2c/ccs/ccs.h index c8a9f4ee093e..6b07e4143ff0 100644 --- a/drivers/media/i2c/ccs/ccs.h +++ b/drivers/media/i2c/ccs/ccs.h @@ -6,7 +6,7 @@ * * Copyright (C) 2020 Intel Corporation * Copyright (C) 2010--2012 Nokia Corporation - * Contact: Sakari Ailus + * Contact: Sakari Ailus */ #ifndef __CCS_H__ From patchwork Tue Nov 24 09:32:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331707 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BDB8FC56201 for ; Tue, 24 Nov 2020 09:38:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 704532076B for ; Tue, 24 Nov 2020 09:38:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731525AbgKXJio (ORCPT ); Tue, 24 Nov 2020 04:38:44 -0500 Received: from retiisi.eu ([95.216.213.190]:44964 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731499AbgKXJig (ORCPT ); Tue, 24 Nov 2020 04:38:36 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id B66A2634CAA; Tue, 24 Nov 2020 11:37:52 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 21/30] =?utf-8?q?ccs=3A_Allow_range_in_between_I=C2=B2C_re?= =?utf-8?q?tries?= Date: Tue, 24 Nov 2020 11:32:17 +0200 Message-Id: <20201124093226.23737-22-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Make the delay between I²C access retries a range between 1 and 2 ms. Also make the number of retries 10 instead of 5, in order not to reduce the total amount of time. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-reg-access.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-reg-access.c b/drivers/media/i2c/ccs/ccs-reg-access.c index aad2727570ec..79efed5e0dad 100644 --- a/drivers/media/i2c/ccs/ccs-reg-access.c +++ b/drivers/media/i2c/ccs/ccs-reg-access.c @@ -256,7 +256,7 @@ int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val) put_unaligned_be16(CCS_REG_ADDR(reg), data); put_unaligned_be32(val << (8 * (sizeof(val) - len)), data + 2); - for (retries = 0; retries < 5; retries++) { + for (retries = 0; retries < 10; retries++) { /* * Due to unknown reason sensor stops responding. This * loop is a temporaty solution until the root cause @@ -271,7 +271,7 @@ int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val) return 0; } - usleep_range(2000, 2000); + usleep_range(1000, 2000); } dev_err(&client->dev, From patchwork Tue Nov 24 09:32:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331711 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 790A4C83017 for ; Tue, 24 Nov 2020 09:38:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 445EE20888 for ; Tue, 24 Nov 2020 09:38:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731535AbgKXJis (ORCPT ); Tue, 24 Nov 2020 04:38:48 -0500 Received: from retiisi.eu ([95.216.213.190]:45026 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731502AbgKXJig (ORCPT ); Tue, 24 Nov 2020 04:38:36 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id CB9A2634CBD; Tue, 24 Nov 2020 11:37:52 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 22/30] ccs: Add support for manufacturer regs from sensor and module files Date: Tue, 24 Nov 2020 11:32:18 +0200 Message-Id: <20201124093226.23737-23-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Write manufacturer specific registers (MSRs) from file to the sensor on sensor power-on. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 23 +++++++ drivers/media/i2c/ccs/ccs-reg-access.c | 94 ++++++++++++++++++++------ drivers/media/i2c/ccs/ccs-reg-access.h | 2 + 3 files changed, 97 insertions(+), 22 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index c53911b1c78b..5e01f22608d7 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -1278,6 +1278,21 @@ static int ccs_setup_flash_strobe(struct ccs_sensor *sensor) * Power management */ +static int ccs_write_msr_regs(struct ccs_sensor *sensor) +{ + int rval; + + rval = ccs_write_data_regs(sensor, + sensor->sdata.sensor_manufacturer_regs, + sensor->sdata.num_sensor_manufacturer_regs); + if (rval) + return rval; + + return ccs_write_data_regs(sensor, + sensor->mdata.module_manufacturer_regs, + sensor->mdata.num_module_manufacturer_regs); +} + static int ccs_power_on(struct device *dev) { struct v4l2_subdev *subdev = dev_get_drvdata(dev); @@ -1383,6 +1398,10 @@ static int ccs_power_on(struct device *dev) if (rval < 0) goto out_cci_addr_fail; + rval = ccs_write_msr_regs(sensor); + if (rval) + goto out_cci_addr_fail; + rval = ccs_call_quirk(sensor, post_poweron); if (rval) { dev_err(dev, "post_poweron quirks failed\n"); @@ -3220,6 +3239,10 @@ static int ccs_probe(struct i2c_client *client) if (rval < 0) goto out_media_entity_cleanup; + rval = ccs_write_msr_regs(sensor); + if (rval) + goto out_media_entity_cleanup; + pm_runtime_set_active(&client->dev); pm_runtime_get_noresume(&client->dev); pm_runtime_enable(&client->dev); diff --git a/drivers/media/i2c/ccs/ccs-reg-access.c b/drivers/media/i2c/ccs/ccs-reg-access.c index 79efed5e0dad..918bc98c226f 100644 --- a/drivers/media/i2c/ccs/ccs-reg-access.c +++ b/drivers/media/i2c/ccs/ccs-reg-access.c @@ -236,12 +236,38 @@ int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val) return ccs_read_addr_raw(sensor, reg, val, false, true, false); } +static int ccs_write_retry(struct i2c_client *client, struct i2c_msg *msg) +{ + unsigned int retries; + int r; + + for (retries = 0; retries < 10; retries++) { + /* + * Due to unknown reason sensor stops responding. This + * loop is a temporaty solution until the root cause + * is found. + */ + r = i2c_transfer(client->adapter, msg, 1); + if (r != 1) { + usleep_range(1000, 2000); + continue; + } + + if (retries) + dev_err(&client->dev, + "sensor i2c stall encountered. retries: %d\n", + retries); + return 0; + } + + return r; +} + int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); struct i2c_msg msg; unsigned char data[6]; - unsigned int retries; unsigned int len = ccs_reg_width(reg); int r; @@ -256,27 +282,11 @@ int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val) put_unaligned_be16(CCS_REG_ADDR(reg), data); put_unaligned_be32(val << (8 * (sizeof(val) - len)), data + 2); - for (retries = 0; retries < 10; retries++) { - /* - * Due to unknown reason sensor stops responding. This - * loop is a temporaty solution until the root cause - * is found. - */ - r = i2c_transfer(client->adapter, &msg, 1); - if (r == 1) { - if (retries) - dev_err(&client->dev, - "sensor i2c stall encountered. retries: %d\n", - retries); - return 0; - } - - usleep_range(1000, 2000); - } - - dev_err(&client->dev, - "wrote 0x%x to offset 0x%x error %d\n", val, - CCS_REG_ADDR(reg), r); + r = ccs_write_retry(client, &msg); + if (r) + dev_err(&client->dev, + "wrote 0x%x to offset 0x%x error %d\n", val, + CCS_REG_ADDR(reg), r); return r; } @@ -297,3 +307,43 @@ int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val) return ccs_write_addr_no_quirk(sensor, reg, val); } + +#define MAX_WRITE_LEN 32U + +int ccs_write_data_regs(struct ccs_sensor *sensor, struct ccs_reg *regs, + size_t num_regs) +{ + struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); + unsigned char buf[2 + MAX_WRITE_LEN]; + struct i2c_msg msg = { + .addr = client->addr, + .buf = buf, + }; + size_t i; + + for (i = 0; i < num_regs; i++, regs++) { + unsigned char *regdata = regs->value; + unsigned int j; + + for (j = 0; j < regs->len; + j += msg.len - 2, regdata += msg.len - 2) { + int rval; + + msg.len = min(regs->len - j, MAX_WRITE_LEN); + + put_unaligned_be16(regs->addr + j, buf); + memcpy(buf + 2, regdata, msg.len); + msg.len += 2; + + rval = ccs_write_retry(client, &msg); + if (rval) { + dev_err(&client->dev, + "error writing %u octets to address 0x%4.4x\n", + msg.len, regs->addr + j); + return rval; + } + } + } + + return 0; +} diff --git a/drivers/media/i2c/ccs/ccs-reg-access.h b/drivers/media/i2c/ccs/ccs-reg-access.h index cfad2e520fe2..78c43f92d99a 100644 --- a/drivers/media/i2c/ccs/ccs-reg-access.h +++ b/drivers/media/i2c/ccs/ccs-reg-access.h @@ -27,6 +27,8 @@ int ccs_read_addr_8only(struct ccs_sensor *sensor, u32 reg, u32 *val); int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val); int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val); int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val); +int ccs_write_data_regs(struct ccs_sensor *sensor, struct ccs_reg *regs, + size_t num_regs); unsigned int ccs_reg_width(u32 reg); u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val); From patchwork Tue Nov 24 09:32:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332636 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DCCEC83014 for ; Tue, 24 Nov 2020 09:38:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 42BD72073C for ; Tue, 24 Nov 2020 09:38:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731524AbgKXJin (ORCPT ); Tue, 24 Nov 2020 04:38:43 -0500 Received: from retiisi.eu ([95.216.213.190]:45030 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731501AbgKXJig (ORCPT ); Tue, 24 Nov 2020 04:38:36 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id E2AD2634CBE; Tue, 24 Nov 2020 11:37:52 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 23/30] ccs: Use static data read-only registers Date: Tue, 24 Nov 2020 11:32:19 +0200 Message-Id: <20201124093226.23737-24-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Access read-only registers from CCS static data. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-reg-access.c | 64 ++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-reg-access.c b/drivers/media/i2c/ccs/ccs-reg-access.c index 918bc98c226f..3de863e3bf26 100644 --- a/drivers/media/i2c/ccs/ccs-reg-access.c +++ b/drivers/media/i2c/ccs/ccs-reg-access.c @@ -198,11 +198,67 @@ static int __ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val, return 0; } +static int __ccs_read_data(struct ccs_reg *regs, size_t num_regs, + u32 reg, u32 *val) +{ + unsigned int width = ccs_reg_width(reg); + size_t i; + + for (i = 0; i < num_regs; i++, regs++) { + uint8_t *data; + + if (regs->addr + regs->len < CCS_REG_ADDR(reg) + width) + continue; + + if (regs->addr > CCS_REG_ADDR(reg)) + break; + + data = ®s->value[CCS_REG_ADDR(reg) - regs->addr]; + + switch (width) { + case sizeof(uint8_t): + *val = *data; + break; + case sizeof(uint16_t): + *val = get_unaligned_be16(data); + break; + case sizeof(uint32_t): + *val = get_unaligned_be32(data); + break; + default: + WARN_ON(1); + return -EINVAL; + } + + return 0; + } + + return -ENOENT; +} + +static int ccs_read_data(struct ccs_sensor *sensor, u32 reg, u32 *val) +{ + if (!__ccs_read_data(sensor->sdata.sensor_read_only_regs, + sensor->sdata.num_sensor_read_only_regs, + reg, val)) + return 0; + + return __ccs_read_data(sensor->mdata.module_read_only_regs, + sensor->mdata.num_module_read_only_regs, + reg, val); +} + static int ccs_read_addr_raw(struct ccs_sensor *sensor, u32 reg, u32 *val, - bool force8, bool quirk, bool conv) + bool force8, bool quirk, bool conv, bool data) { int rval; + if (data) { + rval = ccs_read_data(sensor, reg, val); + if (!rval) + return 0; + } + if (quirk) { *val = 0; rval = ccs_call_quirk(sensor, reg_access, false, ®, val); @@ -223,17 +279,17 @@ static int ccs_read_addr_raw(struct ccs_sensor *sensor, u32 reg, u32 *val, int ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val) { - return ccs_read_addr_raw(sensor, reg, val, false, true, true); + return ccs_read_addr_raw(sensor, reg, val, false, true, true, true); } int ccs_read_addr_8only(struct ccs_sensor *sensor, u32 reg, u32 *val) { - return ccs_read_addr_raw(sensor, reg, val, true, true, true); + return ccs_read_addr_raw(sensor, reg, val, true, true, true, true); } int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val) { - return ccs_read_addr_raw(sensor, reg, val, false, true, false); + return ccs_read_addr_raw(sensor, reg, val, false, true, false, true); } static int ccs_write_retry(struct i2c_client *client, struct i2c_msg *msg) From patchwork Tue Nov 24 09:32:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331705 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 140C3C83013 for ; Tue, 24 Nov 2020 09:38:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D1A4520897 for ; Tue, 24 Nov 2020 09:38:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731523AbgKXJin (ORCPT ); Tue, 24 Nov 2020 04:38:43 -0500 Received: from retiisi.eu ([95.216.213.190]:45006 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731324AbgKXJih (ORCPT ); Tue, 24 Nov 2020 04:38:37 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 04106634CBF; Tue, 24 Nov 2020 11:37:53 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 24/30] ccs: Clean up runtime PM usage Date: Tue, 24 Nov 2020 11:32:20 +0200 Message-Id: <20201124093226.23737-25-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org If pm_runtime_get_sync() fails, there's no need to set the device active again. Also, in the same case to return the usage_count to zero, pm_runtime_put_noidle() is enough. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 5e01f22608d7..c3023570a620 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -1625,8 +1625,6 @@ static int ccs_pm_get_init(struct ccs_sensor *sensor) rval = pm_runtime_get_sync(&client->dev); if (rval < 0) { - if (rval != -EBUSY && rval != -EAGAIN) - pm_runtime_set_active(&client->dev); pm_runtime_put_noidle(&client->dev); return rval; @@ -2842,9 +2840,8 @@ static int __maybe_unused ccs_suspend(struct device *dev) rval = pm_runtime_get_sync(dev); if (rval < 0) { - if (rval != -EBUSY && rval != -EAGAIN) - pm_runtime_set_active(&client->dev); - pm_runtime_put(dev); + pm_runtime_put_noidle(dev); + return -EAGAIN; } From patchwork Tue Nov 24 09:32:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332635 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C08BC8300E for ; Tue, 24 Nov 2020 09:38:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B823B2073C for ; Tue, 24 Nov 2020 09:38:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731515AbgKXJij (ORCPT ); Tue, 24 Nov 2020 04:38:39 -0500 Received: from retiisi.eu ([95.216.213.190]:45032 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731503AbgKXJih (ORCPT ); Tue, 24 Nov 2020 04:38:37 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 1C186634CC0; Tue, 24 Nov 2020 11:37:53 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 25/30] ccs: Wrap long lines, unwrap short ones Date: Tue, 24 Nov 2020 11:32:21 +0200 Message-Id: <20201124093226.23737-26-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Over the years (and renaming) some lines that may well be wrapped ended up being over 80 characters, likewise there are shorter lines that can be merged. Do that. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 45 +++++++++++++------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index c3023570a620..863295b8fb5c 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -657,8 +657,7 @@ static int ccs_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_HBLANK: rval = ccs_write(sensor, LINE_LENGTH_PCK, - sensor->pixel_array->crop[ - CCS_PA_PAD_SRC].width + sensor->pixel_array->crop[CCS_PA_PAD_SRC].width + ctrl->val); break; @@ -989,15 +988,13 @@ static void ccs_update_blanking(struct ccs_sensor *sensor) min = max_t(int, CCS_LIM(sensor, MIN_FRAME_BLANKING_LINES), - min_fll - - sensor->pixel_array->crop[CCS_PA_PAD_SRC].height); + min_fll - sensor->pixel_array->crop[CCS_PA_PAD_SRC].height); max = max_fll - sensor->pixel_array->crop[CCS_PA_PAD_SRC].height; __v4l2_ctrl_modify_range(vblank, min, max, vblank->step, min); min = max_t(int, - min_llp - - sensor->pixel_array->crop[CCS_PA_PAD_SRC].width, + min_llp - sensor->pixel_array->crop[CCS_PA_PAD_SRC].width, min_lbp); max = max_llp - sensor->pixel_array->crop[CCS_PA_PAD_SRC].width; @@ -1784,7 +1781,8 @@ static void ccs_get_crop_compose(struct v4l2_subdev *subdev, } else { if (crops) { for (i = 0; i < subdev->entity.num_pads; i++) - crops[i] = v4l2_subdev_get_try_crop(subdev, cfg, i); + crops[i] = v4l2_subdev_get_try_crop(subdev, + cfg, i); } if (comps) *comps = v4l2_subdev_get_try_compose(subdev, cfg, @@ -1809,8 +1807,7 @@ static void ccs_propagate(struct v4l2_subdev *subdev, comp->height = crops[CCS_PAD_SINK]->height; if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { if (ssd == sensor->scaler) { - sensor->scale_m = - CCS_LIM(sensor, SCALER_N_MIN); + sensor->scale_m = CCS_LIM(sensor, SCALER_N_MIN); sensor->scaling_mode = CCS_SCALING_MODE_NO_SCALING; } else if (ssd == sensor->binner) { @@ -2236,9 +2233,11 @@ static int ccs_set_crop(struct v4l2_subdev *subdev, if (sel->pad == ssd->sink_pad) { _r.left = 0; _r.top = 0; - _r.width = v4l2_subdev_get_try_format(subdev, cfg, sel->pad) + _r.width = v4l2_subdev_get_try_format(subdev, cfg, + sel->pad) ->width; - _r.height = v4l2_subdev_get_try_format(subdev, cfg, sel->pad) + _r.height = v4l2_subdev_get_try_format(subdev, cfg, + sel->pad) ->height; src_size = &_r; } else { @@ -2356,11 +2355,9 @@ static int ccs_set_selection(struct v4l2_subdev *subdev, sel->r.width = CCS_ALIGN_DIM(sel->r.width, sel->flags); sel->r.height = CCS_ALIGN_DIM(sel->r.height, sel->flags); - sel->r.width = max_t(unsigned int, - CCS_LIM(sensor, MIN_X_OUTPUT_SIZE), + sel->r.width = max_t(unsigned int, CCS_LIM(sensor, MIN_X_OUTPUT_SIZE), sel->r.width); - sel->r.height = max_t(unsigned int, - CCS_LIM(sensor, MIN_Y_OUTPUT_SIZE), + sel->r.height = max_t(unsigned int, CCS_LIM(sensor, MIN_Y_OUTPUT_SIZE), sel->r.height); switch (sel->target) { @@ -2613,8 +2610,7 @@ static int ccs_identify_module(struct ccs_sensor *sensor) dev_warn(&client->dev, "no quirks for this module; let's hope it's fully compliant\n"); - dev_dbg(&client->dev, "the sensor is called %s\n", - minfo->name); + dev_dbg(&client->dev, "the sensor is called %s\n", minfo->name); return 0; } @@ -2634,19 +2630,15 @@ static int ccs_register_subdev(struct ccs_sensor *sensor, if (!sink_ssd) return 0; - rval = media_entity_pads_init(&ssd->sd.entity, - ssd->npads, ssd->pads); + rval = media_entity_pads_init(&ssd->sd.entity, ssd->npads, ssd->pads); if (rval) { - dev_err(&client->dev, - "media_entity_pads_init failed\n"); + dev_err(&client->dev, "media_entity_pads_init failed\n"); return rval; } - rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, - &ssd->sd); + rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, &ssd->sd); if (rval) { - dev_err(&client->dev, - "v4l2_device_register_subdev failed\n"); + dev_err(&client->dev, "v4l2_device_register_subdev failed\n"); return rval; } @@ -2654,8 +2646,7 @@ static int ccs_register_subdev(struct ccs_sensor *sensor, &sink_ssd->sd.entity, sink_pad, link_flags); if (rval) { - dev_err(&client->dev, - "media_create_pad_link failed\n"); + dev_err(&client->dev, "media_create_pad_link failed\n"); v4l2_device_unregister_subdev(&ssd->sd); return rval; } From patchwork Tue Nov 24 09:32:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331712 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CF139C83011 for ; Tue, 24 Nov 2020 09:38:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 775322073C for ; Tue, 24 Nov 2020 09:38:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731518AbgKXJil (ORCPT ); Tue, 24 Nov 2020 04:38:41 -0500 Received: from retiisi.eu ([95.216.213.190]:45008 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731505AbgKXJih (ORCPT ); Tue, 24 Nov 2020 04:38:37 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 385DC634CC1; Tue, 24 Nov 2020 11:37:53 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 26/30] =?utf-8?q?ccs=3A_Use_longer_pre-I=C2=B2C_sleep_for_?= =?utf-8?q?CCS_compliant_devices?= Date: Tue, 24 Nov 2020 11:32:22 +0200 Message-Id: <20201124093226.23737-27-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Longer idle period is required on I²C bus before the first transaction after lifting xshutdown. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 863295b8fb5c..5014aa0d7969 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -1300,6 +1300,7 @@ static int ccs_power_on(struct device *dev) */ struct ccs_sensor *sensor = container_of(ssd, struct ccs_sensor, ssds[0]); + const struct ccs_device *ccsdev = device_get_match_data(dev); unsigned int sleep; int rval; @@ -1320,7 +1321,11 @@ static int ccs_power_on(struct device *dev) gpiod_set_value(sensor->reset, 0); gpiod_set_value(sensor->xshutdown, 1); - sleep = SMIAPP_RESET_DELAY(sensor->hwcfg.ext_clk); + if (ccsdev->flags & CCS_DEVICE_FLAG_IS_SMIA) + sleep = SMIAPP_RESET_DELAY(sensor->hwcfg.ext_clk); + else + sleep = 5000; + usleep_range(sleep, sleep); /* From patchwork Tue Nov 24 09:32:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332631 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 792FCC63798 for ; Tue, 24 Nov 2020 09:38:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 493152076B for ; Tue, 24 Nov 2020 09:38:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731517AbgKXJil (ORCPT ); Tue, 24 Nov 2020 04:38:41 -0500 Received: from retiisi.eu ([95.216.213.190]:45010 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731508AbgKXJih (ORCPT ); Tue, 24 Nov 2020 04:38:37 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 51C3F634CCA; Tue, 24 Nov 2020 11:37:53 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 27/30] ccs: Remove unnecessary delays from power-up sequence Date: Tue, 24 Nov 2020 11:32:23 +0200 Message-Id: <20201124093226.23737-28-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org SMIA nor CCS need these delays; remove them. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 5014aa0d7969..89dc09587211 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -1309,14 +1309,12 @@ static int ccs_power_on(struct device *dev) dev_err(dev, "failed to enable vana regulator\n"); return rval; } - usleep_range(1000, 1000); rval = clk_prepare_enable(sensor->ext_clk); if (rval < 0) { dev_dbg(dev, "failed to enable xclk\n"); goto out_xclk_fail; } - usleep_range(1000, 1000); gpiod_set_value(sensor->reset, 0); gpiod_set_value(sensor->xshutdown, 1); From patchwork Tue Nov 24 09:32:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331710 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EE5B6C83012 for ; Tue, 24 Nov 2020 09:38:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A52092076B for ; Tue, 24 Nov 2020 09:38:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731521AbgKXJil (ORCPT ); Tue, 24 Nov 2020 04:38:41 -0500 Received: from retiisi.eu ([95.216.213.190]:45028 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731507AbgKXJih (ORCPT ); Tue, 24 Nov 2020 04:38:37 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 6669F634CCC; Tue, 24 Nov 2020 11:37:53 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 28/30] dt-bindings: mipi,ccs: Don't mention vana voltage Date: Tue, 24 Nov 2020 11:32:24 +0200 Message-Id: <20201124093226.23737-29-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org It was mentioned vana voltage is typically 2,8 volts. This is truly sensor dependent, and nowadays 2,8 volts is a lot. Signed-off-by: Sakari Ailus Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml b/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml index 1d90767a6196..51426a950414 100644 --- a/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml +++ b/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml @@ -37,8 +37,7 @@ properties: maxItems: 1 vana-supply: - description: Analogue voltage supply (VANA), typically 2,8 volts (sensor - dependent). + description: Analogue voltage supply (VANA), sensor dependent. maxItems: 1 clocks: From patchwork Tue Nov 24 09:32:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 332633 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 33590C8300F for ; Tue, 24 Nov 2020 09:38:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E87D22076B for ; Tue, 24 Nov 2020 09:38:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731516AbgKXJij (ORCPT ); Tue, 24 Nov 2020 04:38:39 -0500 Received: from retiisi.eu ([95.216.213.190]:44968 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731491AbgKXJii (ORCPT ); Tue, 24 Nov 2020 04:38:38 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 778DE634CCD; Tue, 24 Nov 2020 11:37:53 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 29/30] dt-bindings: mipi,ccs: Add vcore and vio supplies Date: Tue, 24 Nov 2020 11:32:25 +0200 Message-Id: <20201124093226.23737-30-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Vcore and vio supplies are also part of the spec and used by many sensors. Do not specify the voltages as they are generally sensor dependent. Signed-off-by: Sakari Ailus Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml b/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml index 51426a950414..d94bd67ccea1 100644 --- a/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml +++ b/Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml @@ -40,6 +40,14 @@ properties: description: Analogue voltage supply (VANA), sensor dependent. maxItems: 1 + vcore-supply: + description: Core voltage supply (VCore), sensor dependent. + maxItems: 1 + + vio-supply: + description: I/O voltage supply (VIO), sensor dependent. + maxItems: 1 + clocks: description: External clock to the sensor. maxItems: 1 From patchwork Tue Nov 24 09:32:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 331713 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4F6D3C83010 for ; Tue, 24 Nov 2020 09:38:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1D5312073C for ; Tue, 24 Nov 2020 09:38:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731491AbgKXJil (ORCPT ); Tue, 24 Nov 2020 04:38:41 -0500 Received: from retiisi.eu ([95.216.213.190]:45026 "EHLO hillosipuli.retiisi.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731513AbgKXJii (ORCPT ); Tue, 24 Nov 2020 04:38:38 -0500 Received: from lanttu.localdomain (lanttu-e.localdomain [192.168.1.64]) by hillosipuli.retiisi.eu (Postfix) with ESMTP id 89049634CCF; Tue, 24 Nov 2020 11:37:53 +0200 (EET) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: hverkuil@xs4all.nl, mchehab@kernel.org Subject: [PATCH 30/30] ccs: Use all regulators Date: Tue, 24 Nov 2020 11:32:26 +0200 Message-Id: <20201124093226.23737-31-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201124093226.23737-1-sakari.ailus@linux.intel.com> References: <20201124093226.23737-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Use regulators vio and vcore besides vana. The regulators were always there but on many boards they've been hard wired. Control them explicitly now. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 30 +++++++++++++++++++++++------- drivers/media/i2c/ccs/ccs.h | 2 +- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 89dc09587211..4447ca367a84 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -65,6 +65,8 @@ struct ccs_device { unsigned char flags; }; +static const char * const ccs_regulators[] = { "vcore", "vio", "vana" }; + /* * * Dynamic Capability Identification @@ -1304,7 +1306,8 @@ static int ccs_power_on(struct device *dev) unsigned int sleep; int rval; - rval = regulator_enable(sensor->vana); + rval = regulator_bulk_enable(ARRAY_SIZE(ccs_regulators), + sensor->regulators); if (rval) { dev_err(dev, "failed to enable vana regulator\n"); return rval; @@ -1416,7 +1419,8 @@ static int ccs_power_on(struct device *dev) clk_disable_unprepare(sensor->ext_clk); out_xclk_fail: - regulator_disable(sensor->vana); + regulator_bulk_disable(ARRAY_SIZE(ccs_regulators), + sensor->regulators); return rval; } @@ -1442,7 +1446,8 @@ static int ccs_power_off(struct device *dev) gpiod_set_value(sensor->xshutdown, 0); clk_disable_unprepare(sensor->ext_clk); usleep_range(5000, 5000); - regulator_disable(sensor->vana); + regulator_bulk_disable(ARRAY_SIZE(ccs_regulators), + sensor->regulators); sensor->streaming = false; return 0; @@ -2981,10 +2986,21 @@ static int ccs_probe(struct i2c_client *client) v4l2_i2c_subdev_init(&sensor->src->sd, client, &ccs_ops); sensor->src->sd.internal_ops = &ccs_internal_src_ops; - sensor->vana = devm_regulator_get(&client->dev, "vana"); - if (IS_ERR(sensor->vana)) { - dev_err(&client->dev, "could not get regulator for vana\n"); - return PTR_ERR(sensor->vana); + sensor->regulators = devm_kcalloc(&client->dev, + ARRAY_SIZE(ccs_regulators), + sizeof(*sensor->regulators), + GFP_KERNEL); + if (!sensor->regulators) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(ccs_regulators); i++) + sensor->regulators[i].supply = ccs_regulators[i]; + + rval = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(ccs_regulators), + sensor->regulators); + if (rval) { + dev_err(&client->dev, "could not get regulators\n"); + return rval; } sensor->ext_clk = devm_clk_get(&client->dev, NULL); diff --git a/drivers/media/i2c/ccs/ccs.h b/drivers/media/i2c/ccs/ccs.h index 6b07e4143ff0..356b87c33405 100644 --- a/drivers/media/i2c/ccs/ccs.h +++ b/drivers/media/i2c/ccs/ccs.h @@ -223,7 +223,7 @@ struct ccs_sensor { struct ccs_subdev *scaler; struct ccs_subdev *pixel_array; struct ccs_hwconfig hwcfg; - struct regulator *vana; + struct regulator_bulk_data *regulators; struct clk *ext_clk; struct gpio_desc *xshutdown; struct gpio_desc *reset;